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

assertIsAdmin

func()

assertIsAdmin reads nsdata.GetAdmin() fresh every call — correct even immediately after a TransferAdmin, and correct for a freshly-deployed logic realm with no local state of its own to go stale. Note: admin authority to swap WHICH realm is trustedLogic, or to transfer admin itself, is deliberately NOT exposed here — those live only in nsdata's own admin.gno, callable solely by a direct wallet call from the current admin address, never proxied through logic. That's the one part of the system a compromised or buggy logic realm cannot touch.

Open
OID
0b19ce…a8da:3
assertIsAdmin details

Inspect func

SetLabelPattern

func(pattern string)

SetLabelPattern no longer changes anything, and refuses anything but the rule this realm actually implements. It used to compile an arbitrary regex and store it, with validateLabel reading it back. That flexibility cost 15 GNOT of permanent storage per deploy — see the measurements in validate.gno — for a rule that has never changed and should not change casually. It is kept rather than deleted so that an admin who reaches for it gets told what happened instead of a "function not found". And it refuses a different pattern rather than accepting one it will not enforce: a stored string describing rules the code does not apply is the exact silent divergence the caching version was written to avoid.

Open
OID
0b19ce…a8da:5
SetLabelPattern details

Inspect func

SetLabelLengthLimits

func(minLen int, maxLen int)
Open
OID
0b19ce…a8da:6
SetLabelLengthLimits details

Inspect func

SetDefaultNamePrice

func(microUsd int64)

SetDefaultNamePrice sets the fallback price in micro-USD, used by any domain that has not set its own base. BOUNDED (timelock.gno): a raise up to four times every ten minutes, a cut up to 25% once an hour, or a timelocked proposal for anything else.

Open
OID
0b19ce…a8da:7
SetDefaultNamePrice details

Inspect func

SetUsdRate

func(ugnotPerUsd int64)

SetUsdRate records how many ugnot one USD buys — the bridge between the USD price list and settlement on this chain. It is a MANUAL rate, not a market feed: it sits where it was last written. A stale rate during a sharp move sells names at the wrong price, and no amount of contract logic fixes that — keeping it current is an operational duty. Isolated as one global so a future logic realm can swap in a real oracle without touching the vault or restating a single price. BOUNDED (timelock.gno): a rate of 1 ugnot to the dollar used to be one call away from selling every name for dust. ASYMMETRIC (Ely, 2026-10-16): a higher rate — GNOT fell, names cost more GNOT — moves up to four times every ten minutes, so a 75% crash is followed in one update; a lower rate — the direction that sells names cheap — moves at most 25%, once an hour. Anything larger is a timelocked proposal. THE KEEPER may call this too (keeper.gno), and nothing else: the same bound and the same hourly slot, never the timelock, and KeeperAction on every move. Anybody who is neither gets the admin refusal, as before.

Open
OID
0b19ce…a8da:8
SetUsdRate details

Inspect func

maxLifecycleDays

untyped bigint

// 100 years

Value

(36500 <untyped> bigint)

SetTermLength

func(days int64)

BOTH ARE TIMELOCKED (timelock.gno). A grace period of zero made every name in grace reclaimable by anybody on the spot — owners who could still have renewed lost their names to whoever registered first — and a term change reprices every renewal and moves every holder's tenure.

Open
OID
0b19ce…a8da:9
SetTermLength details

Inspect func

SetGracePeriod

func(days int64)
Open
OID
0b19ce…a8da:10
SetGracePeriod details

Inspect func

SetTokenURIBase

func(base string)

SetTokenURIBase re-points TokenURI at a different renderer, so the NFT artwork can be replaced without touching the vault.

Open
OID
0b19ce…a8da:11
SetTokenURIBase details

Inspect func

SetExtraLimits

func(keyLen int, valueLen int, entries int)
Open
OID
0b19ce…a8da:12
SetExtraLimits details

Inspect func

minExtraKeyLen

untyped bigint

Value

(32 <untyped> bigint)

minExtraValueLen

untyped bigint

Value

(512 <untyped> bigint)

minExtraEntries

untyped bigint

Value

(24 <untyped> bigint)

SetGlobalEntryLimit

func(entries int)

SetGlobalEntryLimit sets how many keys the vault's globals may hold — its own cap now, apart from the per-record extras SetExtraLimits bounds.

Open
OID
0b19ce…a8da:13
SetGlobalEntryLimit details

Inspect func

SetAccountLimits

func(keyLen int, valueLen int, entries int)

SetAccountLimits bounds the vault's per-address store: field name, value, and fields per address. Small numbers, because whoever's transaction writes a field pays for it.

Open
OID
0b19ce…a8da:14
SetAccountLimits details

Inspect func

SetMarketFee

func(spec string)

SetMarketFee is nsmarket's fee control, living here because this is the realm the vault trusts. nsmarket.SetFee could never work: it wrote through nsdata.SetGlobalRecord from a realm deliberately outside the trusted set, so it passed its own admin check and then panicked inside the vault for every caller. Rather than grant nsmarket vault privileges — which would surrender the property that realm is built around — the setter moved to the realm that already has the grant, and the validation moved with it. The spec grammar is nsmarket's, restated here rather than imported so this realm does not take a dependency on the marketplace to set a number: an amount in ugnot ("1000000"), or a percentage ("%2.5"); "0" for none, because "" removes the key and nsmarket then charges its default of one GNOT. A malformed spec would otherwise be read on every sale and resolve silently to zero. A CHANGE THAT COULD RAISE THE FEE IS TIMELOCKED. The fee is read at sale time, so a raise lands on listings sellers made under the old one — up to half of their sale, moved to the treasury, with no notice. A timelocked raise is the notice: sellers see ActionProposed and may unlist. Lowering it, or switching it off, stays instant.

Open
OID
0b19ce…a8da:15
SetMarketFee details

Inspect func

keyMarketFee

untyped string

Value

"marketfee"

defaultMarketFee

untyped string

Value

"1000000"

feeCouldRise

func(old string, next string) bool

