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

stable source realm

Package stablev4 is the permanent half of the gems6v2 split-realm design (stablev3 plus two fixes from the 2026-09-15...

Overview

Package stablev4 is the permanent half of the gems6v2 split-realm design (stablev3 plus two fixes from the 2026-09-15 Pearl test run: a burned token's own page, and no per-token copy of the sealed image) -- a candidate successor to the real gems6/stable, built to prove two things together before either goes anywhere near mainnet: a delayed-reveal mint (fixing the OutOfGasError problem the real gems6/v1's instant-reveal MintAssembled has against Adena's own gas estimation -- confirmed on a throwaway single-realm spike, gno.land/r/g1gn6t0q9wenwhdda47rkrpfd63kcxjvyp7eqwku/revealpoc, before this real split-realm version was attempted), and the approved gemsartfab art package (crystal-look repaint + a real Rose Cut cascade fix + a facet-merge seam fix on Round Brilliant/Oval).

Deployed under a test address (not the vesting wallet) so this whole prototype -- stable, campaign, v2, and gemsartfab itself -- is self-contained and doesn't need the real collection's own keys to validate. Folding a confirmed-good design into the real mainnet deploy is a separate step once this proves out.

Reveal mechanism: MintAssembled records a trait selection and a SEALED placeholder image immediately (cheap, see RecordMint's own doc comment for why this is the whole point). TokenURI/TokenMetadata compute the real image via gemsartfab -- but ONLY once RevealDelayBlocks has passed -- through currentMetadata, which is the one addition to the real stable's own read path. This DOES mean this realm, unlike the real gems6/stable, imports an art package directly: unavoidable given gno's static imports (the realm serving TokenURI has to know how to render, and rendering can't be deferred to "whichever realm is currently approved" the way minting can, since a future version's own art package isn't importable before it exists). Matches the tradeoff the older g20 collection already accepted for the exact same reason -- not a new problem introduced here.

Everything else (ownership, whitelist, royalty, claim log, campaign wiring) is unchanged from the real gems6/stable -- see that package's own doc comments for the full design history.

Ledger: the standard gno.land/p/nt/grc721/v0 (2026-09-26), not a vendored grc721. Adena lists only collections whose NewToken/Transfer events come from that exact package (see ~/gno-land-dev-notes.md), and chain.Emit stamps the emitting package, so this cannot be retrofitted later. The package stores ownership only; every token's metadata is computed here from its traits (sealedData), never stored per token. TokenURI returns the image itself (Adena puts it straight into an <img>); TokenMetadata returns the metadata as a JSON string, and TokenJSON the classic base64 JSON data URI for marketplaces that want it.

Constants 1

const CollectionName, CollectionSymbol, realmRelPath, summaryPageSize, gnowebListLimit, pageWindow, tokenPageImageSize, RevealDelayBlocks

 1const (
 2	CollectionName   = "GNO Gems"
 3	CollectionSymbol = "GEMS"
 4
 5	// realmRelPath: this realm's own gnoweb-relative path, baked in as
 6	// a compile-time constant -- see the real gems6/stable's own
 7	// comment on why (unsaferealm.CurrentRealm() resolves differently
 8	// nested inside Render than called directly). Bumped for this
 9	// deployment, per the gemsartfab handoff's own reminder that this
10	// gets missed.
11	realmRelPath = "/r/g17cjym5e9hhws46lt6329pv2gtx2ay0503hgems/gems/stable"
12
13	// 6, not 10: every read has a 3,000,000,000 gas ceiling (vm
14	// maxGasQuery) and a 3D token renders for up to ~265M (Cushion); 8
15	// renders plus page overhead ran out of gas on a local chain, 6 leave
16	// about half the budget spare
17	// summaryPageSize: tokens per CollectionSummary / WalletSummary call
18	// (the mint site's grids). Thumbnail renders, like the gnoweb table;
19	// TokenSummary of one token keeps the full art.
20	summaryPageSize = 10
21	// gnowebListLimit: rows per page of the gnoweb collection table. Rows
22	// use the art's thumbnail render (~145-165M gas, vs ~245-265M full),
23	// so 10 fit well under the 3B query ceiling; the token page and the
24	// summaries the mint site reads keep the full art.
25	gnowebListLimit    = 10
26	pageWindow         = 2
27	tokenPageImageSize = "420"
28
29	// RevealDelayBlocks: kept short so this candidate design can be
30	// tested end-to-end in one sitting -- a real production value
31	// would be tuned separately before mainnet.
32	RevealDelayBlocks = 5
33)
source

Functions 47

func Age

Action
1func Age(tid grc721.TokenID) int64
source

Age returns real blocks elapsed since tid was minted, or -1 if it doesn't exist / was never sealed.

func Burn

crossing Action
1func Burn(cur realm, tid grc721.TokenID)
source

Burn destroys a token. Caller must be its current owner. Archives the real trait combination as text -- always the real traits, even if burned before the reveal delay passed, since sealedData already has them regardless of whether TokenURI has started showing them publicly yet. Deliberately never renders or stores an image: the archive was only ever a text record (see BurnedTokenSummary/ renderMintedListPage's own "Burned" row), so calling gemsart.RenderTokenSVG here just to immediately discard its output was pure waste -- confirmed live, a burn on an already-revealed token cost ~165M gas, almost entirely that one re-render, roughly the same cost the whole reveal-delay design exists to avoid paying on mint. Releases the trait combo AND the reveal bookkeeping (sealedData/ mintHeight) -- maximizes the real storage-deposit refund, same reasoning the real gems6/stable's own Burn already documents.

func GetName

Action
1func GetName() string
source

GetName/GetSymbol: the Teller-style names some tools look for.

func IsRevealed

Action
1func IsRevealed(tid grc721.TokenID) bool
source

IsRevealed reports whether tid's real metadata is visible yet.

func RecordMint

crossing Action
1func RecordMint(cur realm, to address, payer address, tid grc721.TokenID, chainName string, shapeIdx, colorIdx int, metal string, active bool, comboKey string, rarity string) grc721.TokenID
source

RecordMint: the ENTIRE point of this v2 candidate. Unlike the real gems6/stable's own RecordMint, this does NOT take a full, rendered grc721.Metadata -- it takes the raw trait fields instead, and writes a small fixed-size SEALED placeholder to nft's own storage. The real image is never computed here, or anywhere, during a mint transaction -- see currentMetadata for where it actually happens (a plain read, unbound by any tx-level gas-wanted). Only the approved version realm may call this. Reserves comboKey atomically with the mint, same authoritative-check role the real stable's RecordMint plays.

func SafeTransferFrom

crossing Action
1func SafeTransferFrom(cur realm, from, to address, tid grc721.TokenID)
source

SafeTransferFrom: kept for the standard signature. grc721/v0 has no receiver-contract hook, so it is TransferFrom.

func TokenJSON

Action
1func TokenJSON(tid grc721.TokenID) (string, error)
source

TokenJSON is the classic OpenSea-style metadata (snake_case keys, the image inline) as a base64 JSON data URI, for marketplaces that expect a tokenURI of that shape.

func TokenMetadata

Action
1func TokenMetadata(tid grc721.TokenID) (string, error)
source

TokenMetadata is the metadata as a JSON string in the camelCase shape Adena reads (name, description, backgroundColor, attributes of {traitType, value}). No image in it, so it costs no render: the image is TokenURI.

func TokenURI

Action
1func TokenURI(tid grc721.TokenID) (string, error)
source

TokenURI is the token's image itself, as a data URI: the sealed placeholder until the reveal block, then the full art. Adena puts it straight into an <img>, which also runs the art's CSS animation.

Types 2

type Metadata

struct
1type Metadata struct {
2	Name            string
3	Description     string
4	Image           string
5	BackgroundColor string
6	Attributes      []Trait
7}
source

type Trait

struct
1type Trait struct {
2	TraitType string
3	Value     string
4}
source

Metadata/Trait: the shape every reader here builds (grc721/v0 keeps no metadata of its own). Never stored per token -- see currentMetadata.

Imports 11

Source Files 2