@ftptech/canton-agent-wallet 1.4.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,275 @@
1
+ /**
2
+ * swap-route — the venue-routing half of `swap`: resolve the two legs fail-closed,
3
+ * pick a venue (explicit, default-with-fallback, or `auto` by best quote) and
4
+ * produce the ticket `executeSwap` sends against.
5
+ *
6
+ * This is the ONE copy of that logic. The CLI `swap` command and the MCP `swap`
7
+ * tool both call it, so a routing rule (which venue is tried first, when a
8
+ * fallback is allowed, which minimums are checked) cannot drift between the two
9
+ * the way the quest's "unreadable balance" guard once did.
10
+ *
11
+ * Nothing here moves the swap input. The only money this module can spend is the
12
+ * endpoint's ticket fee, on the non-direct path, through the `payingFetch` the
13
+ * caller supplies (and bounds).
14
+ */
15
+ import { resolveSwapSymbol, KNOWN_INSTRUMENTS } from "./registry-parties.js";
16
+ import { buildLocalTicket, buildCantexTicket, fetchTicketFromEndpoint, tradecraftMinInput, CANTEX_CONNECT_PARTY, CANTEX_CONNECT_URL, CANTEX_MIN_INPUT_CC, } from "./swap.js";
17
+ /** The venue used when the caller names none. */
18
+ export const DEFAULT_SWAP_VENUE = "cantex";
19
+ /** Ceiling on the swap-ticket fee the endpoint may charge, in CC. The live fee is
20
+ * 0.01 CC, so this leaves a wide margin while still bounding a hijacked endpoint
21
+ * to a trivial loss instead of the agent's balance. */
22
+ export const SWAP_MAX_FEE_CC = "0.5";
23
+ /** The Tradecraft AMM-rules contract every pool party derives from. CLIENT-TRUSTED
24
+ * (config, never the endpoint): the receiver of a Tradecraft swap must be a
25
+ * `tc-swp_…::<this>` party, so a compromised endpoint cannot redirect funds. */
26
+ export const DEFAULT_TRADECRAFT_AMM_CID = "122096fe076cc065af0cb38f94caa60e8ddfecbe8f0cfe10655ae7aa06fab99c66b7";
27
+ /** Our x402-gated ticket endpoint (the default, fee-charging path). */
28
+ export const DEFAULT_SWAP_URL = "https://swap.ftptech.xyz";
29
+ /** Tradecraft's public REST (the `direct` path quotes here). */
30
+ export const DEFAULT_TRADECRAFT_API = "https://api.tradecraft.fi";
31
+ /** Parse a venue choice; absent = the default. Throws on anything else. */
32
+ export function parseSwapVenue(raw) {
33
+ const v = (raw ?? DEFAULT_SWAP_VENUE).toLowerCase();
34
+ if (v !== "cantex" && v !== "tradecraft" && v !== "auto") {
35
+ throw new Error("swap: venue must be cantex, tradecraft, or auto");
36
+ }
37
+ return v;
38
+ }
39
+ /** Parse a slippage percentage; absent = 1%. Throws outside [0, 100). */
40
+ export function parseSlippagePct(raw) {
41
+ const pct = raw === undefined ? 1 : Number(raw);
42
+ if (!Number.isFinite(pct) || pct < 0 || pct >= 100) {
43
+ throw new Error("swap: slippage must be a percentage in [0, 100)");
44
+ }
45
+ return pct;
46
+ }
47
+ /**
48
+ * Resolve each leg to a CANONICAL symbol, and FAIL CLOSED on an unrecognized one.
49
+ * Without this an unknown symbol would fall back to native Canton Coin, so a typo
50
+ * like `USDC` (for USDCx) would silently send real CC to a `tc-swp_USDC-…` pool.
51
+ * The canonical casing also targets the real `USDCx` pool, not a case-mismatched
52
+ * non-existent one. `labels` name the two inputs in the error the way the caller
53
+ * spells them (`--in` for the CLI, `in` for a tool argument).
54
+ */
55
+ export function resolveSwapIntent(inSym, outSym, labels = { in: "in", out: "out" }) {
56
+ const inLeg = resolveSwapSymbol(inSym);
57
+ const outLeg = resolveSwapSymbol(outSym);
58
+ for (const [label, sym, leg] of [
59
+ [labels.in, inSym, inLeg],
60
+ [labels.out, outSym, outLeg],
61
+ ]) {
62
+ if (leg.kind === "unknown") {
63
+ throw new Error(`swap: ${label} ${JSON.stringify(sym)} is not a known instrument. ` +
64
+ `Use CC or one of: ${Object.keys(KNOWN_INSTRUMENTS).join(", ")} ` +
65
+ `(add others via CANTON_AGENT_REGISTRY_TRUSTED_PARTIES + code).`);
66
+ }
67
+ }
68
+ if (inLeg.kind === "unknown" || outLeg.kind === "unknown") {
69
+ throw new Error("unreachable"); // narrowed above
70
+ }
71
+ if (inLeg.kind === "cc" && outLeg.kind === "cc") {
72
+ throw new Error(`swap: ${labels.in} and ${labels.out} are both CC — nothing to swap`);
73
+ }
74
+ return {
75
+ inCanon: inLeg.symbol,
76
+ outCanon: outLeg.symbol,
77
+ inInstrument: inLeg.kind === "registry" ? inLeg.instrument : null,
78
+ outInstrument: outLeg.kind === "registry" ? outLeg.instrument : null,
79
+ };
80
+ }
81
+ /**
82
+ * Resolve the ticket for a swap. DEFAULT path = our x402 `/swap` endpoint (a
83
+ * small CC fee for a ticket that stays current with each venue's pools/params);
84
+ * the returned ticket is validated against the trusted per-venue receiver +
85
+ * instruments inside `fetchTicketFromEndpoint`, so the endpoint is trusted for
86
+ * price only. The `direct` path resolves the venue's quote locally (no fee).
87
+ *
88
+ * Venue rules (identical for every caller):
89
+ * - `cantex` (default): a CC input below Cantex's minimum, or a Cantex quote
90
+ * failure, routes to Tradecraft — unless the caller named cantex explicitly,
91
+ * in which case it is an error.
92
+ * - `tradecraft`: Tradecraft only.
93
+ * - `auto`: FREE direct quotes from every eligible venue, best expected output
94
+ * wins; one venue erroring uses the other. Never pays the endpoint fee.
95
+ */
96
+ export async function resolveSwapTicket(opts) {
97
+ const env = opts.env ?? process.env;
98
+ const { intent, amount, slippagePct } = opts;
99
+ const d = {
100
+ buildCantexTicket,
101
+ buildLocalTicket,
102
+ fetchTicketFromEndpoint,
103
+ ...opts.deps,
104
+ };
105
+ const notes = [];
106
+ const note = (level, text) => {
107
+ const n = { level, text };
108
+ notes.push(n);
109
+ opts.onNote?.(n);
110
+ };
111
+ // CLIENT-TRUSTED constants (config, never the endpoint): the receiver of the
112
+ // funds must equal one of these per venue, so a compromised swap endpoint can
113
+ // never redirect the swap to an attacker party.
114
+ const trustedAmmCid = env.CANTON_AGENT_TRADECRAFT_AMM_CID ?? DEFAULT_TRADECRAFT_AMM_CID;
115
+ const trustedCantexParty = CANTEX_CONNECT_PARTY;
116
+ // Cantex Connect handles BOTH directions (CC->token and token->CC). Its minimum
117
+ // is 50 CC-equivalent. We can only check that locally for a CC input; for a
118
+ // token input the CC-equivalent is unknown client-side, so we let Cantex's quote
119
+ // enforce it (and fall back to Tradecraft on failure). Cantex's keyless quote can
120
+ // also transiently fail to price a token input — buildCantexTicket retries, and
121
+ // the default/auto paths fall back to Tradecraft if it still cannot quote.
122
+ const inputIsCC = intent.inInstrument === null;
123
+ const cantexRuledOut = inputIsCC && Number(amount) < CANTEX_MIN_INPUT_CC;
124
+ const resolveDirect = async (v) => {
125
+ if (v === "cantex") {
126
+ if (!opts.dsoParty) {
127
+ throw new Error("swap: cannot resolve the DSO party for Cantex — set CANTON_AGENT_DSO_PARTY");
128
+ }
129
+ return d.buildCantexTicket({
130
+ connectUrl: CANTEX_CONNECT_URL,
131
+ cantexParty: trustedCantexParty,
132
+ dsoParty: opts.dsoParty,
133
+ inSymbol: intent.inCanon,
134
+ outSymbol: intent.outCanon,
135
+ amount,
136
+ slippagePct,
137
+ inInstrument: intent.inInstrument,
138
+ outInstrument: intent.outInstrument,
139
+ });
140
+ }
141
+ const memoKey = env.CANTON_AGENT_TRADECRAFT_MEMO_KEY;
142
+ const tradecraftApi = env.CANTON_AGENT_TRADECRAFT_API ?? DEFAULT_TRADECRAFT_API;
143
+ return d.buildLocalTicket({
144
+ tradecraftApi,
145
+ ammCid: trustedAmmCid,
146
+ ...(memoKey ? { memoKey } : {}),
147
+ inSymbol: intent.inCanon,
148
+ outSymbol: intent.outCanon,
149
+ amount,
150
+ slippagePct,
151
+ inInstrument: intent.inInstrument,
152
+ outInstrument: intent.outInstrument,
153
+ });
154
+ };
155
+ const resolveEndpoint = async (v) => {
156
+ if (!opts.payingFetch) {
157
+ throw new Error("swap: the endpoint path needs a paying fetch (none supplied) — use direct");
158
+ }
159
+ const swapUrl = env.CANTON_AGENT_SWAP_URL ?? DEFAULT_SWAP_URL;
160
+ // Built here, not up front: the endpoint auto-settles whatever 402 it answers
161
+ // before any ticket validation, so the fetch (and its fee bound) must exist
162
+ // only on the path that actually pays.
163
+ const payingFetch = await opts.payingFetch();
164
+ return d.fetchTicketFromEndpoint({
165
+ swapUrl,
166
+ inSymbol: intent.inCanon,
167
+ outSymbol: intent.outCanon,
168
+ amount,
169
+ slippagePct,
170
+ payingFetch,
171
+ inInstrument: intent.inInstrument,
172
+ outInstrument: intent.outInstrument,
173
+ trustedAmmCid,
174
+ trustedCantexParty,
175
+ venue: v,
176
+ });
177
+ };
178
+ const resolveOne = (v) => opts.direct ? resolveDirect(v) : resolveEndpoint(v);
179
+ let ticket;
180
+ if (opts.venue === "auto") {
181
+ // Compare FREE direct quotes from eligible venues and pick the better output
182
+ // (auto never pays the endpoint fee twice). One venue erroring uses the other.
183
+ const candidates = [];
184
+ if (!cantexRuledOut)
185
+ candidates.push("cantex");
186
+ candidates.push("tradecraft");
187
+ const settled = await Promise.allSettled(candidates.map(resolveDirect));
188
+ const ok = settled
189
+ .filter((x) => x.status === "fulfilled")
190
+ .map((x) => x.value);
191
+ if (ok.length === 0) {
192
+ const why = settled.find((r) => r.status === "rejected");
193
+ throw new Error(`swap: no venue could quote ${intent.inCanon}/${intent.outCanon}` +
194
+ (why ? ` — ${why.reason instanceof Error ? why.reason.message : String(why.reason)}` : ""));
195
+ }
196
+ // Rank by numeric quote, best first; a market-fill ticket carries a non-numeric
197
+ // quote ("unknown ...") and must sort LAST so it never beats a real quote on NaN.
198
+ const q = (t) => {
199
+ const n = Number(t.quote);
200
+ return Number.isFinite(n) ? n : -Infinity;
201
+ };
202
+ ok.sort((a, b) => q(b) - q(a));
203
+ ticket = ok[0];
204
+ note("info", `auto: ${ok.map((t) => `${t.venue} ~${t.quote}`).join(", ")} -> chose ${ticket.venue}`);
205
+ }
206
+ else if (opts.venue === "cantex") {
207
+ if (cantexRuledOut) {
208
+ const reason = `Cantex Connect minimum is ${CANTEX_MIN_INPUT_CC} CC (got ${amount} CC)`;
209
+ if (opts.venueExplicit) {
210
+ throw new Error(`swap: ${reason} — use the tradecraft venue`);
211
+ }
212
+ note("warn", `${reason}; routing to Tradecraft`);
213
+ ticket = await resolveOne("tradecraft");
214
+ }
215
+ else {
216
+ // Try Cantex; on a quote failure (e.g. its transient token->CC pricing
217
+ // outage) the DEFAULT falls back to Tradecraft, an EXPLICIT cantex surfaces
218
+ // the error. A failed quote sends NO funds, so this cannot strand.
219
+ try {
220
+ ticket = await resolveOne("cantex");
221
+ }
222
+ catch (e) {
223
+ if (opts.venueExplicit)
224
+ throw e;
225
+ note("warn", `Cantex could not quote (${(e instanceof Error ? e.message : String(e)).slice(0, 120)}); routing to Tradecraft`);
226
+ ticket = await resolveOne("tradecraft");
227
+ }
228
+ }
229
+ }
230
+ else {
231
+ ticket = await resolveOne("tradecraft");
232
+ }
233
+ // Advisory min-input warning for Tradecraft (mirrors its web app; not a hard
234
+ // limit — the pool returns the funds if a small trade will not fill).
235
+ if (ticket.venue === "tradecraft") {
236
+ const minIn = tradecraftMinInput(intent.inCanon);
237
+ if (minIn !== undefined && Number(amount) < minIn) {
238
+ note("warn", `${amount} ${intent.inCanon} is below Tradecraft's advertised minimum of ${minIn} ${intent.inCanon} — ` +
239
+ `the trade may be returned unfilled (no loss). Proceeding.`);
240
+ }
241
+ }
242
+ return { ticket, notes };
243
+ }
244
+ /**
245
+ * What bounds the fill, as lines for the user. Cantex Connect fills at its own
246
+ * rate at execution time: the memo carries the buy symbol, not a client minimum,
247
+ * so NOTHING on-ledger bounds what comes back and slippage only sets the delivery
248
+ * threshold the wait loop reports against. Tradecraft enforces the floor from
249
+ * the memo when a memo key rides; with none it is a market fill and slippage did
250
+ * nothing. Said explicitly every time, so a caller who passed a slippage never
251
+ * reads the quiet quote line as a floor.
252
+ */
253
+ export function swapFloorNotes(ticket, slippagePct, outCanon) {
254
+ if (ticket.venue === "cantex") {
255
+ return [
256
+ { level: "info", text: `~${ticket.quote} ${outCanon} expected (Cantex Connect quote)` },
257
+ {
258
+ level: "warn",
259
+ text: `no on-ledger floor on Cantex — it fills at its rate when it executes; ` +
260
+ `slippage ${slippagePct}% only sets the delivery threshold this swap reports against`,
261
+ },
262
+ ];
263
+ }
264
+ if (ticket.memoKey) {
265
+ return [{ level: "info", text: `min ${ticket.minOutput} enforced at ${slippagePct}% slippage` }];
266
+ }
267
+ return [
268
+ {
269
+ level: "warn",
270
+ text: "no slippage protection on this ticket — filling at market price " +
271
+ "(the swap endpoint set no memo key)",
272
+ },
273
+ ];
274
+ }
275
+ //# sourceMappingURL=swap-route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap-route.js","sourceRoot":"","sources":["../src/swap-route.ts"],"names":[],"mappings":"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"}
package/dist/swap.d.ts CHANGED
@@ -29,21 +29,31 @@ export type SwapInstrument = {
29
29
  admin: string;
30
30
  id: string;
31
31
  } | null;
