Search Apps Documentation Source Content File Folder Download Copy Actions Download

grc721_metadata.gno

3.46 Kb · 130 lines
  1package grc721
  2
  3import (
  4	"chain"
  5
  6	"gno.land/p/g1w93f099t4pp9jamyghp88p60fvkg39dxz2qzrc/avl"
  7)
  8
  9// MetadataNFT represents an NFT with on-chain 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 —
 28// see basic_nft.gno's NewBasicNFT doc comment for how.
 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 := s.extensions.Get(tid.String())
 55	if metadata == nil {
 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}