grc20reg.gno

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