grc20reg.gno
1.81 Kb ยท 79 lines
1package grc20reg
2
3import (
4 "chain"
5 "chain/runtime"
6
7 "gno.land/p/demo/tokens/grc20"
8 "gno.land/p/nt/avl"
9 "gno.land/p/nt/avl/rotree"
10 "gno.land/p/nt/fqname"
11 "gno.land/p/nt/ufmt"
12)
13
14var registry = avl.NewTree() // rlmPath[.slug] -> *Token (slug is optional)
15func Register(cur realm, token *grc20.Token, slug string) {
16 rlmPath := runtime.PreviousRealm().PkgPath()
17 key := fqname.Construct(rlmPath, slug)
18 registry.Set(key, token)
19 chain.Emit(
20 registerEvent,
21 "pkgpath", rlmPath,
22 "slug", slug,
23 )
24}
25
26func Get(key string) *grc20.Token {
27 token, ok := registry.Get(key)
28 if !ok {
29 return nil
30 }
31 return token.(*grc20.Token)
32}
33
34func MustGet(key string) *grc20.Token {
35 token := Get(key)
36 if token == nil {
37 panic("unknown token: " + key)
38 }
39 return token
40}
41
42func Render(path string) string {
43 switch {
44 case path == "": // home
45 // TODO: add pagination
46 s := ""
47 count := 0
48 registry.Iterate("", "", func(key string, tokenI any) bool {
49 count++
50 token := tokenI.(*grc20.Token)
51 rlmPath, slug := fqname.Parse(key)
52 rlmLink := fqname.RenderLink(rlmPath, slug)
53 infoLink := "/r/demo/grc20reg:" + key
54 s += ufmt.Sprintf("- **%s** - %s - [info](%s)\n", token.GetName(), rlmLink, infoLink)
55 return false
56 })
57 if count == 0 {
58 return "No registered token."
59 }
60 return s
61 default: // specific token
62 key := path
63 token := MustGet(key)
64 rlmPath, slug := fqname.Parse(key)
65 rlmLink := fqname.RenderLink(rlmPath, slug)
66 s := ufmt.Sprintf("# %s\n", token.GetName())
67 s += ufmt.Sprintf("- symbol: **%s**\n", token.GetSymbol())
68 s += ufmt.Sprintf("- realm: %s\n", rlmLink)
69 s += ufmt.Sprintf("- decimals: %d\n", token.GetDecimals())
70 s += ufmt.Sprintf("- total supply: %d\n", token.TotalSupply())
71 return s
72 }
73}
74
75const registerEvent = "register"
76
77func GetRegistry() *rotree.ReadOnlyTree {
78 return rotree.Wrap(registry, nil)
79}