1package test23import (4 "chain"5 "chain/banker"6 "chain/runtime/unsafe"7 "strconv"8 "strings"910 "gno.land/p/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/grc721/v0"11 "gno.land/p/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/grc721/metadata/v0"12 "gno.land/p/nt/avl/v0"13 "gno.land/p/nt/seqid/v0"14 "gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/factory"15)1617const (18 maxNameLen = 6419 maxImageLen = 20020 maxSupplyBound = 1_000_00021 maxRoyaltyBps = 100022 nativeDenom = "ugnot"23 publicOrigin = "https://bazaar-gno.vercel.app"24 dropAddCap = 2025 dropSlotHardCap = 1000026 minSlugLen = 227)2829type item struct {30 id int31 name string32 image string33 owner address34 seller address35 price int6436 listed bool37 rarity string38 traits string39 revealed bool40 slot int41}4243type dropSlot struct {44 name string45 image string46 rarity string47 traits string48}4950var (51 items avl.Tree52 dropSlots avl.Tree53 token *grc721.Token54 ledger *grc721.PrivateLedger55 metaView *metadata.Metadata56 metaLed *metadata.Ledger57 tokenSeq seqid.ID58 nextID int59 minted int60 loaded int61 maxSupply int62 mintPrice int6463 royaltyBps int64 paused bool65 inited bool66 creator address67 self address68 colName string69 colSymbol string70 colCover string71 slug string72)7374func Init(cur realm, name, symbol, cover string, maxSupplyN int, mintPriceUgnot int64, royalty int64) {75 if !cur.Previous().IsUserCall() {76 panic("col: EOA only")77 }78 if !cur.IsCurrent() {79 panic("col: spoofed realm")80 }81 if len(symbol) < 1 || len(symbol) > grc721.MaxSymbolLen {82 panic("col: symbol")83 }84 pathSlug := lastElem(cur.PkgPath())85 if !validPkgName(pathSlug) {86 panic("col: slug")87 }88 if maxSupplyN < 0 || maxSupplyN > maxSupplyBound {89 panic("col: maxSupply")90 }91 if mintPriceUgnot < 0 {92 panic("col: mintPrice")93 }94 if royalty < 0 || royalty > maxRoyaltyBps {95 panic("col: royalty")96 }97 if !validName(name) {98 panic("col: name")99 }100 if !validImage(cover) {101 panic("col: cover")102 }103 if inited {104 panic("col: already initialized")105 }106 slug = pathSlug107 reservedWho := factory.ReservedCreator(slug)108 takeLaunchFee(cur)109 tok, led := grc721.NewToken(name, symbol, tokenSeq.Next(), cur)110 token = tok111 ledger = led112 metaView, metaLed = metadata.NewMetadata(led)113 creator = cur.Previous().Address()114 self = cur.Address()115 colName = name116 colSymbol = symbol117 colCover = cover118 maxSupply = maxSupplyN119 mintPrice = mintPriceUgnot120 royaltyBps = int(royalty)121 items = avl.Tree{}122 dropSlots = avl.Tree{}123 loaded = 0124 inited = true125 if reservedWho == "" {126 factory.CreditLaunchFee(cross(cur))127 }128 factory.Register(cross(cur), name, symbol, cover, maxSupplyN, mintPriceUgnot, royalty)129 chain.Emit("Init", "creator", creator.String(), "slug", slug)130}131132func Mint(cur realm, name, imageURL string) int {133 caller := requireUser(cur)134 if caller != creator {135 panic("col: not creator")136 }137 id := mintTo(cur, caller, name, imageURL)138 writeTokenMeta(id)139 chain.Emit("Mint", "id", strconv.Itoa(id), "owner", caller.String())140 return id141}142143func PublicMint(cur realm) int {144 caller := requireUser(cur)145 takeExact(mintPrice)146 name := colName + " #" + strconv.Itoa(minted+1)147 image := publicImage()148 var slot *dropSlot149 slotIndex := -1150 if loaded > 0 {151 if minted >= loaded {152 panic("col: no slot")153 }154 v := dropSlots.Get(slotKey(minted))155 if v == nil {156 panic("col: no slot")157 }158 slot = v.(*dropSlot)159 name = slot.name160 image = slot.image161 slotIndex = minted162 }163 id := mintTo(cur, caller, name, image)164 if slot != nil {165 applySlot(id, slot, slotIndex)166 }167 writeTokenMeta(id)168 if mintPrice > 0 {169 bk := banker.NewBanker(banker.BankerTypeRealmSend, cur)170 bk.SendCoins(self, creator, chain.Coins{{Denom: nativeDenom, Amount: mintPrice}})171 }172 chain.Emit("PublicMint", "id", strconv.Itoa(id), "n", strconv.Itoa(minted))173 return id174}175176func AddDropItems(cur realm, blob string) {177 caller := requireUser(cur)178 if caller != creator {179 panic("col: not creator")180 }181 lines := splitDropLines(blob)182 if len(lines) < 1 || len(lines) > dropAddCap {183 panic("col: slots")184 }185 if loaded+len(lines) > slotCap() {186 panic("col: slots")187 }188 for _, line := range lines {189 name, image, rarity, traits := parseDropLine(line)190 if !validName(name) {191 panic("col: name")192 }193 if !validImage(image) {194 panic("col: image")195 }196 if !validRarity(rarity) {197 panic("col: rarity")198 }199 if !validTraits(traits) {200 panic("col: traits")201 }202 dropSlots.Set(slotKey(loaded), &dropSlot{name: name, image: image, rarity: rarity, traits: traits})203 loaded++204 }205 chain.Emit("AddDropItems", "slug", slug, "loaded", strconv.Itoa(loaded))206}207208func ListDropSlots() string {209 requireInit()210 out := ""211 for i := 0; i < loaded; i++ {212 v := dropSlots.Get(slotKey(i))213 if v == nil {214 continue215 }216 s := v.(*dropSlot)217 if out != "" {218 out += "\n"219 }220 out += strconv.Itoa(i) + "|" + s.name + "|" + s.image + "|" + s.rarity + "|" + s.traits221 }222 return out223}224225func LoadedOf() int {226 requireInit()227 return loaded228}229230func PauseMint(cur realm) {231 caller := requireUser(cur)232 if caller != creator {233 panic("col: not creator")234 }235 paused = true236 chain.Emit("PauseMint", "slug", slug)237}238239func ResumeMint(cur realm) {240 caller := requireUser(cur)241 if caller != creator {242 panic("col: not creator")243 }244 paused = false245 chain.Emit("ResumeMint", "slug", slug)246}247248func OwnerOf(id int) address {249 return mustItem(id).owner250}251252func GrcName() string {253 requireInit()254 return token.GetName()255}256257func GrcSymbol() string {258 requireInit()259 return token.GetSymbol()260}261262func GrcBalanceOf(addr string) int64 {263 requireInit()264 who := address(addr)265 if !who.IsValid() {266 return 0267 }268 n, err := token.BalanceOf(who)269 if err != nil {270 return 0271 }272 return n273}274275func GrcOwnerOf(id int) string {276 requireInit()277 owner, err := token.OwnerOf(itemTid(id))278 if err != nil {279 panic("col: owner")280 }281 return owner.String()282}283284func Name() string {285 return GrcName()286}287288func Symbol() string {289 return GrcSymbol()290}291292func BalanceOf(addr string) int64 {293 return GrcBalanceOf(addr)294}295296func TokenURI(id int) string {297 mustItem(id)298 if metaView != nil {299 u, err := metaView.TokenURI(itemTid(id))300 if err == nil && u != "" {301 return u302 }303 }304 return tokenJSON(mustItem(id))305}306307func guardUnlisted(id int) {308 if mustItem(id).listed {309 panic("col: listed")310 }311}312313func Approve(cur realm, to string, id int) {314 caller := requireUser(cur)315 guardUnlisted(id)316 who := address(to)317 if to != "" && !who.IsValid() {318 panic("col: addr")319 }320 if err := ledger.Approve(caller, who, itemTid(id)); err != nil {321 panic("col: approve")322 }323}324325func SetApprovalForAll(cur realm, operator string, approved bool) {326 caller := requireUser(cur)327 op := address(operator)328 if !op.IsValid() {329 panic("col: addr")330 }331 if err := ledger.SetApprovalForAll(caller, op, approved); err != nil {332 panic("col: approve")333 }334}335336func TransferFrom(cur realm, from, to string, id int) {337 caller := requireUser(cur)338 guardUnlisted(id)339 src := address(from)340 dst := address(to)341 if !src.IsValid() || !dst.IsValid() {342 panic("col: addr")343 }344 if err := ledger.TransferFrom(caller, src, dst, itemTid(id)); err != nil {345 panic("col: transfer")346 }347 it := mustItem(id)348 it.owner = dst349 items.Set(itemKey(id), it)350}351352func GetApproved(id int) string {353 requireInit()354 who, err := token.GetApproved(itemTid(id))355 if err != nil {356 return ""357 }358 return who.String()359}360361func IsApprovedForAll(owner, operator string) bool {362 requireInit()363 a := address(owner)364 b := address(operator)365 if !a.IsValid() || !b.IsValid() {366 return false367 }368 return token.IsApprovedForAll(a, b)369}370371func TotalSupply() int64 {372 requireInit()373 return token.TotalSupply()374}375376func SellerOf(id int) address {377 return mustItem(id).seller378}379380func PriceOf(id int) int64 {381 return mustItem(id).price382}383384func NameOf(id int) string {385 return mustItem(id).name386}387388func ImageOf(id int) string {389 return mustItem(id).image390}391392func Listed(id int) bool {393 return mustItem(id).listed394}395396func NextID() int {397 return nextID398}399400func CollectionOf(_ int) string {401 requireInit()402 return slug403}404405func ItemLine(id int) string {406 it := mustItem(id)407 return strconv.Itoa(it.id) + "|" + it.name + "|" + it.owner.String() + "|" + it.seller.String() + "|" + strconv.FormatInt(it.price, 10) + "|" + strconv.FormatBool(it.listed) + "|" + it.image + "|" + slug + "|" + it.rarity + "|" + it.traits + "|" + strconv.FormatBool(it.revealed) + "|" + strconv.Itoa(it.slot)408}409410func ListOpen() string {411 requireInit()412 out := ""413 n := 0414 items.Iterate("", "", func(_ string, value any) bool {415 it := value.(*item)416 if !it.listed {417 return false418 }419 if n >= 50 {420 return true421 }422 if out != "" {423 out += "\n"424 }425 out += ItemLine(it.id)426 n++427 return false428 })429 return out430}431432func TokensOf(owner address) string {433 requireInit()434 out := ""435 items.Iterate("", "", func(_ string, value any) bool {436 it := value.(*item)437 if it.owner != owner {438 return false439 }440 if out != "" {441 out += ","442 }443 out += strconv.Itoa(it.id)444 return false445 })446 return out447}448449func Creator() string {450 requireInit()451 return creator.String()452}453454func MintPrice() int64 {455 requireInit()456 return mintPrice457}458459func MaxSupply() int {460 requireInit()461 return maxSupply462}463464func Minted() int {465 requireInit()466 return minted467}468469func RoyaltyBps() int {470 requireInit()471 return royaltyBps472}473474func SetRoyalty(cur realm, bps int) {475 caller := requireUser(cur)476 if caller != creator {477 panic("col: not creator")478 }479 if minted != 0 {480 panic("col: minted")481 }482 if bps < 0 || bps > maxRoyaltyBps {483 panic("col: royalty")484 }485 royaltyBps = bps486 factory.NoteRoyalty(cross(cur), bps)487 chain.Emit("SetRoyalty", "slug", slug, "bps", strconv.Itoa(bps))488}489490func RarityOf(id int) string {491 return mustItem(id).rarity492}493494func TraitsOf(id int) string {495 return mustItem(id).traits496}497498func Render(_ string) string {499 if !inited {500 return "# Collection\n\nCall Init first.\n"501 }502 out := "# " + colName + " ($" + colSymbol + ")\n\n"503 out += "- minted: " + strconv.Itoa(minted) + "\n"504 out += "- mint price: " + strconv.FormatInt(mintPrice, 10) + " ugnot\n\n"505 open := ListOpen()506 if open == "" {507 out += "_No open listings._\n"508 } else {509 out += "```\n" + open + "\n```\n"510 }511 return out512}513514func mintTo(cur realm, caller address, name, imageURL string) int {515 requireInit()516 if !cur.IsCurrent() {517 panic("col: spoofed realm")518 }519 if paused {520 panic("col: paused")521 }522 if maxSupply > 0 && minted >= maxSupply {523 panic("col: sold out")524 }525 if !validName(name) {526 panic("col: name")527 }528 if !validImage(imageURL) {529 panic("col: image")530 }531 nextID++532 id := nextID533 it := &item{534 id: id,535 name: name,536 image: imageURL,537 owner: caller,538 rarity: rarityOf(id),539 revealed: true,540 slot: -1,541 }542 items.Set(itemKey(id), it)543 err := ledger.Mint(caller, itemTid(id))544 if err != nil {545 panic("col: mint")546 }547 minted++548 factory.NoteMinted(cross(cur), minted)549 return id550}551552func takeLaunchFee(cur realm) {553 fee := factory.LaunchFee()554 who := factory.ReservedCreator(lastElem(cur.PkgPath()))555 if who != "" && who == cur.Previous().Address().String() {556 takeExact(0)557 return558 }559 takeExact(fee)560 if fee > 0 {561 bk := banker.NewBanker(banker.BankerTypeRealmSend, cur)562 bk.SendCoins(cur.Address(), factory.Address(), chain.Coins{{Denom: nativeDenom, Amount: fee}})563 }564}565566func takeExact(want int64) {567 sent := unsafe.OriginSend()568 if want == 0 {569 if len(sent) != 0 {570 panic("col: extra denoms")571 }572 return573 }574 if len(sent) != 1 || sent[0].Denom != nativeDenom || sent[0].Amount != want {575 panic("col: wrong payment")576 }577}578579func publicImage() string {580 img := "/samples/" + slug + "-0" + strconv.Itoa(minted+1) + ".png"581 if validImage(img) {582 return img583 }584 return colCover585}586587func requireInit() {588 if !inited {589 panic("col: call Init first")590 }591}592593func requireUser(cur realm) address {594 requireInit()595 if !cur.IsCurrent() {596 panic("col: spoofed realm")597 }598 if !cur.Previous().IsUserCall() {599 panic("col: EOA only")600 }601 return cur.Previous().Address()602}603604func itemTid(id int) grc721.TokenID {605 return grc721.TokenID(strconv.Itoa(id))606}607608func mustItem(id int) *item {609 v := items.Get(itemKey(id))610 if v == nil {611 panic("col: unknown item")612 }613 return v.(*item)614}615616func itemKey(id int) string {617 return strconv.Itoa(id)618}619620func lastElem(pkg string) string {621 i := strings.LastIndex(pkg, "/")622 if i < 0 || i+1 >= len(pkg) {623 panic("col: pkg")624 }625 return pkg[i+1:]626}627628func slotKey(i int) string {629 return strconv.Itoa(i)630}631632func slotCap() int {633 if maxSupply > 0 {634 return maxSupply635 }636 return dropSlotHardCap637}638639func applySlot(id int, s *dropSlot, slotIndex int) {640 it := mustItem(id)641 it.name = s.name642 it.image = s.image643 if s.rarity != "" {644 it.rarity = s.rarity645 }646 it.traits = s.traits647 it.revealed = true648 it.slot = slotIndex649 items.Set(itemKey(id), it)650}651652func writeTokenMeta(id int) {653 it := mustItem(id)654 uri := tokenJSON(it)655 if metaLed == nil {656 return657 }658 if err := metaLed.SetTokenURI(itemTid(id), uri); err != nil {659 panic("col: tokenURI")660 }661 if err := metaLed.SetTokenMetadata(itemTid(id), metadata.Data{662 Name: it.name,663 Description: colName + " #" + strconv.Itoa(id),664 Image: absImage(it.image),665 Attributes: traitAttrs(it),666 }); err != nil {667 panic("col: metadata")668 }669}670671func tokenJSON(it *item) string {672 attrs := ""673 for _, tr := range traitAttrs(it) {674 if attrs != "" {675 attrs += ","676 }677 attrs += `{"trait_type":` + jsonStr(tr.TraitType) + `,"value":` + jsonStr(tr.Value) + `}`678 }679 body := `{"name":` + jsonStr(it.name) + `,"description":` + jsonStr(colName+" #"+strconv.Itoa(it.id)) + `,"image":` + jsonStr(absImage(it.image)) + `,"attributes":[` + attrs + `]}`680 return "data:application/json;charset=utf-8," + pctURI(body)681}682683func traitAttrs(it *item) []metadata.Trait {684 out := []metadata.Trait{}685 if it.rarity != "" {686 out = append(out, metadata.Trait{TraitType: "Rarity", Value: it.rarity})687 }688 for _, part := range strings.Split(it.traits, ";") {689 part = strings.TrimSpace(part)690 colon := strings.Index(part, ":")691 if colon <= 0 || colon >= len(part)-1 {692 continue693 }694 key := strings.TrimSpace(part[:colon])695 val := strings.TrimSpace(part[colon+1:])696 if key == "" || val == "" {697 continue698 }699 out = append(out, metadata.Trait{TraitType: key, Value: val})700 }701 return out702}703704func absImage(u string) string {705 if u == "" {706 return u707 }708 if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") || strings.HasPrefix(u, "ipfs://") {709 return u710 }711 if strings.HasPrefix(u, "/") {712 return publicOrigin + u713 }714 return u715}716717func jsonStr(s string) string {718 out := `"`719 for _, r := range s {720 switch r {721 case '"':722 out += `\"`723 case '\\':724 out += `\\`725 case '\n':726 out += `\n`727 case '\r':728 out += `\r`729 case '\t':730 out += `\t`731 default:732 if r < 0x20 {733 out += `\u00`734 hex := "0123456789abcdef"735 out += string([]byte{hex[r>>4], hex[r&15]})736 } else {737 out += string(r)738 }739 }740 }741 return out + `"`742}743744func pctURI(s string) string {745 out := ""746 for i := 0; i < len(s); i++ {747 c := s[i]748 if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~' {749 out += string(c)750 continue751 }752 hex := "0123456789ABCDEF"753 out += "%"754 out += string([]byte{hex[c>>4], hex[c&15]})755 }756 return out757}758759func splitDropLines(blob string) []string {760 raw := strings.Split(blob, "\n")761 out := make([]string, 0, len(raw))762 for _, line := range raw {763 line = strings.TrimSpace(line)764 if line == "" {765 continue766 }767 out = append(out, line)768 }769 return out770}771772func parseDropLine(line string) (string, string, string, string) {773 parts := strings.Split(line, "|")774 name := ""775 image := ""776 rarity := ""777 traits := ""778 if len(parts) > 0 {779 name = strings.TrimSpace(parts[0])780 }781 if len(parts) > 1 {782 image = strings.TrimSpace(parts[1])783 }784 if len(parts) > 2 {785 rarity = strings.TrimSpace(parts[2])786 }787 if len(parts) > 3 {788 traits = strings.TrimSpace(parts[3])789 }790 return name, image, rarity, traits791}792793func validRarity(s string) bool {794 if s == "" {795 return true796 }797 return s == "Common" || s == "Uncommon" || s == "Rare" || s == "Epic" || s == "Legendary"798}799800func validTraits(s string) bool {801 if s == "" {802 return true803 }804 if len(s) > 200 {805 return false806 }807 if strings.ContainsAny(s, "\n\r|") {808 return false809 }810 n := 0811 for _, part := range strings.Split(s, ";") {812 part = strings.TrimSpace(part)813 if part == "" {814 continue815 }816 colon := strings.Index(part, ":")817 if colon <= 0 || colon >= len(part)-1 {818 return false819 }820 key := strings.TrimSpace(part[:colon])821 val := strings.TrimSpace(part[colon+1:])822 if key == "" || val == "" {823 return false824 }825 if !asciiSet(key, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _-") {826 return false827 }828 if !asciiSet(val, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _-") {829 return false830 }831 n++832 if n > 8 {833 return false834 }835 }836 return n >= 1837}838839func validPkgName(s string) bool {840 if len(s) < minSlugLen || len(s) > grc721.MaxSymbolLen {841 return false842 }843 if s[0] < 'a' || s[0] > 'z' {844 return false845 }846 return asciiSet(s, "abcdefghijklmnopqrstuvwxyz0123456789")847}848849func rarityOf(id int) string {850 r := id % 10851 if r == 0 {852 return "Legendary"853 }854 if r == 1 {855 return "Common"856 }857 if r == 2 {858 return "Uncommon"859 }860 if r == 3 {861 return "Rare"862 }863 if r == 4 {864 return "Epic"865 }866 if r <= 7 {867 return "Uncommon"868 }869 return "Common"870}871872func validName(name string) bool {873 if len(name) < 1 || len(name) > maxNameLen {874 return false875 }876 if strings.ContainsAny(name, "\n\r|\t\"\\") {877 return false878 }879 for _, r := range name {880 if r < 0x20 {881 return false882 }883 }884 return true885}886887func validImage(u string) bool {888 if u == "" {889 return true890 }891 if len(u) > maxImageLen {892 return false893 }894 if strings.ContainsAny(u, " \t\n\r|<>\"'`") {895 return false896 }897 if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") {898 return true899 }900 const prefix = "/samples/"901 if !strings.HasPrefix(u, prefix) {902 return false903 }904 rest := u[len(prefix):]905 if rest == "" {906 return false907 }908 return asciiSet(rest, "abcdefghijklmnopqrstuvwxyz0123456789._-")909}910911func asciiSet(s, allowed string) bool {912 for i := 0; i < len(s); i++ {913 if !strings.ContainsRune(allowed, rune(s[i])) {914 return false915 }916 }917 return true918}919AddDropItems(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, blob string)
Approve(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string, id int)
BalanceOf(addr string) int64
Buy(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id int)
Cancel(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id int)
CollectionOf(int) string
Creator() string
GetApproved(id int) string
GrcBalanceOf(addr string) int64
GrcName() string
GrcOwnerOf(id int) string
GrcSymbol() string
ImageOf(id int) string
Init(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, symbol string, cover string, maxSupplyN int, mintPriceUgnot int64, royalty int64)
IsApprovedForAll(owner string, operator string) bool
ItemLine(id int) string
List(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id int, priceUgnot int64)
ListDropSlots() string
Listed(id int) bool
ListOpen() string
LoadedOf() int
MaxSupply() int
Mint(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, imageURL string) int
Minted() int
MintPrice() int64
Name() string
NameOf(id int) string
NextID() int
OwnerOf(id int) string
PauseMint(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})
PriceOf(id int) int64
ProtocolBps() int64
PublicMint(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}) int
RarityOf(id int) string
Render(string) string
ResumeMint(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})
RoyaltyBps() int
SellerOf(id int) string
SetApprovalForAll(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, operator string, approved bool)
SetRoyalty(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, bps int)
Symbol() string
TokensOf(owner string) string
TokenURI(id int) string
TotalSupply() int64
TraitsOf(id int) string
Transfer(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string, id int)
TransferFrom(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, from string, to string, id int)
UpdatePrice(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id int, priceUgnot int64)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.