viewjson.gno
3.74 Kb · 143 lines
1package gnogle_nftmarket
2
3// JSON read helpers for front-ends. These return compact JSON strings so a web
4// client can fetch a whole view in a single vm/qeval call instead of parsing
5// Gno tuple output. They are read-only.
6
7import (
8 "strconv"
9 "strings"
10
11 "gno.land/p/g18wk4a80cr7dqa25vfka2yug5n3pd50udled6y3/grc721"
12 "gno.land/p/nt/ufmt/v0"
13)
14
15// CollectionsJSON returns every collection as a JSON array.
16func CollectionsJSON() string {
17 var b strings.Builder
18 b.WriteString("[")
19 for i, id := range collOrder {
20 v, ok := collections.Get(id)
21 if !ok {
22 continue
23 }
24 c := v.(*Collection)
25 if i > 0 {
26 b.WriteString(",")
27 }
28 b.WriteString(ufmt.Sprintf(
29 `{"id":%s,"name":%s,"symbol":%s,"creator":%s,"baseURI":%s,"mintPrice":%d,"maxSupply":%d,"minted":%d,"burned":%d,"royaltyBps":%d,"sealed":%s,"verified":%s}`,
30 js(c.id), js(c.name), js(c.symbol), js(c.creator.String()), js(c.baseURI),
31 c.mintPrice, c.maxSupply, c.minted, c.burned, c.royaltyBps, jb(c.sealed), jb(c.verified)))
32 }
33 b.WriteString("]")
34 return b.String()
35}
36
37// TokensJSON returns every minted token of a collection with its market state.
38func TokensJSON(collID string) string {
39 coll := mustGetCollection(collID)
40 var b strings.Builder
41 b.WriteString("[")
42 first := true
43 for i := int64(1); i <= coll.minted; i++ {
44 tokenID := strconv.FormatInt(i, 10)
45 owner, err := coll.nft.OwnerOf(grc721.TokenID(tokenID))
46 if err != nil {
47 continue
48 }
49 if !first {
50 b.WriteString(",")
51 }
52 first = false
53
54 listed, price, seller := false, int64(0), ""
55 if l, ok := getListing(collID, tokenID); ok {
56 listed, price, seller = true, l.price, l.seller.String()
57 }
58 auction, minBid, highBid, highBidder, endUnix := false, int64(0), int64(0), "", int64(0)
59 if a, ok := getAuction(collID, tokenID); ok {
60 auction, minBid, highBid, highBidder, endUnix = true, a.minBid, a.highestBid, a.highestBidder.String(), a.endTime.Unix()
61 seller = a.seller.String()
62 }
63
64 b.WriteString(ufmt.Sprintf(
65 `{"id":%s,"owner":%s,"listed":%s,"price":%d,"seller":%s,"auction":%s,"minBid":%d,"highBid":%d,"highBidder":%s,"endUnix":%d}`,
66 js(tokenID), js(owner.String()), jb(listed), price, js(seller),
67 jb(auction), minBid, highBid, js(highBidder), endUnix))
68 }
69 b.WriteString("]")
70 return b.String()
71}
72
73// OffersJSON returns the standing offers on a token.
74func OffersJSON(collID, tokenID string) string {
75 prefix := collID + "/" + tokenID + "/"
76 var b strings.Builder
77 b.WriteString("[")
78 first := true
79 offers.Iterate("", "", func(key string, value any) bool {
80 if !strings.HasPrefix(key, prefix) {
81 return false
82 }
83 o := value.(*Offer)
84 if !first {
85 b.WriteString(",")
86 }
87 first = false
88 b.WriteString(ufmt.Sprintf(`{"buyer":%s,"amount":%d}`, js(o.buyer.String()), o.amount))
89 return false
90 })
91 b.WriteString("]")
92 return b.String()
93}
94
95// AllOffersJSON returns every standing offer across all tokens (for "top offers").
96func AllOffersJSON() string {
97 var b strings.Builder
98 b.WriteString("[")
99 first := true
100 offers.Iterate("", "", func(key string, value any) bool {
101 o := value.(*Offer)
102 if !first {
103 b.WriteString(",")
104 }
105 first = false
106 b.WriteString(ufmt.Sprintf(`{"collID":%s,"tokenID":%s,"buyer":%s,"amount":%d}`,
107 js(o.collID), js(o.tokenID), js(o.buyer.String()), o.amount))
108 return false
109 })
110 b.WriteString("]")
111 return b.String()
112}
113
114// js encodes a string as a JSON string literal.
115func js(s string) string {
116 var b strings.Builder
117 b.WriteString(`"`)
118 for _, r := range s {
119 switch r {
120 case '"':
121 b.WriteString(`\"`)
122 case '\\':
123 b.WriteString(`\\`)
124 case '\n':
125 b.WriteString(`\n`)
126 case '\r':
127 b.WriteString(`\r`)
128 case '\t':
129 b.WriteString(`\t`)
130 default:
131 b.WriteString(string(r))
132 }
133 }
134 b.WriteString(`"`)
135 return b.String()
136}
137
138func jb(v bool) string {
139 if v {
140 return "true"
141 }
142 return "false"
143}