Search Apps Documentation Source Content File Folder Download Copy Actions Download

registry.gno

4.03 Kb ยท 192 lines
  1package nftregistry4
  2
  3import (
  4	"chain/runtime"
  5
  6	"gno.land/p/nt/avl"
  7	"gno.land/p/demo/tokens/grc721"
  8)
  9
 10// CollectionInfo - Extended metadata stored in the registry
 11type CollectionInfo struct {
 12	Address         address
 13	Name            string
 14	Symbol          string
 15	Creator         address
 16	RegisteredAt    int64
 17	Verified        bool
 18	Category        string
 19	Description     string
 20	ExternalURL     string
 21	NFTGetter       grc721.NFTGetter
 22	SupportsMetadata bool
 23}
 24
 25var (
 26	collections avl.Tree
 27	admins avl.Tree
 28	categoriesIndex avl.Tree
 29	owner address
 30	registrationFee int64 = 1000000
 31)
 32
 33func init() {
 34	owner = runtime.PreviousRealm().Address()
 35	admins.Set(owner.String(), true)
 36}
 37
 38// RegisterCollection - Register a new NFT collection
 39func RegisterCollection(
 40	name string,
 41	symbol string,
 42	category string,
 43	description string,
 44	externalURL string,
 45	supportsMetadata bool,
 46	getter grc721.NFTGetter,
 47) {
 48	caller := runtime.PreviousRealm().Address()
 49
 50	// Check if collection already registered
 51	if collections.Has(caller.String()) {
 52		panic("Collection already registered")
 53	}
 54
 55	if getter == nil {
 56		panic("NFT getter function is required")
 57	}
 58
 59	// Validate inputs
 60	if name == "" || symbol == "" {
 61		panic("Name and symbol cannot be empty")
 62	}
 63
 64	// Create collection info
 65	info := &CollectionInfo{
 66		Address:          caller,
 67		Name:             name,
 68		Symbol:           symbol,
 69		Creator:          caller,
 70		RegisteredAt:     runtime.ChainHeight(),
 71		Verified:         false,
 72		Category:         category,
 73		Description:      description,
 74		ExternalURL:      externalURL,
 75		NFTGetter:        getter,
 76		SupportsMetadata: supportsMetadata,
 77	}
 78
 79	collections.Set(caller.String(), info)
 80}
 81
 82func IsRegistered(collectionAddr address) bool {
 83	return collections.Has(collectionAddr.String())
 84}
 85
 86func GetTotalCollections() int {
 87	count := 0
 88	collections.Iterate("", "", func(key string, value interface{}) bool {
 89		count++
 90		return false
 91	})
 92	return count
 93}
 94
 95func GetVerifiedCount() int {
 96	count := 0
 97	collections.Iterate("", "", func(key string, value interface{}) bool {
 98		info := value.(*CollectionInfo)
 99		if info.Verified {
100			count++
101		}
102		return false
103	})
104	return count
105}
106
107func GetCollection(collectionAddr address) *CollectionInfo {
108	val, exists := collections.Get(collectionAddr.String())
109	if !exists {
110		return nil
111	}
112	return val.(*CollectionInfo)
113}
114
115func GetNFTGetter(collectionAddr address) (grc721.NFTGetter, bool) {
116	info := GetCollection(collectionAddr)
117	if info == nil {
118		return nil, false
119	}
120	return info.NFTGetter, true
121}
122
123func GetTokenMetadata(collectionAddr address, tokenId grc721.TokenID) (grc721.Metadata, error) {
124	info := GetCollection(collectionAddr)
125	if info == nil {
126		panic("Collection not registered")
127	}
128
129	if !info.SupportsMetadata {
130		panic("Collection does not support onchain metadata")
131	}
132
133	nftInstance := info.NFTGetter()
134	metadataCollection := nftInstance.(grc721.IGRC721MetadataOnchain)
135
136	return metadataCollection.TokenMetadata(tokenId)
137}
138
139func VerifyCollection(collectionAddr address) {
140	caller := runtime.PreviousRealm().Address()
141
142	if !isAdmin(caller) {
143		panic("Only admins can verify collections")
144	}
145
146	info := GetCollection(collectionAddr)
147	if info == nil {
148		panic("Collection not found")
149	}
150
151	if !info.Verified {
152		info.Verified = true
153		collections.Set(collectionAddr.String(), info)
154	}
155}
156
157func UnverifyCollection(collectionAddr address) {
158	caller := runtime.PreviousRealm().Address()
159
160	if !isAdmin(caller) {
161		panic("Only admins can unverify collections")
162	}
163
164	info := GetCollection(collectionAddr)
165	if info == nil {
166		panic("Collection not found")
167	}
168
169	if info.Verified {
170		info.Verified = false
171		collections.Set(collectionAddr.String(), info)
172	}
173}
174
175func UpdateCollectionInfo(category, description, externalURL string) {
176	caller := runtime.PreviousRealm().Address()
177
178	info := GetCollection(caller)
179	if info == nil {
180		panic("Collection not registered")
181	}
182
183	info.Category = category
184	info.Description = description
185	info.ExternalURL = externalURL
186	collections.Set(caller.String(), info)
187}
188
189func isAdmin(addr address) bool {
190	_, exists := admins.Get(addr.String())
191	return exists
192}