@ftptech/canton-agent-wallet 1.1.0 → 1.3.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.
- package/dist/cli-args.d.ts.map +1 -1
- package/dist/cli-args.js +6 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +173 -4
- package/dist/cli.js.map +1 -1
- package/dist/pay.d.ts +26 -1
- package/dist/pay.d.ts.map +1 -1
- package/dist/pay.js +45 -4
- package/dist/pay.js.map +1 -1
- package/dist/registry-parties.d.ts +36 -7
- package/dist/registry-parties.d.ts.map +1 -1
- package/dist/registry-parties.js +69 -1
- package/dist/registry-parties.js.map +1 -1
- package/dist/swap.d.ts +204 -0
- package/dist/swap.d.ts.map +1 -0
- package/dist/swap.js +360 -0
- package/dist/swap.js.map +1 -0
- package/dist/tx.d.ts +5 -0
- package/dist/tx.d.ts.map +1 -1
- package/dist/tx.js +1 -0
- package/dist/tx.js.map +1 -1
- package/dist/withdraw.d.ts +10 -0
- package/dist/withdraw.d.ts.map +1 -1
- package/dist/withdraw.js +2 -0
- package/dist/withdraw.js.map +1 -1
- package/package.json +3 -3
package/dist/registry-parties.js
CHANGED
|
@@ -36,14 +36,82 @@ export const REGISTRY_TRUSTED_PARTIES_ENV = "CANTON_AGENT_REGISTRY_TRUSTED_PARTI
|
|
|
36
36
|
* the xReserve Bridge-Operator, both confirmed on a live MainNet USDCx
|
|
37
37
|
* `TransferFactory_Transfer`.
|
|
38
38
|
*/
|
|
39
|
+
/** DA Registry Utility operator, shared by EVERY instrument the utility hosts
|
|
40
|
+
* (verified live at /api/utilities/v0/operator — identical for USDCx, CBTC,
|
|
41
|
+
* USDXLR, cETH). It appears on every DA-Utility `TransferFactory_Transfer`. */
|
|
42
|
+
const DA_UTILITY_OPERATOR = "auth0_007c6643538f2eadd3e573dd05b9::12205bcc106efa0eaa7f18dc491e5c6f5fb9b0cc68dc110ae66f4ed6467475d7c78e";
|
|
39
43
|
export const KNOWN_REGISTRY_TRUSTED_PARTIES = {
|
|
40
44
|
"decentralized-usdc-interchain-rep::12208115f1e168dd7e792320be9c4ca720c751a02a3053c7606e1c1cd3dad9bf60ef": [
|
|
41
45
|
// DA Registry Utility operator (from /api/utilities/v0/operator).
|
|
42
|
-
|
|
46
|
+
DA_UTILITY_OPERATOR,
|
|
43
47
|
// xReserve Bridge-Operator (mints/burns USDCx; signatory on the holding).
|
|
44
48
|
"Bridge-Operator::1220c8448890a70e65f6906bd48d797ee6551f094e9e6a53e329fd5b2b549334f13f",
|
|
45
49
|
],
|
|
50
|
+
// CBTC (BitSafe), USDXLR (Excellar), cETH (onRails) — all DA Registry Utility
|
|
51
|
+
// instruments, so each carries the shared operator above. A token-specific infra
|
|
52
|
+
// party is added when its transfers reference one: CBTC declares a fee/config
|
|
53
|
+
// "cbtc-beneficiary" party in its registrar-authored InstrumentConfiguration
|
|
54
|
+
// (verified: it appears only in the authenticated InstrumentConfiguration input
|
|
55
|
+
// contract — never as a value owner or recipient — so a relay cannot forge it).
|
|
56
|
+
// cETH instead uses per-user parties minted UNDER ITS OWN NAMESPACE, which are
|
|
57
|
+
// trusted generically by the same-namespace rule in @ftptech/x402-canton-core's
|
|
58
|
+
// foreign-party backstop, so none need listing here.
|
|
59
|
+
"cbtc-network::12205af3b949a04776fc48cdcc05a060f6bda2e470632935f375d1049a8546a3b262": [
|
|
60
|
+
DA_UTILITY_OPERATOR,
|
|
61
|
+
// CBTC beneficiary declared in the registrar's InstrumentConfiguration.
|
|
62
|
+
"cbtc-beneficiary::1220409a9fcc5ff6422e29ab978c22c004dde33202546b4bcbde24b25b85353366c2",
|
|
63
|
+
],
|
|
64
|
+
"excellar-issuer::12203d1e36930ee0e3fbb898add7e222a47ae9d2a5f0f6187e3a446ea32f871ce2ca": [DA_UTILITY_OPERATOR],
|
|
65
|
+
"rails-cethMain-1::12200350ba6e96e3b701c3048b5aa013a8c1c08833e8ebf54339cff581055c29003a": [DA_UTILITY_OPERATOR],
|
|
66
|
+
"ember-silver::1220ad9c097ae75192b4716854fa413aa8582c86a62b16714663cdab55e025cc79c4": [DA_UTILITY_OPERATOR],
|
|
67
|
+
"ember-gold::1220ad9c097ae75192b4716854fa413aa8582c86a62b16714663cdab55e025cc79c4": [DA_UTILITY_OPERATOR],
|
|
68
|
+
};
|
|
69
|
+
/** MainNet symbol → {admin, id} for the DA Registry Utility instruments this
|
|
70
|
+
* wallet knows out of the box (all `decimals: 10`). Canton Coin is NOT here —
|
|
71
|
+
* it is the native Amulet, named by omitting an instrument. Used by `swap` to
|
|
72
|
+
* resolve `--in USDCx` locally; the fee-ticket path (facilitator /swap) carries
|
|
73
|
+
* its own resolved instruments, which take precedence on DevNet/other networks. */
|
|
74
|
+
export const KNOWN_INSTRUMENTS = {
|
|
75
|
+
USDCx: {
|
|
76
|
+
admin: "decentralized-usdc-interchain-rep::12208115f1e168dd7e792320be9c4ca720c751a02a3053c7606e1c1cd3dad9bf60ef",
|
|
77
|
+
id: "USDCx",
|
|
78
|
+
},
|
|
79
|
+
CBTC: {
|
|
80
|
+
admin: "cbtc-network::12205af3b949a04776fc48cdcc05a060f6bda2e470632935f375d1049a8546a3b262",
|
|
81
|
+
id: "CBTC",
|
|
82
|
+
},
|
|
83
|
+
USDXLR: {
|
|
84
|
+
admin: "excellar-issuer::12203d1e36930ee0e3fbb898add7e222a47ae9d2a5f0f6187e3a446ea32f871ce2ca",
|
|
85
|
+
id: "USDXLR",
|
|
86
|
+
},
|
|
87
|
+
cETH: {
|
|
88
|
+
admin: "rails-cethMain-1::12200350ba6e96e3b701c3048b5aa013a8c1c08833e8ebf54339cff581055c29003a",
|
|
89
|
+
id: "cETH",
|
|
90
|
+
},
|
|
91
|
+
// Ember tokenized metals (eXAG = silver, eXAU = gold), both DA Registry Utility
|
|
92
|
+
// instruments (live metadata resolves, decimals 10) — same shared packages, no new
|
|
93
|
+
// DARs to receive; ids verified from Tradecraft's /v1/tokenB and the DA Utility.
|
|
94
|
+
eXAG: {
|
|
95
|
+
admin: "ember-silver::1220ad9c097ae75192b4716854fa413aa8582c86a62b16714663cdab55e025cc79c4",
|
|
96
|
+
id: "eXAG",
|
|
97
|
+
},
|
|
98
|
+
eXAU: {
|
|
99
|
+
admin: "ember-gold::1220ad9c097ae75192b4716854fa413aa8582c86a62b16714663cdab55e025cc79c4",
|
|
100
|
+
id: "eXAU",
|
|
101
|
+
},
|
|
46
102
|
};
|
|
103
|
+
export function resolveSwapSymbol(symbol) {
|
|
104
|
+
const s = symbol.trim().toLowerCase();
|
|
105
|
+
if (s === "cc" || s === "canton-coin" || s === "amulet") {
|
|
106
|
+
return { kind: "cc", symbol: "CC" };
|
|
107
|
+
}
|
|
108
|
+
for (const [sym, instrument] of Object.entries(KNOWN_INSTRUMENTS)) {
|
|
109
|
+
if (sym.toLowerCase() === s) {
|
|
110
|
+
return { kind: "registry", symbol: sym, instrument };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return { kind: "unknown" };
|
|
114
|
+
}
|
|
47
115
|
/** Parse the env JSON (admin → party[]) fail-closed to `{}` on any malformation. */
|
|
48
116
|
function parseEnvTrustedParties(raw) {
|
|
49
117
|
if (!raw || raw.trim().length === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-parties.js","sourceRoot":"","sources":["../src/registry-parties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,4BAA4B,GAAG,uCAAuC,CAAC;AAEpF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAEvC;IACF,yGAAyG,EACvG;QACE,kEAAkE;QAClE,
|
|
1
|
+
{"version":3,"file":"registry-parties.js","sourceRoot":"","sources":["../src/registry-parties.ts"],"names":[],"mappings":"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"}
|
package/dist/swap.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* swap — a self-custody swap primitive over Tradecraft (an AMM DEX on Canton).
|
|
3
|
+
* A Tradecraft swap is just an on-ledger transfer of the input token to a
|
|
4
|
+
* per-pair pool party (`tc-swp_{IN}-{OUT}::<amm_cid>`); the pool sends the
|
|
5
|
+
* counter-asset back within a minute or two, as a transfer OFFER when the output
|
|
6
|
+
* is not pre-approved (which `claimAll` accepts) or DIRECTLY when it is.
|
|
7
|
+
*
|
|
8
|
+
* SAFETY MODEL (what actually holds):
|
|
9
|
+
* - The recipient is ALWAYS a pool party derived from a trusted `amm_cid`
|
|
10
|
+
* (config/constant), never a client- or 402-supplied address. This is the one
|
|
11
|
+
* unconditional guarantee.
|
|
12
|
+
* - Slippage protection is OPTIONAL: Tradecraft reads the minimum from the
|
|
13
|
+
* transfer's memo field, so it is attached only when a memo key is configured
|
|
14
|
+
* (`ticket.memoKey`, from CANTON_AGENT_TRADECRAFT_MEMO_KEY). With NO key the
|
|
15
|
+
* swap fills at MARKET price — the proven bare flow — and `swap` warns.
|
|
16
|
+
* - Output preapproval is OPT-IN (`preapproveOutput`, `--preapprove`): default is
|
|
17
|
+
* the offer/claim path. Tradecraft's docs note the hazard that on a DIRECT
|
|
18
|
+
* settlement an un-preapproved output can be "consumed on fill with no funds
|
|
19
|
+
* returned"; the default path avoids direct settlement by not pre-approving, so
|
|
20
|
+
* the return arrives as a claimable offer instead. An unfilled trade returns
|
|
21
|
+
* the input either way.
|
|
22
|
+
*/
|
|
23
|
+
import { RelayClient } from "./relay-client.js";
|
|
24
|
+
import { type AgentWallet } from "./store.js";
|
|
25
|
+
import type { HashBindingOptions } from "./verify-prepared.js";
|
|
26
|
+
/** A registry instrument, or `null` for native Canton Coin. */
|
|
27
|
+
export type SwapInstrument = {
|
|
28
|
+
admin: string;
|
|
29
|
+
id: string;
|
|
30
|
+
} | null;
|
|
31
|
+
/** Everything needed to execute one swap, resolved up front (locally, or by the
|
|
32
|
+
* facilitator /swap fee-ticket which knows the network's registrars). */
|
|
33
|
+
export interface SwapTicket {
|
|
34
|
+
/** The pool party to send the input to: `tc-swp_{IN}-{OUT}::<amm_cid>`. */
|
|
35
|
+
poolParty: string;
|
|
36
|
+
/** Slippage-protected minimum output, as a ledger decimal string. Always
|
|
37
|
+
* computed for display; only ENFORCED when `memoKey` is set (see below). */
|
|
38
|
+
minOutput: string;
|
|
39
|
+
/** The transfer-meta key Tradecraft reads the minimum from ("the memo field").
|
|
40
|
+
* When set, the minimum is attached to the input transfer and the pool honors
|
|
41
|
+
* it (below-minimum → the trade fails and the input returns). When UNDEFINED,
|
|
42
|
+
* the swap executes at market price with no slippage protection — exactly the
|
|
43
|
+
* bare "send to the pool" flow, which works. Tradecraft's docs: the minimum is
|
|
44
|
+
* the first text in the memo field, a decimal with ≤10 places. */
|
|
45
|
+
memoKey?: string;
|
|
46
|
+
/** The raw quote (estimated output) that produced `minOutput`. */
|
|
47
|
+
quote: string;
|
|
48
|
+
/** The instrument being sent in (null = CC). */
|
|
49
|
+
inInstrument: SwapInstrument;
|
|
50
|
+
/** The instrument expected back (null = CC). */
|
|
51
|
+
outInstrument: SwapInstrument;
|
|
52
|
+
}
|
|
53
|
+
/** Per-input-token advisory minimums, mirrored from the Tradecraft web app (there
|
|
54
|
+
* is NO API endpoint for these — they are a hardcoded frontend constant). A trade
|
|
55
|
+
* below the minimum is ADVISORY only: the pool safely returns the funds if it will
|
|
56
|
+
* not fill (no loss), and amounts slightly under still often fill. `swap` warns
|
|
57
|
+
* when the amount is under the listed minimum but does not block. Symbols not
|
|
58
|
+
* listed have no advertised minimum. */
|
|
59
|
+
export declare const TRADECRAFT_MIN_INPUT: Readonly<Record<string, number>>;
|
|
60
|
+
/** The advisory minimum input for `symbol` (canonical), or undefined if none is
|
|
61
|
+
* advertised. Case-sensitive on the canonical symbol. */
|
|
62
|
+
export declare function tradecraftMinInput(symbol: string): number | undefined;
|
|
63
|
+
/** Derive the Tradecraft pool party for a pair: `tc-swp_{TOKEN1}-{TOKEN2}::<ammCid>`.
|
|
64
|
+
* `token1`/`token2` MUST be in the pool's CANONICAL order (as listed by /pools),
|
|
65
|
+
* NOT the swap direction: Tradecraft has one pool party per pair that accepts
|
|
66
|
+
* either token and returns the other, so `tc-swp_CC-USDCx` serves both CC→USDCx
|
|
67
|
+
* and USDCx→CC. Deriving from the swap direction (`{in}-{out}`) yields a
|
|
68
|
+
* non-existent party for one of the two directions. The amm_cid is a single
|
|
69
|
+
* AMM-rules contract shared by every pair. Pure. */
|
|
70
|
+
export declare function derivePoolParty(token1: string, token2: string, ammCid: string): string;
|
|
71
|
+
/** One pool row from Tradecraft `/v1/pools`, reduced to what a swap needs: the
|
|
72
|
+
* pair in the pool party's CANONICAL order. That order is the one in
|
|
73
|
+
* `lp_token_name` ("TC {TOKEN1}-{TOKEN2} LP"), which is what the on-ledger pool
|
|
74
|
+
* party `tc-swp_{TOKEN1}-{TOKEN2}::<ammCid>` uses — NOT the row's `token1`/`token2`
|
|
75
|
+
* fields, which are ordered differently for 9 of 34 live pools (e.g. the CBTC/CC
|
|
76
|
+
* pool lists token1=CC,token2=CBTC but its party and LP name are CBTC-CC). */
|
|
77
|
+
export interface TradecraftPool {
|
|
78
|
+
/** First symbol of the pool party, from lp_token_name. */
|
|
79
|
+
token1: string;
|
|
80
|
+
/** Second symbol of the pool party, from lp_token_name. */
|
|
81
|
+
token2: string;
|
|
82
|
+
}
|
|
83
|
+
/** Parse `/v1/pools` into rows carrying each pool's CANONICAL pair order (from
|
|
84
|
+
* `lp_token_name`, falling back to `token1`/`token2`). Tolerates a bare array or
|
|
85
|
+
* `{pools:[…]}`. Exported for unit testing. */
|
|
86
|
+
export declare function parseTradecraftPools(body: unknown): TradecraftPool[];
|
|
87
|
+
/** Find the pool whose pair equals {a, b} (case-insensitive, unordered) and
|
|
88
|
+
* return its CANONICAL token order (the pool party's order). Throws when no such
|
|
89
|
+
* pool exists — exactly the "send to a non-existent pool party" mistake we must
|
|
90
|
+
* not make. Exported for unit testing. */
|
|
91
|
+
export declare function resolvePoolPair(pools: TradecraftPool[], a: string, b: string): {
|
|
92
|
+
token1: string;
|
|
93
|
+
token2: string;
|
|
94
|
+
};
|
|
95
|
+
/** Slippage-protected minimum output: `quote * (1 - slippagePct/100)`, floored to
|
|
96
|
+
* 10 decimals (every DA-Utility instrument and Canton Coin use 10). Floored, not
|
|
97
|
+
* rounded — the minimum must never sit ABOVE the true floor, or an honest fill
|
|
98
|
+
* could be rejected. `slippagePct` must be in [0, 100). Pure. */
|
|
99
|
+
export declare function computeMinOutput(quote: number, slippagePct: number): string;
|
|
100
|
+
/** Parse Tradecraft's `/v1/quoteForFixedInput/{IN}/{OUT}?givingAmount=N` →
|
|
101
|
+
* `{ user_gets: number }`. Exported for unit testing the shape. */
|
|
102
|
+
export declare function parseTradecraftQuote(body: unknown): number;
|
|
103
|
+
/** Fetch a live quote from Tradecraft's public REST and build a ticket locally
|
|
104
|
+
* (the `--no-fee` / test path). The fee path gets its ticket from the
|
|
105
|
+
* facilitator /swap endpoint instead. */
|
|
106
|
+
export declare function buildLocalTicket(opts: {
|
|
107
|
+
tradecraftApi: string;
|
|
108
|
+
ammCid: string;
|
|
109
|
+
/** The memo key that enforces the minimum; omit to swap at market. */
|
|
110
|
+
memoKey?: string;
|
|
111
|
+
inSymbol: string;
|
|
112
|
+
outSymbol: string;
|
|
113
|
+
amount: string;
|
|
114
|
+
slippagePct: number;
|
|
115
|
+
inInstrument: SwapInstrument;
|
|
116
|
+
outInstrument: SwapInstrument;
|
|
117
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
118
|
+
}): Promise<SwapTicket>;
|
|
119
|
+
/** Parse a swap-endpoint ticket response into a SwapTicket, validating the fields
|
|
120
|
+
* the local execute path relies on. Extra fields (e.g. ammCid) are ignored. */
|
|
121
|
+
export declare function parseEndpointTicket(body: unknown): SwapTicket;
|
|
122
|
+
/**
|
|
123
|
+
* Validate an endpoint-returned ticket against LOCALLY-TRUSTED values before it is
|
|
124
|
+
* ever executed. The swap endpoint is UNTRUSTED for money safety: the ticket's
|
|
125
|
+
* `poolParty` becomes the transfer receiver and its instruments become the assets
|
|
126
|
+
* moved, and verify-before-sign only pins those to caller INTENT — so if intent
|
|
127
|
+
* came from the endpoint unchecked, a malicious/compromised endpoint could name an
|
|
128
|
+
* attacker party and drain the swap amount. We therefore pin, client-side:
|
|
129
|
+
* - `poolParty` MUST be `tc-swp_{A}-{B}::<trustedAmmCid>` for the two canonical
|
|
130
|
+
* symbols the caller chose (either pair order) — its namespace equals our own
|
|
131
|
+
* trusted amm_cid, which a hostile endpoint cannot forge, and its localpart is
|
|
132
|
+
* the Tradecraft pool naming for exactly this pair;
|
|
133
|
+
* - the in/out instruments MUST equal the ones the caller resolved locally from
|
|
134
|
+
* KNOWN_INSTRUMENTS.
|
|
135
|
+
* The endpoint is then trusted ONLY for the price/minimum (a bad one loses at most
|
|
136
|
+
* a bad fill, which returns the input) — never for where the funds go.
|
|
137
|
+
*/
|
|
138
|
+
export declare function assertTicketMatchesIntent(ticket: SwapTicket, expect: {
|
|
139
|
+
inCanon: string;
|
|
140
|
+
outCanon: string;
|
|
141
|
+
inInstrument: SwapInstrument;
|
|
142
|
+
outInstrument: SwapInstrument;
|
|
143
|
+
trustedAmmCid: string;
|
|
144
|
+
}): void;
|
|
145
|
+
/** Fetch a swap ticket from OUR x402-gated `/swap` endpoint (the default path): the
|
|
146
|
+
* managed router that stays current with Tradecraft's pools/amm_cid/minimums and
|
|
147
|
+
* charges a small fee. `payingFetch` is a `makePayingFetch` result, so the 402 is
|
|
148
|
+
* paid automatically from the agent's wallet. The endpoint is UNTRUSTED for money
|
|
149
|
+
* safety — the returned ticket is validated against the caller's locally-trusted
|
|
150
|
+
* amm_cid + instruments (see assertTicketMatchesIntent) before it is returned, so
|
|
151
|
+
* a hostile endpoint can only give a bad price, never redirect funds. */
|
|
152
|
+
export declare function fetchTicketFromEndpoint(opts: {
|
|
153
|
+
swapUrl: string;
|
|
154
|
+
inSymbol: string;
|
|
155
|
+
outSymbol: string;
|
|
156
|
+
amount: string;
|
|
157
|
+
slippagePct: number;
|
|
158
|
+
payingFetch: typeof globalThis.fetch;
|
|
159
|
+
/** Locally-resolved input instrument (null = CC) the ticket MUST match. */
|
|
160
|
+
inInstrument: SwapInstrument;
|
|
161
|
+
/** Locally-resolved output instrument (null = CC) the ticket MUST match. */
|
|
162
|
+
outInstrument: SwapInstrument;
|
|
163
|
+
/** The caller's OWN trusted amm_cid the pool party MUST derive from. */
|
|
164
|
+
trustedAmmCid: string;
|
|
165
|
+
}): Promise<SwapTicket>;
|
|
166
|
+
export interface ExecuteSwapOpts {
|
|
167
|
+
amount: string;
|
|
168
|
+
ticket: SwapTicket;
|
|
169
|
+
apiKey?: string | undefined;
|
|
170
|
+
hashBinding?: HashBindingOptions;
|
|
171
|
+
wallet?: AgentWallet;
|
|
172
|
+
relay?: RelayClient;
|
|
173
|
+
/**
|
|
174
|
+
* Self-provision a TransferPreapproval for the OUTPUT instrument before sending
|
|
175
|
+
* the input, so the pool can deliver the counter-asset DIRECTLY. This is
|
|
176
|
+
* REQUIRED for a registry output: a Tradecraft pool holds no preapproval for the
|
|
177
|
+
* payer and does not create a return offer, so without our preapproval the pool
|
|
178
|
+
* keeps the swapped-out asset (the trade does not complete on our side). Defaults
|
|
179
|
+
* to ON for a registry output (`outInstrument` set) and is a no-op for a CC
|
|
180
|
+
* output (Amulet needs none). Set false only to skip it deliberately (e.g. the
|
|
181
|
+
* preapproval already exists, or a test).
|
|
182
|
+
*/
|
|
183
|
+
preapproveOutput?: boolean;
|
|
184
|
+
/** Injectable sleep + poll bounds for the return-claim (tests). */
|
|
185
|
+
sleep?: (ms: number) => Promise<void>;
|
|
186
|
+
claimAttempts?: number;
|
|
187
|
+
claimIntervalMs?: number;
|
|
188
|
+
}
|
|
189
|
+
export interface SwapResult {
|
|
190
|
+
/** updateId of the input transfer we sent to the pool. */
|
|
191
|
+
sentUpdateId: string;
|
|
192
|
+
/** How many returning transfers we claimed (0 if the pool settled directly to
|
|
193
|
+
* our preapproval, or if it has not arrived within the poll window). */
|
|
194
|
+
claimed: number;
|
|
195
|
+
claimedUpdateIds: string[];
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Execute a swap from a resolved ticket: (1) pre-approve the output instrument so
|
|
199
|
+
* the pool's return can never be a consumed-input-no-return loss, (2) send the
|
|
200
|
+
* input to the pool with the minimum in meta, (3) claim the returning transfer if
|
|
201
|
+
* it arrives as an offer rather than settling directly.
|
|
202
|
+
*/
|
|
203
|
+
export declare function executeSwap(opts: ExecuteSwapOpts): Promise<SwapResult>;
|
|
204
|
+
//# sourceMappingURL=swap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../src/swap.ts"],"names":[],"mappings":"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"}
|