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

tba.gno

3.39 Kb · 155 lines
  1package tba
  2
  3import (
  4	"strconv"
  5	"strings"
  6
  7	"chain"
  8	"chain/banker"
  9	"chain/runtime/unsafe"
 10
 11	"gno.land/p/test1/grc721"
 12	"gno.land/p/nt/avl/v0"
 13)
 14
 15const selfPath = "gno.land/r/zeycan1/tba"
 16
 17type tokenMeta struct {
 18	name  string
 19	image string
 20}
 21
 22var (
 23	nft       *grc721.BasicNFT
 24	admin     address
 25	nextID    int64 = 1
 26	allTokens []grc721.TokenID
 27	metaByID  avl.Tree // tokenID string -> *tokenMeta
 28)
 29
 30func init() {
 31	admin = address(unsafe.PreviousRealm().Address())
 32}
 33
 34func Setup(cur realm) {
 35	if nft != nil {
 36		panic("already initialized")
 37	}
 38	caller := cur.Previous().Address()
 39	if caller != admin {
 40		panic("only admin can initialize")
 41	}
 42	nft = grc721.NewBasicNFT(0, cur, "Token Bound Account", "TBA")
 43}
 44
 45func Mint(cur realm, to address, name string, image string) grc721.TokenID {
 46	caller := cur.Previous().Address()
 47	if caller != admin {
 48		panic("only admin can mint")
 49	}
 50	tid := grc721.TokenID(strconv.FormatInt(nextID, 10))
 51	nextID++
 52	if err := nft.Mint(to, tid); err != nil {
 53		panic(err)
 54	}
 55	allTokens = append(allTokens, tid)
 56	metaByID.Set(string(tid), &tokenMeta{name: name, image: image})
 57	return tid
 58}
 59
 60func vaultSubpath(tid grc721.TokenID) string {
 61	return "vault/" + string(tid)
 62}
 63
 64func VaultAddress(tid grc721.TokenID) address {
 65	return chain.DerivePkgSubAddr(selfPath, vaultSubpath(tid))
 66}
 67
 68func Balance(tid grc721.TokenID) int64 {
 69	coins := banker.NewReadonlyBanker().GetCoins(VaultAddress(tid))
 70	return coins.AmountOf("ugnot")
 71}
 72
 73func Withdraw(cur realm, tid grc721.TokenID, to address, amount int64) {
 74	caller := cur.Previous().Address()
 75	owner, err := nft.OwnerOf(tid)
 76	if err != nil {
 77		panic(err)
 78	}
 79	if caller != owner {
 80		panic("caller is not the current owner of this token")
 81	}
 82
 83	sub := cur.Sub(vaultSubpath(tid))
 84	b := banker.NewBanker(banker.BankerTypeRealmSend, sub)
 85	b.SendCoins(sub.Address(), to, chain.NewCoins(chain.NewCoin("ugnot", amount)))
 86}
 87
 88func OwnerOf(tid grc721.TokenID) (address, error) {
 89	return nft.OwnerOf(tid)
 90}
 91
 92func BalanceOfOwner(owner address) (int64, error) {
 93	return nft.BalanceOf(owner)
 94}
 95
 96func TransferFrom(cur realm, from, to address, tid grc721.TokenID) error {
 97	caller := cur.Previous().Address()
 98	return nft.TransferFrom(caller, from, to, tid)
 99}
100
101func AllTokens() []grc721.TokenID {
102	return allTokens
103}
104
105func TokensOf(owner address) []grc721.TokenID {
106	var out []grc721.TokenID
107	for _, tid := range allTokens {
108		o, err := nft.OwnerOf(tid)
109		if err == nil && o == owner {
110			out = append(out, tid)
111		}
112	}
113	return out
114}
115
116func TokenInfo(tid grc721.TokenID) (name string, image string, owner address, vault address, balance int64, err error) {
117	owner, err = nft.OwnerOf(tid)
118	if err != nil {
119		return "", "", "", "", 0, err
120	}
121	vault = VaultAddress(tid)
122	balance = Balance(tid)
123	if v := metaByID.Get(string(tid)); v != nil {
124		m := v.(*tokenMeta)
125		name = m.name
126		image = m.image
127	}
128	return name, image, owner, vault, balance, nil
129}
130
131func Render(path string) string {
132	if nft == nil {
133		return "# Token Bound Accounts\n\nNot initialized yet. Call Setup() first.\n"
134	}
135	return nft.RenderHome()
136}
137
138// --- Frontend-friendly CSV variants (avoid slice-ref parsing issues) ---
139
140func AllTokensCSV() string {
141	ids := make([]string, len(allTokens))
142	for i, t := range allTokens {
143		ids[i] = string(t)
144	}
145	return strings.Join(ids, ",")
146}
147
148func TokensOfCSV(owner address) string {
149	toks := TokensOf(owner)
150	ids := make([]string, len(toks))
151	for i, t := range toks {
152		ids[i] = string(t)
153	}
154	return strings.Join(ids, ",")
155}