32
+ /** The swap venue a ticket routes to. Tradecraft uses pool addresses; Cantex uses
33
+ * the keyless Connect "trade by a simple send" path. Both share the same on-ledger
34
+ * execution primitive (send the input to a party with a memo), so `executeSwap` is
35
+ * venue-agnostic and only ticket resolution differs. */
36
+ export type SwapVenue = "tradecraft" | "cantex";
32
37
  /** Everything needed to execute one swap, resolved up front (locally, or by the
33
38
  * facilitator /swap fee-ticket which knows the network's registrars). */
34
39
  export interface SwapTicket {
35
- /** The pool party to send the input to: `tc-swp_{IN}-{OUT}::<amm_cid>`. */
40
+ /** Which venue resolved this ticket (defaults to tradecraft when absent, for
41
+ * backward compatibility with older endpoint responses). */
42
+ venue?: SwapVenue;
43
+ /** The party to send the input to: Tradecraft `tc-swp_{IN}-{OUT}::<amm_cid>`, or
44
+ * the Cantex Connect swap party. */
36
45
  poolParty: string;
37
46
  /** Slippage-protected minimum output, as a ledger decimal string. Always
38
- * computed for display; only ENFORCED when `memoKey` is set (see below). */
47
+ * computed for the display + delivery-detection threshold; on Tradecraft it is
48
+ * also what rides in the memo as the enforced minimum. */
39
49
  minOutput: string;
40
- /** The transfer-meta key Tradecraft reads the minimum from ("the memo field").
41
- * When set, the minimum is attached to the input transfer and the pool honors
42
- * it (below-minimum → the trade fails and the input returns). When UNDEFINED,
43
- * the swap executes at market price with no slippage protection — exactly the
44
- * bare "send to the pool" flow, which works. Tradecraft's docs: the minimum is
45
- * the first text in the memo field, a decimal with ≤10 places. */
50
+ /** The transfer-meta key the venue reads the memo from. Tradecraft: set only when
51
+ * slippage protection is on (else market fill). Cantex: always the reason key. */
46
52
  memoKey?: string;
53
+ /** The exact string to place in the memo (under `memoKey`). Tradecraft: the
54
+ * min-out decimal. Cantex: the buy-token symbol (e.g. "CBTC"). Defaults to
55
+ * `minOutput` when absent (older Tradecraft-only tickets). */
56
+ memoValue?: string;
47
57
  /** The raw quote (estimated output) that produced `minOutput`. */
48
58
  quote: string;
49
59
  /** The instrument being sent in (null = CC). */
@@ -51,6 +61,17 @@ export interface SwapTicket {
51
61
  /** The instrument expected back (null = CC). */
52
62
  outInstrument: SwapInstrument;
53
63
  }
64
+ /** The Cantex Connect swap party (client-trusted constant; env-overridable). Funds
65
+ * can only ever be sent here for a Cantex swap, so a compromised endpoint cannot
66
+ * redirect them. */
67
+ export declare const CANTEX_CONNECT_PARTY: string;
68
+ /** Cantex Connect quote endpoint (keyless, public). */
69
+ export declare const CANTEX_CONNECT_URL: string;
70
+ /** The Canton token-standard reason key Cantex reads the buy symbol from. */
71
+ export declare const CANTEX_MEMO_KEY = "splice.lfdecentralizedtrust.org/reason";
72
+ /** Cantex Connect minimum input, in CC-equivalent. Trades below this bounce at the
73
+ * quote step. */
74
+ export declare const CANTEX_MIN_INPUT_CC = 50;
54
75
  /** Per-input-token advisory minimums, mirrored from the Tradecraft web app (there
55
76
  * is NO API endpoint for these — they are a hardcoded frontend constant). A trade
56
77
  * below the minimum is ADVISORY only: the pool safely returns the funds if it will
@@ -116,6 +137,30 @@ export declare function buildLocalTicket(opts: {
116
137
  inInstrument: SwapInstrument;
117
138
  outInstrument: SwapInstrument;
118
139
  fetchImpl?: typeof globalThis.fetch;
140
+ /** Retries for a transient Tradecraft 5xx on the pools/quote fetch. Default 4. */
141
+ quoteAttempts?: number;
142
+ }): Promise<SwapTicket>;
143
+ /** Fetch a live Cantex Connect quote and build a ticket locally (the keyless
144
+ * `--direct` path for Cantex — Connect is public and free, so no fee/endpoint is
145
+ * needed). The counter-asset settles directly to the sender's pre-approved wallet.
146
+ * Unlike Tradecraft, Cantex's memo is the BUY SYMBOL (from the quote), not a min;
147
+ * `slippagePct` only sets the local delivery-detection threshold. */
148
+ export declare function buildCantexTicket(opts: {
149
+ connectUrl: string;
150
+ cantexParty: string;
151
+ /** Full DSO party id — Cantex requires the FULL Amulet admin (not "DSO"). */
152
+ dsoParty: string;
153
+ inSymbol: string;
154
+ outSymbol: string;
155
+ amount: string;
156
+ slippagePct: number;
157
+ inInstrument: SwapInstrument;
158
+ outInstrument: SwapInstrument;
159
+ fetchImpl?: typeof globalThis.fetch;
160
+ /** Retries for Cantex's transient "unable to determine CC-equivalent input size"
161
+ * (seen on token->CC quotes when their price backend is briefly degraded). Default 4. */
162
+ quoteAttempts?: number;
163
+ sleep?: (ms: number) => Promise<void>;
119
164
  }): Promise<SwapTicket>;
