Search Apps Documentation Source Content File Folder Download Copy Actions Download

grc721_metadata.gno

3.43 Kb · 130 lines
  1package grc721
  2
  3import (
  4	"chain"
  5
  6	"gno.land/p/nt/avl/v0"
  7)
  8
  9// metadataNFT represents an NFT with metadata extensions.
 10type metadataNFT struct {
 11	*BasicNFT
 12	extensions *avl.Tree // AVL tree for storing metadata extensions
 13}
 14
 15// Ensure that metadataNFT implements the IGRC721MetadataOnchain interface.
 16var _ IGRC721MetadataOnchain = (*metadataNFT)(nil)
 17
 18// NewNFTWithMetadata creates a new basic NFT with metadata extensions.
 19func NewNFTWithMetadata(_ int, rlm realm, name, symbol string) *metadataNFT {
 20	return &metadataNFT{
 21		BasicNFT:   NewBasicNFT(0, rlm, name, symbol),
 22		extensions: avl.NewTree(),
 23	}
 24}
 25
 26// SetTokenMetadata sets metadata for a given token ID. The token must exist and
 27// caller must equal its owner; the owning realm's wrapper derives caller from
 28// rlm.Previous().Address() under IsCurrent (mirrors SetTokenRoyalty).
 29func (s *metadataNFT) SetTokenMetadata(caller address, tid TokenID, metadata Metadata) error {
 30	// Check that the token exists and the caller is its owner.
 31	owner, err := s.OwnerOf(tid)
 32	if err != nil {
 33		return err
 34	}
 35	if caller != owner {
 36		return ErrCallerIsNotOwner
 37	}
 38
 39	// Set the metadata for the token ID in the extensions AVL tree
 40	s.extensions.Set(tid.String(), metadata)
 41
 42	chain.Emit(
 43		MetadataUpdateEvent,
 44		"token", s.ID(),
 45		"tokenId", tid.String(),
 46	)
 47
 48	return nil
 49}
 50
 51// TokenMetadata retrieves metadata for a given token ID.
 52func (s *metadataNFT) TokenMetadata(tid TokenID) (Metadata, error) {
 53	// Retrieve metadata from the extensions AVL tree
 54	metadata, found := s.extensions.Get(tid.String())
 55	if !found {
 56		return Metadata{}, ErrInvalidTokenId
 57	}
 58
 59	return metadata.(Metadata), nil
 60}
 61
 62// Basic NFT methods forwarded to embedded BasicNFT
 63
 64func (s *metadataNFT) Name() string {
 65	return s.BasicNFT.Name()
 66}
 67
 68func (s *metadataNFT) Symbol() string {
 69	return s.BasicNFT.Symbol()
 70}
 71
 72func (s *metadataNFT) TokenCount() int64 {
 73	return s.BasicNFT.TokenCount()
 74}
 75
 76func (s *metadataNFT) BalanceOf(addr address) (int64, error) {
 77	return s.BasicNFT.BalanceOf(addr)
 78}
 79
 80func (s *metadataNFT) OwnerOf(tid TokenID) (address, error) {
 81	return s.BasicNFT.OwnerOf(tid)
 82}
 83
 84func (s *metadataNFT) TokenURI(tid TokenID) (string, error) {
 85	return s.BasicNFT.TokenURI(tid)
 86}
 87
 88func (s *metadataNFT) SetTokenURI(caller address, tid TokenID, tURI TokenURI) (bool, error) {
 89	return s.BasicNFT.SetTokenURI(caller, tid, tURI)
 90}
 91
 92func (s *metadataNFT) IsApprovedForAll(owner, operator address) bool {
 93	return s.BasicNFT.IsApprovedForAll(owner, operator)
 94}
 95
 96func (s *metadataNFT) Approve(caller, to address, tid TokenID) error {
 97	return s.BasicNFT.Approve(caller, to, tid)
 98}
 99
100func (s *metadataNFT) GetApproved(tid TokenID) (address, error) {
101	return s.BasicNFT.GetApproved(tid)
102}
103
104func (s *metadataNFT) SetApprovalForAll(caller, operator address, approved bool) error {
105	return s.BasicNFT.SetApprovalForAll(caller, operator, approved)
106}
107
108func (s *metadataNFT) SafeTransferFrom(caller, from, to address, tid TokenID) error {
109	return s.BasicNFT.SafeTransferFrom(caller, from, to, tid)
110}
111
112func (s *metadataNFT) TransferFrom(caller, from, to address, tid TokenID) error {
113	return s.BasicNFT.TransferFrom(caller, from, to, tid)
114}
115
116func (s *metadataNFT) Mint(to address, tid TokenID) error {
117	return s.BasicNFT.Mint(to, tid)
118}
119
120func (s *metadataNFT) SafeMint(to address, tid TokenID) error {
121	return s.BasicNFT.SafeMint(to, tid)
122}
123
124func (s *metadataNFT) Burn(tid TokenID) error {
125	return s.BasicNFT.Burn(tid)
126}
127
128func (s *metadataNFT) RenderHome() string {
129	return s.BasicNFT.RenderHome()
130}