@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.
@@ -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
- "auth0_007c6643538f2eadd3e573dd05b9::12205bcc106efa0eaa7f18dc491e5c6f5fb9b0cc68dc110ae66f4ed6467475d7c78e",
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":"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"}
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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"}