Search Apps Documentation Source Content File Folder Download Copy Actions Download

getters.gno

3.74 Kb · 107 lines
  1package memba_nft_market_v3_2
  2
  3// v3.1 — structured read getters.
  4//
  5// These let the frontend read listings and offers STRUCTURALLY (full addresses,
  6// deterministic format) instead of scraping the markdown Render(""), which truncated
  7// addresses and capped at 50 rows. Output is one record per line, pipe-delimited, so
  8// the client parses by split — no markdown regex, no truncation.
  9
 10import (
 11	"strings"
 12
 13	"chain/runtime/unsafe"
 14)
 15
 16// MaxPageSize bounds a single page so a getter can never iterate unboundedly (a
 17// gas/DoS surface). The frontend pages with offset/limit.
 18const MaxPageSize = 100
 19
 20// MarketAddress returns this engine realm's own address — the operator a seller
 21// approves on the collection (SetApprovalForAll) and the address the collection
 22// registers via RegisterMarket. Exposed so the frontend and the deploy ceremony can
 23// read the deterministic address directly instead of hardcoding it.
 24func MarketAddress() string { return unsafe.CurrentRealm().Address().String() }
 25
 26// ── NF-2 solvency getters (MAINNET_READINESS §3) ─────────────────────────────
 27//
 28// The offer escrow makes this a pooled-fund realm: without a machine-readable
 29// liabilities figure the solvency monitor can only do a balance-only heuristic.
 30// Invariant the monitor reconciles: realm balance >= TotalLiabilities().
 31
 32// TotalLiabilities returns the total ugnot the realm owes to offer escrows.
 33// Maintained in lockstep with every escrow mutation (see offers.gno).
 34func TotalLiabilities() int64 { return totalEscrowed }
 35
 36// RealmAddress is the NF-2 canonical name for the realm's own address (the
 37// monitor pairs it with TotalLiabilities). Same value as MarketAddress.
 38func RealmAddress() string { return MarketAddress() }
 39
 40// ListingsCount returns the number of active listings (for pagination).
 41func ListingsCount() int { return len(listingOrder) }
 42
 43// GetListingsPage returns a page of active listings, one per line:
 44//
 45//	collectionID|tokenID|seller|price|createdBlk
 46//
 47// Addresses are FULL (never truncated). offset/limit window the insertion-ordered
 48// listing set; limit is clamped to [1, MaxPageSize].
 49func GetListingsPage(offset, limit int) string {
 50	if offset < 0 {
 51		offset = 0
 52	}
 53	if limit <= 0 || limit > MaxPageSize {
 54		limit = MaxPageSize
 55	}
 56	n := len(listingOrder)
 57	end := offset + limit
 58	if end > n {
 59		end = n
 60	}
 61
 62	var sb strings.Builder
 63	for i := offset; i < end; i++ {
 64		v, ok := listings.Get(listingOrder[i])
 65		if !ok {
 66			continue
 67		}
 68		l := v.(*Listing)
 69		sb.WriteString(l.CollectionID)
 70		sb.WriteString("|")
 71		sb.WriteString(l.TokenID)
 72		sb.WriteString("|")
 73		sb.WriteString(l.Seller.String())
 74		sb.WriteString("|")
 75		sb.WriteString(itoa(l.Price))
 76		sb.WriteString("|")
 77		sb.WriteString(itoa(l.CreatedBlk))
 78		sb.WriteString("\n")
 79	}
 80	return sb.String()
 81}
 82
 83// GetOffersForToken returns the active offers on one (collection, token), one per line:
 84//
 85//	buyer|amount|createdBlk
 86//
 87// It uses a PREFIX-RANGE scan over the offer tree — offerKey is "collection:token:buyer",
 88// so the range ["collection:token:", "collection:token;") reads only this token's
 89// offers, never a full-tree scan. This is the read that finally lets the frontend wire
 90// accept-offer and show a token's offers (no offers getter existed before v3.1).
 91func GetOffersForToken(collectionID, tokenID string) string {
 92	start := collectionID + ":" + tokenID + ":"
 93	end := collectionID + ":" + tokenID + ";" // ';' (0x3b) is the byte after ':' (0x3a)
 94
 95	var sb strings.Builder
 96	offers.Iterate(start, end, func(_ string, v interface{}) bool {
 97		o := v.(*Offer)
 98		sb.WriteString(o.Buyer.String())
 99		sb.WriteString("|")
100		sb.WriteString(itoa(o.Amount))
101		sb.WriteString("|")
102		sb.WriteString(itoa(o.CreatedBlk))
103		sb.WriteString("\n")
104		return false
105	})
106	return sb.String()
107}