grc20reg.gno

1.91 Kb ยท 81 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] -> TokenGetter (slug is optional)
14
15func Register(tokenGetter grc20.TokenGetter, slug string) {
16	rlmPath := std.PreviousRealm().PkgPath()
17	key := fqname.Construct(rlmPath, slug)
18	registry.Set(key, tokenGetter)
19	std.Emit(
20		registerEvent,
21		"pkgpath", rlmPath,
22		"slug", slug,
23	)
24}
25
26func Get(key string) grc20.TokenGetter {
27	tokenGetter, ok := registry.Get(key)
28	if !ok {
29		return nil
30	}
31	return tokenGetter.(grc20.TokenGetter)
32}
33
34func MustGet(key string) grc20.TokenGetter {
35	tokenGetter := Get(key)
36	if tokenGetter == nil {
37		panic("unknown token: " + key)
38	}
39	return tokenGetter
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			tokenGetter := tokenI.(grc20.TokenGetter)
51			token := tokenGetter()
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		tokenGetter := MustGet(key)
65		token := tokenGetter()
66		rlmPath, slug := fqname.Parse(key)
67		rlmLink := fqname.RenderLink(rlmPath, slug)
68		s := ufmt.Sprintf("# %s\n", token.GetName())
69		s += ufmt.Sprintf("- symbol: **%s**\n", token.GetSymbol())
70		s += ufmt.Sprintf("- realm: %s\n", rlmLink)
71		s += ufmt.Sprintf("- decimals: %d\n", token.GetDecimals())
72		s += ufmt.Sprintf("- total supply: %d\n", token.TotalSupply())
73		return s
74	}
75}
76
77const registerEvent = "register"
78
79func GetRegistry() *rotree.ReadOnlyTree {
80	return rotree.Wrap(registry, nil)
81}