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

v0 source realm

Package nativereg is the metadata a native coin does not have.

Readme View source

gno.land/r/moul/x/nativereg/v0

The metadata a native coin does not have.

/gno.land/r/moul/x/moultest/v0:moultest is the entire object. The chain stores a string and a balance: no name, no symbol, no decimals, no icon, no link to the issuer. A wallet showing you that balance has only the path to print.

This realm is where a denom says what it is. It is the mirror of r/nt/grc20reg, and the two solve opposite problems: a GRC20 carries its own name and is hard to find, so that registry maps a key to an object; a native denom is trivial to find and carries no name, so this one maps the denom to what it means.

Registration is proved, not claimed

A denom embeds the package path of the realm allowed to issue it, verbatim: "/" + pkgPath + ":" + baseName. So the issuer is readable from the string, and Register simply requires the caller to be it. No allowlist, no owner, no signature scheme.

1import "gno.land/r/moul/x/nativereg/v0"
2
3func init(cur realm) {
4    nativereg.Register(cross(cur), Denom, "My Coin", "MINE", 6,
5        "one line about what it is for")
6}

A user account cannot register anything, not even a denom it holds every unit of: there is no package path in a user call to compare against. What is being described is the issuance, not the holding.

IssuerOf(denom) answers the same question for a denom nobody ever registered, which is the case that matters: given a balance you did not ask for, that is how you find the code that can take it away.

Facts and hints

Denom and Issuer are facts, because the chain enforces the relation between them. Everything else is whatever the issuing realm chose to say, and Decimals in particular is a display hint with nothing behind it: the bank has no notion of divisibility, so a coin wrapped out of a 6-decimal GRC20 is still counted in whole units by every balance query.

Trusting an entry means trusting the realm that wrote it, exactly as much as holding its coin already means trusting it not to call RemoveCoin on you.

?<denom> shows one entry, ?<pkgpath> shows everything one realm issues.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

Dependency graph:

gno.land/r/moul/x/nativereg/v0 dependency graph

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.

Overview

Package nativereg is the metadata a native coin does not have.

A realm-issued coin is a string and a balance. `/gno.land/r/moul/x/moultest/v0:moultest` is the entire object: no name, no symbol, no decimals, no icon, no link to whoever issues it. The bank knows the number and nothing else, so a wallet or an explorer showing you a balance has only that path to print.

This realm is where a denom says what it is. It is the mirror image of `r/nt/grc20reg`, and the two solve opposite problems: a GRC20 is an object that carries its own name and is hard to FIND, so the registry maps a key to the object; a native denom is trivial to find and carries no name, so the registry maps the denom to what it means.

Registration is proved, not claimed

A denom embeds the package path of the realm allowed to issue it, verbatim: `"/" + pkgPath + ":" + baseName` (`chain.CoinDenom`). So the issuer is readable from the denom, and Register simply requires the caller to be it. A realm registers its own coins and nobody else's, with no allowlist, no owner and no signature scheme.

A user account cannot register anything, not even a denom it holds all of: there is no package path in a user call to compare against. That is the intended shape, since the thing being described is the issuance, not the holding.

What is a hint and what is a fact

`Denom` and `Issuer` are facts: the chain enforces the relation between them. Everything else is whatever the issuing realm chose to say, and `Decimals` in particular is a DISPLAY hint with nothing behind it. The bank has no notion of divisibility; a coin wrapped out of a 6-decimal GRC20 is still counted in whole units by every balance query. Rendering 1000000 as 1.000000 is a convention between this realm and whoever reads it.

So trusting an entry means trusting the realm that wrote it, exactly as much as holding its coin already means trusting it not to call `RemoveCoin` on you.

Constants 1

const MaxName, MaxSymbol, MaxDoc, MaxDecimals

 1const (
 2	// MaxName, MaxSymbol and MaxDoc bound what an issuer can store here. The
 3	// registry pays the storage for every byte a caller hands it, so the
 4	// limits are the realm's own cost control, not a style rule.
 5	MaxName   = 40
 6	MaxSymbol = 12
 7	MaxDoc    = 200
 8	// MaxDecimals matches the GRC20 ceiling, which is where a wrapped coin's
 9	// hint comes from in practice.
10	MaxDecimals = 18
11)
source

Functions 9

func IsRegistered

Action
1func IsRegistered(denom string) bool
source

IsRegistered reports whether a denom has said anything about itself.

func IssuerOf

Action
1func IssuerOf(denom string) string
source

IssuerOf returns the package path embedded in a denom, without consulting the registry: the relation is in the string itself. It aborts on anything that is not a realm denom, which includes `ugnot`.

It is exported because it is useful to anybody handling a denom, registered or not: given a balance, this is how you find the code that can take it away.

func Register

crossing Action
1func Register(cur realm, denom, name, symbol string, decimals int, doc string)
source

Register records or rewrites what a denom means. The caller must be the realm the denom names, which is the entire authorization.

Calling it again overwrites the entry and bumps [Entry.Revisions]. An issuer can always re-describe its own coin, and can never describe anybody else's.

func Render

1func Render(path string) string
source

Render lists the registry. `?<denom>` shows one entry, `?<pkgpath>` shows everything one realm issues.

func ByIssuer

Action
1func ByIssuer(pkgPath string) []Entry
source

ByIssuer returns every entry issued by one realm, in registration order.

func Get

Action
1func Get(denom string) (Entry, bool)
source

Get returns the entry for a denom, and whether it has one.

func List

Action
1func List() []Entry
source

List returns every entry, in registration order.

func MustGet

Action
1func MustGet(denom string) Entry
source

MustGet is Get for a caller that treats an unregistered denom as a bug.

Types 1

type Entry

struct
 1type Entry struct {
 2	// Denom is the full chain denom, the key of this registry.
 3	Denom string
 4	// Issuer is the package path embedded in Denom: the only realm that can
 5	// issue, remove or re-describe this coin.
 6	Issuer string
 7	// Name, Symbol and Decimals are display metadata, chosen by the issuer.
 8	// Decimals is a hint; see the package doc.
 9	Name     string
10	Symbol   string
11	Decimals int
12	// Doc is one line about what the coin is for.
13	Doc string
14	// Height is when the entry was last written.
15	Height int64
16	// Revisions counts how many times the issuer has rewritten it.
17	Revisions int
18}
source

Entry is what one denom says about itself.

Imports 6

Source Files 5