Search Apps Documentation Source Content File Folder Download Copy Actions Download

transfer.gno

3.54 Kb · 116 lines
  1package memba_collections
  2
  3import (
  4	"chain"
  5
  6	"gno.land/p/samcrew/grc721"
  7)
  8
  9// ── Owner approvals ─────────────────────────────────────────────────────────
 10
 11// Approve grants single-token transfer approval. Caller must own/operate.
 12func Approve(cur realm, id string, operator address, tid grc721.TokenID) {
 13	c := mustGet(id)
 14	if err := c.nft.Approve(caller(), operator, tid); err != nil {
 15		panic(err.Error())
 16	}
 17}
 18
 19// SetApprovalForAll grants/revokes operator approval for all the caller's
 20// tokens in the collection (this is how a seller authorizes a marketplace).
 21func SetApprovalForAll(cur realm, id string, operator address, approved bool) {
 22	c := mustGet(id)
 23	if err := c.nft.SetApprovalForAll(caller(), operator, approved); err != nil {
 24		panic(err.Error())
 25	}
 26}
 27
 28// ── Burn ─────────────────────────────────────────────────────────────────────
 29
 30// Burn destroys a token the caller owns and clears any per-token royalty.
 31// Burning never reopens a supply slot (nextAutoTokenID only increments, S-2).
 32func Burn(cur realm, id string, tid grc721.TokenID) {
 33	c := mustGet(id)
 34	owner, err := c.nft.OwnerOf(tid)
 35	if err != nil {
 36		panic(err.Error())
 37	}
 38	if caller() != owner {
 39		panic("caller is not owner")
 40	}
 41	if err := c.nft.Burn(tid); err != nil {
 42		panic(err.Error())
 43	}
 44	c.tokenRoyalty.Remove(string(tid))
 45	chain.Emit("Burned", "collectionID", id, "tokenId", string(tid), "owner", owner.String())
 46}
 47
 48// ── Settlement (registered markets only) ─────────────────────────────────────
 49
 50func isRegisteredMarket(a address) bool {
 51	v, ok := registeredMarkets.Get(a.String())
 52	return ok && v.(bool)
 53}
 54
 55// MarketTransfer is the ONLY token-movement path. Only a registered market
 56// realm may call it; it moves the token via the realm's internal ledger with
 57// the market as the grc721 caller (the seller must have approved the market).
 58func MarketTransfer(cur realm, id string, from, to address, tid grc721.TokenID) {
 59	market := caller()
 60	if !isRegisteredMarket(market) {
 61		panic("unauthorized market")
 62	}
 63	c := mustGet(id)
 64	assertNotPaused(c)
 65	if err := c.nft.TransferFrom(market, from, to, tid); err != nil {
 66		panic(err.Error())
 67	}
 68	chain.Emit("MarketTransfer",
 69		"collectionID", id,
 70		"from", from.String(),
 71		"to", to.String(),
 72		"tokenId", string(tid),
 73	)
 74}
 75
 76// ── Reads (IGRC721Reader surface + URI) ──────────────────────────────────────
 77
 78func OwnerOf(id string, tid grc721.TokenID) address {
 79	o, err := mustGet(id).nft.OwnerOf(tid)
 80	if err != nil {
 81		panic(err.Error())
 82	}
 83	return o
 84}
 85
 86func BalanceOf(id string, owner address) int64 {
 87	b, err := mustGet(id).nft.BalanceOf(owner)
 88	if err != nil {
 89		panic(err.Error())
 90	}
 91	return b
 92}
 93
 94func GetApproved(id string, tid grc721.TokenID) address {
 95	a, err := mustGet(id).nft.GetApproved(tid)
 96	if err != nil {
 97		return ""
 98	}
 99	return a
100}
101
102func IsApprovedForAll(id string, owner, operator address) bool {
103	return mustGet(id).nft.IsApprovedForAll(owner, operator)
104}
105
106func TokenURI(id string, tid grc721.TokenID) string {
107	u, err := mustGet(id).nft.TokenURI(tid)
108	if err != nil {
109		return ""
110	}
111	return u
112}
113
114func TokenCount(id string) int64 { return mustGet(id).nft.TokenCount() }
115
116func IsRegisteredMarket(a address) bool { return isRegisteredMarket(a) }