Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

list_venue.gno

4.87 Kb · 198 lines
  1package padv2
  2
  3import (
  4	"chain"
  5	"strconv"
  6	"strings"
  7
  8	"gno.land/p/nt/avl/v0"
  9)
 10
 11// ListVenue IDs (compile-time switch in tryListVenue). Adding a new DEX
 12// means a new case + adapter file and a new pad version — Gno cannot
 13// dynamically import by path string.
 14const (
 15	VenueGnoswap = "gnoswap"
 16	VenueZdex    = "zdex"
 17)
 18
 19// listVenueMeta is registry metadata (not a callable adapter).
 20type listVenueMeta struct {
 21	ID           string
 22	Label        string
 23	Enabled      bool
 24	FeeAssetHint string // e.g. "GNS" for CreatePool fee UX
 25}
 26
 27var (
 28	listVenues       avl.Tree // id -> *listVenueMeta
 29	defaultListVenue string
 30)
 31
 32func ensureListVenuesSeeded() {
 33	if listVenues.Size() > 0 {
 34		return
 35	}
 36	// Mainnet-first: zdex default (hub listable when adapter + realm live).
 37	// Gnoswap registered but disabled until mainnet router/pool exist — enable via SetListVenue.
 38	registerListVenue(VenueZdex, "zdex", true, "ugnot")
 39	registerListVenue(VenueGnoswap, "Gnoswap", false, "GNS")
 40	if defaultListVenue == "" {
 41		defaultListVenue = VenueZdex
 42	}
 43}
 44
 45func registerListVenue(id, label string, enabled bool, feeHint string) {
 46	id = strings.TrimSpace(strings.ToLower(id))
 47	if id == "" {
 48		return
 49	}
 50	label = strings.TrimSpace(label)
 51	if label == "" {
 52		label = id
 53	}
 54	listVenues.Set(id, &listVenueMeta{
 55		ID:           id,
 56		Label:        label,
 57		Enabled:      enabled,
 58		FeeAssetHint: strings.TrimSpace(feeHint),
 59	})
 60}
 61
 62func normalizeVenueID(venueId string) string {
 63	ensureListVenuesSeeded()
 64	v := strings.TrimSpace(strings.ToLower(venueId))
 65	if v == "" {
 66		if defaultListVenue != "" {
 67			return defaultListVenue
 68		}
 69		return VenueZdex
 70	}
 71	return v
 72}
 73
 74func venueEnabled(venueId string) bool {
 75	ensureListVenuesSeeded()
 76	id := normalizeVenueID(venueId)
 77	raw := listVenues.Get(id)
 78	if raw == nil {
 79		return false
 80	}
 81	m, ok := raw.(*listVenueMeta)
 82	return ok && m != nil && m.Enabled
 83}
 84
 85// DefaultListVenue returns the venue id used when callers pass "".
 86func DefaultListVenue() string {
 87	ensureListVenuesSeeded()
 88	if defaultListVenue == "" {
 89		return VenueZdex
 90	}
 91	return defaultListVenue
 92}
 93
 94// SetDefaultListVenue sets the default list venue (protocol only).
 95func SetDefaultListVenue(cur realm, venueId string) {
 96	requireProtocol(cur)
 97	ensureListVenuesSeeded()
 98	id := strings.TrimSpace(strings.ToLower(venueId))
 99	if id == "" {
100		panic("pad: empty venue")
101	}
102	if listVenues.Get(id) == nil {
103		panic("pad: unknown venue")
104	}
105	defaultListVenue = id
106	chain.Emit("SetDefaultListVenue", "venue", id)
107}
108
109// SetListVenue registers or updates venue metadata (protocol only).
110// Does not add compile-time dispatch — unknown ids stay non-listable until
111// tryListVenue gains a case in a future pad version.
112func SetListVenue(cur realm, id, label string, enabled bool, feeAssetHint string) {
113	requireProtocol(cur)
114	ensureListVenuesSeeded()
115	id = strings.TrimSpace(strings.ToLower(id))
116	if id == "" || len(id) > 32 {
117		panic("pad: invalid venue id")
118	}
119	for _, c := range id {
120		if !((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_' || c == '-') {
121			panic("pad: venue id charset")
122		}
123	}
124	registerListVenue(id, label, enabled, feeAssetHint)
125	chain.Emit("SetListVenue",
126		"id", id,
127		"label", strings.TrimSpace(label),
128		"enabled", strconv.FormatBool(enabled),
129		"feeHint", strings.TrimSpace(feeAssetHint),
130	)
131}
132
133// ListVenues returns newline-separated "id|label|enabled|feeHint" (enabled 0|1).
134func ListVenues() string {
135	ensureListVenuesSeeded()
136	out := ""
137	listVenues.Iterate("", "", func(key string, value any) bool {
138		m, ok := value.(*listVenueMeta)
139		if !ok || m == nil {
140			return false
141		}
142		en := "0"
143		if m.Enabled {
144			en = "1"
145		}
146		line := m.ID + "|" + m.Label + "|" + en + "|" + m.FeeAssetHint
147		if out != "" {
148			out += "\n"
149		}
150		out += line
151		return false
152	})
153	return out
154}
155
156// ListVenueOf returns the venue id used for a successful list (or "").
157func ListVenueOf(id string) string {
158	return mustLaunch(id).ListVenue
159}
160
161// resetListVenuesForTest clears venue registry (unit tests).
162func resetListVenuesForTest() {
163	listVenues = avl.Tree{}
164	defaultListVenue = ""
165}
166
167// tryListVenue dispatches to a compile-time adapter. Unknown / disabled
168// venues soft-fail with a note (no panic) so UI can show ListNeed guidance.
169func tryListVenue(cur realm, l *Launch, venueId string, raisedUgnot, liqTokens int64) bool {
170	ensureListVenuesSeeded()
171	id := normalizeVenueID(venueId)
172	if !venueEnabled(id) {
173		if l != nil {
174			l.GnoswapNote = "list skip: venue disabled or unknown: " + id
175		}
176		return false
177	}
178	switch id {
179	case VenueZdex:
180		ok := tryListOnZdex(cur, l, raisedUgnot, liqTokens)
181		if ok && l != nil {
182			l.ListVenue = VenueZdex
183		}
184		return ok
185	case VenueGnoswap:
186		ok := listOnGnoswapWithFunding(cur, l, raisedUgnot, liqTokens)
187		if ok && l != nil {
188			l.ListVenue = VenueGnoswap
189		}
190		return ok
191	default:
192		// Registered in metadata but no adapter case yet.
193		if l != nil {
194			l.GnoswapNote = "list skip: venue adapter not linked in this pad: " + id
195		}
196		return false
197	}
198}