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.

v1 state

Back to all declarations

pendingAction

type

Value

v1.pendingAction

pendingActions

v0.Tree

// id -> \*pendingAction

Open
OID
0a344a…4a09:4
pendingActions details

Inspect ref

maxPendingActions

int

Value

32

actionWindow

int64

Value

604800

maxActionIDLen

untyped bigint

Value

(2048 <untyped> bigint)

minActionWindow

int64

Value

3600

maxActionWindowS

int64

Value

7776000

getAction

func(id string) *v1.pendingAction
Open
OID
0a344a…4a09:7
getAction details

Inspect func

assertActionID

func(id string)
Open
OID
0a344a…4a09:9
assertActionID details

Inspect func

ProposeAction

func(id string)

ProposeAction starts the clock on one admin action. Proposing an id already pending restarts its clock: the latest proposal is the one that must survive its window.

Open
OID
0a344a…4a09:10
ProposeAction details

Inspect func

CancelAction

func(id string)

CancelAction withdraws one pending action. Admin or recovery: the admin changing its mind, or recovery vetoing a key it no longer trusts.

Open
OID
0a344a…4a09:11
CancelAction details

Inspect func

CancelAllActions

func()

CancelAllActions withdraws every pending action at once — the incident call, when nobody wants to read a list before acting. From recovery it is a veto: the admin proposes no action for one timelock.

Open
OID
0a344a…4a09:12
CancelAllActions details

Inspect func

ConsumeAction

func(id string)

ConsumeAction spends a matured action. Trusted logic only, so it is also gated by the pause: a paused registry executes nothing, timelocked or not. It refuses an action proposed by anybody but the CURRENT admin. Rotation already drops them all; this is the second lock on the same door, because a matured proposal is a loaded instruction and the vault should not rely on one rule to unload it.

Open
OID
0a344a…4a09:13
ConsumeAction details

Inspect func

ActionReady

func(id string) bool

ActionReady reports whether an action could be consumed right now.

Open
OID
0a344a…4a09:14
ActionReady details

Inspect func

GetAction

func(id string) (executableAt int64, expiresAt int64, by .uverse.address)

GetAction reports a pending action: when it matures, when it expires, and who proposed it. All zero when nothing by that id is pending.

Open
OID
0a344a…4a09:15
GetAction details

Inspect func

ListActions

func(after string, limit int) (ids string, next string)

ListActions pages through pending action ids, ONE PER LINE: an id may contain commas (a price rule does), never a newline.

Open
OID
0a344a…4a09:16
ListActions details

Inspect func

GetActionWindow

func() int64
Open
OID
0a344a…4a09:17
GetActionWindow details

Inspect func

SetActionWindow

func(seconds int64)

SetActionWindow sets how long a matured action stays executable, between an hour and ninety days.

Open
OID
0a344a…4a09:18
SetActionWindow details

Inspect func

pruneExpiredActions

func(now int64)

pruneExpiredActions frees the slots of actions nobody can execute any more. Bounded by maxPendingActions.

Open
OID
0a344a…4a09:19
pruneExpiredActions details

Inspect func

dropAllActions

func(reason string) int
Open
OID
0a344a…4a09:20
dropAllActions details

Inspect func

isFresh

func(n *v1.Name, tid string) bool

isFresh reports whether a name's profile data belongs to the token's CURRENT ownership epoch. See Name.epoch and freshen.

Open
OID
0a344a…4a09:21
isFresh details

Inspect func

freshAt

func(n *v1.Name, epoch int64) bool

freshAt is isFresh with the ledger's answer passed in. See freshenTo.

Open
OID
0a344a…4a09:23
freshAt details

Inspect func

ownsNow

func(addr .uverse.address, tid string) bool