120
165
  /** Parse a swap-endpoint ticket response into a SwapTicket, validating the fields
121
166
  * the local execute path relies on. Extra fields (e.g. ammCid) are ignored. */
@@ -142,6 +187,8 @@ export declare function assertTicketMatchesIntent(ticket: SwapTicket, expect: {
142
187
  inInstrument: SwapInstrument;
143
188
  outInstrument: SwapInstrument;
144
189
  trustedAmmCid: string;
190
+ /** The client-trusted Cantex Connect party (for cantex-venue tickets). */
191
+ trustedCantexParty: string;
145
192
  }): void;
146
193
  /** Fetch a swap ticket from OUR x402-gated `/swap` endpoint (the default path): the
147
194
  * managed router that stays current with Tradecraft's pools/amm_cid/minimums and
@@ -161,8 +208,12 @@ export declare function fetchTicketFromEndpoint(opts: {
161
208
  inInstrument: SwapInstrument;
162
209
  /** Locally-resolved output instrument (null = CC) the ticket MUST match. */
163
210
  outInstrument: SwapInstrument;
164
- /** The caller's OWN trusted amm_cid the pool party MUST derive from. */
211
+ /** The caller's OWN trusted amm_cid the pool party MUST derive from (Tradecraft). */
165
212
  trustedAmmCid: string;
