render.gno
5.82 Kb ยท 212 lines
1package tokenhub
2
3import (
4 "regexp"
5 "strings"
6
7 "gno.land/p/demo/avl/pager"
8 "gno.land/p/demo/fqname"
9 "gno.land/p/demo/grc/grc20"
10 "gno.land/p/demo/grc/grc721"
11 "gno.land/p/demo/ufmt"
12 "gno.land/p/moul/md"
13 "gno.land/r/demo/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/grc/grc20"
60 "gno.land/p/demo/grc/grc721"
61 "gno.land/p/demo/grc/grc1155"
62)
63
64// GRC20 token
65myToken, myLedger := grc20.NewToken("My Token", "MTK", 6)
66myTokenPath := tokenhub.RegisterToken(myToken.Getter(), "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 tokenGetter := item.Value.(grc20.TokenGetter)
109 token := tokenGetter()
110 pkgPath, _ := fqname.Parse(item.Key)
111 linkURL := formatLinkURL(pkgPath, 0)
112
113 tokenItems = append(tokenItems, ufmt.Sprintf("%s (%s) - %s",
114 md.Link(token.GetName(), linkURL),
115 md.InlineCode(token.GetSymbol()),
116 md.InlineCode(item.Key)))
117 }
118
119 out += renderItemsList(tokenItems, page, "No tokens registered yet")
120 return out
121}
122
123func renderNFT(path string) string {
124 out := md.H1("GRC721 NFTs")
125 out += md.Paragraph("Below is a list of all registered GRC721 NFT collections and their registry keys (keys are used to query token information).")
126
127 var nftItems []string
128 nftPager := pager.NewPager(registeredNFTs, pageSize, false)
129 page := nftPager.MustGetPageByPath(path)
130
131 for _, item := range page.Items {
132 nftGetter := item.Value.(grc721.NFTGetter)
133 nft := nftGetter()
134 metadata, ok := nft.(grc721.IGRC721CollectionMetadata)
135 if !ok {
136 continue
137 }
138
139 pkgPath, _ := fqname.Parse(item.Key)
140 linkURL := formatLinkURL(pkgPath, 2)
141
142 nftItems = append(nftItems, ufmt.Sprintf("%s (%s) - %s",
143 md.Link(metadata.Name(), linkURL),
144 md.InlineCode(metadata.Symbol()),
145 md.InlineCode(item.Key)))
146 }
147
148 out += renderItemsList(nftItems, page, "No NFTs registered yet")
149 return out
150}
151
152func renderMT(path string) string {
153 out := md.H1("GRC1155 Multi-Tokens")
154 out += md.Paragraph("Below is a list of all registered GRC1155 multi-tokens and their registry keys (keys are used to query token information).")
155
156 var mtItems []string
157
158 mtPager := pager.NewPager(registeredMTs, pageSize, false)
159 page := mtPager.MustGetPageByPath(path)
160
161 for _, item := range page.Items {
162 info := item.Value.(GRC1155TokenInfo)
163 pkgPath, _ := fqname.Parse(item.Key)
164 linkURL := formatLinkURL(pkgPath, 1)
165
166 mtItems = append(mtItems, ufmt.Sprintf("%s %s - %s",
167 md.Bold("TokenID:"),
168 md.Link(md.InlineCode(info.TokenID), linkURL),
169 md.InlineCode(item.Key)))
170 }
171
172 out += renderItemsList(mtItems, page, "No multi-tokens registered yet")
173 return out
174}
175
176func renderItemsList(items []string, page *pager.Page, emptyMessage string) string {
177 var out string
178 if len(items) == 0 {
179 out += md.Italic(emptyMessage)
180 out += "\n"
181 return out
182 }
183
184 out += md.BulletList(items)
185 out += "\n"
186 out += md.HorizontalRule()
187
188 picker := page.Picker(page.Pager.PageQueryParam)
189 if picker != "" {
190 out += md.Paragraph(picker)
191 }
192
193 return out
194}
195
196func formatLinkURL(pkgPath string, trailingSegmentsToRemove int) string {
197 re1 := regexp.MustCompile(`gno\.land/r/matijamarjanovic/tokenhub\.`)
198 pkgPath = re1.ReplaceAllString(pkgPath, "")
199
200 re2 := regexp.MustCompile(`gno\.land`)
201 url := re2.ReplaceAllString(pkgPath, "")
202
203 if trailingSegmentsToRemove > 0 {
204 re3 := regexp.MustCompile(`\.`)
205 parts := re3.Split(url, -1)
206 if len(parts) > trailingSegmentsToRemove {
207 url = strings.Join(parts[:len(parts)-trailingSegmentsToRemove], ".")
208 }
209 }
210
211 return url
212}