viewjson.gno
3.12 Kb · 123 lines
1package 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,"royaltyBps":%d}`,
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.royaltyBps))
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 }
62
63 b.WriteString(ufmt.Sprintf(
64 `{"id":%s,"owner":%s,"listed":%s,"price":%d,"seller":%s,"auction":%s,"minBid":%d,"highBid":%d,"highBidder":%s,"endUnix":%d}`,
65 js(tokenID), js(owner.String()), jb(listed), price, js(seller),
66 jb(auction), minBid, highBid, js(highBidder), endUnix))
67 }
68 b.WriteString("]")
69 return b.String()
70}
71
72// OffersJSON returns the standing offers on a token.
73func OffersJSON(collID, tokenID string) string {
74 prefix := collID + "/" + tokenID + "/"
75 var b strings.Builder
76 b.WriteString("[")
77 first := true
78 offers.Iterate("", "", func(key string, value any) bool {
79 if !strings.HasPrefix(key, prefix) {
80 return false
81 }
82 o := value.(*Offer)
83 if !first {
84 b.WriteString(",")
85 }
86 first = false
87 b.WriteString(ufmt.Sprintf(`{"buyer":%s,"amount":%d}`, js(o.buyer.String()), o.amount))
88 return false
89 })
90 b.WriteString("]")
91 return b.String()
92}
93
94// js encodes a string as a JSON string literal.
95func js(s string) string {
96 var b strings.Builder
97 b.WriteString(`"`)
98 for _, r := range s {
99 switch r {
100 case '"':
101 b.WriteString(`\"`)
102 case '\\':
103 b.WriteString(`\\`)
104 case '\n':
105 b.WriteString(`\n`)
106 case '\r':
107 b.WriteString(`\r`)
108 case '\t':
109 b.WriteString(`\t`)
110 default:
111 b.WriteString(string(r))
112 }
113 }
114 b.WriteString(`"`)
115 return b.String()
116}
117
118func jb(v bool) string {
119 if v {
120 return "true"
121 }
122 return "false"
123}