tokenhub.gno
2.48 Kb ยท 90 lines
1package tokenhub
2
3import (
4 "std"
5
6 "gno.land/p/demo/avl"
7 "gno.land/p/demo/fqname"
8 "gno.land/p/demo/grc/grc1155"
9 "gno.land/p/demo/grc/grc20"
10 "gno.land/p/demo/grc/grc721"
11 "gno.land/r/demo/grc20reg"
12 "gno.land/r/leon/hof"
13)
14
15type GRC1155TokenInfo struct {
16 Collection grc1155.MultiTokenGetter
17 TokenID string
18}
19
20var (
21 registeredTokens = avl.NewTree() // rlmPath[.slug] -> grc20.TokenGetter
22 registeredNFTs = avl.NewTree() // rlmPath[.slug] -> grc721.NFTGetter
23 registeredMTs = avl.NewTree() // rlmPath[.slug] -> GRC1155TokenInfo
24)
25
26const pageSize = 10
27
28func init() {
29 hof.Register("Token Hub", "Registry for tokens and NFTs on gno.land")
30}
31
32// RegisterToken is a function that uses gno.land/r/demo/grc20reg to register a token
33// It uses the slug to construct a key and then registers the token in the registry
34// The logic is the same as in grc20reg, but it's done here so the key path is callers pkgpath and not of this realm
35// After doing so, the token hub realm uses grc20reg's registry as a read-only avl.Tree
36//
37// Note: register token returns the key path that can be used to retrieve the token
38func RegisterToken(tokenGetter grc20.TokenGetter, slug string) string {
39 rlmPath := std.PreviousRealm().PkgPath()
40 key := fqname.Construct(rlmPath, slug)
41 grc20reg.Register(tokenGetter, key)
42
43 return fqname.Construct(std.CurrentRealm().PkgPath(), key)
44}
45
46// RegisterNFT is a function that registers an NFT in an avl.Tree
47func RegisterNFT(nftGetter grc721.NFTGetter, collection string, tokenId string) error {
48 nft := nftGetter()
49 _, ok := nft.(grc721.IGRC721CollectionMetadata)
50 if !ok {
51 return ErrNFTNotMetadata
52 }
53
54 nftOwner, err := nft.OwnerOf(grc721.TokenID(tokenId))
55
56 if err != nil {
57 return err
58 }
59 if !nftOwner.IsValid() {
60 return ErrNFTtokIDNotExists
61 }
62
63 rlmPath := std.PreviousRealm().PkgPath()
64 key := rlmPath + "." + collection + "." + tokenId
65
66 if registeredNFTs.Has(key) {
67 return ErrNFTAlreadyRegistered
68 }
69
70 registeredNFTs.Set(key, nftGetter)
71 return nil
72}
73
74// RegisterMultiToken is a function that registers a multi-token in an avl.Tree
75// The avl.Tree value is a struct defined in this realm. It contains not only the getter (like other token types) but also the tokenID
76func RegisterMultiToken(mtGetter grc1155.MultiTokenGetter, tokenID string) error {
77 rlmPath := std.PreviousRealm().PkgPath()
78
79 key := rlmPath + "." + tokenID
80
81 if registeredMTs.Has(key) {
82 return ErrMTAlreadyRegistered
83 }
84
85 registeredMTs.Set(key, GRC1155TokenInfo{
86 Collection: mtGetter,
87 TokenID: tokenID,
88 })
89 return nil
90}