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}