Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches: [main]
pull_request:

# CI runs the same `make` targets a contributor runs locally, so the two can
# never drift. The toolchain is built from gnolang/gno master: this repo is the
# first thing a newcomer runs, so it has to work against what they install today.
jobs:
test:
runs-on: ubuntu-latest
Expand All @@ -23,7 +26,7 @@ jobs:
echo "$HOME/.gno/bin" >> "$GITHUB_PATH"

- name: Test
run: gno test .
run: make test

- name: Lint
run: gno lint .
run: make lint
52 changes: 52 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# AGENTS.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could enhance agents.md to index main documentations and document main error users could encounter if they modify that realm (as you did with gno is not go). We could modify the README in that direction (you can modify that realm, agent.md is made to help beginner // you can use an agent to create your first realm).

Close to other tools/skills we already made but here self contained, minimal and beginner oriented, which could work with "cheap model". No need to make something super fancy IMO, ~10/50 lines would do the work.

Example: missing realm param when calling with maketx call, render is not displaying (if putting incorrect names), else...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took the indexing half, dropped the expansion. "Gno is not Go" is now six links (realms, interrealm, Go/Gno compatibility, stdlibs, testing, effective-gno) in place of five hand-written bullets: same length, nothing to keep in sync. The error catalogue you describe is worth having, but in the docs, not in a 52-line file that goes stale silently.


Guide for coding agents (and humans in a hurry) working in this repository.
It is deliberately tiny, like the repo.

## What this is

One Gno realm, `hello.gno`, plus its test. `gnomod.toml` declares the on-chain
path it deploys to. Nothing else. Keep it that way: this repo's whole job is to
be understandable in five minutes.

## Commands

```sh
make # list every target
make install # build the gno toolchain into $HOME/.gno/bin (then add it to PATH)
make dev # local chain + web UI on http://localhost:8888, reloads on save
make test # gno test .
make lint # gno lint .
make fmt # gno fmt -w .
```

`make test lint` is the bar for any change. CI runs those two targets against a
`gno` built from `gnolang/gno` master, while yours is whatever you installed
last, so re-run `make install` before trusting a green local run.

## Gno is not Go

Close enough that Go habits compile in your head and fail on the chain. Read,
do not guess:

