tokenhub.gno

2.51 Kb ยท 97 lines
 1package tokenhub
 2
 3import (
 4	"std"
 5
 6	"gno.land/p/demo/fqname"
 7	"gno.land/p/demo/grc/grc20"
 8	"gno.land/r/demo/grc20reg"
 9
10	"gno.land/p/demo/avl"
11	"gno.land/p/demo/grc/grc1155"
12	"gno.land/p/demo/grc/grc721"
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	cross(hor.Register)("Token Hub", "Registry for tokens and NFTs on gno.land")
32}
33
34// RegisterToken is a function that uses gno.land/r/demo/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(token *grc20.Token, slug string) string {
41	crossing()
42	rlmPath := std.PreviousRealm().PkgPath()
43	key := fqname.Construct(rlmPath, slug)
44
45	cross(grc20reg.Register)(token, key)
46
47	return fqname.Construct(std.CurrentRealm().PkgPath(), key)
48}
49
50// RegisterNFT is a function that registers an NFT in an avl.Tree
51func RegisterNFT(nftGetter grc721.NFTGetter, collection string, tokenId string) error {
52	crossing()
53
54	nft := nftGetter()
55	_, ok := nft.(grc721.IGRC721CollectionMetadata)
56	if !ok {
57		return ErrNFTNotMetadata
58	}
59
60	nftOwner, err := nft.OwnerOf(grc721.TokenID(tokenId))
61
62	if err != nil {
63		return err
64	}
65	if !nftOwner.IsValid() {
66		return ErrNFTtokIDNotExists
67	}
68
69	rlmPath := std.PreviousRealm().PkgPath()
70	key := rlmPath + "." + collection + "." + tokenId
71
72	if registeredNFTs.Has(key) {
73		return ErrNFTAlreadyRegistered
74	}
75
76	registeredNFTs.Set(key, nftGetter)
77	return nil
78}
79
80// RegisterMultiToken is a function that registers a multi-token in an avl.Tree
81// 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
82func RegisterMultiToken(mtGetter grc1155.MultiTokenGetter, tokenID string) error {
83	crossing()
84	rlmPath := std.PreviousRealm().PkgPath()
85
86	key := rlmPath + "." + tokenID
87
88	if registeredMTs.Has(key) {
89		return ErrMTAlreadyRegistered
90	}
91
92	registeredMTs.Set(key, GRC1155TokenInfo{
93		Collection: mtGetter,
94		TokenID:    tokenID,
95	})
96	return nil
97}