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