Buy
func(skinID string) int64Buy buys one token of a skin design for the caller and returns its id. The exact price must be attached to the transaction (-send "\<price>ugnot") and is forwarded to the treasury of the game realm before the call returns. An address owns at most one token of a design: a skin cannot be given away, so a second copy would be of no use. It must be called directly by a user (maketx call): a call relayed by another realm or by a maketx run script is refused.
- OID
- 0ab54f…c6d1:3
Buy details
Burn
func(id int64)Burn destroys a skin token. Only its owner can. The storage deposit paid at purchase comes back; the price does not. The owner can buy the design again, while it is listed.
- OID
- 0ab54f…c6d1:5
Burn details
ownedKey
func(addr .uverse.address, skinID string) stringownedKey is the key of owned: the address, then the design.
- OID
- 0ab54f…c6d1:6
ownedKey details
skinOf
func(id int64) stringskinOf returns the design of token id, "" when there is no such token.
- OID
- 0ab54f…c6d1:7
skinOf details
ownerOf
func(id int64) .uverse.address- OID
- 0ab54f…c6d1:8
ownerOf details
catalog
untyped stringcatalog is the skin catalog at deploy, one design per line, sorted by id: id|name|model|pilot|body|wing|accent|price The rules are those of SetSkin (see validate.gno); the tests check every line. The website reads this file too, at build, to serve the metadata of each design at [https://gnofly.xyz/nft/skins/](https://gnofly.xyz/nft/skins/)\<id>.json: a design added later with SetSkin needs a line here as well for its JSON to exist. Classic, the look every pilot flies by default, is not here: it is free and drawn by the client, not a token.
Value
"baron|Red Baron|biplane|none|#c1121f|#780000|#fdf0d5|7000000\ngnome|Garden Gnome|prop|none|#2a9d8f|#e9c46a|#264653|77000000\ngoldie|Golden Goose|jet|none|#ffd60a|#ffc300|#000814|7777000000\nstealth|Night Shift|jet|none|#22223b|#4a4e69|#f72585|777000000"
errSpoofedRealm
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: spoofed realm"
errNotAdmin
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: caller is not an admin"
errBadCatalog
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: corrupt catalog line"
errInvalidID
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: id must be 1 to 32 characters of [a-z0-9-]"
errReservedID
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: classic is the free look of every pilot, not a skin to sell"
errInvalidName
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: name must be 1 to 40 characters of [A-Za-z0-9 '.!-]"
errInvalidModel
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: model must be 1 to 16 characters of [a-z0-9-]"
errInvalidPilot
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: pilot must be none or gnome"
errInvalidColor
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: colors must be #rrggbb in lowercase"
errInvalidPrice
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: price must be between 1 and 1000000000000 ugnot"
errInvalidSupply
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: max supply must be 0 (unlimited) or more"
errUnknownSkin
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: unknown skin"
errSkinUnlisted
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: this skin is not for sale"
errSoldOut
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: every copy of this skin is sold"
errAlreadyOwned
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: this address already owns this skin"
errNotUserCall
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: Buy must be called directly by a user (maketx call)"
errNotMinted
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: no such skin token"
errNotSkinOwner
untyped stringThe refusals of this realm, as string constants: a string costs its length in storage where an errors.New value costs about 1.15 KB (see the planes realm). A panic with a string aborts the call with the same message.
Value
"gnofly: caller does not own this skin token"
CatalogJSON
func() stringCatalogJSON returns every design, sorted by id, as a JSON array: [ { "id": "baron", "name": "Red Baron", "model": "biplane", "pilot": "none", "body": "#c1121f", "wing": "#780000", "accent": "#fdf0d5", "price": 1000000, "listed": true, "minted": 3, "maxSupply": 0 } ] The output has no whitespace. maxSupply 0 is unlimited. Classic, the free look, is not in it: the client draws it without a token.
- OID
- 0ab54f…c6d1:9
CatalogJSON details
SkinsOf
func(addr .uverse.address) stringSkinsOf returns the designs addr owns a token of, sorted by id, as a JSON array: \["baron","goldie"]. It is \[] for an address without skins.
- OID
- 0ab54f…c6d1:11
SkinsOf details
OwnerOf
func(tid v0.TokenID) (.uverse.address, .uverse.error)- OID
- 0ab54f…c6d1:12
OwnerOf details
BalanceOf
func(addr .uverse.address) (int64, .uverse.error)BalanceOf returns how many skin tokens addr owns, one per design at most.
- OID
- 0ab54f…c6d1:13
BalanceOf details
TokenMetadata
func(tid v0.TokenID) (string, .uverse.error)TokenMetadata returns the metadata of skin token tid as JSON, the same for every token of a design, with the keys Adena reads: {"name":"Red Baron","description":"A gnofly skin, a biplane. ...", "image":"https://gnofly.xyz/nft/skins/baron.png", "attributes":[{"traitType":"model","value":"biplane"}, ...]}
- OID
- 0ab54f…c6d1:14
TokenMetadata details
mintedID
func(tid v0.TokenID) (int64, .uverse.error)mintedID reads a token id, "1" and up in decimal, and checks it exists.
- OID
- 0ab54f…c6d1:15
mintedID details
SkinOf
func(id int64) stringSkinOf returns the design of skin token id, "" when there is no such token.
- OID
- 0ab54f…c6d1:16
SkinOf details
TokenURI
func(tid v0.TokenID) (string, .uverse.error)TokenURI returns the image of skin token tid, "[https://gnofly.xyz/nft/skins/](https://gnofly.xyz/nft/skins/)\<design>.png": what a wallet shows (Adena puts it in an \<img>). The metadata is TokenMetadata, or "[https://gnofly.xyz/nft/skins/](https://gnofly.xyz/nft/skins/)\<design>.json" on the website. It is computed, not stored: a token costs no URI in deposit.
- OID
- 0ab54f…c6d1:17
TokenURI details
encode
func(n *v0.Node) stringencode marshals a document built above; it cannot fail on one.
- OID
- 0ab54f…c6d1:18
encode details
Render
func(path string) stringRender returns the shop as markdown, for gnoweb: "" the catalog "skin/<id>" one design "player/<addr>" the skins of one address Everything printed went through validate.gno when it was written, or is an address the chain gave the realm; the caller-supplied id and address are printed only once found valid.
- OID
- 0ab54f…c6d1:19
Render details
link
func(path string) string- OID
- 0ab54f…c6d1:21
link details
renderHome
func() string- OID
- 0ab54f…c6d1:22
renderHome details
renderDesign
func(d *skins.design) string- OID
- 0ab54f…c6d1:23
renderDesign details
renderPlayer
func(addr .uverse.address) string- OID
- 0ab54f…c6d1:24
renderPlayer details
designLink
func(d *skins.design) string- OID
- 0ab54f…c6d1:25
designLink details
supplyText
func(n int64) string- OID
- 0ab54f…c6d1:26
supplyText details
gnot
func(ugnot int64) stringgnot writes ugnot as GNOT: 1000000 -> "1 GNOT", 1500000 -> "1.5 GNOT".
- OID
- 0ab54f…c6d1:27
gnot details
yesNo
func(b bool) string- OID
- 0ab54f…c6d1:28
yesNo details
authority
typeauthority is the set of questions this realm asks about roles.
Value
skins.authority
gameRoles
typegameRoles answers with the roles of the game realm.
Value
skins.gameRoles
roles
skins.gameRolesroles is the authority of this realm: the game realm, always. It is a variable for one reason. Under \`gno test\` an imported realm is initialized without a deployer, and a test of this package has no way to become an admin of the game realm, so the tests put their own answers here. Nothing outside the test files assigns it, and there is no setter.
- OID
- 0ab54f…c6d1:30
roles details
callerOf
func(int, rlm .uverse.realm) .uverse.address- OID
- 0ab54f…c6d1:31
callerOf details
assertAdmin
func(int, rlm .uverse.realm) .uverse.address- OID
- 0ab54f…c6d1:33
assertAdmin details
design
typedesign is one skin of the catalog: what it looks like and how it sells.
Value
skins.design
token
*v0.TokenThe state. Nothing is exported by reference: the ledger and the trees are /p/ types with mutator methods. The token itself is not exported either: its tellers move tokens, and a skin never moves (soulbound, see doc.gno).
- OID
- 0ab54f…c6d1:64
token details
ledger
*v0.PrivateLedgerThe state. Nothing is exported by reference: the ledger and the trees are /p/ types with mutator methods. The token itself is not exported either: its tellers move tokens, and a skin never moves (soulbound, see doc.gno).
- OID
- 0ab54f…c6d1:66
ledger details
designs
v0.BPTree// design id -> \*design
- OID
- 0ab54f…c6d1:72
designs details
tokenSkin
v0.BPTree// token id -> design id
- OID
- 0ab54f…c6d1:89
tokenSkin details
owned
v0.BPTree// "\<addr>/\<design>" -> token id
- OID
- 0ab54f…c6d1:90
owned details
nextID
int64// the id of the next token, 1 first
Value
4
webPath
string// "/r/.../gnofly/nfts/skins", for the links of Render
Value
"/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/nfts/skins"
tokenName
untyped stringValue
"gnofly skins"
tokenSymbol
untyped stringValue
"SKIN"
payDenom
untyped stringValue
"ugnot"
maxPrice
int64Value
1000000000000
uriBase
untyped stringValue
"https://gnofly.xyz/nft/skins/"
classic
untyped string// the free look, never a token
Value
"classic"
init.61
func()- OID
- 0ab54f…c6d1:44
init.61 details
bootstrap
func(int, rlm .uverse.realm)bootstrap (re)creates the state and seeds the catalog. The tests call it to start over.
- OID
- 0ab54f…c6d1:46
bootstrap details
getDesign
func(id string) *skins.designgetDesign returns the design registered under id, or nil.
- OID
- 0ab54f…c6d1:47
getDesign details
putDesign
func(id string, name string, model string, pilot string, body string, wing string, accent string, price int64, maxSupply int64)putDesign validates and stores a design. An existing one keeps its count and its listed flag; a new one starts listed.
- OID
- 0ab54f…c6d1:48
putDesign details
SetSkin
func(id string, name string, model string, pilot string, body string, wing string, accent string, price int64, maxSupply int64)SetSkin creates or updates a design. Admin only. id is \[a-z0-9-]{1,32} and not "classic", name \[A-Za-z0-9 '.!-]{1,40}, model \[a-z0-9-]{1,16}, pilot none or gnome, colours "#rrggbb" in lowercase, price 1 to 1e12 ugnot, maxSupply 0 for unlimited. A max supply under what is already minted stops the sales, it takes nothing back. Owners keep their tokens whatever happens to the design; its look is read from here, so a change of colours repaints every copy.
- OID
- 0ab54f…c6d1:49
SetSkin details
SetSkinListed
func(id string, listed bool)SetSkinListed puts a design on or off sale. Admin only.
- OID
- 0ab54f…c6d1:50
SetSkinListed details
webPathOf
func(pkgPath string) stringwebPathOf turns "gno.land/r/..." into "/r/...".
- OID
- 0ab54f…c6d1:51
webPathOf details
itoa
func(n int64) string- OID
- 0ab54f…c6d1:52
itoa details
boolString
func(b bool) string- OID
- 0ab54f…c6d1:53
boolString details
maxIDLen
untyped bigintValue
(32 <untyped> bigint)
maxModelLen
untyped bigintValue
(16 <untyped> bigint)
maxNameLen
untyped bigintValue
(40 <untyped> bigint)
validID
func(s string) boolvalidID reports whether s matches \[a-z0-9-]{1,32}.
- OID
- 0ab54f…c6d1:54
validID details
validModel
func(s string) boolvalidModel reports whether s matches \[a-z0-9-]{1,16}.
- OID
- 0ab54f…c6d1:56
validModel details
validName
func(s string) boolvalidName reports whether s matches \[A-Za-z0-9 '.!-]{1,40}. The charset is deliberately narrow so that a name can be embedded in JSON and markdown without escaping.
- OID
- 0ab54f…c6d1:57
validName details
validColor
func(s string) boolvalidColor reports whether s is "#rrggbb" with lowercase hex digits.
- OID
- 0ab54f…c6d1:58
validColor details
validAddress
func(addr .uverse.address) boolvalidAddress reports whether addr is a valid address in its canonical, lowercase form. Bech32 can also be written in all capitals, and address.IsValid accepts that. To this realm the capitals would be a second key for the same account: a second player record, a second line on a leaderboard, an admin who can never be matched to a caller. Bech32 does not allow mixing cases, so looking at the first character is enough.
- OID
- 0ab54f…c6d1:59
validAddress details
isSlug
func(s string, max int) boolisSlug reports whether s is 1 to max characters of \[a-z0-9-].
- OID
- 0ab54f…c6d1:60