feeCouldRise reports whether moving from the stored spec \`old\` to \`next\` could raise the fee on any sale. Both are read the way nsmarket reads them: unset means the default. A move to zero never rises; a change of kind — flat to percentage or back — rises on some price, so it counts.

Open
OID
0b19ce…a8da:16
feeCouldRise details

Inspect func

feeParts

func(spec string) (flat int64, bps int64)

feeParts splits a spec into (flat ugnot, basis points), the way nsmarket.parseFee does; unset is the default fee, and an unreadable spec is zero — which is also how nsmarket charges it.

Open
OID
0b19ce…a8da:17
feeParts details

Inspect func

assertValidFeeSpec

func(spec string)

assertValidFeeSpec mirrors nsmarket.parseFee. Percentages are carried as basis points so a fee is expressible without floating point anywhere near money.

Open
OID
0b19ce…a8da:18
assertValidFeeSpec details

Inspect func

SetGlobal

func(key string, value string)

SetGlobal writes an arbitrary project-wide key into the vault's package-level extension slot — the escape hatch for global state that does not exist yet, and for keys other realms read (cardfx). It refuses every key a setter here owns: the escape hatch used to walk round every bound and timelock on them. See managedGlobal.

Open
OID
0b19ce…a8da:19
SetGlobal details

Inspect func

setGlobal

func(key string, value string)
Open
OID
0b19ce…a8da:20
setGlobal details

Inspect func

SetTreasury

func(newTreasury .uverse.address)

SetTreasury moves the revenue-receiving role — independent of nsdata's TransferAdmin, same reasoning as the original build's admin/treasury separation. TIMELOCKED. It took effect at once and said nothing, so a stolen admin key redirected every later sale — names, renewals, skins, market fees — in one call (audit M4). Now it is announced and waits, and recovery can cancel it.

Open
OID
0b19ce…a8da:21
SetTreasury details

Inspect func

SelfAddress

func() .uverse.address
Open
OID
0b19ce…a8da:22
SelfAddress details

Inspect func

blockChunks

untyped bigint

Value

(8 <untyped> bigint)

blockKeyStem

untyped string

Value

"block"

blockChunkMax

untyped bigint

Value

(512 <untyped> bigint)

blockKey

func(i int) string

blockKey is the global name for one chunk: block0 … block7.

Open
OID
0b19ce…a8da:23
blockKey details

Inspect func

BlockedLabel

func(label string) bool

BlockedLabel reports whether a label may not be registered at all. Compares against the label as the registry stores it — lowercase, already validated — so a caller cannot slip past with different casing. Every comparison is exact: this list holds whole labels, not substrings, because "contains" matching turns a list of a dozen words into an unpredictable filter that refuses names nobody meant to refuse.

Open
OID
0b19ce…a8da:25
BlockedLabel details

Inspect func

BlockList

func(i int) string

BlockList returns one chunk, so the panel can show and edit what is actually stored rather than what somebody believes is stored.

Open
OID
0b19ce…a8da:26
BlockList details

Inspect func

BlockChunks

func() int

BlockChunks is the number of chunks, so the panel does not hard-code a constant that this file might later change.

Open
OID
0b19ce…a8da:27
BlockChunks details

Inspect func

SetBlockList

func(i int, csv string)

SetBlockList replaces one chunk. Admin only. Replaces rather than appends: an append-only list has no way to correct a mistake, and a mistake here refuses somebody a name for reasons nobody can see. The panel reads the chunk, edits it, and writes it back whole.

Open
OID
0b19ce…a8da:28
SetBlockList details

Inspect func

assertNotBlocked

func(label string)

assertNotBlocked is the gate both doors pass through — the paid registration and the free grant. One function, called twice, because a block that only covers one route is not a block.

Open
OID
0b19ce…a8da:29
assertNotBlocked details

Inspect func

keyCredit

untyped string

// account field: the record above

Value

"cr"

keyClaimEnd

untyped string

// global: unix second the claim window closes; unset means closed

Value

"claimend"

keyClaimMax

untyped string

// global: highest list price, micro-USD, a credit covers

Value

"claimmax"

maxCreditsPerAddress

untyped bigint

Value

(100 <untyped> bigint)

maxGrantBatch

untyped bigint

Value

(100 <untyped> bigint)

maxClaimWindowDays

untyped bigint

// one setting cannot promise more than two years

Value

(730 <untyped> bigint)

credit

type

Value

v1.credit

parseCredit

func(v string) v1.credit

parseCredit FAILS CLOSED: anything it cannot read is no credit at all. A malformed record must never be read as a free name. Four fields is the record before the grant time existed; five carries it.

Open
OID
0b19ce…a8da:30
parseCredit details

Inspect func

readCredit

func(owner .uverse.address) v1.credit
Open
OID
0b19ce…a8da:32
readCredit details

Inspect func

writeCredit

func(owner .uverse.address, c v1.credit)
Open
OID
0b19ce…a8da:33
writeCredit details

Inspect func

CreditsOf

func(owner .uverse.address) (available int64, granted int64, used int64, expires int64, sellable bool)

CreditsOf reports an address's credits: how many it may redeem right now, and the record behind that answer. \`sellable\` is whether the names they buy come without the free-tier hold — true unless the grant said not. Credits recovery voided are not available; the window, a pause and a quarantine are the registry's state, reported by CreditRefusal.

Open
OID
0b19ce…a8da:34
CreditsOf details

Inspect func

CreditGrantedAt

func(owner .uverse.address) int64

CreditGrantedAt is when an address's credits were last granted (unix seconds; 0 for none, or for a record from before the field existed).

Open
OID
0b19ce…a8da:35
CreditGrantedAt details

Inspect func

ClaimWindowEnd

func() int64

ClaimWindowEnd is the unix second redemption closes, or 0 when no window is set — which means CLOSED. An entitlement nobody bounded is a liability that never ends, so the default is no window at all.

Open
OID
0b19ce…a8da:36
ClaimWindowEnd details

Inspect func

ClaimWindowOpen

func() bool
Open
OID
0b19ce…a8da:37
ClaimWindowOpen details

Inspect func

readClaimWindow

func(v string, now int64) bool

readClaimWindow fails closed on anything it cannot read, the same rule the free tier's window follows: a mistyped setting must not give names away.

Open
OID
0b19ce…a8da:38
readClaimWindow details

Inspect func

SetClaimWindow

func(end int64)

SetClaimWindow opens redemption until \`end\` (unix seconds), at most two years ahead, or closes it with 0. Closing is the one call to reach for on a Sunday when something about the grants looks wrong.

Open
OID
0b19ce…a8da:39
SetClaimWindow details

Inspect func

ClaimMaxPriceUSD

func() int64

ClaimMaxPriceUSD is the highest list price, in micro-USD, a credit can be spent on, or 0 while no cap is set — and while none is set no credit redeems at all (ClaimCapSet). IT NEVER FOLLOWS THE DEFAULT PRICE (re-audit 2026-10-16, H-1). It used to fall back to DefaultPriceUSD while unset, which is how a registry is born. The default moves fast in its "dearer" direction — four times, every ten minutes, instantly — and premium prices do not move with it, so each dearer step on the default carried the cap past another tier of premium names: a stolen admin key took the $300 x\*doge with a free credit in forty minutes, never touching SetClaimMaxPrice, whose raise is meant to be the slow step. So the cap stands on its own now, an unset or unreadable one covers nothing, and the first cap is a decision (SetClaimMaxPrice).

Open
OID
0b19ce…a8da:40
ClaimMaxPriceUSD details

Inspect func

ClaimCapSet

func() bool

ClaimCapSet reports whether a cap is set at all. Unset — or unreadable, which is read the same way — no credit can be spent on anything.

Open
OID
0b19ce…a8da:41
ClaimCapSet details

Inspect func

SetClaimMaxPrice

func(microUsd int64)

SetClaimMaxPrice is BOUNDED like a price (timelock.gno), with the direction turned round: RAISING the cap is what makes names cheaper — a credit then covers pricier names, premium ones in the end — so a raise is the slow step (25%, once an hour) and a cut the fast one (down to a quarter, every ten minutes). Anything else is a timelocked proposal. THE FIRST CAP IS NOT A STEP. From no cap there is nothing to step from, so setting one is always the timelocked proposal: instant at a fresh vault's delay of zero, which is when the deploy sets it, and recovery's to veto once the delay is raised.

Open
OID
0b19ce…a8da:43
SetClaimMaxPrice details

Inspect func

GrantCredits

func(to .uverse.address, n int64, expires int64, sellable bool)

GrantCredits SETS how many free registrations \`to\` is entitled to in total, with an optional expiry (0 for none) and whether the names they buy are SELLABLE — true is the default to pass; false mints them with the free-tier hold. 0 revokes whatever is unredeemed. See the note at the top of this file on why a grant sets rather than adds.

Open
OID
0b19ce…a8da:44
GrantCredits details

Inspect func

GrantCreditsBatch

func(addrs string, n int64, expires int64, sellable bool) int

GrantCreditsBatch is GrantCredits for a comma-separated list of addresses, up to 100 a call — the migration grant is one entry per testnet wallet. Returns how many were written. One bad address fails the whole batch, so a typo cannot silently leave somebody out.

Open
OID
0b19ce…a8da:45
GrantCreditsBatch details

Inspect func

grantCredits

func(to .uverse.address, n int64, expires int64, sellable bool, now int64)
Open
OID
0b19ce…a8da:46
grantCredits details

Inspect func

RedeemCredit

func(label string, domainLabel string)

RedeemCredit registers label\*domain to the caller and spends one of the caller's credits. The caller signs, so the caller pays the storage deposit and gas; the name itself costs nothing.

Open
OID
0b19ce…a8da:47
RedeemCredit details

Inspect func

RegisterFor

func(owner .uverse.address, label string, domainLabel string)

RegisterFor registers label\*domain to \`owner\` and spends one of OWNER'S credits — the project signs and pays the storage and gas, which is the only way a holder with no GNOT can get a name at all. Admin or granter: the same machine that issues free names relays these, and it can spend only credits the admin granted, only into the holder's own wallet.

Open
OID
0b19ce…a8da:48
RegisterFor details

Inspect func

CreditRefusal

func(owner .uverse.address, label string, domainLabel string) string

CreditRefusal is why \`owner\` could not spend a credit on label\*domain right now, or "" when nothing about the credit stands in the way. For the site, before anybody signs; the label rules are checked separately.

Open
OID
0b19ce…a8da:49
CreditRefusal details

Inspect func

creditRefusal

func(owner .uverse.address, label string, domainLabel string, now int64) string
Open
OID
0b19ce…a8da:50
creditRefusal details

Inspect func

redeemCredit

func(owner .uverse.address, label string, domainLabel string)

redeemCredit is both doors. Every check runs before anything is written, the registration lands before the credit is spent, and either failing reverts the other: the credit cannot be spent on a name that did not arrive, and a name cannot arrive without its credit being spent.

Open
OID
0b19ce…a8da:51
redeemCredit details

Inspect func

RegisterDomain

func(label string)

RegisterDomain mints a new \`\*domain\` — ADMIN-ONLY (2026-08-15 policy: domains are never sold or owned by third parties). No payment: the project isn't paying itself. Domains are also permanently non-transferable by users (see nft.gno's TransferFrom).

Open
OID
0b19ce…a8da:52
RegisterDomain details

Inspect func

RenewDomain

func(label string)

RenewDomain extends a domain's expiry by exactly one year from its PREVIOUS due date, not from the payment date. No payment — domains are always project-owned, so this is self-service upkeep, not a sale. Deliberately does not call validateLabel — a tightened pattern only gates new registrations, never renewals of what's already registered.

Open
OID
0b19ce…a8da:54
RenewDomain details

Inspect func

ReassignDomain

func(label string, newOwner .uverse.address)

ReassignDomain moves a domain record to a new owner. ADMIN-ONLY, and the deliberate exception to "domains are non-transferable". It exists because domain ownership is snapshotted into the record at registration time, while \`admin\` is a rotatable role. After the planned EOA-to-multisig rotation, the incoming admin could not renew or reprice any domain the outgoing key had registered — and if the rotation happened \*because\* the old key was compromised, the attacker could still reprice those domains afterwards. This is the recovery lever for exactly that situation. Not a loophole in the non-transferability policy: that policy exists to stop domains reaching third parties as tradeable assets, and this path is reachable only by the current admin, moving a project domain between project-controlled addresses. TIMELOCKED (timelock.gno): a stolen admin key could otherwise move every project domain to itself in one block. Genesis domains run ten years, so the honest recovery this exists for loses nothing by waiting.

Open
OID
0b19ce…a8da:55
ReassignDomain details

Inspect func

SetDomainOpen

func(label string, open bool)

SetDomainOpen enables or disables registration of new names under a domain. Existing names are untouched: closing a domain stops new mints, it does not seize anything already held.

Open
OID
0b19ce…a8da:56
SetDomainOpen details

Inspect func

SetDomainBasePrice

func(label string, microUsd int64)

SetDomainBasePrice sets the domain's base price in micro-USD. Every "%N" rule under the domain is relative to this, so one call reprices the whole domain. BOUNDED (timelock.gno): a raise up to four times every ten minutes, a cut up to 25% once an hour; a move to or from free, or anything larger, is a timelocked proposal.

Open
OID
0b19ce…a8da:57
SetDomainBasePrice details

Inspect func

SetDomainLengthRules

func(label string, rules string)

SetDomainLengthRules prices by label length: "3:2000000,4:%150,5:0" means 3-char names cost $2.00, 4-char names cost 150% of the domain base, and 5-char names are free. TIMELOCKED, with the price rules below: one rule can make any length free ("3:0"), so a rule set is not a tweak whatever it says. Propose the NORMALISED form, which the refusal prints.

Open
OID
0b19ce…a8da:58
SetDomainLengthRules details

Inspect func

SetDomainNameOverrides

func(label string, rules string)

SetDomainNameOverrides prices specific labels: "420:5000000,gm:%500". Highest precedence — this beats length rules and the base. TIMELOCKED, like the length rules: "premiumname:0" was a one-call way to take one.

Open
OID
0b19ce…a8da:59
SetDomainNameOverrides details

Inspect func

SetDomainField

func(label string, key string, value string)

SetDomainField writes an arbitrary key on a domain, for whatever a future feature needs without a vault change — the domain's art among them. It refuses the keys this realm's own setters own, which it used to write straight past ("price" to zero, with no bound).

Open
OID
0b19ce…a8da:60
SetDomainField details

Inspect func

setDomainExtra

func(label string, key string, value string)
Open
OID
0b19ce…a8da:61
setDomainExtra details

Inspect func

DeleteDomain

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

FreezeDomain / UnfreezeDomain: project-only power to permanently block re-registration of a domain even after its grace period lapses. DeleteDomain destroys a domain and every name beneath it. THE VAULT PRIMITIVE EXISTED BEFORE THIS DID, AND THAT MADE IT UNREACHABLE. nsdata.DeleteDomainRecord gates on assertIsTrustedLogic, so the only way to reach it is a function in this realm — and there was not one. The capability shipped in the vault and could not be used, which is worse than not shipping it, because it reads as present. Bounded by the vault at maxDeletePerCall names per call. It returns how many it removed and whether it finished, so a large domain is several calls rather than a transaction that cannot fit in a block. Repeat until done is true; calling it on a domain that is already gone reports done rather than panicking, so a loop terminates cleanly. ADMIN ONLY, and deliberately not owner-callable: domains are project-owned (SPEC.md §17b) and this destroys other people's names. TIMELOCKED (timelock.gno). It burned every live name under a domain at once — and paid the deleter the holders' storage deposits, about 57 GNOT per hundred names. One proposal, "DeleteDomain \<label>", covers every call of a multi-call deletion while it stays matured, and is spent by the call that finishes; recovery can cancel it between calls.

Open
OID
0b19ce…a8da:62
DeleteDomain details

Inspect func

SetDomainTTL

func(label string, seconds int64)

SetDomainTTL sets how long a resolver may cache answers about this domain, in seconds, where 0 means never cache — the ENS rule. Admin only, since domains are project-owned.

Open
OID
0b19ce…a8da:63
SetDomainTTL details

Inspect func

FreezeDomain

func(label string)
Open
OID
0b19ce…a8da:64
FreezeDomain details

Inspect func

UnfreezeDomain

func(label string)
Open
OID
0b19ce…a8da:65
UnfreezeDomain details

Inspect func

emitAdmin

func(fn string, kv []string)

EVERY ADMIN ACTION EMITS AdminAction, with the signer and the call. There was no event anywhere in this realm, so a stolen admin key's treasury change, rate change or deletion was invisible until its effects showed up somewhere else (audit M-4/M-6). The vault now says what changed (nsdata/events.gno); this says who asked, through which call, with which arguments — the line a monitor alerts on. A failed call emits nothing: an aborted transaction keeps no events. One event type, "AdminAction", with "fn" naming the call, so a monitor subscribes once and a new admin call is covered without anybody updating a list. Profile values replayed by a restore are not repeated here, only their keys, for the reason given in nsdata/events.gno.

Open
OID
0b19ce…a8da:66
emitAdmin details

Inspect func

keyFreeDomain

untyped string

// per-domain: "1" means the free tier is open here

Value

"free"

keyGrantEnd

untyped string

// global: unix seconds, or "never"

Value

"grantend"

keyGranter

untyped string

// global: the address allowed to issue grants

Value

"granter"

SetGranter

func(a .uverse.address)

SetGranter delegates grant issuance, or withdraws it. Passing the empty address is the revocation, and it is the first thing to reach for if the issuing machine is ever in doubt — instant, always. NAMING a granter is TIMELOCKED (timelock.gno): a stolen admin key would otherwise hand itself a second, quieter key that gives names away and spends people's credits, and keep it after the admin key is rotated out.

Open
OID
0b19ce…a8da:73
SetGranter details

Inspect func

SetFreeLengths

func(min int, max int)

SetFreeLengths tunes which lengths the free tier will issue. In the panel rather than in a redeploy: nslogic is about 22 GNOT to deploy, and "should four-character names be free this month" is a marketing question that should cost a signature, not a deployment. IT DOES NOT REACH BACKWARDS. Raising the minimum stops NEW issuance of short names; every one already granted stays granted and keeps renewing free. FreeLabelAllowed is called by GrantFreeName and by nothing else, which is what makes that true — see the note on it in reserved.gno.

Open
OID
0b19ce…a8da:74
SetFreeLengths details

Inspect func

DomainFree

func(domainLabel string) bool

DomainFree reports whether a domain accepts free-tier registrations. Off by default, and per-domain on purpose: the free tier is a promotion aimed at a few domains, not a property of the registry.

Open
OID
0b19ce…a8da:76
DomainFree details

Inspect func

SetDomainFree

func(domainLabel string, on bool)

SetDomainFree opens or closes the free tier for one domain.

Open
OID
0b19ce…a8da:77
SetDomainFree details

Inspect func

GrantWindowOpen

func() bool

GrantWindowOpen reports whether free grants are being issued at all. A single global switch that closes everything at once, because the failure this guards against is not a clever attack — it is noticing on a Sunday that something is wrong and wanting one call that stops it. An unset value means open; "never" means open with no end date, which is what the admin panel already writes.

Open
OID
0b19ce…a8da:78
GrantWindowOpen details

Inspect func

readGrantWindow

func(v string, now int64) bool

readGrantWindow is GrantWindowOpen with the clock and the stored value handed in, so the reading can be tested without a chain.

Open
OID
0b19ce…a8da:79
readGrantWindow details

Inspect func

GrantFreeName

func(label string, domainLabel string, owner .uverse.address)

GrantFreeName registers a free-tier record to somebody else. ADMIN OR GRANTER, and that is the whole trust model: the eligibility rules — which Twitter account, how old, how many followers, whether the label is a dictionary word — live off chain with the issuer. Putting them here would freeze a marketing policy into a realm and cost storage to do it. What the chain enforces is the part that must not depend on our correctness: the label is structurally allowed, the domain opted in, and the window is open. \`owner\` may be an address the recipient generated in their browser seconds ago and has never funded. That is the point.

Open
OID
0b19ce…a8da:80
GrantFreeName details

Inspect func

UpgradeFreeName

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

UpgradeFreeName mints the token for a free-tier record, at full price. This is the only way a free name becomes sellable, and the price is the ordinary list price with no referral discount — a discount is for bringing somebody new, and this person is already here. \`newOwner\` exists because the common case is somebody who has decided to sell and, in the same moment, wants the name in a wallet they actually control rather than the browser key they were given. The vault handles that move inside UpgradeFreeRecord. Callable by the record's current owner only. Anyone may PAY for somebody else's upgrade in the sense that they can hand over the money, but they cannot perform it — a stranger promoting your name into a token and choosing where it lands is a theft with a receipt.

Open
OID
0b19ce…a8da:81
UpgradeFreeName details

Inspect func

GrantFreeRenewal

func(label string, domainLabel string)

GrantFreeRenewal extends a free-tier name at no charge. THE DEAL IS THE DISPLAY, and it is checked off chain: the issuer signs somebody in on X, reads their display name, and finds the name in it. That single act proves both halves at once — that a real account still exists, and that it is still carrying the name — which is why renewal is one click a year rather than a form. FREE-TIER RECORDS ONLY. A paid name renewed for nothing is revenue given away by accident, and the two are told apart by whether a token was ever minted — now, whether the token still carries the free-tier hold. The hold is the registry's flag, read through GetNameInfo's \`paid\`. NO OWNERSHIP PROOF IS ASKED FOR, and that is deliberate rather than missing. Renewing somebody else's name is a GIFT — it takes nothing, moves nothing, and grants the caller no power over it. The only cost of allowing it is ours, and the vault's renewal cap already bounds how far any single name can be pushed. A proof requirement here would buy nothing and would cost the one-click renewal that makes the deal work. RenewNameRecord insists the caller is the owner, so the owner is looked up and passed. That is not a bypass: this realm is the trusted logic, and what it is asserting is exactly true — this renewal is on that owner's behalf.

Open
OID
0b19ce…a8da:82
GrantFreeRenewal details

Inspect func

IsFreeTier

func(label string, domainLabel string) bool

IsFreeTier reports whether a name is a record without a token — the free tier. Exported because the site and the issuer both need to ask before offering a free renewal, and neither should infer it.

Open
OID
0b19ce…a8da:83
IsFreeTier details

Inspect func

maxHoldingsPage

untyped bigint

Answering "what does this address hold" in ONE read. The site used to ask the chain for every name in the REGISTRY and then throw away the ones that did not match — one HTTP round trip per name in the world to draw one person's collection. Six names took three seconds, and it gets linearly worse for everybody every time anybody else registers anything. The scan itself is unavoidable: nsdata keys names by domain\*label and has no index by owner, and nsdata is the permanent vault so no index can be added to it now. But the scan does not have to happen across the network. nslogic is swappable and can walk the same records inside a single query, which turns N round trips into one. Nothing is cached and nothing is trusted from the caller: every row is read from the vault at the moment of the query, exactly as before. Paged, because a query has a gas ceiling of its own and a registry with fifty thousand names in it must not become one enormous read that nobody can complete. \`after\` is the vault's own cursor, so paging here is the same paging ExportNames already does.

Value

(200 <untyped> bigint)

NamesOwnedBy

func(owner .uverse.address, after string, limit int) (rows string, next string)

NamesOwnedBy returns rows of \`label\*domain,registered,expires,streak,frozen\` separated by ";", plus the cursor to continue from. Labels are restricted to \[a-z0-9-] so neither separator can appear inside a field. \`next\` is empty when the scan has reached the end of the registry. It is NOT empty merely because this page found no matches: a page of two hundred names belonging to other people returns no rows and a cursor, and the caller keeps going.

Open
OID
0b19ce…a8da:84
NamesOwnedBy details

Inspect func

CountNamesOwnedBy

func(owner .uverse.address, after string, limit int) (n int, next string)

CountNamesOwnedBy is the same walk without the strings, for a header that wants a number before the list has finished arriving.

Open
OID
0b19ce…a8da:86
CountNamesOwnedBy details

Inspect func

ProfileOf

func(label string, domainLabel string, keys string) string

Everything the profile page draws, in ONE read. It was making seventeen queries: three to establish that the name exists and when it expires, then fourteen more — one per extension slot — that could not start until the first three had come back. Two waves, and the node serves only a few at a time, so a profile took seconds to assemble out of values that all live in the same record. Values come back in the ORDER THE KEYS WERE ASKED FOR rather than as key=value pairs. An extension key is allowed to contain "=" (only commas and newlines are forbidden), so a pair encoding would have an ambiguous split; positional has none. Line 0 is the record: owner, registered, expires, streak, frozen, and the grace period, which is global but is one more query the page would otherwise have to make on its own. An empty return means the name is not registered. That is a real answer rather than an error: asking about a name nobody owns is the normal case on a profile URL somebody typed.

Open
OID
0b19ce…a8da:87
ProfileOf details

Inspect func

escapeValue

func(s string) string

Extension VALUES are free text — a bio can hold anything a person can type, newlines included — so they cannot be newline-separated raw. Escaping is done here rather than stripping, because silently eating a line break out of somebody's bio is data loss on a read path.

Open
OID
0b19ce…a8da:88
escapeValue details

Inspect func

RecentNames

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

RecentNames answers "what has just been registered" in one read. The site used to build this by listing every key and then reading each record one at a time — the same shape NamesOwnedBy replaced for a wallet's holdings, and the same problem: fine at thirteen names, one query per name forever after. A feed that gets slower every time somebody registers is a feed that eventually stops loading on the busy day you most wanted it. Returns rows of "label\*domain,registered,expires,owner", newest first, and a cursor. Sorting happens across a PAGE, not the whole registry: the vault stores names alphabetically and there is no index by date, so a caller that wants the true newest reads every page and merges. That is one query per 200 names instead of one per name — enough of a difference to stop mattering, without pretending the vault has an index it does not have.

Open
OID
0b19ce…a8da:89
RecentNames details

Inspect func

keyKeeper

untyped string

// global: the address that may move the rate

Value

"keeper"

SetKeeper

func(a .uverse.address)

SetKeeper names the keeper. Admin only, and TIMELOCKED: propose exactly "SetKeeper \<addr>" with nsdata.ProposeAction, then call once it matures. ClearKeeper removes the role.

Open
OID
0b19ce…a8da:92
SetKeeper details

Inspect func

ClearKeeper

func()

ClearKeeper removes the keeper at once. Admin, recovery or guardian — the guardian bot's answer to a KeeperAction it did not expect. Clearing when there is no keeper does nothing and still succeeds, so a bot may call it without reading first.

Open
OID
0b19ce…a8da:93
ClearKeeper details

Inspect func

isGovernor

func(a .uverse.address) bool

isGovernor is the vault's three roles, read fresh. An unset role matches nobody.

Open
OID
0b19ce…a8da:94
isGovernor details

Inspect func

assertIsKeeper

func(caller .uverse.address)

assertIsKeeper lets the keeper through and nobody else, with the refusal a stranger has always had from an admin call.

Open
OID
0b19ce…a8da:95
assertIsKeeper details

Inspect func

keeperSetRate

func(ugnotPerUsd int64)

keeperSetRate is SetUsdRate for the keeper: the same range check, the bound and the shared hourly slot, and no door into the timelock. Every move emits KeeperAction, with the value it replaced.

Open
OID
0b19ce…a8da:96
keeperSetRate details

Inspect func

keeperStep

func(setting string, old int64, next int64)

keeperStep is authorizeTweak with the timelock door bricked up: an instant step inside its direction's bound, after that direction's rest, or a refusal. It writes the same clocks, so the admin's next instant move in that direction waits the same time.

Open
OID
0b19ce…a8da:97
keeperStep details

Inspect func

keyDisplayName

untyped string

Profile field names inside a name's extension slot. The vault stores them as opaque strings and bounds their size; what they MEAN is this realm's convention, so new profile fields need no vault change.

Value

"displayName"

keyBio

untyped string

Profile field names inside a name's extension slot. The vault stores them as opaque strings and bounds their size; what they MEAN is this realm's convention, so new profile fields need no vault change.

Value

"bio"

keyWebsite

untyped string

Profile field names inside a name's extension slot. The vault stores them as opaque strings and bounds their size; what they MEAN is this realm's convention, so new profile fields need no vault change.

Value

"website"

keyAvatar

untyped string

Profile field names inside a name's extension slot. The vault stores them as opaque strings and bounds their size; what they MEAN is this realm's convention, so new profile fields need no vault change.

Value

"avatar"

RegisterName

func(label string, domainLabel string)

RegisterName mints \`label\*domain\` under an existing domain. Anyone may call this. Minting still works while the parent domain is past its own due date, as long as its grace period hasn't fully lapsed and it isn't frozen — nsdata's RegisterNameRecord enforces that.

Open
OID
0b19ce…a8da:98
RegisterName details

Inspect func

RegisterNameRef

func(label string, domainLabel string, refName string)

RegisterNameRef is RegisterName with a referral code — the NAME of whoever sent the buyer here, as it appears in the link. It is a second entry point rather than a third argument on the first one because the first one is already deployed and already being called by wallets and by the site. Changing its arity would break every one of those callers at the same instant, which is exactly the failure the voting realm produced last time; adding a function breaks nothing and lets the front end pick whichever the deployed realm actually has. A code that does not earn — misspelt, lapsed, the buyer's own name, a free-tier name, or one not yet held for thirty days (referral.gno) — is IGNORED, not rejected. The registration goes through at list price. Refusing to sell somebody a name because they mistyped somebody else's would be an absurd way to lose a sale.

Open
OID
0b19ce…a8da:100
RegisterNameRef details

Inspect func

registerName

func(label string, domainLabel string, refName string)
Open
OID
0b19ce…a8da:101
registerName details

Inspect func

RenewName

func(label string, domainLabel string)

RenewName — same anchoring rule as RenewDomain: extends from the previous due date, not from the payment date. Deliberately does not call validateLabel — an already-registered name must keep renewing under whatever pattern was in force when it was minted.

Open
OID
0b19ce…a8da:102
RenewName details

Inspect func

SetProfile

func(label string, domainLabel string, displayName string, bio string, website string, avatar string)

SetProfile writes the four conventional profile fields. Each lands in the name's extension slot, where the vault enforces size bounds.

Open
OID
0b19ce…a8da:103
SetProfile details

Inspect func

SetNameField

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

SetNameField writes a single arbitrary key — cross-chain addresses and anything else a future feature needs, with no vault change required. Keys used by this realm's own machinery are reserved.

Open
OID
0b19ce…a8da:104
SetNameField details

Inspect func

setExtra

func(label string, domainLabel string, key string, value string)
Open
OID
0b19ce…a8da:105
setExtra details

Inspect func

assertNameOwner

func(label string, domainLabel string)
Open
OID
0b19ce…a8da:106
assertNameOwner details

Inspect func

SetPrimaryName

func(label string, domainLabel string)

SetPrimaryName lets a wallet explicitly choose (and later change) which of its names is used for reverse resolution.

Open
OID
0b19ce…a8da:107
SetPrimaryName details

Inspect func

ClearPrimaryName

func()

ClearPrimaryName switches reverse resolution OFF for the caller. WHY THIS HAS TO EXIST, and it is a hole rather than a feature request. nsdata sets the reverse pointer AUTOMATICALLY on a wallet's first registration — RegisterNameRecord does it, and nothing asked the person first. From that moment their address answers with their name, so anybody who sees that address anywhere can find the persona attached to it, and every transaction it has ever made becomes attributable. Retroactively: the chain is permanent and indexers keep copies. And until now there was NO WAY OUT. ClearPrimaryRecord is gated to trusted logic, and no logic realm exposed it, so the one person the pointer is about could not remove it. A name service is a bridge between a persona and a wallet; publishing that bridge without consent and without an exit is the worst version of it. This is the exit. It takes no arguments on purpose: a wallet has exactly one reverse pointer, and the only address it can clear is its own, so there is nothing to pass and nothing to get wrong. WHAT IT DOES NOT DO, said plainly because a promise we cannot keep would be worse than the hole: clearing stops FUTURE lookups. It does not unpublish what was already visible, and it cannot — the history is on chain and other people have copies. The honest sequence is to choose before publishing, which is why the site now shows what the link exposes before it offers to make it.

Open
OID
0b19ce…a8da:108
ClearPrimaryName details

Inspect func

maxTTL

int64

maxTTL caps a cache policy, a name's or a domain's: 2^31-1 seconds, about 68 years, the ceiling DNS itself uses (RFC 2181). Anything longer reads as forever to every resolver, and an unbounded value did not survive a snapshot (restore.gno, ttlSecs).

Value

2147483647

SetNameTTL

func(label string, domainLabel string, seconds int64)

SetNameTTL is the owner's cache policy for their own name, in seconds, where 0 MEANS NEVER CACHE — copied from the ENS registry so integrators need not read anything of ours to handle it. The owner sets it rather than the registry because only they know the risk: a name being used to receive payments wants 0, since a cached answer after a sale pays the previous owner; a name used as a display handle can safely be cached for a long time. At most maxTTL.

Open
OID
0b19ce…a8da:109
SetNameTTL details

Inspect func

FreezeName

func(label string, domainLabel string)
Open
OID
0b19ce…a8da:110
FreezeName details

Inspect func

UnfreezeName

func(label string, domainLabel string)

UnfreezeName is TIMELOCKED (timelock.gno); freezing stays instant. A freeze is the takedown and dispute lever — a disputed or stolen name is held while it is sorted out — so releasing one instantly would let a stolen admin key free a name and move it in the same transaction.

Open
OID
0b19ce…a8da:111
UnfreezeName details

Inspect func

maxUnfreezeBatch

untyped bigint

UnfreezeNames releases several names behind ONE timelocked action: propose exactly "UnfreezeNames a\*meme,b\*doge,…" (token ids, comma- separated, at most maxUnfreezeBatch). A stolen key freezes names one call each and instantly, about a thousand a block; releasing them one action each, with at most 32 actions pending, took ⌈N/32⌉ timelocks (re-audit 2026-10-16, L-3). One unknown or malformed name refuses the whole call.

Value

(64 <untyped> bigint)

UnfreezeNames

func(tids string)
Open
OID
0b19ce…a8da:112
UnfreezeNames details

Inspect func

ResolveName

func(label string, domainLabel string) .uverse.address
Open
OID
0b19ce…a8da:113
ResolveName details

Inspect func

ResolveAddress

func(addr .uverse.address) string

ResolveAddress performs reverse resolution: address -> name. It must verify the ownership it is asserting, not merely that the pointed-at name exists and is unexpired. nsdata's \`primary\` tree is a record of what an address last SELECTED, not proof of what it still owns — and although nsdata now clears the pointer on transfer and reclaim, this check is the half that lives in the swappable realm and therefore stays correct even against pointers written by an older version of the logic. Without it, an address that sold or lost a name kept reverse-resolving to it, impersonating the new owner.

Open
OID
0b19ce…a8da:114
ResolveAddress details

Inspect func

splitTokenID

func(tid string) (label string, domainLabel string)

splitTokenID splits a \`label\*domain\` token ID.

Open
OID
0b19ce…a8da:115
splitTokenID details

Inspect func

isDomainToken

func(tid string) bool
Open
OID
0b19ce…a8da:116
isDomainToken details

Inspect func

isTokenValid

func(tid string) bool

isTokenValid checks the underlying domain/name's expiry via nsdata's own validity reads — the anti-scam pattern (an expired name must not be sellable) enforced at the transfer boundary, not just at read time.

Open
OID
0b19ce…a8da:118
isTokenValid details

Inspect func

assertNotFrozen

func(tid string)

assertNotFrozen is the check that made freezing mean something. FreezeName set a bit that only ever gated RE-REGISTRATION after a lapse. Transfer, approval, listing and sale all ignored it, so the one manual lever the takedown process relies on did nothing about the case it exists for: a disputed or stolen name could be approved to a fresh wallet, listed and sold while the interface showed it as frozen. The bit was already stored and already readable — GetNameInfo returns it — so this needs no change to the permanent vault, only the read that was never performed.

Open
OID
0b19ce…a8da:119
assertNotFrozen details

Inspect func

takePayment

func(price int64)

takePayment verifies the attached send-envelope covers \`price\` ugnot, forwards the price to the treasury, and refunds any overpayment to the caller in the same transaction. Nothing is ever retained: every ugnot that arrives leaves again, as either payment or refund. It used to take a \`beneficiary\` and split the price fee/remainder, routing the remainder to treasury only while \`beneficiary == admin\`. That comparison was a proxy for "is this a project-owned domain", and it silently broke the moment \`admin\` rotated — the planned EOA-to- multisig step — because a domain's owner is frozen into its record at registration time. After a rotation, every registration's remainder would have been paid to the retired key instead of the treasury, with no error and no log line. The heuristic is gone rather than patched. Domains are admin-only to create and permanently non-transferable, so every domain is project-owned by construction and 100% of every payment belongs to the treasury. \`platformFeeBps\` stays in nsdata's config for a future logic realm that reintroduces third-party domain ownership; reinstating the split is then a logic-realm swap, not a migration.

Open
OID
0b19ce…a8da:120
takePayment details

Inspect func

takePaymentSplit

func(price int64, cutTo .uverse.address, cut int64)

takePaymentSplit is takePayment with a referrer's cut carved out of the same price. The buyer pays exactly what they were quoted; the cut is not added on top, it is a share of what the treasury would otherwise have received. All three legs settle inside the buyer's own transaction — treasury, referrer, refund — so this realm's balance is the same after the call as before it. That is not a stylistic preference: holding a referrer's cut until they claim it would make this an account you can have a balance in, and that is a different kind of thing to operate, subject to a different set of rules, run by people with licences. The cut is paid now or it is not paid.

Open
OID
0b19ce…a8da:122
takePaymentSplit details

Inspect func

assertOnlyUgnot

func(sent chain.Coins)

assertOnlyUgnot rejects any other denomination outright. Only the ugnot amount was ever accounted for, and neither realm has a withdrawal path, so a foreign coin sent alongside a payment would have been stranded in this realm's address permanently. Refusing the whole transaction is simpler than sweeping it back and keeps the "this realm never retains funds" invariant absolute.

Open
OID
0b19ce…a8da:123
assertOnlyUgnot details

Inspect func

assertNoSend

func()

assertNoSend guards every entry point that has no price. Without it, coins attached to a free call (a renewal of a project domain, a profile edit, an admin setter) would land in this realm's address with no way back out. IT APPLIES TO DIRECT WALLET CALLS ONLY, and that qualification is not a loosening — it is the guard finally matching its own reason. OriginSend() reports what the TRANSACTION carried, not what this call received. Measured on sapphire-1 with a pair of probe realms: a user attaches 500000ugnot to realm A, A calls realm B, and B's OriginSend() reads 500000ugnot even though every one of those coins is sitting in A's address. B never saw them and cannot strand them. So for a realm-to-realm call this was rejecting a payment this realm never received. It is the reason a marketplace could not transfer a name inside the same transaction that pays for it — the transfer is a free call, the transaction is not, and the two are unrelated. A two-transaction sale is the alternative, and that means somebody's money or somebody's name sitting somewhere in between. Not here.

Open
OID
0b19ce…a8da:124
assertNoSend details

Inspect func

keyGlobalLens

untyped string

// global length rules

Value

"glen"

keyPremium

untyped string

// premium1, premium2, ... see below

Value

"premium"

maxPremiumKeys

untyped bigint

Global pricing layers that sit ACROSS every domain rather than inside one — see SPEC.md §27. Two of them, and they work at different points: GLOBAL LENGTH RULES are a FLOOR beneath each domain's own length rules, consulted only when the domain has nothing to say about that length. "three-character names cost $5 everywhere" becomes one entry instead of an edit to all twenty-seven domains, and a domain that wants its own answer still overrides it. GLOBAL NAME PREMIUMS are an ADJUSTMENT applied after the price has already resolved. Making `og` premium is one entry covering `og*degen`, `og*meme` and every domain invented later. Deliberately not the per-name override, which REPLACES a price outright: "this name costs exactly X here" and "this name is worth more everywhere" are different tools and both are worth having. Full order, most specific first: 1. per-name override (domain "nm") 2. per-domain length rule (domain "len") 3. global length rule (global "glen") 4. domain base price (domain "price") 5. global default (global "defaultPrice") then the global name premium modifies the result, then any referral discount comes off what is left.

Value

(8 <untyped> bigint)

GlobalLengthRule

func(n int) (string, bool)

GlobalLengthRule returns the global rule for a label length, if any.

Open
OID
0b19ce…a8da:125
GlobalLengthRule details

Inspect func

PremiumFor

func(label string) string

PremiumFor returns the raw modifier for a name across all premium keys, or "" when the name is not premium anywhere.

Open
OID
0b19ce…a8da:127
PremiumFor details

Inspect func

applyPremium

func(mod string, price int64) int64

applyPremium adjusts an already-resolved price. ZERO ALWAYS STAYS ZERO. A fixed "+$2.00" would otherwise silently undo a giveaway tier set months earlier, and a free tier that quietly stops being free is worse than never having offered one. This is decided explicitly rather than inherited from the percentage case happening to work out at zero. Forms: "%5" / "+%5" five percent more · "-%10" ten percent less · "2.00" two dollars more · "-0.25" twenty-five cents less · "=5.00" exactly five dollars, ignoring everything resolved above.

Open
OID
0b19ce…a8da:128
applyPremium details

Inspect func

parseUSD

func(s string) (int64, bool)

parseUSD reads a human dollar figure — "2", "2.5", "2.50", "0.069" — into micro-USD. Written by hand rather than with floats: a float would make "0.07" cost a different number of micro-dollars depending on the platform, and prices must be exact.

Open
OID
0b19ce…a8da:129
parseUSD details

Inspect func

SetGlobalLengthRules

func(rules string)

SetGlobalLengthRules writes the project-wide length rules: "1:300000000,2:150000000,3:60000000" prices one, two and three character names everywhere a domain has not said otherwise. IT HAD NO SETTER UNTIL NOW, which meant the only way to write it was the generic SetGlobal escape hatch — straight past normalizeRules, so a typo stored fine and then vanished at lookup time, because lookupRule skips a malformed pair in silence. A pricing layer whose only writer cannot validate is a pricing layer that fails open. TIMELOCKED (timelock.gno), like every price rule set: "3:0" here makes short names free on every domain that has no rule of its own.

Open
OID
0b19ce…a8da:130
SetGlobalLengthRules details

Inspect func

SetPremiumNames

func(page int, csv string)

SetPremiumNames writes one page of the premium keyword list, 1-based. The list is paged because the vault caps an extension value at 512 bytes; see maxPremiumKeys. Same gap as above: normalizePremiums existed and nothing exported called it.

Open
OID
0b19ce…a8da:131
SetPremiumNames details

Inspect func

PremiumNames

func(page int) string

PremiumNames reads one page back, so the admin panel can show what is stored rather than what it last sent.

Open
OID
0b19ce…a8da:132
PremiumNames details

Inspect func

GlobalLengthRules

func() string

GlobalLengthRules returns the whole rule string, for the same reason.

Open
OID
0b19ce…a8da:133
GlobalLengthRules details

Inspect func

normalizePremiums

func(csv string) string

normalizePremiums validates a premium list before storage. Same reasoning as normalizeRules: a malformed entry must never reach the vault, because every later lookup would carry it.

Open
OID
0b19ce…a8da:134
normalizePremiums details

Inspect func

validPremiumValue

func(v string) bool
Open
OID
0b19ce…a8da:135
validPremiumValue details

Inspect func

keyPrice

untyped string

// domain base, micro-USD

Value

"price"

keyLens

untyped string

// length rules

Value

"len"

keyNames

untyped string

// per-name overrides

Value

"nm"

keyOpen

untyped string

// "0" closes the domain to new names

Value

"open"

keyDefaultPrice

untyped string

Pricing lives here, not in the vault. The vault stores numbers as opaque strings and has no opinion about what they mean, so the whole model can be replaced by swapping this realm. PRICES ARE DENOMINATED IN USD, held as MICRO-USD (1 USD = 1\_000\_000) so fractions of a cent are expressible — a name that costs about a gumball needs that. Nothing is stored in ugnot: the chain's token is just the settlement rail, converted at payment time from a stored rate. Accepting a second token later is then only a second rate, not a second price list. PRECEDENCE — most specific wins: 1. per-name override (keyNames: "420:5000000,gm:%500") 2. per-length rule (keyLens: "3:2000000,4:%150,5:0") 3. GLOBAL length rule (global keyGlobalLens — see premium.gno) 4. domain base price (keyPrice: "500000" = $0.50) 5. global default (global keyDefaultPrice) then the GLOBAL NAME PREMIUM adjusts the result, and a referral discount comes off last. Both live in premium.gno. A rule value is either an absolute micro-USD amount or "%N", meaning N percent of that domain's base — so repricing a domain once carries every relative rule under it. "0" means free, which is how giveaway tiers are expressed: "all five-character names under \*pleb are free" is just a length rule resolving to zero. Rules are stored as CSV in ONE key each rather than one key per rule. The vault caps extension keys at 32 bytes and 24 entries per record; a key like "nm:somelongname" breaks the first and a few dozen premium names break the second. Two CSV keys sidestep both.

Value

"defaultPrice"

keyRate

untyped string

// ugnot equal to 1 USD

Value

"rateUgnotPerUsd"

microUSD

int64

Pricing lives here, not in the vault. The vault stores numbers as opaque strings and has no opinion about what they mean, so the whole model can be replaced by swapping this realm. PRICES ARE DENOMINATED IN USD, held as MICRO-USD (1 USD = 1\_000\_000) so fractions of a cent are expressible — a name that costs about a gumball needs that. Nothing is stored in ugnot: the chain's token is just the settlement rail, converted at payment time from a stored rate. Accepting a second token later is then only a second rate, not a second price list. PRECEDENCE — most specific wins: 1. per-name override (keyNames: "420:5000000,gm:%500") 2. per-length rule (keyLens: "3:2000000,4:%150,5:0") 3. GLOBAL length rule (global keyGlobalLens — see premium.gno) 4. domain base price (keyPrice: "500000" = $0.50) 5. global default (global keyDefaultPrice) then the GLOBAL NAME PREMIUM adjusts the result, and a referral discount comes off last. Both live in premium.gno. A rule value is either an absolute micro-USD amount or "%N", meaning N percent of that domain's base — so repricing a domain once carries every relative rule under it. "0" means free, which is how giveaway tiers are expressed: "all five-character names under \*pleb are free" is just a length rule resolving to zero. Rules are stored as CSV in ONE key each rather than one key per rule. The vault caps extension keys at 32 bytes and 24 entries per record; a key like "nm:somelongname" breaks the first and a few dozen premium names break the second. Two CSV keys sidestep both.

Value

1000000

fallbackPriceUSD

int64

// $0.50

Value

500000

fallbackRate

int64

Pricing lives here, not in the vault. The vault stores numbers as opaque strings and has no opinion about what they mean, so the whole model can be replaced by swapping this realm. PRICES ARE DENOMINATED IN USD, held as MICRO-USD (1 USD = 1\_000\_000) so fractions of a cent are expressible — a name that costs about a gumball needs that. Nothing is stored in ugnot: the chain's token is just the settlement rail, converted at payment time from a stored rate. Accepting a second token later is then only a second rate, not a second price list. PRECEDENCE — most specific wins: 1. per-name override (keyNames: "420:5000000,gm:%500") 2. per-length rule (keyLens: "3:2000000,4:%150,5:0") 3. GLOBAL length rule (global keyGlobalLens — see premium.gno) 4. domain base price (keyPrice: "500000" = $0.50) 5. global default (global keyDefaultPrice) then the GLOBAL NAME PREMIUM adjusts the result, and a referral discount comes off last. Both live in premium.gno. A rule value is either an absolute micro-USD amount or "%N", meaning N percent of that domain's base — so repricing a domain once carries every relative rule under it. "0" means free, which is how giveaway tiers are expressed: "all five-character names under \*pleb are free" is just a length rule resolving to zero. Rules are stored as CSV in ONE key each rather than one key per rule. The vault caps extension keys at 32 bytes and 24 entries per record; a key like "nm:somelongname" breaks the first and a few dozen premium names break the second. Two CSV keys sidestep both.

Value

14492753

maxRules

untyped bigint

Pricing lives here, not in the vault. The vault stores numbers as opaque strings and has no opinion about what they mean, so the whole model can be replaced by swapping this realm. PRICES ARE DENOMINATED IN USD, held as MICRO-USD (1 USD = 1\_000\_000) so fractions of a cent are expressible — a name that costs about a gumball needs that. Nothing is stored in ugnot: the chain's token is just the settlement rail, converted at payment time from a stored rate. Accepting a second token later is then only a second rate, not a second price list. PRECEDENCE — most specific wins: 1. per-name override (keyNames: "420:5000000,gm:%500") 2. per-length rule (keyLens: "3:2000000,4:%150,5:0") 3. GLOBAL length rule (global keyGlobalLens — see premium.gno) 4. domain base price (keyPrice: "500000" = $0.50) 5. global default (global keyDefaultPrice) then the GLOBAL NAME PREMIUM adjusts the result, and a referral discount comes off last. Both live in premium.gno. A rule value is either an absolute micro-USD amount or "%N", meaning N percent of that domain's base — so repricing a domain once carries every relative rule under it. "0" means free, which is how giveaway tiers are expressed: "all five-character names under \*pleb are free" is just a length rule resolving to zero. Rules are stored as CSV in ONE key each rather than one key per rule. The vault caps extension keys at 32 bytes and 24 entries per record; a key like "nm:somelongname" breaks the first and a few dozen premium names break the second. Two CSV keys sidestep both.

Value

(64 <untyped> bigint)

maxPriceUSD

int64

Pricing lives here, not in the vault. The vault stores numbers as opaque strings and has no opinion about what they mean, so the whole model can be replaced by swapping this realm. PRICES ARE DENOMINATED IN USD, held as MICRO-USD (1 USD = 1\_000\_000) so fractions of a cent are expressible — a name that costs about a gumball needs that. Nothing is stored in ugnot: the chain's token is just the settlement rail, converted at payment time from a stored rate. Accepting a second token later is then only a second rate, not a second price list. PRECEDENCE — most specific wins: 1. per-name override (keyNames: "420:5000000,gm:%500") 2. per-length rule (keyLens: "3:2000000,4:%150,5:0") 3. GLOBAL length rule (global keyGlobalLens — see premium.gno) 4. domain base price (keyPrice: "500000" = $0.50) 5. global default (global keyDefaultPrice) then the GLOBAL NAME PREMIUM adjusts the result, and a referral discount comes off last. Both live in premium.gno. A rule value is either an absolute micro-USD amount or "%N", meaning N percent of that domain's base — so repricing a domain once carries every relative rule under it. "0" means free, which is how giveaway tiers are expressed: "all five-character names under \*pleb are free" is just a length rule resolving to zero. Rules are stored as CSV in ONE key each rather than one key per rule. The vault caps extension keys at 32 bytes and 24 entries per record; a key like "nm:somelongname" breaks the first and a few dozen premium names break the second. Two CSV keys sidestep both.

Value

1000000000000

maxRulePct

untyped bigint

Pricing lives here, not in the vault. The vault stores numbers as opaque strings and has no opinion about what they mean, so the whole model can be replaced by swapping this realm. PRICES ARE DENOMINATED IN USD, held as MICRO-USD (1 USD = 1\_000\_000) so fractions of a cent are expressible — a name that costs about a gumball needs that. Nothing is stored in ugnot: the chain's token is just the settlement rail, converted at payment time from a stored rate. Accepting a second token later is then only a second rate, not a second price list. PRECEDENCE — most specific wins: 1. per-name override (keyNames: "420:5000000,gm:%500") 2. per-length rule (keyLens: "3:2000000,4:%150,5:0") 3. GLOBAL length rule (global keyGlobalLens — see premium.gno) 4. domain base price (keyPrice: "500000" = $0.50) 5. global default (global keyDefaultPrice) then the GLOBAL NAME PREMIUM adjusts the result, and a referral discount comes off last. Both live in premium.gno. A rule value is either an absolute micro-USD amount or "%N", meaning N percent of that domain's base — so repricing a domain once carries every relative rule under it. "0" means free, which is how giveaway tiers are expressed: "all five-character names under \*pleb are free" is just a length rule resolving to zero. Rules are stored as CSV in ONE key each rather than one key per rule. The vault caps extension keys at 32 bytes and 24 entries per record; a key like "nm:somelongname" breaks the first and a few dozen premium names break the second. Two CSV keys sidestep both.

Value

(10000 <untyped> bigint)

DomainOpen

func(domainLabel string) bool

DomainOpen reports whether names may currently be registered under a domain. An absent key means open — a domain created before this existed must not silently close.

Open
OID
0b19ce…a8da:136
DomainOpen details

Inspect func

DefaultPriceUSD

func() int64
Open
OID
0b19ce…a8da:138
DefaultPriceUSD details

Inspect func

DomainBasePriceUSD

func(domainLabel string) int64
Open
OID
0b19ce…a8da:139
DomainBasePriceUSD details

Inspect func

NamePriceUSD

func(domainLabel string, label string) int64

NamePriceUSD resolves the four inputs in precedence order and returns micro-USD. This is the authoritative price; ugnot is derived from it.

Open
OID
0b19ce…a8da:140
NamePriceUSD details

Inspect func

resolveBeforePremium

func(domainLabel string, label string) int64

resolveBeforePremium runs steps 1-5. Separated from NamePriceUSD so the admin panel can show WHY a price is what it is: the figure before the premium and the figure after are both meaningful, and a single function returning only the total makes a wrong price impossible to diagnose.

Open
OID
0b19ce…a8da:141
resolveBeforePremium details

Inspect func

ExplainPriceUSD

func(domainLabel string, label string) (beforePremium int64, modifier string, final int64)

ExplainPriceUSD returns each stage of the resolution, so the control panel can show the arithmetic rather than assert a total. Returns the price before any premium, the premium modifier that applied (empty if none), and the final price.

Open
OID
0b19ce…a8da:142
ExplainPriceUSD details

Inspect func

RateUgnotPerUsd

func() int64

RateUgnotPerUsd is how many ugnot one USD buys. This is a MANUALLY MAINTAINED rate, not a market oracle: an admin writes it and it sits there until rewritten. That is a real operational hazard — a stale rate during a sharp move sells names at the wrong price in whichever direction hurts — and the mitigation is keeping it fresh, not anything this code can do. Kept as one global so a future logic realm can swap in a real oracle without touching the vault or restating a single price.

Open
OID
0b19ce…a8da:143
RateUgnotPerUsd details

Inspect func

NamePrice

func(domainLabel string, label string) int64

NamePrice converts the USD price to ugnot for settlement. Rounds UP, so rounding never sells a name below its listed price; a free name stays exactly free. IT REFUSES TO OVERFLOW. usd\*rate is int64 arithmetic, which wraps silently, and a wrapped product is a price of millions of GNOT or a negative one — and a negative price made takePaymentSplit refund more than was paid (audit L5). A price that cannot be computed is refused, which fails closed: no sale, never a wrong one.

Open
OID
0b19ce…a8da:144
NamePrice details

Inspect func

applyRule

func(v string, base int64) int64

applyRule reads a stored rule. An out-of-range one is treated like a malformed one — the base applies — because stored values can arrive by the restore window, unvalidated, and an unbounded percentage would wrap the multiplication into a small, wrong, price.

Open
OID
0b19ce…a8da:145
applyRule details

Inspect func

lookupRule

func(csv string, want string) (string, bool)
Open
OID
0b19ce…a8da:146
lookupRule details

Inspect func

normalizeRules

func(csv string, numericKeys bool) string

normalizeRules validates and canonicalises a rule string before it is stored, so a malformed entry can never reach storage and poison every later lookup.

Open
OID
0b19ce…a8da:147
normalizeRules details

Inspect func

keyRef

untyped string

// on a NAME: the referrer's address

Value

"ref"

keyRefCut

untyped string

// global: the referrer's percentage, stored "0:N"

Value

"refcut"

keyRefDisc

untyped string

// global: the buyer's discount, stored "0:N"

Value

"refdisc"

keyRefCount

untyped string

// ACCOUNT field (nsdata's per-address store): how many referred

Value

"rc"

keyRefWin

untyped string

// global: days a captured code stays valid

Value

"refwin"

maxRefPercent

untyped bigint

// cut plus discount, together; an admin may lower it, never exceed it

Value

(10 <untyped> bigint)

refHoldDays

untyped bigint

// a code earns only once its holder has kept a paid name this long

Value

(30 <untyped> bigint)

tierPercent

func(spec string, years int64) int64

tierPercent reads a stored rate. The canonical form is a one-tier table at year zero, "0:N", which every reader of the old escalating tables — the site among them — reads as N at any tenure. A legacy multi-tier table counts only at year zero (RefRates asks for nothing else), so a table that once escalated cannot escalate now. Junk entries are skipped, not fatal, so one bad character cannot stop every sale; a percentage above the cap is clamped.

Open
OID
0b19ce…a8da:148
tierPercent details

Inspect func

RefRates

func() (cutPct int64, discountPct int64)

RefRates is the flat cut and discount in force, in percent, clamped so that together they never exceed maxRefPercent whatever is stored. The discount is kept and the cut gives way: what a buyer was quoted is the promise, the cut is the treasury's to shrink.

Open
OID
0b19ce…a8da:150
RefRates details

Inspect func

clampRates

func(cut int64, disc int64) (int64, int64)

clampRates is the 10% ceiling on its own, so it can be tested without a vault: negative inputs are zero, the discount is capped first, and the cut takes whatever room is left.

Open
OID
0b19ce…a8da:151
clampRates details

Inspect func

defaultRefCut

untyped string

THE PRESET THE PROJECT LAUNCHES WITH: five percent to the referrer, five off for the buyer — the whole 10% the owner allowed, split evenly. Written here rather than typed into the admin panel at launch because a number that exists only in somebody's memory of a conversation gets set wrong once and noticed a month later. It is a DEFAULT, not a policy: SetReferralRules overwrites it, and empty rates switch the programme off.

Value

"0:5"

defaultRefDiscount

untyped string

THE PRESET THE PROJECT LAUNCHES WITH: five percent to the referrer, five off for the buyer — the whole 10% the owner allowed, split evenly. Written here rather than typed into the admin panel at launch because a number that exists only in somebody's memory of a conversation gets set wrong once and noticed a month later. It is a DEFAULT, not a policy: SetReferralRules overwrites it, and empty rates switch the programme off.

Value

"0:5"

DefaultReferralRules

func() (cut string, discount string)

DefaultReferralRules lets the site show the presets before anybody commits them.

Open
OID
0b19ce…a8da:152
DefaultReferralRules details

Inspect func

SeedReferralRules

func()

SeedReferralRules writes the presets, and ONLY into empty rates. Not an init(): at init a fresh logic realm is not yet trusted by the vault. Refusing to overwrite makes it safe to call twice and safe to call by mistake.

Open
OID
0b19ce…a8da:153
SeedReferralRules details

Inspect func

RefDiscountRules

func() string
Open
OID
0b19ce…a8da:155
RefDiscountRules details

Inspect func

RefWindowDays

func() int64

RefWindowDays is how long a clicked link keeps counting for. It is enforced by the browser that captured the code, not by this realm — the chain never sees the click, only the registration that quotes a code — so it is stored here purely to be ONE number rather than a constant baked separately into the site, the FAQ and the rules page. Zero means the default; the site treats an absent value the same way.

Open
OID
0b19ce…a8da:156
RefWindowDays details

Inspect func

SetReferralWindow

func(days int64)
Open
OID
0b19ce…a8da:157
SetReferralWindow details

Inspect func

ReferralQuote

func(refName string, buyer .uverse.address) (referrer .uverse.address, tenure int64, discountPct int64, cutPct int64)
Open
OID
0b19ce…a8da:158
ReferralQuote details

Inspect func

SetReferralRules

func(cutSpec string, discountSpec string)

SetReferralRules sets both rates at once, because setting one without the other is how a cut ends up larger than the margin. Each is "N" or "0:N" (percent), or empty for none; two empties switch the programme off. Together they may not exceed maxRefPercent. A multi-tier table is refused: the programme has one tier.

Open
OID
0b19ce…a8da:159
SetReferralRules details

Inspect func

normalizeRate

func(spec string) (stored string, pct int64)

normalizeRate reads one rate as an admin types it — "5", "0:5", or "" — and returns its stored form, "0:5" or "" for none, and the percent. Anything else panics before it can reach storage.

Open
OID
0b19ce…a8da:160
normalizeRate details

Inspect func

TenureYears

func(who .uverse.address) int64

TenureYears is how long a wallet counts as having been here, measured from its PRIMARY name. It used to pick the referral tier; it moves no money now, and stays because the referral page shows it. A lapsed or missing primary is zero years, not an error.

Open
OID
0b19ce…a8da:161
TenureYears details

Inspect func

PayoutFor

func(who .uverse.address) .uverse.address
Open
OID
0b19ce…a8da:162
PayoutFor details

Inspect func

ReferrerOf

func(label string, domainLabel string) .uverse.address
Open
OID
0b19ce…a8da:163
ReferrerOf details

Inspect func

resolveReferrer

func(refName string, buyer .uverse.address) .uverse.address
Open
OID
0b19ce…a8da:164
resolveReferrer details

Inspect func

heldLongEnough

func(since int64, now int64) bool

heldLongEnough is the thirty-day rule on its own. A zero \`since\` means the registry has not seen the current holder yet — never long enough.

Open
OID
0b19ce…a8da:165
heldLongEnough details

Inspect func

StartReferralClock

func(label string, domainLabel string)

StartReferralClock starts the holding clock on a name the caller BOUGHT, so that thirty days later it can be a referral code. A sale that settles on the token ledger never calls the registry, so the registry first sees a buyer at their first write to the name. A buyer who never edits a profile would otherwise never qualify. This is that first write, with nothing in it: it clears the seller's stale data, which every read already hides, and stamps the clock. Names you registered yourself start their clock at registration and need nothing.

Open
OID
0b19ce…a8da:166
StartReferralClock details

Inspect func

PriceWithReferral

func(domainLabel string, label string, refName string, buyer .uverse.address) int64

PriceWithReferral is what a buyer actually pays given the code they arrived with. Exported so the site can display the number the chain will charge instead of computing its own and hoping they agree.

Open
OID
0b19ce…a8da:167
PriceWithReferral details

Inspect func

referralCut

func(ref .uverse.address, price int64) (.uverse.address, int64)
Open
OID
0b19ce…a8da:168
referralCut details

Inspect func

creditReferral

func(ref .uverse.address)

creditReferral records one paid referral against a wallet. The COUNT and nothing else. There was a running total of micro-USD beside it, and it is gone, because a number stored in the vault is a number anyone with an RPC endpoint can read — there is no such thing as an admin-only global on a public chain, and building the site as though there were would be the kind of privacy that works right up until somebody checks. Not storing it is the only real reduction available. The payments are still in the block history and always will be, so anyone determined can add them up; what we can decline to do is publish a convenient running total ourselves. tools/referrals.py reconstructs it from the chain when we want it, which costs no storage and publishes nothing. The registrant's transaction pays for this entry: one small field, written once per referrer and overwritten after — the price of the discount they just received. IT LIVES IN THE VAULT'S PER-ADDRESS STORE, and until it did, no referred registration ever succeeded. It was the global "ref:" + address, 44 bytes against a 32-byte cap on global keys; the vault refused it, this panicked, and the whole purchase reverted after the price was taken — on every chain the programme ran on. A key that short would only have moved the failure: globals held at most 24 entries, shared with the price list, so it would have broken again at about the twenty-first referrer. An address is a key there now, and each wallet's fields are bounded on their own.

Open
OID
0b19ce…a8da:169
creditReferral details

Inspect func

ReferralCount

func(who .uverse.address) int64

ReferralCount is how many paid registrations a wallet has been credited with. Public, like everything in the vault.

Open
OID
0b19ce…a8da:170
ReferralCount details

Inspect func

parseInt64

func(s string) int64
Open
OID
0b19ce…a8da:171
parseInt64 details

Inspect func

refBoardPages

untyped bigint

How many vault pages one ReferralBoard call may scan.

Value

(5 <untyped> bigint)

ReferralBoard

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

ReferralBoard pages through every credited wallet for the leaderboard: one "address,count" row per line. It walks the vault's per-address store, where other fields (credits) sit beside the counters, so a page can scan more keys than it returns. \`next\` is an opaque cursor — pass it back as \`after\` — and is non-empty whenever the walk stopped before the end, including when it stopped on its scanning budget with fewer rows than asked for. A caller keeps going until \`next\` is empty.

Open
OID
0b19ce…a8da:172
ReferralBoard details

Inspect func

defaultFreeMinLength

untyped bigint

Value

(5 <untyped> bigint)

defaultFreeMaxLength

untyped bigint

Value

(63 <untyped> bigint)

keyFreeMin

untyped string

Value

"freemin"

keyFreeMax

untyped string

Value

"freemax"

FreeMinLength

func() int

FreeMinLength is the shortest label the free tier will issue. Settable from the panel, because which lengths are worth money is a commercial judgement that moves.

Open
OID
0b19ce…a8da:173
FreeMinLength details

Inspect func

FreeLabelAllowed

func(label string) bool

FreeLabelAllowed reports whether a label may be ISSUED on the free tier. ISSUED, and never renewed. This is called by GrantFreeName and by nothing else, deliberately: if the minimum length rises from three to five, somebody who already holds a three-character free name keeps it and keeps renewing it free. Tightening a rule must not reach backwards and take away what was already given — that is the single fastest way to make a giveaway cost more trust than it ever bought. A name that LAPSES and is registered again is a new issuance, and gets whatever the rules say that day. That is not retroactive; it is a different name event.

Open
OID
0b19ce…a8da:176
FreeLabelAllowed details

Inspect func

keyRestore

untyped string

The vault key holding the state of this whole mechanism.

Value

"restore"

restoreNever

untyped string

// never opened; the normal state forever

Value

""

restoreSealed

untyped string

// closed permanently; cannot be reopened

Value

"sealed"

restoreOpen

untyped string

// followed by the unix second it lapses

Value

"open:"

maxRestoreDays

untyped bigint

The longest a restore window may be left open. A restore is a day of work, not a season, and an unbounded window is just "open forever" spelled differently — the failure here is nobody remembering to seal it, so the deadline seals it for them.

Value

(30 <untyped> bigint)

RestoreStatus

func() (state string, deadline int64, restored int64)

RestoreStatus reports the state of the restore mechanism in a form a person can read, and is deliberately PUBLIC AND UNAUTHENTICATED. Anybody at all can check whether this registry currently has a door in it, without asking us and without trusting the answer we would give. Returns the state ("never", "open", "expired" or "sealed"), the unix second an open window lapses (0 otherwise), and how many records have been restored in the lifetime of this vault.

Open
OID
0b19ce…a8da:177
RestoreStatus details

Inspect func

readRestoreState

func(raw string, now int64) (state string, deadline int64)

readRestoreState is the state machine on its own, with the clock passed in. Split out so the one piece of logic that decides whether the door is open can be tested exhaustively without a chain under it.

Open
OID
0b19ce…a8da:179
readRestoreState details

Inspect func

keyRestoredCount

untyped string

Value

"restored"

restoredCount

func() int64
Open
OID
0b19ce…a8da:180
restoredCount details

Inspect func

setRestoreKey

func(key string, value string)

THE RESTORE KEYS GO THROUGH THE VAULT'S RESERVED DOOR, and every refusal panics. They used to go through SetGlobalRecord, written for the first vault, which had no reserved keys. This vault refuses "restore" and "restored" there — and the three call sites threw the error away. So SealRestore returned success and sealed nothing, OpenRestore returned success and opened nothing (every Restore\* call then said "never been opened", in the middle of a paused migration), and the counter never moved. A returned error in gno does not revert anything; ignoring one is how a control reads as live while doing nothing. SetReservedGlobalRecord is the machinery's own door, and the vault now refuses to change a seal through it as well: a sealed restore stays sealed whatever any logic realm asks, so a future logic generation cannot talk its way out of it either.

Open
OID
0b19ce…a8da:181
setRestoreKey details

Inspect func

assertNotRestoring

func()

assertNotRestoring CLOSES REGISTRATION WHILE A RESTORE WINDOW IS OPEN (re-audit 2026-10-16, M-4). The window opens on an empty registry, and the snapshots it replays are committed to the repository, so the list of who held what is public: anybody could register a holder's name before its batch arrived — at the genesis price, before the price rules were back — and the holder never got it back, while the batch holding it reverted and stopped the run. Every door that creates a name, or makes a free one sellable, passes this: RegisterName and RegisterNameRef, RedeemCredit and RegisterFor, GrantFreeName, UpgradeFreeName (and the lab's RegisterLabName). Sealed, or lapsed, the registry sells again.

Open
OID
0b19ce…a8da:183
assertNotRestoring details

Inspect func

assertRestoring

func()

assertRestoring is the gate every Restore\* function passes through.

Open
OID
0b19ce…a8da:184
assertRestoring details

Inspect func

OpenRestore

func(days int64)

OpenRestore opens the window, once, for a bounded number of days. Only ever valid on a chain where the registry is EMPTY because the previous chain was retired. It cannot be called on a vault that has been sealed, and it cannot be called twice.

Open
OID
0b19ce…a8da:185
OpenRestore details

Inspect func

SealRestore

func()

SealRestore closes the door permanently. Valid from any state, including "never" — which is how it should be called on a chain that has nothing to restore, so that the capability is provably dead rather than merely unused. There is no matching unseal, and adding one later would defeat every word written at the top of this file.

Open
OID
0b19ce…a8da:186
SealRestore details

Inspect func

RestoreDomain

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

RestoreDomain re-creates one domain with its original dates. ORDER MATTERS: domains before their names. The vault refuses to register a name under a domain that does not exist or had lapsed at the moment the name claims to have been registered, which is correct behaviour and also exactly the order a snapshot should be replayed in. The vault's own registration path sets \`registered\` to whatever instant it is handed and derives the expiry from the term length, so the registration date is restored by passing the ORIGINAL one, and the expiry is then corrected to the recorded value rather than a computed one. Anything else would quietly hand everybody a fresh term.

Open
OID
0b19ce…a8da:187
RestoreDomain details

Inspect func

RestoreName

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

RestoreName re-creates one name. See RestoreDomain on ordering and on why the dates are passed rather than computed. isNFT is carried across under its old name so snapshot blobs stay readable, and now means PAID: false restores a free-tier name with the hold on its token, so a restore can never quietly make a free name sellable.

Open
OID
0b19ce…a8da:188
RestoreName details

Inspect func

RestoreNames

func(blob string) int

RestoreNames replays many names in ONE transaction. WHY A BLOB AND NOT A LOOP OF CALLS. A restore is done in one sitting against a clock: the window is bounded and the people whose names are missing are watching. One transaction per name is one signature per name, and at a few hundred names that is an afternoon of clicking during which a single mistimed refresh loses the thread. The compact form here is unpleasant to read and it is the difference between a restore that gets finished and one that gets abandoned half way. The format is records separated by "|", fields separated by ",": label,domain,owner,registered,expires,ttl,frozen,isNFT Neither a label nor a domain may contain "," or "|" — the character set is enforced at registration — and an address contains neither, so the split is unambiguous. tools/snapshot.js writes the JSON this is built from; see tools/restore-blob.js for the conversion. It stops at the first bad record and panics, taking the whole transaction with it. That is deliberate: a partial batch that silently skipped four names would leave four people without theirs and nothing anywhere saying which four.

Open
OID
0b19ce…a8da:189
RestoreNames details

Inspect func

restoreRec

type

restoreRec is one parsed line of the blob.

Value

v1.restoreRec

parseRestoreRecord

func(rec string, i int) v1.restoreRec

parseRestoreRecord reads one record and refuses anything it is not sure about. EVERY CHECK HERE IS A PANIC AND NOT A SKIP. The blob is machine-written from a snapshot, so a malformed record does not mean "this one name is odd", it means the file is not what it was believed to be — and the worst outcome available is a restore that appears to succeed while quietly dropping the records it could not read. Somebody would find out months later when one person asked where their name went.

Open
OID
0b19ce…a8da:190
parseRestoreRecord details

Inspect func

mustSecs

func(s string, i int, what string) int64
Open
OID
0b19ce…a8da:191
mustSecs details

Inspect func

ttlSecs

func(s string, i int) int64

ttlSecs reads a TTL and caps it at maxTTL (name.gno). A holder may have set any non-negative int64 before the cap existed, and a snapshot written by JavaScript rounded such a value above 2^53 — MaxInt64 came back as 9223372036854776000, which no int64 holds — so the whole batch of fifty reverted (re-audit 2026-10-16, M-3). A run of digits too large to parse is read as the longest a TTL may be; anything else malformed still refuses the record.

Open
OID
0b19ce…a8da:192
ttlSecs details

Inspect func

RestoreNameField

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

RestoreNameField and RestoreDomainField put back a record's extension keys — profiles, cross-chain addresses, tier markers, and a domain's pricing rules. Separate calls because the extension slot has no fixed shape by design, which is the same reason the snapshot captures it by enumeration rather than by schema.

Open
OID
0b19ce…a8da:194
RestoreNameField details

Inspect func

RestoreDomainField

func(label string, key string, value string)
Open
OID
0b19ce…a8da:195
RestoreDomainField details

Inspect func

RestoreGlobal

func(key string, value string)

RestoreGlobal puts back the vault's global slot — where the default price, the referral tiers and the seasonal card effects live. It refuses to write the restore keys themselves. Without that, a snapshot taken while a window was open would, on being replayed, cheerfully restore the open window along with everything else — and a seal that a backup file can undo is not a seal.

Open
OID
0b19ce…a8da:196
RestoreGlobal details

Inspect func

RestoreAccountField

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

RestoreAccountField puts back one field of the per-address store — credits and their redemptions, referral counts. Without it a rebuilt registry would forget who had already spent their free name, and the migration grant could be claimed twice.

Open
OID
0b19ce…a8da:197
RestoreAccountField details

Inspect func

RestorePrimary

func(owner .uverse.address, label string, domainLabel string)

RestorePrimary puts back reverse resolution — which name an address answers to. Registration already sets this for an owner who had none, so this exists for the owners who had chosen a different one. SKIPPED, NOT REFUSED, when the vault would refuse it — the name is not there, or the ledger says somebody else holds it (a sale leaves the seller's pointer behind): pointers travel fifty to a transaction, and one stale pointer must not revert everybody else's (re-audit 2026-10-16, M-3).

Open
OID
0b19ce…a8da:198
RestorePrimary details

Inspect func

keyMaxTerm

untyped string

// domain extra AND global: years of runway

Value

"maxterm"

defaultMaxTerm

int64

How far ahead a name may be paid. Renewal was unbounded. RenewNameRecord adds one term to the previous due date and asks no further questions, so a holder pressing renew seven times bought seven years of runway, and nothing anywhere said that was not intended. It is a bug in two directions at once: - Free domains have a base price of zero. Renewal is free too, so a script could take every good name under \*gnoland and hold it for a century for the cost of gas. There is no economic brake on a free name at all; the term limit IS the brake. - A paid name held fifty years ahead is fifty years of a promise we have made against a rate written by hand and a testnet that will be replaced. Selling that is easy and honouring it is not. The limit is RUNWAY, not total lifetime: at most N years may be outstanding at any moment. Nobody is stopped from holding a name forever — they renew as the runway burns down, which is the same arrangement every domain registrar has always used and the one people already understand. Per domain first, then a project-wide default, so a free domain can be capped at one year without capping anything else.

Value

5

maxMaxTermYears

int64

How far ahead a name may be paid. Renewal was unbounded. RenewNameRecord adds one term to the previous due date and asks no further questions, so a holder pressing renew seven times bought seven years of runway, and nothing anywhere said that was not intended. It is a bug in two directions at once: - Free domains have a base price of zero. Renewal is free too, so a script could take every good name under \*gnoland and hold it for a century for the cost of gas. There is no economic brake on a free name at all; the term limit IS the brake. - A paid name held fifty years ahead is fifty years of a promise we have made against a rate written by hand and a testnet that will be replaced. Selling that is easy and honouring it is not. The limit is RUNWAY, not total lifetime: at most N years may be outstanding at any moment. Nobody is stopped from holding a name forever — they renew as the runway burns down, which is the same arrangement every domain registrar has always used and the one people already understand. Per domain first, then a project-wide default, so a free domain can be capped at one year without capping anything else.

Value

100

MaxTermYears

func(domainLabel string) int64

MaxTermYears is the cap that applies to names under this domain.

Open
OID
0b19ce…a8da:199
MaxTermYears details

Inspect func

SetMaxTerm

func(domainLabel string, years int64)

SetMaxTerm caps a single domain, or the whole project when the domain label is empty. A domain's own cap always wins, so tightening one free domain does not disturb the rest.

Open
OID
0b19ce…a8da:201
SetMaxTerm details

Inspect func

RenewalsLeft

func(label string, domainLabel string) int64

RenewalsLeft is how many more years may be added to a name right now. Zero means the renew button should be off, and the site reads this rather than doing the arithmetic itself — the cap can be per domain, and a page that guesses it will guess wrong on exactly the domains where it matters. An unregistered name reports the full allowance: nothing is holding runway yet.

Open
OID
0b19ce…a8da:202
RenewalsLeft details

Inspect func

renewalsLeft

func(expires int64, now int64, term int64, maxYears int64) int64

renewalsLeft is the arithmetic on its own, so it can be tested without a chain under it. Runway is measured from NOW, not from the registration date, so a name deep in its grace period counts as zero rather than as a negative that would then read as extra room. Years already bought round UP: a name with thirteen months left is holding two of its five, because the alternative lets somebody sit permanently at four-years-and-eleven- months and renew every month forever.

Open
OID
0b19ce…a8da:203
renewalsLeft details

Inspect func

assertRoomToRenew

func(label string, domainLabel string)

assertRoomToRenew is the enforcement. It runs before payment is taken, so a rejected renewal costs gas and nothing else — taking the money first and reverting would work too, but only because a panic reverts, and depending on that for a refund is a habit that eventually meets a path where it is not true.

Open
OID
0b19ce…a8da:204
assertRoomToRenew details

Inspect func

actionID

func(fn string, args []string) string

actionID is the canonical name of one call: the function and its arguments, separated by single spaces, an empty argument written "". It is what the admin proposes and what the call spends, so a proposal authorizes exactly one change with exactly those arguments.

Open
OID
0b19ce…a8da:205
actionID details

Inspect func

assertActionReady

func(id string)

assertActionReady explains, before anything is written, why a timelocked call cannot run yet. The vault's ConsumeAction is the authority; this only makes the refusal say what to do.

Open
OID
0b19ce…a8da:207
assertActionReady details

Inspect func

requireAction

func(id string)

requireAction lets a timelocked call through only on a matured proposal for exactly this call, and spends it.

Open
OID
0b19ce…a8da:208
requireAction details

Inspect func

cheapMaxPct

untyped bigint

Value

(25 <untyped> bigint)

cheapCooldown

untyped bigint

Value

(3600 <untyped> bigint)

dearMaxFactor

untyped bigint

Value

(4 <untyped> bigint)

dearCooldown

untyped bigint

Value

(600 <untyped> bigint)

maxRate

int64

Value

1000000000000

lastTweak

v0.Tree

lastTweak is the ONE piece of state this realm keeps: when each bounded setting last moved, one clock per direction. Not a record — losing it costs nothing but one early tweak — so it lives here rather than in the vault, and a logic swap simply starts it empty.

Open
OID
0b19ce…a8da:210
lastTweak details

Inspect ref

clockKey

func(setting string, dearer bool) string
Open
OID
0b19ce…a8da:211
clockKey details

Inspect func

authorizeTweak

func(setting string, old int64, next int64, dearer bool, id string)

authorizeTweak lets a bounded setting move from \`old\` to \`next\` instantly when the move stays inside its direction's bound and that direction's clock has rested; otherwise it needs a matured proposal of \`id\`, which it spends. \`dearer\` says whether the move makes names dearer — for the rate and the prices that is a rise, for the credit cap a fall — and the caller, which knows what its setting means, decides it. A move to or from zero is never an instant step: a free domain, or a price restored from free, is a decision.

Open
OID
0b19ce…a8da:212
authorizeTweak details

Inspect func

authorizeTweakOn

func(settings []string, old int64, next int64, dearer bool, id string)

authorizeTweakOn is authorizeTweak for a move that rides more than one clock: every clock named must have rested, and all of them are stamped. An unpriced domain's base price IS the default, so its first price of its own is measured against the default — after the default has already been cut, on a clock of its own. Rate, default and domain then each took 25% in one block: 0.75^3 of the price, 58% off, not the two levers (about 44%) this file promises (re-audit 2026-10-16, L-1). So that first own price rides the default's clocks too (domain.gno): in any hour, either the default or an unpriced domain's first own price moves, never both.

Open
OID
0b19ce…a8da:213
authorizeTweakOn details

Inspect func

withinStep

func(old int64, next int64, dearer bool) bool

withinStep is the bound on its own. New values are capped (maxPriceUSD, maxRate); an old value stored before the caps, or by a restore, is not, so anything too large to multiply safely is simply not an instant step.

Open
OID
0b19ce…a8da:214
withinStep details

Inspect func

inheritClocks

func(to string, from string)

inheritClocks gives \`to\` every last-move time of \`from\` that is later than its own, in both directions: a setting that starts out as another one's value starts on that one's clocks.

Open
OID
0b19ce…a8da:215
inheritClocks details

Inspect func

clockRested

func(setting string, dearer bool, now int64) bool
Open
OID
0b19ce…a8da:216
clockRested details

Inspect func

stepRefusal

func(setting string, old int64, next int64, dearer bool) string
Open
OID
0b19ce…a8da:217
stepRefusal details

Inspect func

restRefusal

func(setting string, dearer bool) string
Open
OID
0b19ce…a8da:218
restRefusal details

Inspect func

LastTweak

func(setting string) (dearer int64, cheaper int64)

LastTweak reports when a bounded setting last moved instantly in each direction (unix seconds, 0 for never), so the panel can say when the next step each way is due: dearer after ten minutes, cheaper after an hour.

Open
OID
0b19ce…a8da:219
LastTweak details

Inspect func

managedGlobal

func(key string) bool

managedGlobal reports whether SetGlobal must refuse a key, because a setter in this realm owns it — bounded, timelocked or validated. The escape hatch wrote any key, so it walked straight round every one of those rules: SetGlobal("rateUgnotPerUsd", "1") was a one-call way to sell every name for dust.

Open
OID
0b19ce…a8da:220
managedGlobal details

Inspect func

managedDomainKey

func(key string) bool

managedDomainKey is the same rule for SetDomainField.

Open
OID
0b19ce…a8da:221
managedDomainKey details

Inspect func

ugnot

untyped string

Value

"ugnot"

bpsDenom

untyped bigint

Value

(10000 <untyped> bigint)

labelRule

untyped string

labelRule is the pattern this realm implements, kept as a string so nsdata, the error messages and the site all quote the same thing.

Value

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

matchesLabelRule

func(s string) bool

matchesLabelRule is that pattern, by hand: lowercase letters and digits, single hyphens between them, none at either end.

Open
OID
0b19ce…a8da:222
matchesLabelRule details

Inspect func

looksLikeAddress

func(s string) bool

looksLikeAddress was \`^g1\[a-z0-9]{20,38}$\`. Anything shaped like a real gno.land address is refused as a label, so a name can never be mistaken for a raw wallet address in a UI.

Open
OID
0b19ce…a8da:224
looksLikeAddress details

Inspect func

validateLabel

func(label string)

validateLabel — same policy as the original single-realm build (see NOTES.md for the ENS/Starname/r/sys/users research behind it). The length bounds are still read from nsdata, so they survive a swap of this realm; the character rule is now this realm's own. Call sites, and why: RegisterName/RegisterDomain only (both the first-ever mint AND reclaiming a past-grace slot — a reclaim is a genuine new mint with a new owner). RenewName/RenewDomain deliberately do NOT call this — an already-registered name must keep renewing under whatever rule was in force when it was minted.

Open
OID
0b19ce…a8da:225
validateLabel details

Inspect func
assertIsAdmin : func() Inspect
SetLabelPattern : func(pattern string) Inspect
SetLabelLengthLimits : func(minLen int, maxLen int) Inspect
SetDefaultNamePrice : func(microUsd int64) Inspect
SetUsdRate : func(ugnotPerUsd int64) Inspect
maxLifecycleDays : untyped bigint =(36500 <untyped> bigint)
SetTermLength : func(days int64) Inspect
SetGracePeriod : func(days int64) Inspect
SetTokenURIBase : func(base string) Inspect
SetExtraLimits : func(keyLen int, valueLen int, entries int) Inspect
minExtraKeyLen : untyped bigint =(32 <untyped> bigint)
minExtraValueLen : untyped bigint =(512 <untyped> bigint)
minExtraEntries : untyped bigint =(24 <untyped> bigint)
SetGlobalEntryLimit : func(entries int) Inspect
SetAccountLimits : func(keyLen int, valueLen int, entries int) Inspect
SetMarketFee : func(spec string) Inspect
keyMarketFee : untyped string ="marketfee"
defaultMarketFee : untyped string ="1000000"
feeCouldRise : func(old string, next string) bool Inspect
feeParts : func(spec string) (flat int64, bps int64) Inspect
assertValidFeeSpec : func(spec string) Inspect
SetGlobal : func(key string, value string) Inspect
setGlobal : func(key string, value string) Inspect
SetTreasury : func(newTreasury .uverse.address) Inspect
SelfAddress : func() .uverse.address Inspect
blockChunks : untyped bigint =(8 <untyped> bigint)
blockKeyStem : untyped string ="block"
blockChunkMax : untyped bigint =(512 <untyped> bigint)
blockKey : func(i int) string Inspect
BlockedLabel : func(label string) bool Inspect
BlockList : func(i int) string Inspect
BlockChunks : func() int Inspect
SetBlockList : func(i int, csv string) Inspect
assertNotBlocked : func(label string) Inspect
keyCredit : untyped string ="cr"
keyClaimEnd : untyped string ="claimend"
keyClaimMax : untyped string ="claimmax"
maxCreditsPerAddress : untyped bigint =(100 <untyped> bigint)
maxGrantBatch : untyped bigint =(100 <untyped> bigint)
maxClaimWindowDays : untyped bigint =(730 <untyped> bigint)
credit : type =v1.credit
parseCredit : func(v string) v1.credit Inspect
readCredit : func(owner .uverse.address) v1.credit Inspect
writeCredit : func(owner .uverse.address, c v1.credit) Inspect
CreditsOf : func(owner .uverse.address) (available int64, granted int64, used int64, expires int64, sellable bool) Inspect
CreditGrantedAt : func(owner .uverse.address) int64 Inspect
ClaimWindowEnd : func() int64 Inspect
ClaimWindowOpen : func() bool Inspect
readClaimWindow : func(v string, now int64) bool Inspect
SetClaimWindow : func(end int64) Inspect
ClaimMaxPriceUSD : func() int64 Inspect
ClaimCapSet : func() bool Inspect
claimCap : func() (int64, bool) Inspect
SetClaimMaxPrice : func(microUsd int64) Inspect
GrantCredits : func(to .uverse.address, n int64, expires int64, sellable bool) Inspect
GrantCreditsBatch : func(addrs string, n int64, expires int64, sellable bool) int Inspect
grantCredits : func(to .uverse.address, n int64, expires int64, sellable bool, now int64) Inspect
RedeemCredit : func(label string, domainLabel string) Inspect
RegisterFor : func(owner .uverse.address, label string, domainLabel string) Inspect
CreditRefusal : func(owner .uverse.address, label string, domainLabel string) string Inspect
creditRefusal : func(owner .uverse.address, label string, domainLabel string, now int64) string Inspect
redeemCredit : func(owner .uverse.address, label string, domainLabel string) Inspect
RegisterDomain : func(label string) Inspect
RenewDomain : func(label string) Inspect
ReassignDomain : func(label string, newOwner .uverse.address) Inspect
SetDomainOpen : func(label string, open bool) Inspect
SetDomainBasePrice : func(label string, microUsd int64) Inspect
SetDomainLengthRules : func(label string, rules string) Inspect
SetDomainNameOverrides : func(label string, rules string) Inspect
SetDomainField : func(label string, key string, value string) Inspect
setDomainExtra : func(label string, key string, value string) Inspect
DeleteDomain : func(label string) (removed int64, done bool) Inspect
SetDomainTTL : func(label string, seconds int64) Inspect
FreezeDomain : func(label string) Inspect
UnfreezeDomain : func(label string) Inspect
emitAdmin : func(fn string, kv []string) Inspect
fmtInt : func(n int64) string Inspect
fmtI : func(n int) string Inspect
fmtBool : func(b bool) string Inspect
keyFreeDomain : untyped string ="free"
keyGrantEnd : untyped string ="grantend"
keyGranter : untyped string ="granter"
Granter : func() .uverse.address Inspect
SetGranter : func(a .uverse.address) Inspect
SetFreeLengths : func(min int, max int) Inspect
assertMayGrant : func() Inspect
DomainFree : func(domainLabel string) bool Inspect
SetDomainFree : func(domainLabel string, on bool) Inspect
GrantWindowOpen : func() bool Inspect
readGrantWindow : func(v string, now int64) bool Inspect
GrantFreeName : func(label string, domainLabel string, owner .uverse.address) Inspect
UpgradeFreeName : func(label string, domainLabel string, newOwner .uverse.address) Inspect
GrantFreeRenewal : func(label string, domainLabel string) Inspect
IsFreeTier : func(label string, domainLabel string) bool Inspect
maxHoldingsPage : untyped bigint =(200 <untyped> bigint)
NamesOwnedBy : func(owner .uverse.address, after string, limit int) (rows string, next string) Inspect
CountNamesOwnedBy : func(owner .uverse.address, after string, limit int) (n int, next string) Inspect
ProfileOf : func(label string, domainLabel string, keys string) string Inspect
escapeValue : func(s string) string Inspect
RecentNames : func(after string, limit int) (rows string, next string) Inspect
keyKeeper : untyped string ="keeper"
Keeper : func() .uverse.address Inspect
SetKeeper : func(a .uverse.address) Inspect
ClearKeeper : func() Inspect
isGovernor : func(a .uverse.address) bool Inspect
assertIsKeeper : func(caller .uverse.address) Inspect
keeperSetRate : func(ugnotPerUsd int64) Inspect
keeperStep : func(setting string, old int64, next int64) Inspect
keyDisplayName : untyped string ="displayName"
keyBio : untyped string ="bio"
keyWebsite : untyped string ="website"
keyAvatar : untyped string ="avatar"
RegisterName : func(label string, domainLabel string) Inspect
RegisterNameRef : func(label string, domainLabel string, refName string) Inspect
registerName : func(label string, domainLabel string, refName string) Inspect
RenewName : func(label string, domainLabel string) Inspect
SetProfile : func(label string, domainLabel string, displayName string, bio string, website string, avatar string) Inspect
SetNameField : func(label string, domainLabel string, key string, value string) Inspect
setExtra : func(label string, domainLabel string, key string, value string) Inspect
assertNameOwner : func(label string, domainLabel string) Inspect
SetPrimaryName : func(label string, domainLabel string) Inspect
ClearPrimaryName : func() Inspect
maxTTL : int64 =2147483647
SetNameTTL : func(label string, domainLabel string, seconds int64) Inspect
FreezeName : func(label string, domainLabel string) Inspect
UnfreezeName : func(label string, domainLabel string) Inspect
maxUnfreezeBatch : untyped bigint =(64 <untyped> bigint)
UnfreezeNames : func(tids string) Inspect
ResolveName : func(label string, domainLabel string) .uverse.address Inspect
ResolveAddress : func(addr .uverse.address) string Inspect
splitTokenID : func(tid string) (label string, domainLabel string) Inspect
isDomainToken : func(tid string) bool Inspect
isTokenValid : func(tid string) bool Inspect
assertNotFrozen : func(tid string) Inspect
takePayment : func(price int64) Inspect
takePaymentSplit : func(price int64, cutTo .uverse.address, cut int64) Inspect
assertOnlyUgnot : func(sent chain.Coins) Inspect
assertNoSend : func() Inspect
keyGlobalLens : untyped string ="glen"
keyPremium : untyped string ="premium"
maxPremiumKeys : untyped bigint =(8 <untyped> bigint)
GlobalLengthRule : func(n int) (string, bool) Inspect
PremiumFor : func(label string) string Inspect
applyPremium : func(mod string, price int64) int64 Inspect
parseUSD : func(s string) (int64, bool) Inspect
SetGlobalLengthRules : func(rules string) Inspect
SetPremiumNames : func(page int, csv string) Inspect
PremiumNames : func(page int) string Inspect
GlobalLengthRules : func() string Inspect
normalizePremiums : func(csv string) string Inspect
validPremiumValue : func(v string) bool Inspect
keyPrice : untyped string ="price"
keyLens : untyped string ="len"
keyNames : untyped string ="nm"
keyOpen : untyped string ="open"
keyDefaultPrice : untyped string ="defaultPrice"
keyRate : untyped string ="rateUgnotPerUsd"
microUSD : int64 =1000000
fallbackPriceUSD : int64 =500000
fallbackRate : int64 =14492753
maxRules : untyped bigint =(64 <untyped> bigint)
maxPriceUSD : int64 =1000000000000
maxRulePct : untyped bigint =(10000 <untyped> bigint)
DomainOpen : func(domainLabel string) bool Inspect
DefaultPriceUSD : func() int64 Inspect
DomainBasePriceUSD : func(domainLabel string) int64 Inspect
NamePriceUSD : func(domainLabel string, label string) int64 Inspect
resolveBeforePremium : func(domainLabel string, label string) int64 Inspect
ExplainPriceUSD : func(domainLabel string, label string) (beforePremium int64, modifier string, final int64) Inspect
RateUgnotPerUsd : func() int64 Inspect
NamePrice : func(domainLabel string, label string) int64 Inspect
applyRule : func(v string, base int64) int64 Inspect
lookupRule : func(csv string, want string) (string, bool) Inspect
normalizeRules : func(csv string, numericKeys bool) string Inspect
keyRef : untyped string ="ref"
keyRefCut : untyped string ="refcut"
keyRefDisc : untyped string ="refdisc"
keyRefCount : untyped string ="rc"
keyRefWin : untyped string ="refwin"
maxRefPercent : untyped bigint =(10 <untyped> bigint)
refHoldDays : untyped bigint =(30 <untyped> bigint)
tierPercent : func(spec string, years int64) int64 Inspect
RefRates : func() (cutPct int64, discountPct int64) Inspect
clampRates : func(cut int64, disc int64) (int64, int64) Inspect
defaultRefCut : untyped string ="0:5"
defaultRefDiscount : untyped string ="0:5"
DefaultReferralRules : func() (cut string, discount string) Inspect
SeedReferralRules : func() Inspect
RefCutRules : func() string Inspect
RefDiscountRules : func() string Inspect
RefWindowDays : func() int64 Inspect
SetReferralWindow : func(days int64) Inspect
ReferralQuote : func(refName string, buyer .uverse.address) (referrer .uverse.address, tenure int64, discountPct int64, cutPct int64) Inspect
SetReferralRules : func(cutSpec string, discountSpec string) Inspect
normalizeRate : func(spec string) (stored string, pct int64) Inspect
TenureYears : func(who .uverse.address) int64 Inspect
PayoutFor : func(who .uverse.address) .uverse.address Inspect
ReferrerOf : func(label string, domainLabel string) .uverse.address Inspect
resolveReferrer : func(refName string, buyer .uverse.address) .uverse.address Inspect
heldLongEnough : func(since int64, now int64) bool Inspect
StartReferralClock : func(label string, domainLabel string) Inspect
PriceWithReferral : func(domainLabel string, label string, refName string, buyer .uverse.address) int64 Inspect
referralCut : func(ref .uverse.address, price int64) (.uverse.address, int64) Inspect
creditReferral : func(ref .uverse.address) Inspect
ReferralCount : func(who .uverse.address) int64 Inspect
parseInt64 : func(s string) int64 Inspect
refBoardPages : untyped bigint =(5 <untyped> bigint)
ReferralBoard : func(after string, limit int) (rows string, next string) Inspect
defaultFreeMinLength : untyped bigint =(5 <untyped> bigint)
defaultFreeMaxLength : untyped bigint =(63 <untyped> bigint)
keyFreeMin : untyped string ="freemin"
keyFreeMax : untyped string ="freemax"
FreeMinLength : func() int Inspect
FreeMaxLength : func() int Inspect
FreeLabelAllowed : func(label string) bool Inspect
keyRestore : untyped string ="restore"
restoreNever : untyped string =""
restoreSealed : untyped string ="sealed"
restoreOpen : untyped string ="open:"
maxRestoreDays : untyped bigint =(30 <untyped> bigint)
RestoreStatus : func() (state string, deadline int64, restored int64) Inspect
readRestoreState : func(raw string, now int64) (state string, deadline int64) Inspect
keyRestoredCount : untyped string ="restored"
restoredCount : func() int64 Inspect
setRestoreKey : func(key string, value string) Inspect
bumpRestored : func(n int64) Inspect
assertNotRestoring : func() Inspect
assertRestoring : func() Inspect
OpenRestore : func(days int64) Inspect
SealRestore : func() Inspect
RestoreDomain : func(label string, owner .uverse.address, registered int64, expires int64, ttl int64, frozen bool) Inspect
RestoreName : func(label string, domainLabel string, owner .uverse.address, registered int64, expires int64, ttl int64, frozen bool, isNFT bool) Inspect
RestoreNames : func(blob string) int Inspect
restoreRec : type =v1.restoreRec
parseRestoreRecord : func(rec string, i int) v1.restoreRec Inspect
mustSecs : func(s string, i int, what string) int64 Inspect
ttlSecs : func(s string, i int) int64 Inspect
clampTTL : func(v int64) int64 Inspect
RestoreNameField : func(label string, domainLabel string, key string, value string) Inspect
RestoreDomainField : func(label string, key string, value string) Inspect
RestoreGlobal : func(key string, value string) Inspect
RestoreAccountField : func(owner .uverse.address, key string, value string) Inspect
RestorePrimary : func(owner .uverse.address, label string, domainLabel string) Inspect
keyMaxTerm : untyped string ="maxterm"
defaultMaxTerm : int64 =5
maxMaxTermYears : int64 =100
MaxTermYears : func(domainLabel string) int64 Inspect
SetMaxTerm : func(domainLabel string, years int64) Inspect
RenewalsLeft : func(label string, domainLabel string) int64 Inspect
renewalsLeft : func(expires int64, now int64, term int64, maxYears int64) int64 Inspect
assertRoomToRenew : func(label string, domainLabel string) Inspect
actionID : func(fn string, args []string) string Inspect
assertActionReady : func(id string) Inspect
requireAction : func(id string) Inspect
cheapMaxPct : untyped bigint =(25 <untyped> bigint)
cheapCooldown : untyped bigint =(3600 <untyped> bigint)
dearMaxFactor : untyped bigint =(4 <untyped> bigint)
dearCooldown : untyped bigint =(600 <untyped> bigint)
maxRate : int64 =1000000000000
lastTweak : v0.Tree Inspect
clockKey : func(setting string, dearer bool) string Inspect
authorizeTweak : func(setting string, old int64, next int64, dearer bool, id string) Inspect
authorizeTweakOn : func(settings []string, old int64, next int64, dearer bool, id string) Inspect
withinStep : func(old int64, next int64, dearer bool) bool Inspect
inheritClocks : func(to string, from string) Inspect
clockRested : func(setting string, dearer bool, now int64) bool Inspect
stepRefusal : func(setting string, old int64, next int64, dearer bool) string Inspect
restRefusal : func(setting string, dearer bool) string Inspect
LastTweak : func(setting string) (dearer int64, cheaper int64) Inspect
managedGlobal : func(key string) bool Inspect
managedDomainKey : func(key string) bool Inspect
ugnot : untyped string ="ugnot"
bpsDenom : untyped bigint =(10000 <untyped> bigint)
labelRule : untyped string ="^[a-z0-9]+(-[a-z0-9]+)*$"
matchesLabelRule : func(s string) bool Inspect
looksLikeAddress : func(s string) bool Inspect
validateLabel : func(label string) Inspect