- [Realms](https://docs.gno.land/resources/realms): `Render` and realm state
- [Interrealm](https://docs.gno.land/resources/gno-interrealm): crossing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

functions, the `realm` parameter, `cross(...)`
- [Go/Gno compatibility](https://docs.gno.land/resources/go-gno-compatibility):
what the language keeps, drops and adds
- [Standard libraries](https://docs.gno.land/resources/gno-stdlibs): the subset
that exists, and `chain/*` in place of Go's runtime packages
- [Testing](https://docs.gno.land/resources/gno-testing): including why an
`Example*` function needs an `// Output:` block
- [Effective Gno](https://docs.gno.land/resources/effective-gno): idioms worth
copying

## Tooling worth having

- [`gnoverse/gno-mcp`](https://github.com/gnoverse/gno-mcp): MCP server plus
agent skills for gno.land. Read and render realms, evaluate expressions,
deploy to a testnet, audit a realm. Pre-release, and writes are gated to
dev/testnet.
- [`gnoverse/gnopls`](https://github.com/gnoverse/gnopls): the Gno language
server, for editors. Setup in
[Editor Setup](https://docs.gno.land/builders/editor-setup).
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See [AGENTS.md](./AGENTS.md).
29 changes: 22 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
.PHONY: install dev test
# getting-started. Run `make` (or `make help`) to see every target.

install:
GNO ?= gno
GNODEV ?= gnodev

.DEFAULT_GOAL := help
.PHONY: help install dev test lint fmt

help: ## list the available targets
@awk 'BEGIN{FS=":.*?## "} /^[a-zA-Z_-]+:.*?## /{printf " %-8s %s\n",$$1,$$2}' $(MAKEFILE_LIST)

install: ## build the gno toolchain into $HOME/.gno/bin
# --from-source is required: the installer's prebuilt-binary mode looks for
# v* release tags, and gnolang/gno only publishes chain/* tags today.
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/gnolang/gno/master/misc/install.sh | sh -s -- --from-source
@echo '>> binaries are in $$HOME/.gno/bin — add it to your PATH:'
@echo '>> binaries are in $$HOME/.gno/bin, add it to your PATH:'
@echo ' export PATH="$$HOME/.gno/bin:$$PATH"'

dev:
gnodev .
dev: ## run a local chain + web UI on http://localhost:8888, reloading on save
$(GNODEV) .

test: ## run the tests
$(GNO) test .

lint: ## catch what only the chain would otherwise catch
$(GNO) lint .

test:
gno test .
fmt: ## format every .gno file in place
$(GNO) fmt -w .
76 changes: 41 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
# Getting Started with Gno

This repository is intentionally kept minimal and simple. It's designed to help
you get your first experience with Gno in under five minutes, focusing on the
most common tools and basic concepts.

If you're already familiar with Gno or looking for a more comprehensive setup,
check out the "Next Steps" section below for links to more advanced resources.
One Gno realm, its test, and a Makefile, small enough to read in five minutes.
Everything this file does not explain is in the [Gno documentation](https://docs.gno.land).

## Quick Start

Expand All @@ -14,50 +10,60 @@ check out the "Next Steps" section below for links to more advanced resources.
git clone https://github.com/gnolang/getting-started.git
cd getting-started

2. Install dependencies:
2. Install the toolchain:

make install

This clones `gnolang/gno` and builds `gno`, `gnokey`, `gnodev`, `gnobro` and
`gnoweb` into `$HOME/.gno/bin`. It needs Go, git and make, and takes a few
minutes the first time. Add the directory to your `PATH` before continuing:

export PATH="$HOME/.gno/bin:$PATH"

(The installer also has a faster prebuilt-binary mode, but it currently looks
for `v*` release tags and `gnolang/gno` only publishes `chain/*` tags, so
`--from-source` is the path that works today.)
This builds `gno`, `gnokey`, `gnodev` and `gnoweb` from source into
`$HOME/.gno/bin`. Other ways to install them:
[Installation](https://docs.gno.land/builders/install).

3. Start the development server:

make dev

4. Open your browser and visit http://localhost:8888

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Say going to http://localhost:8888 on gnodev should redirect to that link if done correctly, with some troubleshoot if not

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linked it rather than written it: Local development with gnodev. Troubleshooting that drifts out of sync with gnodev is exactly what this pass is removing.


## What's Included
Edit `hello.gno` while `make dev` runs and the page reloads with your change.
Run `make` at any point to see every available target. What else `gnodev` can do:
[Local development with gnodev](https://docs.gno.land/builders/local-dev-with-gnodev).

This repository contains a simple Gno realm with:
- A `Render` function that displays a welcome message and instructions
- A `Set` function to update the realm's state
- A `Get` function to retrieve the stored message
## What's in here

## Deploying it
- `hello.gno`: a realm with `Render` (what gnoweb displays), plus `Set` and `Get`.
- `hello_test.gno`: one test for the state-changing function, one that calls
`Render`. Every realm wants both.

`gnodev` runs a throwaway local chain. When you want your realm on a real
network:
Why `Set` takes a `realm` parameter and the test calls `cross(...)`:
[Realms](https://docs.gno.land/resources/realms) and
[Interrealm](https://docs.gno.land/resources/gno-interrealm).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


- **A testnet** — start here. Testnets are renamed and replaced every few
weeks, so look up the current one and its RPC endpoint in
[Gno networks](https://docs.gno.land/resources/gnoland-networks), and get
tokens from the [faucet](https://faucet.gno.land).
- **[Mainnet](https://gno.land)** (`gnoland-1`,
`https://rpc.gno.land:443`) has been live since 12 September 2026. Real
GNOT, no faucet.
## Testing it

## Next Steps
make test # run the tests
make lint # catch what only the chain would otherwise catch
make fmt # format every .gno file in place

Ready to learn more? Check out these resources:
More: [Testing Gno code](https://docs.gno.land/resources/gno-testing).

## Deploying it

`gnodev` runs a throwaway local chain. To put your realm on a real network,
point `module` in `gnomod.toml` at a path you control (`gno.land/r/<your-address>/hello`
always works and needs no registration), then follow
[Deploy to a shared network](https://docs.gno.land/builders/getting-started#deploy-to-a-shared-network),
which covers the key, the faucet, the namespace and the deploy command itself.

## Next Steps

- Gno Documentation: https://docs.gno.land
- Gno Repository Template: https://github.com/gnolang/repo-template
<!--- Gno by Examples: https://github.com/gnolang/by-examples-->
- [Gno documentation](https://docs.gno.land)
- [Editor setup](https://docs.gno.land/builders/editor-setup), with the
[`gnopls`](https://github.com/gnoverse/gnopls) language server
- [gnoverse/gno-mcp](https://github.com/gnoverse/gno-mcp): MCP server plus
skills that put an AI agent on gno.land
- [examples/](https://github.com/gnolang/gno/tree/master/examples): the realms
and packages that ship with the chain
- [moul/gno-contracts](https://github.com/moul/gno-contracts): what a serious
Gno repository grows into
- [gnoverse/awesome-gno](https://github.com/gnoverse/awesome-gno): everything else
11 changes: 4 additions & 7 deletions hello.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ var message string = "Hello, Gno!"
func Render(path string) string {
return `# ` + message + `

This is a simple Gno realm that demonstrates basic functionality.
Try it out with gnokey:
This page is what Render returns. Edit hello.gno while "make dev" is running
and it reloads with your change.

gnokey add myaccount
gnokey list

[And click here](/r/example/hello$help&func=Set&newMsg=Hello%20from%20Gnokey!)
`
Add $help to this page's URL to call Set from your browser.
`
}

func Set(_ realm, newMsg string) {
Expand Down
10 changes: 10 additions & 0 deletions hello_test.gno
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hello

import (
"strings"
"testing"
)

Expand All @@ -16,3 +17,12 @@ func TestSetAndGet(cur realm, t *testing.T) {
t.Errorf("Expected 'Hello, Test!', got %s", got)
}
}

// gnoweb calls Render for every page view, so always keep a test that actually
// calls it. A realm with an untested Render only fails once it is on-chain.
func TestRender(t *testing.T) {
out := Render("")
if !strings.Contains(out, Get()) {
t.Errorf("Render() should show the message %q, got:\n%s", Get(), out)
}
}
Loading