Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

garden/v2 package

Overview

Package garden is Gnotchi's Phase 1 on-chain slice, v2: everything v1's garden realm does (Adopt, GnomeByAddress, Render, soulbound, one gnome per address, the validated name/hat/coat rules, the OriginSend refusal -- every fix from v1's three audit rounds, carried over rather than rewritten from memory, see below for exactly which lines are unchanged from realms/garden/garden.gno) plus the new thing Phase 1 actually needs: SaveDay, the "one signature saves the whole day" call the brief's section 5.2 and the build brief's own paragraph 2 promise and that the deployed v1 realm does not have.

v1 (realms/garden/garden.gno) is deployed to the onyx testnet at gno.land/r/g1r4aw43kagaaquhegxw6xr346h9f2qu2ezf0jar/garden/v1 and, per DECISIONS.md, cannot be edited -- this file is deliberately a sibling, not a modification. v1 is left completely untouched as the deployed record.

THIS FILE IS NOT DEPLOYED. Authored and tested locally only, per this assignment's own brief: no gnokey, no key material, no deploy.

Everything below this comment that is unchanged from v1 (the soulboundExtension, Adopt's validation chain, the name-charset allowlist/denylist, Render's path validation, GnomeByAddress) is carried over with its original comments intact, because those comments are the audit trail for *why* each check exists -- deleting them to make this file shorter would silently discard that trail. New material (the care-state fields on gnome, SaveDay and its helpers, CareState) is clearly marked "v2:" in its own comments.

SECURITY: the same warning v1 carries applies here unchanged and is reprinted in full, because it is load-bearing and not something a reader should have to go find in a different file to understand this one: no code in this realm, now or later, may ever recover() around a call into ledger or token (grc721's PrivateLedger/Token). The soulbound guarantee below is real, but it is NOT that the ledger write never happens -- it does, before the panic -- it is that an *uncaught* panic aborts the whole enclosing transaction, so that write (and everything else the transaction did) is discarded and never committed on chain. p/nt/grc721/v0/types.gno says this outright, about extension hooks like soulboundExtension below: "Hooks run after the ledger write so they observe the post-movement state; only a caller that recovers from the panic keeps that write." A recover() anywhere between a ledger call and the transaction boundary -- even one added for an unrelated reason, even one several call-frames away -- would silently convert every refused transfer into a permanent, successful one. Don't add one. This is not limited to code textually inside this file: a pure `p/` package this realm calls runs in garden's own call frame too, so a helper as innocuous as `Try(func(){ ledger.TransferFrom(...) })` imported from some future `p/` dependency would break the same guarantee just as surely as a recover() written here directly. The same rule now also applies to SaveDay's own validate-then-commit pattern below: SaveDay never recovers from its own internal panics either, by design -- see that function's comment.

Function

Adopt

func Adopt(cur realm, name, hat, coat string)
Ask AI Claude ChatGPT

Adopt: unchanged from v1 in every validation it performs (same order, same messages, same OriginSend refusal, same caller derivation). v2 only adds initialising the new care-state fields at the bottom, where v1 only set level/gnomeType/adoptedAt.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1r4aw43kagaaquhegxw6xr346h9f2qu2ezf0jar/garden/v2" -func "Adopt" -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "onyx-1" -remote "https://rpc.onyx.testnets.gno.land" ADDRESSgnokey query -remote "https://rpc.onyx.testnets.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1r4aw43kagaaquhegxw6xr346h9f2qu2ezf0jar/garden/v2" -func "Adopt" -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "onyx-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.onyx.testnets.gno.land" call.tx