func Add
crossing ActionAdd appends a note. It is the only mutating function here, and it carries both guards a real one should.
Package devtools is the worked example of wiring moul's developer packages into one realm: what a new realm should copy.
gno.land/r/moul/x/allinone/devtoolsThe worked example of wiring moul's developer packages into one realm: what a new realm should copy.
Eight packages, each earning its place in the output:
| package | what it contributes |
|---|---|
r/moul/config |
the notice block, the pause guard, which explorer to link |
p/moul/mygnoscan |
the explorer routes |
p/moul/debug |
the ?debug=1 panel |
p/moul/realmpath |
reading the render path |
p/moul/kit/ui |
escaping caller input, and the tables |
p/moul/md |
the markdown |
p/moul/txlink |
the call links |
p/moul/fifo |
the bounded note list |
1func Render(path string) string {
2 return config.TopBlockFor(realmPath) + body + config.BottomBlockFor(realmPath)
3}
4
5func Add(cur realm, body string) {
6 config.AssertWritableFor(realmPath) // honours the pause switch
7 notes.Append(ui.Inline(body)) // escapes what a caller typed
8}
The first gives the realm a place for a warning and a pause banner without
shipping any banner code, and returns "" while nothing is set, so a page that
concatenates it unconditionally is unchanged by default.
The second is two separate guards and both have to be there: the pause one so an incident can stop writes from outside this realm and without a redeploy, and the escaping one because a string a caller typed is the oldest way to break a page.
Render("") is the root and is free of anything that moves, so an example test
can pin it. Everything live (the height, the chain id, the links built from
them) is under :chain, which is also what keeps the pinned output stable.
State is disposable: the note list is bounded by fifo at 10 entries and this
realm is private = true, so a redeploy wipes it on purpose.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
Dependency graph:

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.
Package devtools is the worked example of wiring moul's developer packages into one realm: what a new realm should copy.
Everything here is a COMBINATION. Any one of these packages has its own demo showing it alone; the thing that is hard to find is what they look like used together, which is the only form a real realm ever meets them in. So this realm imports eight of them and every one earns its place in the output:
1r/moul/config the notice block, the pause switch, the explorer to link
2p/moul/mygnoscan the explorer routes themselves
3p/moul/debug a metadata panel behind ?debug=1
4p/moul/realmpath reading the query string Render was handed
5p/moul/kit/ui escaping what a caller typed, and the tables
6p/moul/md the markdown, without hand-rolled strings
7p/moul/txlink the "call this function" link
8p/moul/fifo the bounded note list, so the state cannot grow forever
A realm that does nothing else should still do these:
1func Render(path string) string {
2 return config.TopBlockFor(realmPath) + body + config.BottomBlockFor(realmPath)
3}
4
5func Mutate(cur realm, s string) {
6 config.AssertWritableFor(realmPath) // honours the pause switch
7 notes.Append(ui.Inline(s)) // escapes what a caller typed
8}
The first gives every realm a place to put a warning and a pause banner without shipping banner code. The second is two separate guards that both have to be there: the pause one so an incident can stop writes from outside the realm, and the escaping one because a string a caller typed is the oldest way to break a page.
Add appends a note. It is the only mutating function here, and it carries both guards a real one should.
Render shows every package at work. The root view is deliberately free of anything that moves on its own, so an example test can pin it; the live numbers live under "chain".
Reset empties the list, so the realm can be put back to a known state without a redeploy. Not gated by the pause switch: clearing up is the thing you still want to do while paused.