Search Apps Documentation Source Content File Folder Download Copy Actions Download

registry.gno

4.01 Kb ยท 191 lines
  1package nftregistry8
  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	realmAddr address,
 41	name string,
 42	symbol string,
 43	category string,
 44	description string,
 45	externalURL string,
 46	supportsMetadata bool,
 47	getter grc721.NFTGetter,
 48) {
 49	creator := runtime.OriginCaller()
 50
 51	// Check if collection already registered
 52	if collections.Has(realmAddr.String()) {
 53		panic("Collection already registered")
 54	}
 55
 56	if getter == nil {
 57		panic("NFT getter function is required")
 58	}
 59
 60	if name == "" || symbol == "" {
 61		panic("Name and symbol cannot be empty")
 62	}
 63
 64	info := &CollectionInfo{
 65		Address:          realmAddr,
 66		Creator:          creator,
 67		Name:             name,
 68		Symbol:           symbol,
 69		RegisteredAt:     runtime.ChainHeight(),
 70		Verified:         false,
 71		Category:         category,
 72		Description:      description,
 73		ExternalURL:      externalURL,
 74		NFTGetter:        getter,
 75		SupportsMetadata: supportsMetadata,
 76	}
 77
 78	collections.Set(realmAddr.String(), info)
 79}
 80
 81func IsRegistered(collectionAddr address) bool {
 82	return collections.Has(collectionAddr.String())
 83}
 84
 85func GetTotalCollections() int {
 86	count := 0
 87	collections.Iterate("", "", func(key string, value interface{}) bool {
 88		count++
 89		return false
 90	})
 91	return count
 92}
 93
 94func GetVerifiedCount() int {
 95	count := 0
 96	collections.Iterate("", "", func(key string, value interface{}) bool {
 97		info := value.(*CollectionInfo)
 98		if info.Verified {
 99			count++
100		}
101		return false
102	})
103	return count
104}
105
106func GetCollection(collectionAddr address) *CollectionInfo {
107	val, exists := collections.Get(collectionAddr.String())
108	if !exists {
109		return nil
110	}
111	return val.(*CollectionInfo)
112}
113
114func GetNFTGetter(collectionAddr address) (grc721.NFTGetter, bool) {
115	info := GetCollection(collectionAddr)
116	if info == nil {
117		return nil, false
118	}
119	return info.NFTGetter, true
120}
121
122func GetTokenMetadata(collectionAddr address, tokenId grc721.TokenID) (grc721.Metadata, error) {
123	info := GetCollection(collectionAddr)
124	if info == nil {
125		panic("Collection not registered")
126	}
127
128	if !info.SupportsMetadata {
129		panic("Collection does not support onchain metadata")
130	}
131
132	nftInstance := info.NFTGetter()
133	metadataCollection := nftInstance.(grc721.IGRC721MetadataOnchain)
134
135	return metadataCollection.TokenMetadata(tokenId)
136}
137
138func VerifyCollection(collectionAddr address) {
139	caller := runtime.PreviousRealm().Address()
140
141	if !isAdmin(caller) {
142		panic("Only admins can verify collections")
143	}
144
145	info := GetCollection(collectionAddr)
146	if info == nil {
147		panic("Collection not found")
148	}
149
150	if !info.Verified {
151		info.Verified = true
152		collections.Set(collectionAddr.String(), info)
153	}
154}
155
156func UnverifyCollection(collectionAddr address) {
157	caller := runtime.PreviousRealm().Address()
158
159	if !isAdmin(caller) {
160		panic("Only admins can unverify collections")
161	}
162
163	info := GetCollection(collectionAddr)
164	if info == nil {
165		panic("Collection not found")
166	}
167
168	if info.Verified {
169		info.Verified = false
170		collections.Set(collectionAddr.String(), info)
171	}
172}
173
174func UpdateCollectionInfo(category, description, externalURL string) {
175	caller := runtime.PreviousRealm().Address()
176
177	info := GetCollection(caller)
178	if info == nil {
179		panic("Collection not registered")
180	}
181
182	info.Category = category
183	info.Description = description
184	info.ExternalURL = externalURL
185	collections.Set(caller.String(), info)
186}
187
188func isAdmin(addr address) bool {
189	_, exists := admins.Get(addr.String())
190	return exists
191}