render.gno
5.79 Kb ยท 211 lines
1package tokenhub
2
3import (
4 "regexp"
5 "strings"
6
7 "gno.land/p/demo/tokens/grc20"
8 "gno.land/p/demo/tokens/grc721"
9 "gno.land/p/moul/md"
10 "gno.land/p/nt/avl/pager"
11 "gno.land/p/nt/fqname"
12 "gno.land/p/nt/ufmt"
13 "gno.land/r/demo/defi/grc20reg"
14)
15
16const (
17 token = "token" // grc20
18 nft = "nft" // grc721
19 mt = "mt" // grc1155
20)
21
22func Render(path string) string {
23 var out string
24
25 switch {
26 case path == "":
27 out = renderHome()
28
29 case strings.HasPrefix(path, token):
30 out = renderToken(path)
31
32 case strings.HasPrefix(path, nft):
33 out = renderNFT(path)
34
35 case strings.HasPrefix(path, mt):
36 out = renderMT(path)
37 }
38
39 return out
40}
41
42func renderHome() string {
43 out := md.H1("Token Hub")
44 out += md.Paragraph("Token Hub provides listings of all existing token types on Gno.land - GRC20 tokens, GRC721 NFTs, and GRC1155 multi-tokens. You can browse these listings to find available tokens, check balances, and access token metadata. If you're developing wallets or interfaces, you can query this registry to display token information to your users.")
45
46 links := []string{
47 "[GRC20 Tokens](/r/matijamarjanovic/tokenhub:tokens)",
48 "[GRC721 NFTs](/r/matijamarjanovic/tokenhub:nfts)",
49 "[GRC1155 Multi-Tokens](/r/matijamarjanovic/tokenhub:mts)",
50 }
51 out += md.BulletList(links)
52
53 out += md.H2("How to Register Your Tokens")
54 out += md.Paragraph("You can register your tokens with the following import and function calls:")
55
56 registerCode := `// Import packages
57import (
58 "gno.land/r/matijamarjanovic/tokenhub"
59 "gno.land/p/demo/tokens/grc20"
60 "gno.land/p/demo/tokens/grc721"
61 "gno.land/p/demo/tokens/grc1155"
62)
63
64// GRC20 token
65myToken, myLedger := grc20.NewToken("My Token", "MTK", 6)
66myTokenPath := tokenhub.RegisterToken(myToken, "my_token")
67
68// GRC721 NFT
69myNFT := grc721.NewBasicNFT("My NFT Collection", "MNFT")
70myNFT.Mint("g1your_address_here", "1")
71err := tokenhub.RegisterNFT(myNFT.Getter(), "my_collection", "1")
72
73// GRC1155 multi-token
74myMultiToken := grc1155.NewBasicGRC1155Token("https://metadata.example.com/")
75myMultiToken.SafeMint("g1your_address_here", "123", 10)
76err := tokenhub.RegisterMultiToken(myMultiToken.Getter(), "123")`
77
78 out += md.LanguageCodeBlock("go", registerCode)
79
80 out += "\n"
81 out += md.H2("Querying Token Information")
82 out += md.Paragraph("You can query token information and balances using functions like:")
83
84 queryCode := `// Get all registered tokens
85allTokens := tokenhub.GetAllTokens()
86
87// Get token balances for a user
88balances := tokenhub.GetUserTokenBalances("g1...")
89
90// Get non-zero token balances
91nonZeroBalances := tokenhub.GetUserTokenBalancesNonZero("g1...")`
92
93 out += md.LanguageCodeBlock("go", queryCode)
94
95 return out
96}
97
98func renderToken(path string) string {
99 out := md.H1("GRC20 Tokens")
100 out += md.Paragraph("Below is a list of all registered GRC20 tokens and their registry keys (keys are used to query token information).")
101
102 var tokenItems []string
103
104 tokenPager := pager.NewPager(grc20reg.GetRegistry(), pageSize, false)
105 page := tokenPager.MustGetPageByPath(path)
106
107 for _, item := range page.Items {
108 token := item.Value.(*grc20.Token)
109 pkgPath, _ := fqname.Parse(item.Key)
110 linkURL := formatLinkURL(pkgPath, 0)
111
112 tokenItems = append(tokenItems, ufmt.Sprintf("%s (%s) - %s",
113 md.Link(token.GetName(), linkURL),
114 md.InlineCode(token.GetSymbol()),
115 md.InlineCode(item.Key)))
116 }
117
118 out += renderItemsList(tokenItems, page, "No tokens registered yet")
119 return out
120}
121
122func renderNFT(path string) string {
123 out := md.H1("GRC721 NFTs")
124 out += md.Paragraph("Below is a list of all registered GRC721 NFT collections and their registry keys (keys are used to query token information).")
125
126 var nftItems []string
127 nftPager := pager.NewPager(registeredNFTs, pageSize, false)
128 page := nftPager.MustGetPageByPath(path)
129
130 for _, item := range page.Items {
131 nftGetter := item.Value.(grc721.NFTGetter)
132 nft := nftGetter()
133 metadata, ok := nft.(grc721.IGRC721CollectionMetadata)
134 if !ok {
135 continue
136 }
137
138 pkgPath, _ := fqname.Parse(item.Key)
139 linkURL := formatLinkURL(pkgPath, 2)
140
141 nftItems = append(nftItems, ufmt.Sprintf("%s (%s) - %s",
142 md.Link(metadata.Name(), linkURL),
143 md.InlineCode(metadata.Symbol()),
144 md.InlineCode(item.Key)))
145 }
146
147 out += renderItemsList(nftItems, page, "No NFTs registered yet")
148 return out
149}
150
151func renderMT(path string) string {
152 out := md.H1("GRC1155 Multi-Tokens")
153 out += md.Paragraph("Below is a list of all registered GRC1155 multi-tokens and their registry keys (keys are used to query token information).")
154
155 var mtItems []string
156
157 mtPager := pager.NewPager(registeredMTs, pageSize, false)
158 page := mtPager.MustGetPageByPath(path)
159
160 for _, item := range page.Items {
161 info := item.Value.(GRC1155TokenInfo)
162 pkgPath, _ := fqname.Parse(item.Key)
163 linkURL := formatLinkURL(pkgPath, 1)
164
165 mtItems = append(mtItems, ufmt.Sprintf("%s %s - %s",
166 md.Bold("TokenID:"),
167 md.Link(md.InlineCode(info.TokenID), linkURL),
168 md.InlineCode(item.Key)))
169 }
170
171 out += renderItemsList(mtItems, page, "No multi-tokens registered yet")
172 return out
173}
174
175func renderItemsList(items []string, page *pager.Page, emptyMessage string) string {
176 var out string
177 if len(items) == 0 {
178 out += md.Italic(emptyMessage)
179 out += "\n"
180 return out
181 }
182
183 out += md.BulletList(items)
184 out += "\n"
185 out += md.HorizontalRule()
186
187 picker := page.Picker(page.Pager.PageQueryParam)
188 if picker != "" {
189 out += md.Paragraph(picker)
190 }
191
192 return out
193}
194
195func formatLinkURL(pkgPath string, trailingSegmentsToRemove int) string {
196 re1 := regexp.MustCompile(`gno\.land/r/matijamarjanovic/tokenhub\.`)
197 pkgPath = re1.ReplaceAllString(pkgPath, "")
198
199 re2 := regexp.MustCompile(`gno\.land`)
200 url := re2.ReplaceAllString(pkgPath, "")
201
202 if trailingSegmentsToRemove > 0 {
203 re3 := regexp.MustCompile(`\.`)
204 parts := re3.Split(url, -1)
205 if len(parts) > trailingSegmentsToRemove {
206 url = strings.Join(parts[:len(parts)-trailingSegmentsToRemove], ".")
207 }
208 }
209
210 return url
211}