render.gno
2.95 Kb · 102 lines
1package memba_nft_market_v2
2
3// Render — public read-only views.
4//
5// Routes:
6// "" — home: active listings count + volume
7// "stats" — platform fee, totals
8// "sales" — recent sales (up to 20)
9// * — 404
10
11import (
12 "strings"
13
14 "gno.land/p/nt/ufmt/v0"
15)
16
17func Render(path string) string {
18 switch path {
19 case "":
20 return renderHome()
21 case "stats":
22 return renderStats()
23 case "sales":
24 return renderSales()
25 default:
26 return "# 404\nNot found: " + path
27 }
28}
29
30func renderHome() string {
31 var sb strings.Builder
32 sb.WriteString("# NFT Marketplace\n\n")
33 sb.WriteString(ufmt.Sprintf("**Active Listings:** %d\n", listings.Size()))
34 volGnot := ufmt.Sprintf("%d.%06d", totalVolume/1_000_000, totalVolume%1_000_000)
35 sb.WriteString(ufmt.Sprintf("**Total Volume:** %s GNOT\n", volGnot))
36
37 if len(listingOrder) == 0 {
38 sb.WriteString("\n*No active listings.*\n")
39 return sb.String()
40 }
41
42 const homePageCap = 50
43
44 sb.WriteString("\n| # | Collection | Token | Price | Seller |\n")
45 sb.WriteString("|---|-----------|-------|-------|--------|\n")
46 shown := 0
47 for i, key := range listingOrder {
48 if shown >= homePageCap {
49 break
50 }
51 val, exists := listings.Get(key)
52 if !exists {
53 continue
54 }
55 l := val.(*Listing)
56 priceGnot := ufmt.Sprintf("%d.%06d", l.Price/1_000_000, l.Price%1_000_000)
57 sb.WriteString(ufmt.Sprintf("| %d | %s | %s | %s GNOT | %s |\n",
58 i+1, truncPath(l.CollectionID), l.TokenID, priceGnot, truncAddr(l.Seller)))
59 shown++
60 }
61 if len(listingOrder) > homePageCap {
62 sb.WriteString(ufmt.Sprintf("\n*… showing first %d of %d listings.*\n", homePageCap, len(listingOrder)))
63 }
64 return sb.String()
65}
66
67func renderStats() string {
68 var sb strings.Builder
69 sb.WriteString("# Marketplace Stats\n\n")
70 sb.WriteString(ufmt.Sprintf("**Active Listings:** %d\n", listings.Size()))
71 sb.WriteString(ufmt.Sprintf("**Total Sales:** %d\n", salesLog.Size()))
72 volGnot := ufmt.Sprintf("%d.%06d", totalVolume/1_000_000, totalVolume%1_000_000)
73 sb.WriteString(ufmt.Sprintf("**Total Volume:** %s GNOT\n", volGnot))
74 sb.WriteString(ufmt.Sprintf("**Active Offers:** %d\n", offers.Size()))
75 sb.WriteString("**Platform Fee:** 2.50%\n")
76 sb.WriteString(ufmt.Sprintf("**Max Royalty:** %d%%\n", MaxRoyaltyBPS/100))
77 return sb.String()
78}
79
80func renderSales() string {
81 var sb strings.Builder
82 sb.WriteString("# Recent Sales\n\n")
83 if salesLog.Size() == 0 {
84 sb.WriteString("*No sales yet.*\n")
85 return sb.String()
86 }
87
88 sb.WriteString("| Sale | Collection | Token | Price | Seller | Buyer |\n")
89 sb.WriteString("|------|-----------|-------|-------|--------|-------|\n")
90
91 count := 0
92 salesLog.ReverseIterate("", "", func(key string, val interface{}) bool {
93 s := val.(*Sale)
94 priceGnot := ufmt.Sprintf("%d.%06d", s.Price/1_000_000, s.Price%1_000_000)
95 sb.WriteString(ufmt.Sprintf("| %s | %s | %s | %s GNOT | %s | %s |\n",
96 key, truncPath(s.CollectionID), s.TokenID, priceGnot,
97 truncAddr(s.Seller), truncAddr(s.Buyer)))
98 count++
99 return count >= 20
100 })
101 return sb.String()
102}