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