213
+ /** The caller's OWN trusted Cantex Connect party the pool party MUST equal (Cantex). */
214
+ trustedCantexParty: string;
215
+ /** Which venue to request. Default cantex. */
216
+ venue?: SwapVenue;
166
217
  }): Promise<SwapTicket>;
167
218
  export interface ExecuteSwapOpts {
168
219
  amount: string;
@@ -217,6 +268,14 @@ export interface SwapResult {
217
268
  * minimum — an unrelated inbound, or a partial/odd settlement. Undefined when
218
269
  * zero or when `delivered` is set. */
219
270
  partialRise?: string;
271
+ /** True when the INPUT came back instead of the output: a CC input to a venue
272
+ * that would not fill the trade (below its minimum) is handed back as CC —
273
+ * directly, to a wallet holding a CC preapproval — which the output watch
274
+ * cannot see. Detected from the CC balance standing back at its pre-send
275
+ * level (≥99% of the amount, from the second tick on), and it ends the wait
276
+ * early. A balance delta, not a per-transfer receipt: a concurrent inbound of
277
+ * the same size reads the same. Only watched for a CC input + token output. */
278
+ inputReturned: boolean;
220
279
  /** True when we waited but the output had not arrived by the end of the window. */
221
280
  timedOut: boolean;
222
281
  /** Relay read/claim errors survived during the wait. NOTHING thrown after the
@@ -1 +1 @@
1
- {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../src/swap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAO/D,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAElE;0EAC0E;AAC1E,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB;iFAC6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;uEAKmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,YAAY,EAAE,cAAc,CAAC;IAC7B,gDAAgD;IAChD,aAAa,EAAE,cAAc,CAAC;CAC/B;AAID;;;;;yCAKyC;AACzC,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAejE,CAAC;AAEF;0DAC0D;AAC1D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErE;AAED;;;;;;qDAMqD;AACrD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED;;;;;+EAK+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;CAChB;AAUD;;gDAEgD;AAChD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,EAAE,CAuBpE;AAED;;;2CAG2C;AAC3C,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,EAAE,EACvB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAapC;AAED;;;kEAGkE;AAClE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAmB3E;AAED;oEACoE;AACpE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAW1D;AAED;;0CAE0C;AAC1C,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,cAAc,CAAC;IAC7B,aAAa,EAAE,cAAc,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACrC,GAAG,OAAO,CAAC,UAAU,CAAC,CAoCtB;AAYD;gFACgF;AAChF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAiB7D;AAQD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE;IACN,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,cAAc,CAAC;IAC7B,aAAa,EAAE,cAAc,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;CACvB,GACA,IAAI,CAyBN;AAED;;;;;;0EAM0E;AAC1E,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACrC,2EAA2E;IAC3E,YAAY,EAAE,cAAc,CAAC;IAC7B,4EAA4E;IAC5E,aAAa,EAAE,cAAc,CAAC;IAC9B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,UAAU,CAAC,CAqBtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,sEAAsE;IACtE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB;;;+EAG2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;6CAKyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;2CAEuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,QAAQ,EAAE,OAAO,CAAC;IAClB;;iEAE6D;IAC7D,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAsI5E"}
1
+ {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../src/swap.ts"],"names":[],"mappings":"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"}