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}