From 8749bf88695b24aca1a30e93f27504aca93614ee Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:09:05 +0200 Subject: [PATCH 01/10] feat: make help, lint, fmt and deploy targets; CI runs the same targets --- .github/workflows/ci.yml | 7 +++++-- Makefile | 45 +++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 253f0b7..45e09df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 @@ -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 diff --git a/Makefile b/Makefile index aa8bc85..f291f4e 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,49 @@ -.PHONY: install dev test +# getting-started — run `make` (or `make help`) to see every target. -install: +GNO ?= gno + +.DEFAULT_GOAL := help +.PHONY: help install dev test lint fmt deploy + +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 ' export PATH="$$HOME/.gno/bin:$$PATH"' -dev: +dev: ## run a local chain + web UI on http://localhost:8888, reloading on save gnodev . -test: - gno test . +test: ## run the tests + $(GNO) test . + +lint: ## catch what only the chain would otherwise catch + $(GNO) lint . + +fmt: ## format every .gno file in place + $(GNO) fmt -w . + +# Publishing on-chain needs three things: +# 1. a key with funds — `gnokey add mykey`, then a testnet faucet +# (https://faucet.gno.land); mainnet has none, it costs real GNOT. +# 2. a namespace you control — set `module` in gnomod.toml to +# gno.land/r//hello. Your own address always works and +# needs no registration; a short name has to be registered first. +# 3. the RPC endpoint + chain id of the network you are targeting, from +# https://docs.gno.land/resources/gnoland-networks +# (mainnet is https://rpc.gno.land:443, chain id gnoland-1). +PKGPATH ?= $(shell sed -n 's/^module *= *"\(.*\)"/\1/p' gnomod.toml) + +deploy: ## publish on-chain: make deploy KEY= REMOTE= CHAINID= + @if [ -z "$(KEY)" ] || [ -z "$(REMOTE)" ] || [ -z "$(CHAINID)" ]; then \ + echo 'usage: make deploy KEY= REMOTE= CHAINID='; \ + echo 'pick a network: https://docs.gno.land/resources/gnoland-networks'; \ + exit 1; \ + fi + gnokey maketx addpkg -pkgpath "$(PKGPATH)" -pkgdir . \ + -gas-fee 1000000ugnot -gas-wanted 20000000 \ + -broadcast -remote "$(REMOTE)" -chainid "$(CHAINID)" "$(KEY)" From 0c2145212e315908e66f9b10f97613b9da9c163f Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:09:05 +0200 Subject: [PATCH 02/10] test: cover Render, the realm's only public surface --- hello_test.gno | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hello_test.gno b/hello_test.gno index 2be6411..c7e03ef 100644 --- a/hello_test.gno +++ b/hello_test.gno @@ -1,6 +1,7 @@ package hello import ( + "strings" "testing" ) @@ -16,3 +17,13 @@ func TestSetAndGet(cur realm, t *testing.T) { t.Errorf("Expected 'Hello, Test!', got %s", got) } } + +// Render is the realm's entire public surface — it is what gnoweb calls for +// every page view — so always have 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) + } +} From 3e6efaa6ef48154577cb9b565c455fcace23b43f Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:09:05 +0200 Subject: [PATCH 03/10] feat: AGENTS.md for coding agents, and .gno syntax highlighting --- .gitattributes | 2 ++ AGENTS.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 3 files changed, 54 insertions(+) create mode 100644 .gitattributes create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..da30f02 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Gno is Go — give .gno files Go syntax highlighting, diffs and language stats. +*.gno linguist-language=Go diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5bc4675 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,51 @@ +# AGENTS.md + +Guide for coding agents (and humans in a hurry) working in this repository. +It is deliberately tiny — so is 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 deploy # publish on-chain (needs KEY, REMOTE, CHAINID — see the Makefile) +``` + +`make test lint` is the bar for any change. CI runs exactly those two targets +against a gno built from `gnolang/gno` master, so a green local run means a +green CI. + +## Gno is not quite Go + +Close enough that Go habits compile in your head and fail on the chain: + +- **State-mutating exported functions are "crossing" functions**: they take a + first parameter `cur realm`, and callers use `cross(cur)`. See `Set` in + `hello.gno` and its call in `hello_test.gno`. +- **`Render(path string) string` is the realm's whole public surface.** gnoweb + calls it for every page view. Always keep a test that calls it. +- **`Example*` tests need an `// Output:` block** or `gno test` skips them + silently — an example without one asserts nothing. +- **Render must be deterministic.** Map iteration order is unspecified, so never + build output by ranging a map. +- **The standard library is a subset.** `sort.Slice` does not exist, and `ufmt` + supports no width or padding flags (`ufmt.Sprintf("%03d", 7)` returns `"7"`). + +## Conventions + +- Conventional single-line commits: `feat: …`, `fix: …`, `chore: …`. +- No AI co-author trailers. +- Don't add folders, CI jobs, or dependencies. Simplicity is the feature; if + something needs more machinery, it belongs in + [gnolang/repo-template](https://github.com/gnolang/repo-template) or + [moul/gno-contracts](https://github.com/moul/gno-contracts), not here. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..fded5dc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +See [AGENTS.md](./AGENTS.md). From 7b262163a72c1e964892c85856f6dff5895426c3 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:09:05 +0200 Subject: [PATCH 04/10] docs: how to test, how to deploy, and where to go next --- README.md | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7f45f0c..5b57a40 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,9 @@ for `v*` release tags and `gnolang/gno` only publishes `chain/*` tags, so 4. Open your browser and visit http://localhost:8888 +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's Included This repository contains a simple Gno realm with: @@ -41,18 +44,42 @@ This repository contains a simple Gno realm with: - A `Set` function to update the realm's state - A `Get` function to retrieve the stored message +## Testing it + + make test # run the tests + make lint # catch what only the chain would otherwise catch + make fmt # format every .gno file in place + +`hello_test.gno` shows the two tests every realm wants: one that exercises the +state-changing function (note the `cur realm` parameter and the `cross(cur)` +call — that's how Gno marks a "crossing" call into a realm), and one that calls +`Render`, which is the realm's entire public surface. + ## Deploying it -`gnodev` runs a throwaway local chain. When you want your realm on a real -network: +`gnodev` runs a throwaway local chain. To put your realm on a real network you +need a key, a namespace, and a network: + +1. **A key with funds.** + + gnokey add mykey + + On a testnet, fund it from the [faucet](https://faucet.gno.land). Mainnet has + no faucet — it costs real GNOT. + +2. **A namespace you control.** Edit `module` in `gnomod.toml` to + `gno.land/r//hello`. Deploying under your own address always + works and needs no registration; a short name has to be registered first. + +3. **A network.** Look up its RPC endpoint and chain id in + [Gno networks](https://docs.gno.land/resources/gnoland-networks). Testnets + are renamed and replaced every few weeks, so check the page rather than + trusting a name you saw somewhere. [Mainnet](https://gno.land) has been live + since 12 September 2026 at `https://rpc.gno.land:443`, chain id `gnoland-1`. + +Then: -- **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. + make deploy KEY=mykey REMOTE= CHAINID= ## Next Steps @@ -60,4 +87,9 @@ Ready to learn more? Check out these resources: - Gno Documentation: https://docs.gno.land - Gno Repository Template: https://github.com/gnolang/repo-template +- Real-world packages and realms to read and copy from: + https://github.com/moul/gno-contracts — 50+ versioned, self-contained + contracts, each with a README and tests, continuously built against gno + master. A good look at what a serious Gno repository grows into. +- Everything else Gno: https://github.com/gnoverse/awesome-gno From 2369645db397f5b4429a4009f529e0a7d690b274 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:17:04 +0200 Subject: [PATCH 05/10] Delete .gitattributes --- .gitattributes | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index da30f02..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Gno is Go — give .gno files Go syntax highlighting, diffs and language stats. -*.gno linguist-language=Go From 375b0211052753291b2fba6f3c1fd42b5226fec2 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:21:41 +0200 Subject: [PATCH 06/10] docs: link docs.gno.land for deploying, drop the deploy target and repo-template link --- AGENTS.md | 4 +--- Makefile | 23 +---------------------- README.md | 33 +++++++++------------------------ 3 files changed, 11 insertions(+), 49 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5bc4675..988d9a8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -18,7 +18,6 @@ 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 deploy # publish on-chain (needs KEY, REMOTE, CHAINID — see the Makefile) ``` `make test lint` is the bar for any change. CI runs exactly those two targets @@ -46,6 +45,5 @@ Close enough that Go habits compile in your head and fail on the chain: - Conventional single-line commits: `feat: …`, `fix: …`, `chore: …`. - No AI co-author trailers. - Don't add folders, CI jobs, or dependencies. Simplicity is the feature; if - something needs more machinery, it belongs in - [gnolang/repo-template](https://github.com/gnolang/repo-template) or + something needs more machinery, it belongs in a bigger repo such as [moul/gno-contracts](https://github.com/moul/gno-contracts), not here. diff --git a/Makefile b/Makefile index f291f4e..064b9ca 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GNO ?= gno .DEFAULT_GOAL := help -.PHONY: help install dev test lint fmt deploy +.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) @@ -26,24 +26,3 @@ lint: ## catch what only the chain would otherwise catch fmt: ## format every .gno file in place $(GNO) fmt -w . - -# Publishing on-chain needs three things: -# 1. a key with funds — `gnokey add mykey`, then a testnet faucet -# (https://faucet.gno.land); mainnet has none, it costs real GNOT. -# 2. a namespace you control — set `module` in gnomod.toml to -# gno.land/r//hello. Your own address always works and -# needs no registration; a short name has to be registered first. -# 3. the RPC endpoint + chain id of the network you are targeting, from -# https://docs.gno.land/resources/gnoland-networks -# (mainnet is https://rpc.gno.land:443, chain id gnoland-1). -PKGPATH ?= $(shell sed -n 's/^module *= *"\(.*\)"/\1/p' gnomod.toml) - -deploy: ## publish on-chain: make deploy KEY= REMOTE= CHAINID= - @if [ -z "$(KEY)" ] || [ -z "$(REMOTE)" ] || [ -z "$(CHAINID)" ]; then \ - echo 'usage: make deploy KEY= REMOTE= CHAINID='; \ - echo 'pick a network: https://docs.gno.land/resources/gnoland-networks'; \ - exit 1; \ - fi - gnokey maketx addpkg -pkgpath "$(PKGPATH)" -pkgdir . \ - -gas-fee 1000000ugnot -gas-wanted 20000000 \ - -broadcast -remote "$(REMOTE)" -chainid "$(CHAINID)" "$(KEY)" diff --git a/README.md b/README.md index 5b57a40..b2306e0 100644 --- a/README.md +++ b/README.md @@ -57,36 +57,21 @@ call — that's how Gno marks a "crossing" call into a realm), and one that call ## Deploying it -`gnodev` runs a throwaway local chain. To put your realm on a real network you -need a key, a namespace, and a network: - -1. **A key with funds.** - - gnokey add mykey - - On a testnet, fund it from the [faucet](https://faucet.gno.land). Mainnet has - no faucet — it costs real GNOT. - -2. **A namespace you control.** Edit `module` in `gnomod.toml` to - `gno.land/r//hello`. Deploying under your own address always - works and needs no registration; a short name has to be registered first. - -3. **A network.** Look up its RPC endpoint and chain id in - [Gno networks](https://docs.gno.land/resources/gnoland-networks). Testnets - are renamed and replaced every few weeks, so check the page rather than - trusting a name you saw somewhere. [Mainnet](https://gno.land) has been live - since 12 September 2026 at `https://rpc.gno.land:443`, chain id `gnoland-1`. - -Then: - - make deploy KEY=mykey REMOTE= CHAINID= +`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//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 `gnokey maketx addpkg` +command for every network. ## Next Steps Ready to learn more? Check out these resources: - Gno Documentation: https://docs.gno.land -- Gno Repository Template: https://github.com/gnolang/repo-template +- The realms and packages that ship with the chain: + https://github.com/gnolang/gno/tree/master/examples — the standard library of + Gno, from `r/gnoland/home` to the `p/demo` packages everything else builds on. - Real-world packages and realms to read and copy from: https://github.com/moul/gno-contracts — 50+ versioned, self-contained contracts, each with a README and tests, continuously built against gno From 94f6b1866467f8f9e15d552e51976315e754e73b Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:24:42 +0200 Subject: [PATCH 07/10] Apply suggestion from @moul --- AGENTS.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 988d9a8..04d27a8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,12 +38,3 @@ Close enough that Go habits compile in your head and fail on the chain: - **Render must be deterministic.** Map iteration order is unspecified, so never build output by ranging a map. - **The standard library is a subset.** `sort.Slice` does not exist, and `ufmt` - supports no width or padding flags (`ufmt.Sprintf("%03d", 7)` returns `"7"`). - -## Conventions - -- Conventional single-line commits: `feat: …`, `fix: …`, `chore: …`. -- No AI co-author trailers. -- Don't add folders, CI jobs, or dependencies. Simplicity is the feature; if - something needs more machinery, it belongs in a bigger repo such as - [moul/gno-contracts](https://github.com/moul/gno-contracts), not here. From dda245ddc4556d0b83e471b67830d17c0df7b666 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:29:31 +0200 Subject: [PATCH 08/10] docs: link gnopls and gno-mcp, restore the truncated ufmt line --- AGENTS.md | 13 +++++++++++++ README.md | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 04d27a8..819ddd5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,6 +24,17 @@ make fmt # gno fmt -w . against a gno built from `gnolang/gno` master, so a green local run means a green CI. +## 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. Its `gno` skill is the knowledge layer + this file is deliberately too small to be. Pre-release; writes are gated to + dev/testnet. +- [`gnoverse/gnopls`](https://github.com/gnoverse/gnopls) — the Gno language + server, for editors. Experimental; setup in + [Editor Setup](https://docs.gno.land/builders/editor-setup). + ## Gno is not quite Go Close enough that Go habits compile in your head and fail on the chain: @@ -38,3 +49,5 @@ Close enough that Go habits compile in your head and fail on the chain: - **Render must be deterministic.** Map iteration order is unspecified, so never build output by ranging a map. - **The standard library is a subset.** `sort.Slice` does not exist, and `ufmt` + honours only some of `fmt`'s flags: `ufmt.Sprintf("%03d", 7)` returns `"7"`, + and `%-5s` comes back as `(unhandled verb: %-)`. diff --git a/README.md b/README.md index b2306e0..cf7f853 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,12 @@ command for every network. Ready to learn more? Check out these resources: - Gno Documentation: https://docs.gno.land +- Editor setup, with the `gnopls` language server: + https://docs.gno.land/builders/editor-setup — + https://github.com/gnoverse/gnopls +- Put your AI agent on gno.land: https://github.com/gnoverse/gno-mcp — an MCP + server plus skills that let an agent read realms, deploy to a testnet and + audit on-chain code. Pre-release. - The realms and packages that ship with the chain: https://github.com/gnolang/gno/tree/master/examples — the standard library of Gno, from `r/gnoland/home` to the `p/demo` packages everything else builds on. From 694afe59640b35a356160c185657f075ca70c220 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 18:38:06 +0200 Subject: [PATCH 09/10] docs: link the official docs instead of restating them --- AGENTS.md | 45 +++++++++++++++++---------------- Makefile | 3 ++- README.md | 74 ++++++++++++++++++++++--------------------------------- hello.gno | 11 +++------ 4 files changed, 57 insertions(+), 76 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 819ddd5..3c1d54f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,34 +20,33 @@ make lint # gno lint . make fmt # gno fmt -w . ``` -`make test lint` is the bar for any change. CI runs exactly those two targets -against a gno built from `gnolang/gno` master, so a green local run means a -green CI. +`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 — 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 + 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. Its `gno` skill is the knowledge layer - this file is deliberately too small to be. Pre-release; writes are gated to + deploy to a testnet, audit a realm. Pre-release; writes are gated to dev/testnet. - [`gnoverse/gnopls`](https://github.com/gnoverse/gnopls) — the Gno language - server, for editors. Experimental; setup in + server, for editors. Setup in [Editor Setup](https://docs.gno.land/builders/editor-setup). - -## Gno is not quite Go - -Close enough that Go habits compile in your head and fail on the chain: - -- **State-mutating exported functions are "crossing" functions**: they take a - first parameter `cur realm`, and callers use `cross(cur)`. See `Set` in - `hello.gno` and its call in `hello_test.gno`. -- **`Render(path string) string` is the realm's whole public surface.** gnoweb - calls it for every page view. Always keep a test that calls it. -- **`Example*` tests need an `// Output:` block** or `gno test` skips them - silently — an example without one asserts nothing. -- **Render must be deterministic.** Map iteration order is unspecified, so never - build output by ranging a map. -- **The standard library is a subset.** `sort.Slice` does not exist, and `ufmt` - honours only some of `fmt`'s flags: `ufmt.Sprintf("%03d", 7)` returns `"7"`, - and `%-5s` comes back as `(unhandled verb: %-)`. diff --git a/Makefile b/Makefile index 064b9ca..ce96166 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ # getting-started — run `make` (or `make help`) to see every target. GNO ?= gno +GNODEV ?= gnodev .DEFAULT_GOAL := help .PHONY: help install dev test lint fmt @@ -16,7 +17,7 @@ install: ## build the gno toolchain into $HOME/.gno/bin @echo ' export PATH="$$HOME/.gno/bin:$$PATH"' dev: ## run a local chain + web UI on http://localhost:8888, reloading on save - gnodev . + $(GNODEV) . test: ## run the tests $(GNO) test . diff --git a/README.md b/README.md index cf7f853..fb36838 100644 --- a/README.md +++ b/README.md @@ -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 @@ -14,19 +10,14 @@ 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: @@ -35,14 +26,19 @@ for `v*` release tags and `gnolang/gno` only publishes `chain/*` tags, so 4. Open your browser and visit http://localhost:8888 Edit `hello.gno` while `make dev` runs and the page reloads with your change. -Run `make` at any point to see every available target. +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). + +## What's in here -## What's Included +- `hello.gno` — a realm with `Render`, which is what gnoweb displays, plus `Set` + and `Get`. +- `hello_test.gno` — the two tests every realm wants: one for the state-changing + function, one that calls `Render`. -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 +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). ## Testing it @@ -50,10 +46,7 @@ This repository contains a simple Gno realm with: make lint # catch what only the chain would otherwise catch make fmt # format every .gno file in place -`hello_test.gno` shows the two tests every realm wants: one that exercises the -state-changing function (note the `cur realm` parameter and the `cross(cur)` -call — that's how Gno marks a "crossing" call into a realm), and one that calls -`Render`, which is the realm's entire public surface. +More: [Testing Gno code](https://docs.gno.land/resources/gno-testing). ## Deploying it @@ -61,26 +54,17 @@ call — that's how Gno marks a "crossing" call into a realm), and one that call point `module` in `gnomod.toml` at a path you control — `gno.land/r//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 `gnokey maketx addpkg` -command for every network. +which covers the key, the faucet, the namespace and the deploy command itself. ## Next Steps -Ready to learn more? Check out these resources: - -- Gno Documentation: https://docs.gno.land -- Editor setup, with the `gnopls` language server: - https://docs.gno.land/builders/editor-setup — - https://github.com/gnoverse/gnopls -- Put your AI agent on gno.land: https://github.com/gnoverse/gno-mcp — an MCP - server plus skills that let an agent read realms, deploy to a testnet and - audit on-chain code. Pre-release. -- The realms and packages that ship with the chain: - https://github.com/gnolang/gno/tree/master/examples — the standard library of - Gno, from `r/gnoland/home` to the `p/demo` packages everything else builds on. -- Real-world packages and realms to read and copy from: - https://github.com/moul/gno-contracts — 50+ versioned, self-contained - contracts, each with a README and tests, continuously built against gno - master. A good look at what a serious Gno repository grows into. -- Everything else Gno: https://github.com/gnoverse/awesome-gno - +- [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 diff --git a/hello.gno b/hello.gno index 30b75cd..882955f 100644 --- a/hello.gno +++ b/hello.gno @@ -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) { From 68398270c810d7c5db06bac52c155e8ed2653225 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 17 Sep 2026 18:39:48 +0200 Subject: [PATCH 10/10] docs: drop em dashes --- AGENTS.md | 24 ++++++++++++------------ Makefile | 4 ++-- README.md | 21 ++++++++++----------- hello_test.gno | 5 ++--- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3c1d54f..86a1465 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,7 +1,7 @@ # AGENTS.md Guide for coding agents (and humans in a hurry) working in this repository. -It is deliberately tiny — so is the repo. +It is deliberately tiny, like the repo. ## What this is @@ -22,31 +22,31 @@ 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 — re-run `make install` before trusting a green local run. +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 +- [Realms](https://docs.gno.land/resources/realms): `Render` and realm state +- [Interrealm](https://docs.gno.land/resources/gno-interrealm): crossing functions, the `realm` parameter, `cross(...)` -- [Go/Gno compatibility](https://docs.gno.land/resources/go-gno-compatibility) — +- [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 +- [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 +- [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 +- [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; writes are gated to +- [`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 +- [`gnoverse/gnopls`](https://github.com/gnoverse/gnopls): the Gno language server, for editors. Setup in [Editor Setup](https://docs.gno.land/builders/editor-setup). diff --git a/Makefile b/Makefile index ce96166..dde6370 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# getting-started — run `make` (or `make help`) to see every target. +# getting-started. Run `make` (or `make help`) to see every target. GNO ?= gno GNODEV ?= gnodev @@ -13,7 +13,7 @@ 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: ## run a local chain + web UI on http://localhost:8888, reloading on save diff --git a/README.md b/README.md index fb36838..0f1e46f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Getting Started with Gno -One Gno realm, its test, and a Makefile — small enough to read in five minutes. +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 @@ -31,10 +31,9 @@ Run `make` at any point to see every available target. What else `gnodev` can do ## What's in here -- `hello.gno` — a realm with `Render`, which is what gnoweb displays, plus `Set` - and `Get`. -- `hello_test.gno` — the two tests every realm wants: one for the state-changing - function, one that calls `Render`. +- `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. Why `Set` takes a `realm` parameter and the test calls `cross(...)`: [Realms](https://docs.gno.land/resources/realms) and @@ -51,8 +50,8 @@ 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//hello` -always works and needs no registration — then follow +point `module` in `gnomod.toml` at a path you control (`gno.land/r//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. @@ -61,10 +60,10 @@ which covers the key, the faucet, the namespace and the deploy command itself. - [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 +- [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 +- [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 +- [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 +- [gnoverse/awesome-gno](https://github.com/gnoverse/awesome-gno): everything else diff --git a/hello_test.gno b/hello_test.gno index c7e03ef..b470fb0 100644 --- a/hello_test.gno +++ b/hello_test.gno @@ -18,9 +18,8 @@ func TestSetAndGet(cur realm, t *testing.T) { } } -// Render is the realm's entire public surface — it is what gnoweb calls for -// every page view — so always have a test that actually calls it. A realm with -// an untested Render only fails once it is on-chain. +// 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()) {