ownsNow reports whether \`addr\` holds the token right now, per the ledger.

Open
OID
0a344a…4a09:24
ownsNow details

Inspect func

isValidNow

func(expires int64, now int64) bool

isValidNow / isReclaimable are pure integer math over \`termLength\` and \`gracePeriod\`, both of which are settable — so the lifecycle rules themselves can be retuned after deployment. All times are unix seconds.

Open
OID
0a344a…4a09:25
isValidNow details

Inspect func

isReclaimable

func(expires int64, now int64) bool

isReclaimable compares the elapsed time with the grace period instead of adding the grace period to the expiry. The sum wrapped: an expiry of math.MaxInt64 — the natural "never expires" value — read as valid AND reclaimable at once, and a stranger could take the name (audit L-2). A name that has not expired is never reclaimable, whatever grace says.

Open
OID
0a344a…4a09:26
isReclaimable details

Inspect func

streakOf

func(registered int64, now int64) int64

streakOf derives how many whole terms a holder has actually lived through, replacing the counter that used to be stored on the record. The stored version counted RENEWAL CALLS, so it measured transactions rather than time: prepaying five years bumped it five times on a name registered that morning, and an earlier version could be run up arbitrarily by calling renew in a loop within one block. Deriving it from the registration date makes it unbuyable by construction — the only way to increase it is for time to pass — and it resets on its own when a lapsed name is reclaimed, because a reclaim writes a fresh record with a new \`registered\`. termLength is settable and could legitimately be zero, which would otherwise divide by zero in a realm that cannot be redeployed.

Open
OID
0a344a…4a09:27
streakOf details

Inspect func

assertIsTrustedLogic

func()

assertIsTrustedLogic is the gate on every mutation function below. cur.Previous().Address() resolves to the CALLING realm's own address when invoked via cross(cur) from another realm — same idiom already used for assertIsAdmin, just checking a different address. A stray call from anywhere else (a different realm, a direct user tx trying to call these directly) is rejected.

Open
OID
0a344a…4a09:28
assertIsTrustedLogic details

Inspect func

nameTreeKey

func(label string, domain string) string
Open
OID
0a344a…4a09:29
nameTreeKey details

Inspect func

nameTokenID

func(label string, domain string) string
Open
OID
0a344a…4a09:30
nameTokenID details

Inspect func

domainRange

func(domain string) (start string, end string)

domainRange returns the \[start, end) key bounds covering exactly the names stored under \`domain\`. '+' (0x2B) is the next byte after '\*' (0x2A), so \`domain+"+"\` sorts immediately past every \`domain+"\*"+...\` key while still sorting before any longer domain (e.g. "meme+" falls between "meme\*zzz" and "memes\*a").

Open
OID
0a344a…4a09:31
domainRange details

Inspect func

accountKey

func(owner .uverse.address, field string) string

accountKey is the per-address store's key: the address, a colon, the field. A bech32 address never contains ":" and a field may not (see assertAccountKey), so the split is unambiguous, and every field of one address sorts into one span.

Open
OID
0a344a…4a09:32
accountKey details

Inspect func

accountRange

func(owner .uverse.address) (start string, end string)

accountRange bounds exactly one address's fields. ';' (0x3B) is the byte after ':' (0x3A), the same trick domainRange plays with '\*' and '+'.

Open
OID
0a344a…4a09:33
accountRange details

Inspect func

splitTokenID

func(tid string) (label string, domain string)

splitTokenID splits a \`label\*domain\` TOKEN ID. Do not use it on a storage key — see the ordering note above.

Open
OID
0a344a…4a09:34
splitTokenID details

Inspect func

mustGetDomain

func(label string) *v1.Domain
Open
OID
0a344a…4a09:35
mustGetDomain details

Inspect func

getDomain

func(label string) (*v1.Domain, bool)
Open
OID
0a344a…4a09:36
getDomain details

Inspect func

mustGetName

func(label string, domain string) *v1.Name
Open
OID
0a344a…4a09:37
mustGetName details

Inspect func

getName

func(label string, domain string) (*v1.Name, bool)
Open
OID
0a344a…4a09:38
getName details

Inspect func

clearPrimaryIfPointingAt

func(owner .uverse.address, tid string)

clearPrimaryIfPointingAt drops \`owner\`'s reverse-resolution pointer when (and only when) it still points at \`tid\`. Called on every ownership change — transfer and reclaim. Without this, \`primary\` was a write-only tree: it had a Set path and no Remove path anywhere in the realm, so selling or losing a name left the previous holder permanently reverse-resolving to a name somebody else now owns. Reverse resolution asserting ownership that is no longer true is the one thing a name service must never do.

Open
OID
0a344a…4a09:39
clearPrimaryIfPointingAt details

Inspect func

emitBy

func(typ string, kv []string)
Open
OID
0a344a…4a09:40
emitBy details

Inspect func

emitConfig

func(key string, value string)

emitConfig is the one event for every typed vault setting.

Open
OID
0a344a…4a09:44
emitConfig details

Inspect func

maxPage

untyped bigint

Value

(200 <untyped> bigint)

pageKeys

func(t *v0.Tree, start string, end string, after string, limit int) (csv string, next string)

pageKeys walks a key span and returns up to \`limit\` keys after the \`after\` cursor, plus the cursor to pass next (empty when exhausted).

Open
OID
0a344a…4a09:45
pageKeys details

Inspect func

ExportDomains

func(after string, limit int) (labels string, next string)

ExportDomains pages through every domain label.

Open
OID
0a344a…4a09:47
ExportDomains details

Inspect func

ExportNames

func(domainLabel string, after string, limit int) (keys string, next string)

ExportNames pages through every name in the registry, as raw storage keys (\`domain\*label\`). Pass an empty domainLabel to walk the whole tree, or a domain to walk just that domain's span.

Open
OID
0a344a…4a09:48
ExportNames details

Inspect func

ExportPrimary

func(after string, limit int) (owners string, next string)

ExportPrimary pages through the reverse-resolution table as owner addresses; pair with GetPrimary to read each value.

Open
OID
0a344a…4a09:49
ExportPrimary details

Inspect func

ExportGlobalKeys

func(after string, limit int) (keys string, next string)

ExportGlobalKeys lists the package-level extension slot's keys; pair with GetGlobal for values.

Open
OID
0a344a…4a09:50
ExportGlobalKeys details

Inspect func

ExportAccounts

func(after string, limit int) (keys string, next string)

ExportAccounts pages through the per-address store as raw keys \`\<address>:\<field>\`; pair with GetAccount for each value. Field names are comma-free by construction (see assertAccountKey).

Open
OID
0a344a…4a09:51
ExportAccounts details

Inspect func

AccountCount

func() int

AccountCount is how many per-address fields exist, so a snapshot of the store can be checked for completeness. A separate read rather than a fifth value from Sizes, whose shape the snapshot tools already parse.

Open
OID
0a344a…4a09:52
AccountCount details

Inspect func

ExportDomainExtraKeys

func(label string, after string, limit int) (keys string, next string)

ExportDomainExtraKeys / ExportNameExtraKeys list a record's extension keys so a snapshot can capture data this realm has no schema for. Keys are comma-free by construction (see assertExtraKey), so a CSV listing is unambiguous.

Open
OID
0a344a…4a09:53
ExportDomainExtraKeys details

Inspect func

ExportNameExtraKeys

func(label string, domainLabel string, after string, limit int) (keys string, next string)

A previous holder's keys are not exported. A snapshot that captured them would carry the seller's payment addresses into a restore as the buyer's.

Open
OID
0a344a…4a09:54
ExportNameExtraKeys details

Inspect func

Sizes

func() (domainCount int, nameCount int, primaryCount int, globalCount int)

Sizes let an operator verify a snapshot is complete rather than trusting that pagination terminated correctly.

Open
OID
0a344a…4a09:55
Sizes details

Inspect func

genesisDomainTerms

untyped bigint

Genesis domains get a long runway. They are project-owned and all created in the same block, so a single term would have every one of them lapse on the same day a year later — and a lapsed domain refuses every registration under it. Renewing them is still the admin's job; this just stops the first renewal being a cliff.

Value

(10 <untyped> bigint)

refusedInGenesis

func(key string, value string) bool

refusedInGenesis names what may never be baked into a registry's birth. Anything whose VALUE is an address: a key that holds power — the free-tier granter was the one that shipped by accident — is set deliberately, after deploy, on the chain it belongs to, never inherited from whatever chain a snapshot was taken on. And the lab nomination, which belongs to a sandbox generation and would otherwise let a hand-edited data file ship a lab on a real domain. No regexp: one compiled pattern costs more storage than this whole file.

Open
OID
0a344a…4a09:56
refusedInGenesis details

Inspect func

looksLikeAddress

func(v string) bool
Open
OID
0a344a…4a09:58
looksLikeAddress details

Inspect func

genesisCfg

type

Value

v1.genesisCfg

genesisDomain

type

Value

v1.genesisDomain

applyGenesis

func(deployer .uverse.address, now int64)
Open
OID
0a344a…4a09:59
applyGenesis details

Inspect func

genesisConfig

func() v1.genesisCfg
Open
OID
0a344a…4a09:60
genesisConfig details

Inspect func

genesisGlobals

func() [][2]string
Open
OID
0a344a…4a09:62
genesisGlobals details

Inspect func

genesisDomains

func() []v1.genesisDomain
Open
OID
0a344a…4a09:63
genesisDomains details

Inspect func

pendingOp

type

Governance and emergency response for a realm that can never be redeployed. Everything here is callable ONLY by a direct wallet transaction — never through a logic realm — so a compromised or buggy logic realm can never touch it. Three powers, deliberately not held by the same key: admin — day-to-day authority: grants/revokes logic realms, tunes config. The warm key. recovery — cannot operate the registry at all. Can only rotate admin, cancel a pending change, revoke a logic realm, and pause. MUST be a multisig in production; see the trust note below for why that is not optional. guardian — can ONLY pause. Nothing else. Safe to keep hot (a monitoring bot), because its compromise costs an outage, never the registry. GRANTING POWER IS SLOW, REVOKING IT IS INSTANT. Handing authority to a new admin or a new logic realm goes through a timelock, and so — since actions.gno — does every admin action in the logic realm that destroys or moves names or money (deletion, lifecycle and treasury changes, unfreezing, reassigning, pricing rules, large price moves). Revocation, cancellation and pause are immediate; undoing a pause takes recovery or the timelock. An attacker holding one key cannot act instantly: they must announce and wait, and every step emits an event. EACH ROLE CAN ROTATE THE OTHER, AND THE ADMIN CANNOT VETO ITS OWN REPLACEMENT. A rotation recovery proposes — of the admin, or of itself — can be cancelled or displaced only by recovery. An admin-initiated rotation of recovery is the admin's to withdraw and, since the re-audit of 2026-10-16, recovery's to veto too: recovery is the root (see the trust note below), and a veto it could not send in its incident sitting reverted the whole sitting, eviction included. A LOST recovery cancels nothing, so the admin can still replace it. Proposals live in PER-KIND slots so an admin rotation and a recovery rotation can never contend for the same slot — an earlier single-slot design let one in-flight proposal freeze the entire governance surface, which meant the honest key could not even propose a response. THE TRUST ASYMMETRY, chosen rather than papered over. Both roles rotate the other on the same timelock, and it used to be that whichever proposed FIRST matured first and won — so a thief holding the admin key, acting before anybody noticed, could take recovery too. Since the re-audit of 2026-10-16 (M-1) RECOVERY WINS: once recovery's eviction is pending, nothing the admin proposed executes before it, a rotation of recovery the admin queued earlier included, and the eviction drops all of it. Every asymmetry hands the mirror-image power to whoever steals the favoured role, and this one is deliberate, the same as the ledger's (nsnft governance.gno): a stolen RECOVERY key now beats an honest admin, which is why recovery must be the cold multisig and the admin the key that is used. The mitigation is therefore operational as well as contractual: - recovery MUST be a multisig, so no single stolen key can use it; - timelockDelay must be long enough that you will actually notice an event within it; - watch for GovernanceProposed and ActionProposed and treat one you did not initiate as an active incident. THE INCIDENT RUNBOOK, in this order (MAINNET.md §1b has it in full). First RevokeTrustedLogic on every entry of ListTrustedLogic(): guardian, admin or recovery may, it is instant, and re-granting needs the timelock, so no stolen key can switch the logic back on. Then Pause, and Disarm (incident.gno). Then, from recovery: the counter-rotation FIRST and alone — proposing it drops everything the admin had pending — then VoidGrantsSince and SetQuarantine (incident.gno), and CancelAllActions / CancelPending on anything left, which cannot revert; execute the eviction at maturity, before anything else. Pause does NOT stop ExecutePending — it stops registry mutations, which limits damage but does not stop a rotation. Do not rely on it for that. RECOVERY'S EVICTION LANDS FIRST, by rule (re-audit 2026-10-16, M-1). An eviction used to drop the admin's plans only when it executed, and anyone chose the order matured proposals ran in: the thief could re-propose a cancelled grant the block after recovery's sitting, or execute recovery's own move to a new cold key first, which dropped recovery's eviction. Now: recovery proposing the eviction DROPS everything the admin had pending — grants, delay, unpause, a rotation of recovery, every timelocked action — so nothing of the admin's is held to spring back if the eviction is cancelled; while it is pending (EvictionPending) the admin proposes nothing, nothing it proposed may execute, and logic can spend none of its actions; a veto holds: what recovery cancels of the admin's, the admin may not propose again for one timelock (any action, after an action veto), so the sitting cannot be re-proposed around; recovery's eviction landing clears the vetoes, and nothing else does; recovery moving ITSELF keeps its eviction: the eviction is protected by the recovery role, which the new key holds, and recovery's rotation of itself is recovery's alone to cancel or displace. Only an admin-initiated replacement of recovery drops the replaced key's eviction. recovery's cancellations are idempotent: cancelling what is no longer pending does nothing, so a thief withdrawing its own proposal first cannot make recovery's batched sitting revert.

Value

v1.pendingOp

recovery

.uverse.address

Value

<gnolang.StringValue>

guardian

.uverse.address

Value

<gnolang.StringValue>

paused

bool

Value

false

timelockDelay

time.Duration

Value

<zero>

maxTimelockDelay

time.Duration

Value

<zero>

absoluteMaxTimelock

time.Duration

Value

<zero>

successor

string

Value

""

assertIsAdminOrRecovery

func()
Open
OID
0a344a…4a09:77
assertIsAdminOrRecovery details

Inspect func

Pause

func()

Pause halts every registry mutation, timelocked actions included. Reads are unaffected, so names stay resolvable while writes are frozen. It deliberately does NOT gate ExecutePending: governance must keep working during an incident — recovery's counter-rotation above all. A pause also drops a pending admin-proposed unpause, so the guardian bot can hold the registry paused against a stolen admin key simply by pausing again whenever it sees UnpauseProposed.

Open
OID
0a344a…4a09:79
Pause details

Inspect func

Unpause

func()

Unpause restarts the registry at once, and only RECOVERY may do that. It used to be open to the admin too, which made a pause useless against the key most likely to be stolen: the admin could unpause in the same multi-message transaction as whatever it did next, so a pause stopped only writers that did not hold admin. An audit showed it. The admin can still unpause — ProposeUnpause, then the timelock — so a false alarm costs a delay rather than the cold key; recovery can cancel that proposal, and any new pause drops it. The guardian is excluded as before: a hot key that can stop the system must not also be able to restart it.

Open
OID
0a344a…4a09:80
Unpause details

Inspect func

ProposeUnpause

func()

ProposeUnpause is the admin's way back from a pause: a proposal like any grant of power, executable by anyone once it matures.

Open
OID
0a344a…4a09:81
ProposeUnpause details

Inspect func

IsTrustedLogic

func(addr .uverse.address) bool
Open
OID
0a344a…4a09:83
IsTrustedLogic details

Inspect func

ListTrustedLogic

func() string
Open
OID
0a344a…4a09:84
ListTrustedLogic details

Inspect func

RevokeTrustedLogic

func(logicAddr .uverse.address)

RevokeTrustedLogic is INSTANT and available to the guardian, because cutting off a misbehaving logic realm is the emergency action that must never wait on a timelock.

Open
OID
0a344a…4a09:85
RevokeTrustedLogic details

Inspect func

ProposeAdminTransfer

func(newAdmin .uverse.address)

ProposeAdminTransfer starts an admin rotation. When recovery initiates it, only recovery may cancel it — the admin being replaced gets no veto over their own replacement.

Open
OID
0a344a…4a09:86
ProposeAdminTransfer details

Inspect func

ProposeRecoveryTransfer

func(newRecovery .uverse.address)

ProposeRecoveryTransfer is the mirror image: when admin initiates it, only admin may cancel it, so a compromised recovery key cannot block its own replacement either.

Open
OID
0a344a…4a09:87
ProposeRecoveryTransfer details

Inspect func

ProposeTrustedLogicGrant

func(logicAddr .uverse.address)
Open
OID
0a344a…4a09:88
ProposeTrustedLogicGrant details

Inspect func

ProposeTimelockDelay

func(seconds int64)

ProposeTimelockDelay is bounded on BOTH sides. An unbounded delay would let a single execution stamp every future proposal with an unreachable maturity, permanently disabling governance in an unredeployable realm.

Open
OID
0a344a…4a09:89
ProposeTimelockDelay details

Inspect func

SetMaxTimelockDelay

func(seconds int64)

SetMaxTimelockDelay raises or lowers the ceiling on timelockDelay. Bounded by absoluteMaxTimelock, and it cannot be set below the delay currently in force.

Open
OID
0a344a…4a09:90
SetMaxTimelockDelay details

Inspect func

canControl

func(op *v1.pendingOp, caller .uverse.address) bool
Open
OID
0a344a…4a09:91
canControl details

Inspect func

getPendingOp

func(kind string) *v1.pendingOp
Open
OID
0a344a…4a09:92
getPendingOp details

Inspect func

EvictionPending

func() bool

EvictionPending reports a pending rotation of the admin that recovery proposed while the two roles are separate keys: recovery replacing an admin it no longer trusts. See the note above pendingOp.

Open
OID
0a344a…4a09:93
EvictionPending details

Inspect func

adminAlone

func(a .uverse.address) bool

adminAlone: the address is the admin and not also recovery — the case every eviction rule is about. While one key holds both, nothing is.

Open
OID
0a344a…4a09:94
adminAlone details

Inspect func

assertAdminMayPropose

func(caller .uverse.address, kind string)

assertAdminMayPropose refuses the admin while recovery is replacing it, and for one timelock after recovery vetoed a proposal of this kind.

Open
OID
0a344a…4a09:95
assertAdminMayPropose details

Inspect func

veto

func(caller .uverse.address, kind string, proposer .uverse.address)

veto starts the cooldown on a kind, when recovery has just cancelled something the admin proposed.

Open
OID
0a344a…4a09:96
veto details

Inspect func

setPending

func(op *v1.pendingOp)
Open
OID
0a344a…4a09:97
setPending details

Inspect func

CancelPending

func(kind string)

CancelPending cancels the pending change of one kind. A proposal with a protectorRole can be cancelled only by that role, so a compromised key cannot veto its own replacement.

Open
OID
0a344a…4a09:98
CancelPending details

Inspect func

ExecutePending

func(kind string)

ExecutePending applies a matured change. Callable by anyone on purpose: execution must not depend on a particular key still being available, since key unavailability is one of the things being recovered from. It only applies what was already proposed and survived its window.

Open
OID
0a344a…4a09:99
ExecutePending details

Inspect func

dropPendingProtectedBy

func(kind string, role string)

dropPendingProtectedBy removes the pending change of \`kind\` when it is protected by \`role\` — used when that role's key has just been replaced.

Open
OID
0a344a…4a09:100
dropPendingProtectedBy details

Inspect func

adminOnlyKinds

[]string (len=3)

adminOnlyKinds are the proposals only the admin can make. Every one of them dies when the admin rotates: whoever proposed it no longer holds the key that could, and an eviction that leaves the evicted key's plans running has not evicted anybody.

Open
OID
0a344a…4a09:102
adminOnlyKinds details (len=3)

+3 more Inspect slice

dropAdminProposals

func(reason string)
Open
OID
0a344a…4a09:103
dropAdminProposals details

Inspect func

GetPending

func(kind string) (addr .uverse.address, executableAt time.Time, protectorRole string)
Open
OID
0a344a…4a09:104
GetPending details

Inspect func

GetPendingDetail

func(kind string) (addr .uverse.address, seconds int64, executableAt time.Time, protectorRole string, by .uverse.address)

GetPendingDetail is GetPending with the rest of the proposal: the delay a "delay" proposal would install, in seconds — which GetPending could not show, so "set the delay to zero" and "raise it" looked identical — and who proposed it.

Open
OID
0a344a…4a09:105
GetPendingDetail details

Inspect func

SetGuardian

func(addr .uverse.address)

SetGuardian takes the RECOVERY key, to seat a guardian as much as to replace one. Replacing took recovery from the start: otherwise the first move of anyone who steals the admin key is to point the guardian at themselves, disarming the emergency stop before you can use it. Seating an EMPTY seat used to be the admin's too, and that was the same hole: a stolen admin key seated its own bot, and after its eviction that bot could still pause and revoke, removable only by recovery (re-audit 2026-10-16, L-4). The deploy seats the guardian while its key still holds recovery.

Open
OID
0a344a…4a09:107
SetGuardian details

Inspect func

ClearGuardian

func()

ClearGuardian stands the pause capability down. "Removing a power is never the dangerous direction" was the old reasoning here, and it is wrong in one specific way: removing this power restores the state in which SetGuardian is admin-callable. SetGuardian demands the RECOVERY key whenever a guardian is already set, and says why — a stolen admin key must not be able to disarm the emergency stop. ClearGuardian then SetGuardian was a two-transaction admin-only replacement of a live guardian, which defeats exactly that rule. So standing down a LIVE guardian now takes the same key that replacing one takes. Clearing when there is no guardian stays open to either role, because then there is nothing to defeat. The practical stakes are small — assertCanPause admits admin, recovery and guardian, so an operator holding recovery keeps Pause and RevokeTrustedLogic either way. It is fixed because this realm can never be redeployed, and a documented authorization rule that a two-call sequence walks around is not something to leave in permanent code.

Open
OID
0a344a…4a09:108
ClearGuardian details

Inspect func

SetSuccessor

func(s string)

SetSuccessor records where this registry moved, if it ever has to be abandoned. Pair it with Pause() so the retired registry cannot drift away from the snapshot its successor was built from.

Open
OID
0a344a…4a09:109
SetSuccessor details

Inspect func

GetAdmin

func() .uverse.address
Open
OID
0a344a…4a09:110
GetAdmin details

Inspect func

GetRecovery

func() .uverse.address
Open
OID
0a344a…4a09:111
GetRecovery details

Inspect func

GetGuardian

func() .uverse.address
Open
OID
0a344a…4a09:112
GetGuardian details

Inspect func

GetTimelockDelay

func() time.Duration
Open
OID
0a344a…4a09:114
GetTimelockDelay details

Inspect func

GetMaxTimelockDelay

func() time.Duration
Open
OID
0a344a…4a09:115
GetMaxTimelockDelay details

Inspect func

disarmKeys

[]string (len=3)

disarmKeys are the globals whose presence is a power and whose absence is the safe reading (nslogic: credits.gno, freetier.gno, keeper.gno).

Open
OID
0a344a…4a09:117
disarmKeys details (len=3)

+3 more Inspect slice

maxGrantVoids

untyped bigint

// void windows kept; the oldest two merge past it

Value

(8 <untyped> bigint)

maxQuarantine

int64

// the furthest a quarantine may reach, in seconds

Value

2592000

quarantineUntil

int64

Value

0

assertIsRecovery

func()
Open
OID
0a344a…4a09:120
assertIsRecovery details

Inspect func

Disarm

func()

Disarm deletes the claim window, the granter and the keeper at once. Admin, recovery or guardian, as a direct wallet call; it works while the registry is paused and with every logic realm revoked.

Open
OID
0a344a…4a09:122
Disarm details

Inspect func

VoidGrantsSince

func(since int64)

VoidGrantsSince voids every grant made at or after \`since\`, up to now. Recovery only. \`since\` may be 0 (everything so far) and may not be in the future. The window joins the ones already in force; past maxGrantVoids the two oldest merge, which can only void more, never less.

Open
OID
0a344a…4a09:123
VoidGrantsSince details

Inspect func

insertVoid

func(ws [][2]int64, w [2]int64) [][2]int64

insertVoid keeps the windows sorted by start and folds overlapping ones together, so "the gap between two windows" means what it says.

Open
OID
0a344a…4a09:124
insertVoid details

Inspect func

GrantVoided

func(at int64) bool

GrantVoided reports whether a grant made at unix second \`at\` falls inside a void recovery declared.

Open
OID
0a344a…4a09:125
GrantVoided details

Inspect func

GrantVoids

func() string

GrantVoids lists the void windows, "from-to" comma-separated, oldest first.

Open
OID
0a344a…4a09:126
GrantVoids details

Inspect func

SetQuarantine

func(until int64)

SetQuarantine holds every giveaway shut until \`until\` (unix seconds), at most maxQuarantine ahead; 0 lifts it. Recovery only.

Open
OID
0a344a…4a09:127
SetQuarantine details

Inspect func

QuarantineUntil

func() int64

QuarantineUntil is the unix second giveaways may run again, 0 for none.

Open
OID
0a344a…4a09:128
QuarantineUntil details

Inspect func

Quarantined

func() bool

Quarantined reports whether a quarantine holds right now.

Open
OID
0a344a…4a09:129
Quarantined details

Inspect func

isTokenValid

func(tid string) bool
Open
OID
0a344a…4a09:130
isTokenValid details

Inspect func

BalanceOf

func(owner .uverse.address) int64

BalanceOf counts every token an address holds — including free-tier tokens, which are held rather than absent. That is a real change from the previous generation, where a free name had no token and counted for nothing; nsvote gates on this, so free-tier holders now have a vote.

Open
OID
0a344a…4a09:132
BalanceOf details

Inspect func

OwnerOf

func(tid string) .uverse.address
Open
OID
0a344a…4a09:133
OwnerOf details

Inspect func

GetApproved

func(tid string) .uverse.address
Open
OID
0a344a…4a09:134
GetApproved details

Inspect func

IsApprovedFor

func(tid string, operator .uverse.address) bool

IsApprovedFor is the question a marketplace actually has: may this operator move this token, by either route?

Open
OID
0a344a…4a09:135
IsApprovedFor details

Inspect func

IsApprovedForAll

func(owner .uverse.address, operator .uverse.address) bool
Open
OID
0a344a…4a09:136
IsApprovedForAll details

Inspect func

TokenURI

func(tid string) string

TokenURI returns a pointer at whichever view realm renders the art. nsnft has its own URI base for external marketplaces; both are set to the same view realm at wiring time.

Open
OID
0a344a…4a09:137
TokenURI details

Inspect func

ListNames

func(domainLabel string) string

ListNames and CountNames scan only the key span belonging to \`domainLabel\` (see domainRange in auth.gno), costing O(names in that domain) rather than O(every name in the registry).

Open
OID
0a344a…4a09:140
ListNames details

Inspect func

CountNames

func(domainLabel string) int64
Open
OID
0a344a…4a09:141
CountNames details

Inspect func

DomainExists

func(label string) bool
Open
OID
0a344a…4a09:143
DomainExists details

Inspect func

NameExists

func(label string, domainLabel string) bool
Open
OID
0a344a…4a09:144
NameExists details

Inspect func

GetDomainOwner

func(label string) .uverse.address
Open
OID
0a344a…4a09:145
GetDomainOwner details

Inspect func

GetNameOwner

func(label string, domainLabel string) .uverse.address
Open
OID
0a344a…4a09:146
GetNameOwner details

Inspect func

GetDomainInfo

func(label string) (owner .uverse.address, registered int64, expires int64, streak int64, frozen bool)

GetDomainInfo / GetNameInfo return a whole record in one call, so a view realm can render a page without six round trips. Timestamps come back as unix SECONDS. They used to be time.Time, which vm/qeval rendered using gno's internal epoch, so every consumer had to know to subtract 62135596800 — our own frontend did exactly that. Returning unix seconds stops leaking that offset into every integration, and it is what the records now hold anyway. \`streak\` is computed from the registration date rather than read from a stored field. See streakOf.

Open
OID
0a344a…4a09:147
GetDomainInfo details

Inspect func

GetNameInfo

func(label string, domainLabel string) (owner .uverse.address, registered int64, expires int64, streak int64, frozen bool, paid bool)

GetNameInfo keeps its six-value shape so every existing reader — nslogic, nsview, nsskin, nsvote, the site, both snapshot tools — goes on parsing it unchanged. Two of the six are now answered differently: owner is read from nsnft, never stored here. The snapshot tools record whatever this returns, so they now record the real owner — the restore-hands-sold-names-back bug the first attempt had cannot happen, because there is no stale copy for them to read. paid replaces isNFT and means exactly one thing: the name is NOT held as an un-upgraded free-tier record. It is deliberately not "transferable" — a frozen paid name is locked too, and reading the lock would have made a frozen paid name look free, which is precisely the proxy bug that let free renewals renew paid names.

Open
OID
0a344a…4a09:148
GetNameInfo details

Inspect func

GetNameTTL

func(label string, domainLabel string) int64

GetNameTTL / GetDomainTTL report how long a resolver may cache an answer about this record, in seconds, where 0 MEANS NEVER CACHE — the ENS registry's rule, deliberately, so integrators need not read anything of ours to handle it correctly. A TTL written for a previous holder is not this holder's cache policy. A stale one reads as 0 — never cache — which is the safe answer during exactly the window after a sale when a cached answer pays the seller.

Open
OID
0a344a…4a09:149
GetNameTTL details

Inspect func

GetDomainTTL

func(label string) int64
Open
OID
0a344a…4a09:150
GetDomainTTL details

Inspect func

GetNameHeldSince

func(label string, domainLabel string) int64

GetNameHeldSince is when the current holder's holding began, in unix seconds — or 0 when the ledger has moved on since this registry last saw the record (a sale it has not yet observed). It can understate a holding, never overstate one. See Name.since.

Open
OID
0a344a…4a09:151
GetNameHeldSince details

Inspect func

RestoredFor

func(label string, domainLabel string) .uverse.address
Open
OID
0a344a…4a09:152
RestoredFor details

Inspect func

IsNamePaid

func(label string, domainLabel string) bool

IsNamePaid reports that a name is not held as an un-upgraded free-tier record. See GetNameInfo on why this is not "transferable".

Open
OID
0a344a…4a09:153
IsNamePaid details

Inspect func

IsDomainValid

func(label string) bool
Open
OID
0a344a…4a09:154
IsDomainValid details

Inspect func

IsNameValid

func(label string, domainLabel string) bool
Open
OID
0a344a…4a09:155
IsNameValid details

Inspect func

GetDomainExtra

func(label string, key string) string
Open
OID
0a344a…4a09:156
GetDomainExtra details

Inspect func

GetNameExtra

func(label string, domainLabel string, key string) string

GetNameExtra answers EMPTY for data written in a previous ownership epoch. This is the read half of the lazy wipe. A sale that settles on nsnft — through our marketplace or anybody else's — never calls this realm, so nothing here can clear the seller's payment addresses at the moment it happens. What this CAN do is refuse to repeat them: the instant the ledger's epoch moves, every extra on the name stops answering, for every reader, before anybody has written anything. The write half, which destroys the stale data rather than hiding it, is freshen in write.gno. Both halves are needed: hiding alone is what the first attempt shipped, and the buyer's first edit brought the seller's Bitcoin address back as the buyer's.

Open
OID
0a344a…4a09:157
GetNameExtra details

Inspect func

GetGlobal

func(key string) string
Open
OID
0a344a…4a09:158
GetGlobal details

Inspect func

GetAccount

func(owner .uverse.address, key string) string

GetAccount reads one field of an address's own record, or "" when it has none. See \`accounts\` in types.gno.

Open
OID
0a344a…4a09:159
GetAccount details

Inspect func

GetPrimary

func(owner .uverse.address) string

GetPrimary is a raw pointer lookup. It reports what an address last SELECTED, not what it still owns — callers presenting this as reverse resolution must re-check ownership (see nslogic.ResolveAddress).

Open
OID
0a344a…4a09:160
GetPrimary details

Inspect func

GetTreasury

func() .uverse.address
Open
OID
0a344a…4a09:161
GetTreasury details

Inspect func

GetTermLength

func() int64
Open
OID
0a344a…4a09:162
GetTermLength details

Inspect func

GetGracePeriod

func() int64
Open
OID
0a344a…4a09:163
GetGracePeriod details

Inspect func

GetMaxDeletePerCall

func() int
Open
OID
0a344a…4a09:164
GetMaxDeletePerCall details

Inspect func

GetLabelPattern

func() string
Open
OID
0a344a…4a09:165
GetLabelPattern details

Inspect func

GetLabelLength

func() (min int, max int)
Open
OID
0a344a…4a09:166
GetLabelLength details

Inspect func

GetTokenURIBase

func() string
Open
OID
0a344a…4a09:167
GetTokenURIBase details

Inspect func

GetExtraLimits

func() (k int, v int, entries int)
Open
OID
0a344a…4a09:168
GetExtraLimits details

Inspect func

GetGlobalEntryLimit

func() int
Open
OID
0a344a…4a09:169
GetGlobalEntryLimit details

Inspect func

GetAccountLimits

func() (k int, v int, entries int)
Open
OID
0a344a…4a09:170
GetAccountLimits details

Inspect func

Render

func(path string) string

The real human-facing view moved OUT of this realm into \`nsview\` (2026-08-21), after an adversarial review found three separate defects in the old Render() — unescaped profile-field injection into the markdown, an O(domains × names) home page any user could inflate into a permanent DoS, and links that 404'd — none of which could ever be fixed, because this realm is deployed once and never replaced. The lesson generalised: "it's only display code, it has no authorization surface" was the wrong test for what belongs in an immutable realm. The right test is whether a bug in it would be permanent. Display code changes far more often than storage schemas do, so it belongs in something swappable. What remains here is deliberately a fixed string: no user-authored data, no iteration over state, nothing that can be wrong later.

Open
OID
0a344a…4a09:171
Render details

Inspect func

Domain

type

Timestamps are unix SECONDS, not time.Time, and that is the single biggest storage decision in this file. Measured on three throwaway realms (MAINNET.md §3d-i): two time.Time fields were 70% of a record, because each carries an unused nanosecond field and a \*Location pointer for a value that is always UTC. Switching to int64 takes a real 7,385-byte domain record to 6,246 bytes on its own, and turns every lifecycle comparison into integer arithmetic. Nothing here stores a label. The AVL key already holds it — \`label\` for a domain, \`domain\*label\` for a name — so a copy inside the record was paying storage forever to duplicate the thing used to find it.

Value

v1.Domain

Name

type

Name has NO OWNER FIELD, and that absence is the whole design. The first attempt at moving ownership into a token realm kept a copy of the owner here, and every bug it had followed from the copy: renewal checked the copy and refused the real owner after a sale, snapshots recorded the copy and would have handed sold names back to their sellers on restore. There is one owner and it lives in nsnft. Every read asks it. It also has no isNFT flag. Every name is a token; a free-tier name is a token with a hold on it (lockBitFree). Four separate places used to read "has no token" as "is free", and deleting the flag deletes that class of bug rather than fixing four instances of it.

Value

v1.Name

lockBitFree

untyped bigint

// free tier, not yet paid for: not sellable

Value

(0 <untyped> bigint)

lockBitFrozen

untyped bigint

// frozen by an admin: not movable while disputed

Value

(1 <untyped> bigint)

admin

.uverse.address

// the vault door — see governance.gno for the full role model

Value

<gnolang.StringValue>

trustedLogicSet

v0.Tree
Open
OID
0a344a…4a09:185
trustedLogicSet details

Inspect ref

treasury

.uverse.address

Value

<gnolang.StringValue>

termLength

int64

Value

31536000

gracePeriod

int64

Value

7776000

labelPattern

string

Value

"^[a-z0-9]+(-[a-z0-9]+)*$"

minLabelLen

int

Value

1

maxLabelLen

int

Value

63

maxExtraKeyLen

int

Value

32

maxExtraValueLen

int

Value

512

maxExtraEntries

int

Value

24

maxGlobalEntries

int

Value

64

maxAccountKeyLen

int

Value

16

maxAccountValueLen

int

Value

128

maxAccountEntries

int

Value

8

maxDeletePerCall

int

Value

100

tokenURIBase

string

Value

"/r/nym-mnsrehearsal001/nsview/v1:token/"

RegisterDomainRecord

func(label string, owner .uverse.address, now int64) .uverse.error
Open
OID
0a344a…4a09:203
RegisterDomainRecord details

Inspect func

ReassignDomainRecord

func(label string, to .uverse.address) .uverse.error

ReassignDomainRecord moves a domain to a new owner and leaves its configuration exactly where it was. This is the durable fix nslogic.ReassignDomain's comment was waiting for. The old path moved a domain through the name-transfer machinery, whose wipe exists to clear a SELLER'S payment addresses — and so it silently reopened closed domains, dropped their pricing to the default and released their term caps, during the key-compromise recovery it exists for. A domain's extras are its settings, not a previous holder's data, and there is no previous holder: domains never reach a third party. TTL resets, because it is the one field that is a caching promise made by whoever held the record.

Open
OID
0a344a…4a09:205
ReassignDomainRecord details

Inspect func

RenewDomainRecord

func(label string, caller .uverse.address, now int64) .uverse.error
Open
OID
0a344a…4a09:206
RenewDomainRecord details

Inspect func

advanceTerm

func(expires int64, now int64) int64

advanceTerm extends a term by exactly one term-length from its PREVIOUS due date — never from \`now\`, because the grace period must not silently extend the term somebody paid for. It no longer returns a streak. The streak used to be maintained here, with a guard against renewing repeatedly in one block to inflate it; that whole class of problem disappeared when the streak became a function of the registration date instead of a stored counter. See streakOf in auth.gno.

Open
OID
0a344a…4a09:207
advanceTerm details

Inspect func

SetDomainFrozen

func(label string, frozen bool)
Open
OID
0a344a…4a09:208
SetDomainFrozen details

Inspect func

SetDomainExpiryRecord

func(label string, expires int64)
Open
OID
0a344a…4a09:209
SetDomainExpiryRecord details

Inspect func

SetDomainTTLRecord

func(label string, ttl int64) .uverse.error

SetDomainTTLRecord sets how long a resolver may cache answers about this domain, in seconds, where 0 means never cache. See Domain.ttl.

Open
OID
0a344a…4a09:210
SetDomainTTLRecord details

Inspect func

SetDomainExtraRecord

func(label string, key string, value string) .uverse.error

SetDomainExtraRecord writes one arbitrary key on a domain — pricing, or whatever a future logic realm needs. An empty value deletes the key, so storage can be reclaimed.

Open
OID
0a344a…4a09:211
SetDomainExtraRecord details

Inspect func

DeleteDomainRecord

func(label string) (removed int64, done bool)

DeleteDomainRecord destroys a domain and the names beneath it: it burns every token, drops every reverse-resolution pointer into them, removes the records, and finally removes the domain itself. WHY IT EXISTS. Retiring a domain after a brand complaint, recovering the storage deposit on a domain that never sold, and clearing out fad domains nobody renewed. A logic realm cannot provide any of this, because the vault owns the trees and exposed no delete path — the only Remove call for a domain lived inside RegisterDomainRecord as the evict-and-replace step of re-registration. IT DELIBERATELY WORKS ON A DOMAIN WITH LIVE NAMES UNDER IT. The case this exists for is a demand to remove a domain entirely, where waiting for names to lapse is not an option. Compensating the holders is handled off chain and is deliberately not a contract concern. WHERE THIS DEPARTS FROM THE SPEC, stated plainly because it is a real difference: MAINNET.md §3d asks for all of it "in one call". It is bounded instead, deleting at most maxDeletePerCall names per call and reporting whether it finished. An unbounded loop over a tree that may hold any number of names is a transaction that stops fitting in a block once a domain gets popular — which would mean the domains most likely to attract a complaint are exactly the ones that could never be deleted, in a realm that can never be fixed. The caller repeats until \`done\`; for any domain of realistic size that is one call, so the no-preconditions requirement is preserved. What is NOT preserved is atomicity: a multi-call deletion is visible half-done between calls. Freeze the domain first if that matters, so nothing new lands under it meanwhile. Not Pause(): a paused registry deletes nothing at all, since this passes the same trust gate as every write. Calling it on a domain that does not exist is a no-op reporting done, so a repeat loop terminates cleanly rather than panicking on the call that follows the last one.

Open
OID
0a344a…4a09:212
DeleteDomainRecord details

Inspect func

RegisterNameRecord

func(label string, domainLabel string, owner .uverse.address, now int64, paid bool) .uverse.error

RegisterNameRecord creates \`label\*domain\` and mints its token in nsnft. \`paid\` false registers a FREE-TIER name: the token is minted with the free hold already set, so there is never an instant in which it could be approved and sold before a lock arrived. There is no longer any such thing as a name without a token — see Name. RECLAIM burns the previous holder's token first. The owner is read from the ledger, never from the record, because the record has no owner. AN ORPHAN TOKEN IS REFUSED. A token that exists with no record behind it means a registry swap is mid-migration or something has gone wrong; either way, registering over it would mint a second claim to a name somebody already holds. RestoreNameRecord is the door for adopting one.

Open
OID
0a344a…4a09:213
RegisterNameRecord details

Inspect func

holdBits

func(paid bool, frozen bool) int
Open
OID
0a344a…4a09:214
holdBits details

Inspect func

setPrimaryIfNone

func(owner .uverse.address, tid string)

setPrimaryIfNone gives an address a reverse pointer when it has none — or when the one it has points at a name it no longer holds. The second half is new. A pointer used to be cleared on every transfer, because transfers went through this realm. They no longer do: a sale that settles on nsnft leaves the seller's pointer aimed at a name they sold. nslogic.ResolveAddress already refuses to answer with it, so it never misleads anybody — but left in place it also blocked the seller's NEXT registration from becoming their primary, which would have looked like a bug in registration rather than a stale pointer.

Open
OID
0a344a…4a09:215
setPrimaryIfNone details

Inspect func

UpgradeFreeRecord

func(label string, domainLabel string, newOwner .uverse.address) .uverse.error

UpgradeFreeRecord lifts the free-tier hold — the paid upgrade. Preserves the dates: this is not a re-registration. \`newOwner\` exists because the common case is somebody who decided to sell and, in the same moment, wants the name in a wallet they control rather than the key they were given. That move is a burn and a mint here, because a held token cannot be transferred by design. THE PROFILE DOES NOT GO WITH IT, and it used to. The move re-stamped the old data to the new epoch and gave the recipient a reverse pointer — and \`newOwner\` can be ANY address. An audit spelled out the attack: fill a free name's profile with your own pay addresses, pay list price to upgrade it into a victim's wallet, and the victim's name now asks people to pay you, their address reverse-resolves to it, and their own later edits do not clear it because the epoch is already current. So the data is left in the previous epoch, where every read hides it and the next write destroys it, and the recipient gets no pointer they never chose. A person moving their own name to a new wallet re-enters their profile once; that is the price of the move not being usable against somebody else. Refused for a frozen name. Upgrading must never be the way a disputed name gets out of its hold.

Open
OID
0a344a…4a09:216
UpgradeFreeRecord details

Inspect func

RestoreNameRecord

func(label string, domainLabel string, owner .uverse.address, registered int64, paid bool) .uverse.error

RestoreNameRecord is the migration door: records move, tokens do not. A registry swapped in behind the same nsnft finds tokens that already exist. This writes the record for one and ADOPTS its token, or mints one when the ledger has none. It never moves a token: a snapshot must never take a name from its current holder. WHEN THE LEDGER DISAGREES WITH THE SNAPSHOT, IT WINS. This used to refuse, and an audit showed where refusing leads: a name sold between the snapshot and the restore panics the batch, gets dropped to finish the rest, and the window seals — leaving the buyer's token with no record behind it, unable to be renewed, resolved or registered, forever. So the record is written for whoever holds the token now, and the snapshot's profile data is NOT replayable onto it (restoredFor stays empty), because it was the seller's. Gated like every write, and nslogic only reaches it through the restore window, which is one-shot.

Open
OID
0a344a…4a09:217
RestoreNameRecord details

Inspect func

RenewNameRecord

func(label string, domainLabel string, caller .uverse.address, now int64) .uverse.error
Open
OID
0a344a…4a09:218
RenewNameRecord details

Inspect func

SetNameFrozen

func(label string, domainLabel string, frozen bool)

SetNameFrozen sets the record's frozen bit AND the matching hold on the token, in the same call. The record bit alone used to be the whole mechanism, and it bound nothing outside our own transfer wrappers — a disputed name could be moved on any marketplace that called the token directly. The hold in nsnft binds every path there is.

Open
OID
0a344a…4a09:219
SetNameFrozen details

Inspect func

SetNameExpiryRecord

func(label string, domainLabel string, expires int64)

SetNameExpiryRecord sets an expiry directly. Backs the admin free-extension lever (SPEC.md §19) and any future term mechanic; the logic realm decides who may call it.

Open
OID
0a344a…4a09:220
SetNameExpiryRecord details

Inspect func

SetNameTTLRecord

func(label string, domainLabel string, ttl int64) .uverse.error

SetNameTTLRecord sets how long a resolver may cache answers about this name, in seconds, where 0 means never cache. See Domain.ttl for why this exists and why the owner rather than the registry sets it.

Open
OID
0a344a…4a09:221
SetNameTTLRecord details

Inspect func

SetNameExtraRecord

func(label string, domainLabel string, key string, value string) .uverse.error

SetNameExtraRecord writes one arbitrary key on a name. This is where profile fields, cross-chain addresses, management-key hashes and tier markers live. An empty value deletes the key.

Open
OID
0a344a…4a09:222
SetNameExtraRecord details

Inspect func

freshen

func(n *v1.Name, tid string)

freshen is the WRITE half of the lazy wipe, and it is the half the first attempt described in prose and never wrote. If a name's data belongs to a previous ownership epoch, every extra and the TTL are destroyed, and the record is re-stamped to the current epoch — BEFORE the new value is written. So the buyer's first edit cannot carry the seller's Bitcoin address forward as the buyer's: by the time the edit lands, the address is gone. It wipes everything rather than a list of sensitive keys, for the same reason the old transfer wipe did: which keys matter is policy, and a list kept here would be wrong the first time nslogic invents a key. The read half — hiding stale data from everybody the instant the epoch moves — is isFresh, used by every name read. It is also where a buyer's holding clock starts (Name.since): the first moment this realm can see that the ledger has moved on.

Open
OID
0a344a…4a09:223
freshen details

Inspect func

freshenTo

func(n *v1.Name, epoch int64, now int64)

freshenTo is freshen with the ledger's answer and the clock passed in, so the rule itself can be tested without a registry the ledger trusts.

Open
OID
0a344a…4a09:224
freshenTo details

Inspect func

FreshenNameRecord

func(label string, domainLabel string) .uverse.error

FreshenNameRecord applies freshen and writes nothing else: the way a holder who bought a name starts its clock (Name.since) without having to invent a profile edit. For the current holder, freshen destroys only data every read already hides.

Open
OID
0a344a…4a09:225
FreshenNameRecord details

Inspect func

SetPrimaryRecord

func(owner .uverse.address, label string, domainLabel string) .uverse.error
Open
OID
0a344a…4a09:226
SetPrimaryRecord details

Inspect func

ClearPrimaryRecord

func(owner .uverse.address)
Open
OID
0a344a…4a09:227
ClearPrimaryRecord details

Inspect func

SetTreasuryRecord

func(addr .uverse.address)
Open
OID
0a344a…4a09:228
SetTreasuryRecord details

Inspect func

SetTermLengthRecord

func(seconds int64)

The lifecycle setters refuse the two values that would break the lifecycle for everybody: a term of zero or less, and a negative grace period, which made live names reclaimable early (audit L-2). nslogic bounds both too; a future logic realm need not.

Open
OID
0a344a…4a09:229
SetTermLengthRecord details

Inspect func

SetGracePeriodRecord

func(seconds int64)
Open
OID
0a344a…4a09:230
SetGracePeriodRecord details

Inspect func

SetMaxDeletePerCallRecord

func(n int)

SetMaxDeletePerCallRecord tunes how much work one DeleteDomainRecord call will do. See maxDeletePerCall in types.gno.

Open
OID
0a344a…4a09:231
SetMaxDeletePerCallRecord details

Inspect func

SetLabelPatternRecord

func(pattern string)
Open
OID
0a344a…4a09:232
SetLabelPatternRecord details

Inspect func

SetTokenURIBaseRecord

func(base string)
Open
OID
0a344a…4a09:233
SetTokenURIBaseRecord details

Inspect func

SetLabelLengthRecord

func(minLen int, maxLen int)
Open
OID
0a344a…4a09:234
SetLabelLengthRecord details

Inspect func

SetExtraLimitsRecord

func(keyLen int, valueLen int, entries int)
Open
OID
0a344a…4a09:235
SetExtraLimitsRecord details

Inspect func

SetGlobalEntryLimitRecord

func(entries int)

SetGlobalEntryLimitRecord sets how many keys globals may hold, apart from the per-record extras cap. See maxGlobalEntries.

Open
OID
0a344a…4a09:236
SetGlobalEntryLimitRecord details

Inspect func

SetAccountLimitsRecord

func(keyLen int, valueLen int, entries int)

SetAccountLimitsRecord bounds the per-address store. Lowering a cap never deletes anything; it only refuses the next write that exceeds it.

Open
OID
0a344a…4a09:237
SetAccountLimitsRecord details

Inspect func

SetAccountRecord

func(owner .uverse.address, key string, value string) .uverse.error

SetAccountRecord writes one field of an address's own record: a credit balance, a counter, whatever a logic realm keeps per wallet. An empty value deletes the field, so its storage can be reclaimed. Bounded like the extras, with caps of its own: the field name, the value, and how many fields one address may hold. The fields-per-address cap is what keeps any single wallet's footprint small, whoever pays for it.

Open
OID
0a344a…4a09:238
SetAccountRecord details

Inspect func

accountFields

func(owner .uverse.address) int

accountFields counts one address's fields, stopping at the cap: the only question asked of it is whether the cap is reached, and an unbounded walk is not something a write path should contain.

Open
OID
0a344a…4a09:239
accountFields details

Inspect func

assertAccountKey

func(key string) .uverse.error

assertAccountKey keeps field names short and free of the characters that would make a snapshot listing ambiguous, and of ':', which separates the address from the field.

Open
OID
0a344a…4a09:240
assertAccountKey details

Inspect func

reservedGlobals

[]string (len=2)

SetGlobalRecord writes one arbitrary package-level key — fee rates, default prices, a custodian address, points balances, claim records. Anything global that does not exist yet goes here instead of needing a package variable that could never be added after deployment. Keys the restore machinery owns. Written only by RestoreGlobal's own path, never by a general setter — because nslogic's SetGlobal forwards whatever key an admin passes, and one call writing "restore" reopened a seal that restore.gno calls irreversible. Enforced HERE as well as there, so a future logic realm cannot drop the guard by forgetting it.

Open
OID
0a344a…4a09:242
reservedGlobals details (len=2)

+2 more Inspect slice

SetGlobalRecord

func(key string, value string) .uverse.error
Open
OID
0a344a…4a09:243
SetGlobalRecord details

Inspect func

setGlobal

func(key string, value string) .uverse.error

setGlobal is setExtra held to globals' own entry cap.

Open
OID
0a344a…4a09:244
setGlobal details

Inspect func

SetReservedGlobalRecord

func(key string, value string) .uverse.error

SetReservedGlobalRecord is the restore machinery's own door to the keys above. Same trust gate; separate name, so a general-purpose setter can never reach them by accident.

Open
OID
0a344a…4a09:245
SetReservedGlobalRecord details

Inspect func

setExtra

func(t *v0.Tree, key string, value string) .uverse.error

setExtra applies the shared bounds and the delete-on-empty rule to a name's or a domain's extras.

Open
OID
0a344a…4a09:246
setExtra details

Inspect func

setExtraCapped

func(t *v0.Tree, key string, value string, maxEntries int) .uverse.error
Open
OID
0a344a…4a09:247
setExtraCapped details

Inspect func

assertExtraKey

func(key string) .uverse.error

assertExtraKey keeps extension keys free of the characters that would make a snapshot ambiguous. Export lists keys as CSV, so a key containing a comma or a newline would silently corrupt a backup — and a backup you cannot trust is the one thing this realm cannot afford.

Open
OID
0a344a…4a09:248
assertExtraKey details

Inspect func

assertLabelKeySafe

func(label string) .uverse.error

assertLabelKeySafe is a STRUCTURAL check, not a policy one. Character policy lives in the logic realm's tunable labelPattern; this is the narrow set of characters that would break the vault's own machinery no matter what policy is in force: "*" is the separator in both key encodings, so a label containing one makes storage keys and token ids ambiguous; "," and newlines would corrupt the CSV snapshot exports, which are the disaster-recovery guarantee — assertExtraKey already refuses them for extension keys, and labels become keys just as much; "" cannot address a record at all. Enforcing it here rather than trusting the logic realm matters because labelPattern is admin-tunable: loosening it must never be able to silently corrupt a backup in a realm that cannot be redeployed.

Open
OID
0a344a…4a09:249
assertLabelKeySafe details

Inspect func

errStr

func(s string) .uverse.error
Open
OID
0a344a…4a09:250
errStr details

Inspect func
pendingAction : type =v1.pendingAction
pendingActions : v0.Tree Inspect
maxPendingActions : int =32
actionWindow : int64 =604800
maxActionIDLen : untyped bigint =(2048 <untyped> bigint)
minActionWindow : int64 =3600
maxActionWindowS : int64 =7776000
getAction : func(id string) *v1.pendingAction Inspect
assertActionID : func(id string) Inspect
ProposeAction : func(id string) Inspect
CancelAction : func(id string) Inspect
CancelAllActions : func() Inspect
ConsumeAction : func(id string) Inspect
ActionReady : func(id string) bool Inspect
GetAction : func(id string) (executableAt int64, expiresAt int64, by .uverse.address) Inspect
ListActions : func(after string, limit int) (ids string, next string) Inspect
GetActionWindow : func() int64 Inspect
SetActionWindow : func(seconds int64) Inspect
pruneExpiredActions : func(now int64) Inspect
dropAllActions : func(reason string) int Inspect
isFresh : func(n *v1.Name, tid string) bool Inspect
freshAt : func(n *v1.Name, epoch int64) bool Inspect
ownsNow : func(addr .uverse.address, tid string) bool Inspect
isValidNow : func(expires int64, now int64) bool Inspect
isReclaimable : func(expires int64, now int64) bool Inspect
streakOf : func(registered int64, now int64) int64 Inspect
assertIsTrustedLogic : func() Inspect
nameTreeKey : func(label string, domain string) string Inspect
nameTokenID : func(label string, domain string) string Inspect
domainRange : func(domain string) (start string, end string) Inspect
accountKey : func(owner .uverse.address, field string) string Inspect
accountRange : func(owner .uverse.address) (start string, end string) Inspect
splitTokenID : func(tid string) (label string, domain string) Inspect
mustGetDomain : func(label string) *v1.Domain Inspect
getDomain : func(label string) (*v1.Domain, bool) Inspect
mustGetName : func(label string, domain string) *v1.Name Inspect
getName : func(label string, domain string) (*v1.Name, bool) Inspect
clearPrimaryIfPointingAt : func(owner .uverse.address, tid string) Inspect
emitBy : func(typ string, kv []string) Inspect
i64 : func(n int64) string Inspect
boolStr : func(b bool) string Inspect
emitConfig : func(key string, value string) Inspect
maxPage : untyped bigint =(200 <untyped> bigint)
pageKeys : func(t *v0.Tree, start string, end string, after string, limit int) (csv string, next string) Inspect
ExportDomains : func(after string, limit int) (labels string, next string) Inspect
ExportNames : func(domainLabel string, after string, limit int) (keys string, next string) Inspect
ExportPrimary : func(after string, limit int) (owners string, next string) Inspect
ExportGlobalKeys : func(after string, limit int) (keys string, next string) Inspect
ExportAccounts : func(after string, limit int) (keys string, next string) Inspect
AccountCount : func() int Inspect
ExportDomainExtraKeys : func(label string, after string, limit int) (keys string, next string) Inspect
ExportNameExtraKeys : func(label string, domainLabel string, after string, limit int) (keys string, next string) Inspect
Sizes : func() (domainCount int, nameCount int, primaryCount int, globalCount int) Inspect
genesisDomainTerms : untyped bigint =(10 <untyped> bigint)
refusedInGenesis : func(key string, value string) bool Inspect
looksLikeAddress : func(v string) bool Inspect
genesisCfg : type =v1.genesisCfg
genesisDomain : type =v1.genesisDomain
applyGenesis : func(deployer .uverse.address, now int64) Inspect
genesisConfig : func() v1.genesisCfg Inspect
genesisGlobals : func() [][2]string Inspect
genesisDomains : func() []v1.genesisDomain Inspect
pendingOp : type =v1.pendingOp
recovery : .uverse.address =<gnolang.StringValue>
guardian : .uverse.address =<gnolang.StringValue>
paused : bool =false
timelockDelay : time.Duration =<zero>
maxTimelockDelay : time.Duration =<zero>
absoluteMaxTimelock : time.Duration =<zero>
pendingOps : v0.Tree Inspect
successor : string =""
vetoUntil : v0.Tree Inspect
assertIsAdmin : func() Inspect
assertIsAdminOrRecovery : func() Inspect
assertCanPause : func() Inspect
Pause : func() Inspect
Unpause : func() Inspect
ProposeUnpause : func() Inspect
IsPaused : func() bool Inspect
IsTrustedLogic : func(addr .uverse.address) bool Inspect
ListTrustedLogic : func() string Inspect
RevokeTrustedLogic : func(logicAddr .uverse.address) Inspect
ProposeAdminTransfer : func(newAdmin .uverse.address) Inspect
ProposeRecoveryTransfer : func(newRecovery .uverse.address) Inspect
ProposeTrustedLogicGrant : func(logicAddr .uverse.address) Inspect
ProposeTimelockDelay : func(seconds int64) Inspect
SetMaxTimelockDelay : func(seconds int64) Inspect
canControl : func(op *v1.pendingOp, caller .uverse.address) bool Inspect
getPendingOp : func(kind string) *v1.pendingOp Inspect
EvictionPending : func() bool Inspect
adminAlone : func(a .uverse.address) bool Inspect
assertAdminMayPropose : func(caller .uverse.address, kind string) Inspect
veto : func(caller .uverse.address, kind string, proposer .uverse.address) Inspect
setPending : func(op *v1.pendingOp) Inspect
CancelPending : func(kind string) Inspect
ExecutePending : func(kind string) Inspect
dropPendingProtectedBy : func(kind string, role string) Inspect
adminOnlyKinds : []string (len=3) Inspect
dropAdminProposals : func(reason string) Inspect
GetPending : func(kind string) (addr .uverse.address, executableAt time.Time, protectorRole string) Inspect
GetPendingDetail : func(kind string) (addr .uverse.address, seconds int64, executableAt time.Time, protectorRole string, by .uverse.address) Inspect
ListPending : func() string Inspect
SetGuardian : func(addr .uverse.address) Inspect
ClearGuardian : func() Inspect
SetSuccessor : func(s string) Inspect
GetAdmin : func() .uverse.address Inspect
GetRecovery : func() .uverse.address Inspect
GetGuardian : func() .uverse.address Inspect
GetSuccessor : func() string Inspect
GetTimelockDelay : func() time.Duration Inspect
GetMaxTimelockDelay : func() time.Duration Inspect
disarmKeys : []string (len=3) Inspect
maxGrantVoids : untyped bigint =(8 <untyped> bigint)
maxQuarantine : int64 =2592000
grantVoids : [][2]int64 (len=1) Inspect
quarantineUntil : int64 =0
assertIsRecovery : func() Inspect
Disarm : func() Inspect
VoidGrantsSince : func(since int64) Inspect
insertVoid : func(ws [][2]int64, w [2]int64) [][2]int64 Inspect
GrantVoided : func(at int64) bool Inspect
GrantVoids : func() string Inspect
SetQuarantine : func(until int64) Inspect
QuarantineUntil : func() int64 Inspect
Quarantined : func() bool Inspect
isTokenValid : func(tid string) bool Inspect
BalanceOf : func(owner .uverse.address) int64 Inspect
OwnerOf : func(tid string) .uverse.address Inspect
GetApproved : func(tid string) .uverse.address Inspect
IsApprovedFor : func(tid string, operator .uverse.address) bool Inspect
IsApprovedForAll : func(owner .uverse.address, operator .uverse.address) bool Inspect
TokenURI : func(tid string) string Inspect
ListDomains : func() string Inspect
ListNames : func(domainLabel string) string Inspect
CountNames : func(domainLabel string) int64 Inspect
CountDomains : func() int64 Inspect
DomainExists : func(label string) bool Inspect
NameExists : func(label string, domainLabel string) bool Inspect
GetDomainOwner : func(label string) .uverse.address Inspect
GetNameOwner : func(label string, domainLabel string) .uverse.address Inspect
GetDomainInfo : func(label string) (owner .uverse.address, registered int64, expires int64, streak int64, frozen bool) Inspect
GetNameInfo : func(label string, domainLabel string) (owner .uverse.address, registered int64, expires int64, streak int64, frozen bool, paid bool) Inspect
GetNameTTL : func(label string, domainLabel string) int64 Inspect
GetDomainTTL : func(label string) int64 Inspect
GetNameHeldSince : func(label string, domainLabel string) int64 Inspect
RestoredFor : func(label string, domainLabel string) .uverse.address Inspect
IsNamePaid : func(label string, domainLabel string) bool Inspect
IsDomainValid : func(label string) bool Inspect
IsNameValid : func(label string, domainLabel string) bool Inspect
GetDomainExtra : func(label string, key string) string Inspect
GetNameExtra : func(label string, domainLabel string, key string) string Inspect
GetGlobal : func(key string) string Inspect
GetAccount : func(owner .uverse.address, key string) string Inspect
GetPrimary : func(owner .uverse.address) string Inspect
GetTreasury : func() .uverse.address Inspect
GetTermLength : func() int64 Inspect
GetGracePeriod : func() int64 Inspect
GetMaxDeletePerCall : func() int Inspect
GetLabelPattern : func() string Inspect
GetLabelLength : func() (min int, max int) Inspect
GetTokenURIBase : func() string Inspect
GetExtraLimits : func() (k int, v int, entries int) Inspect
GetGlobalEntryLimit : func() int Inspect
GetAccountLimits : func() (k int, v int, entries int) Inspect
Render : func(path string) string Inspect
Domain : type =v1.Domain
Name : type =v1.Name
lockBitFree : untyped bigint =(0 <untyped> bigint)
lockBitFrozen : untyped bigint =(1 <untyped> bigint)
domains : v0.Tree Inspect
names : v0.Tree Inspect
primary : v0.Tree Inspect
globals : v0.Tree Inspect
accounts : v0.Tree Inspect
admin : .uverse.address =<gnolang.StringValue>
trustedLogicSet : v0.Tree Inspect
treasury : .uverse.address =<gnolang.StringValue>
termLength : int64 =31536000
gracePeriod : int64 =7776000
labelPattern : string ="^[a-z0-9]+(-[a-z0-9]+)*$"
minLabelLen : int =1
maxLabelLen : int =63
maxExtraKeyLen : int =32
maxExtraValueLen : int =512
maxExtraEntries : int =24
maxGlobalEntries : int =64
maxAccountKeyLen : int =16
maxAccountValueLen : int =128
maxAccountEntries : int =8
maxDeletePerCall : int =100
tokenURIBase : string ="/r/nym-mnsrehearsal001/nsview/v1:token/"
init.191 : func() Inspect
RegisterDomainRecord : func(label string, owner .uverse.address, now int64) .uverse.error Inspect
ReassignDomainRecord : func(label string, to .uverse.address) .uverse.error Inspect
RenewDomainRecord : func(label string, caller .uverse.address, now int64) .uverse.error Inspect
advanceTerm : func(expires int64, now int64) int64 Inspect
SetDomainFrozen : func(label string, frozen bool) Inspect
SetDomainExpiryRecord : func(label string, expires int64) Inspect
SetDomainTTLRecord : func(label string, ttl int64) .uverse.error Inspect
SetDomainExtraRecord : func(label string, key string, value string) .uverse.error Inspect
DeleteDomainRecord : func(label string) (removed int64, done bool) Inspect
RegisterNameRecord : func(label string, domainLabel string, owner .uverse.address, now int64, paid bool) .uverse.error Inspect
holdBits : func(paid bool, frozen bool) int Inspect
setPrimaryIfNone : func(owner .uverse.address, tid string) Inspect
UpgradeFreeRecord : func(label string, domainLabel string, newOwner .uverse.address) .uverse.error Inspect
RestoreNameRecord : func(label string, domainLabel string, owner .uverse.address, registered int64, paid bool) .uverse.error Inspect
RenewNameRecord : func(label string, domainLabel string, caller .uverse.address, now int64) .uverse.error Inspect
SetNameFrozen : func(label string, domainLabel string, frozen bool) Inspect
SetNameExpiryRecord : func(label string, domainLabel string, expires int64) Inspect
SetNameTTLRecord : func(label string, domainLabel string, ttl int64) .uverse.error Inspect
SetNameExtraRecord : func(label string, domainLabel string, key string, value string) .uverse.error Inspect
freshen : func(n *v1.Name, tid string) Inspect
freshenTo : func(n *v1.Name, epoch int64, now int64) Inspect
FreshenNameRecord : func(label string, domainLabel string) .uverse.error Inspect
SetPrimaryRecord : func(owner .uverse.address, label string, domainLabel string) .uverse.error Inspect
ClearPrimaryRecord : func(owner .uverse.address) Inspect
SetTreasuryRecord : func(addr .uverse.address) Inspect
SetTermLengthRecord : func(seconds int64) Inspect
SetGracePeriodRecord : func(seconds int64) Inspect
SetMaxDeletePerCallRecord : func(n int) Inspect
SetLabelPatternRecord : func(pattern string) Inspect
SetTokenURIBaseRecord : func(base string) Inspect
SetLabelLengthRecord : func(minLen int, maxLen int) Inspect
SetExtraLimitsRecord : func(keyLen int, valueLen int, entries int) Inspect
SetGlobalEntryLimitRecord : func(entries int) Inspect
SetAccountLimitsRecord : func(keyLen int, valueLen int, entries int) Inspect
SetAccountRecord : func(owner .uverse.address, key string, value string) .uverse.error Inspect
accountFields : func(owner .uverse.address) int Inspect
assertAccountKey : func(key string) .uverse.error Inspect
reservedGlobals : []string (len=2) Inspect
SetGlobalRecord : func(key string, value string) .uverse.error Inspect
setGlobal : func(key string, value string) .uverse.error Inspect
SetReservedGlobalRecord : func(key string, value string) .uverse.error Inspect
setExtra : func(t *v0.Tree, key string, value string) .uverse.error Inspect
setExtraCapped : func(t *v0.Tree, key string, value string, maxEntries int) .uverse.error Inspect
assertExtraKey : func(key string) .uverse.error Inspect
assertLabelKeySafe : func(label string) .uverse.error Inspect
errStr : func(s string) .uverse.error Inspect