@ftptech/canton-agent-wallet 0.1.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.
Files changed (63) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +134 -0
  3. package/dist/canton-hash.d.ts +61 -0
  4. package/dist/canton-hash.d.ts.map +1 -0
  5. package/dist/canton-hash.js +108 -0
  6. package/dist/canton-hash.js.map +1 -0
  7. package/dist/cli-args.d.ts +31 -0
  8. package/dist/cli-args.d.ts.map +1 -0
  9. package/dist/cli-args.js +56 -0
  10. package/dist/cli-args.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +123 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/hash-binding.d.ts +40 -0
  16. package/dist/hash-binding.d.ts.map +1 -0
  17. package/dist/hash-binding.js +20 -0
  18. package/dist/hash-binding.js.map +1 -0
  19. package/dist/index.d.ts +13 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +13 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/keys.d.ts +26 -0
  24. package/dist/keys.d.ts.map +1 -0
  25. package/dist/keys.js +38 -0
  26. package/dist/keys.js.map +1 -0
  27. package/dist/onboard.d.ts +12 -0
  28. package/dist/onboard.d.ts.map +1 -0
  29. package/dist/onboard.js +152 -0
  30. package/dist/onboard.js.map +1 -0
  31. package/dist/pay.d.ts +16 -0
  32. package/dist/pay.d.ts.map +1 -0
  33. package/dist/pay.js +19 -0
  34. package/dist/pay.js.map +1 -0
  35. package/dist/relay-client.d.ts +128 -0
  36. package/dist/relay-client.d.ts.map +1 -0
  37. package/dist/relay-client.js +67 -0
  38. package/dist/relay-client.js.map +1 -0
  39. package/dist/relay-signer.d.ts +33 -0
  40. package/dist/relay-signer.d.ts.map +1 -0
  41. package/dist/relay-signer.js +44 -0
  42. package/dist/relay-signer.js.map +1 -0
  43. package/dist/store.d.ts +15 -0
  44. package/dist/store.d.ts.map +1 -0
  45. package/dist/store.js +33 -0
  46. package/dist/store.js.map +1 -0
  47. package/dist/trusted-dso.d.ts +33 -0
  48. package/dist/trusted-dso.d.ts.map +1 -0
  49. package/dist/trusted-dso.js +36 -0
  50. package/dist/trusted-dso.js.map +1 -0
  51. package/dist/tx.d.ts +102 -0
  52. package/dist/tx.d.ts.map +1 -0
  53. package/dist/tx.js +328 -0
  54. package/dist/tx.js.map +1 -0
  55. package/dist/verify-prepared.d.ts +361 -0
  56. package/dist/verify-prepared.d.ts.map +1 -0
  57. package/dist/verify-prepared.js +2235 -0
  58. package/dist/verify-prepared.js.map +1 -0
  59. package/dist/withdraw.d.ts +18 -0
  60. package/dist/withdraw.d.ts.map +1 -0
  61. package/dist/withdraw.js +31 -0
  62. package/dist/withdraw.js.map +1 -0
  63. package/package.json +33 -0
package/dist/tx.js ADDED
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Transfer primitives for the agent's self-custody wallet, all routed through
3
+ * the relay: resolve the factory / accept context (the agent has no Scan
4
+ * access), build the choice, sign the prepared-tx hash LOCALLY with the agent's
5
+ * key, execute via the relay. The relay only prepares + forwards; it can never
6
+ * sign, so it can never move the agent's funds.
7
+ */
8
+ import { signHashB64 } from "./keys.js";
9
+ import { resolveHashBinding } from "./hash-binding.js";
10
+ import { assertHashBinding, assertPreparedTransferMatches, assertPreparedCreateTransferCommandMatches, assertPreparedAcceptMatches, } from "./verify-prepared.js";
11
+ const TI_IFACE = "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferInstruction";
12
+ /**
13
+ * The instrument id the agent's self-custody wallet pays in: Canton Coin is the
14
+ * Splice "Amulet" instrument. This is CALLER INTENT — a fixed value the agent
15
+ * knows independently of the relay — so it can be used as a trust anchor when
16
+ * verifying the relay-prepared transfer. We deliberately do NOT anchor on the
17
+ * relay-resolved instrument ADMIN (the DSO party), because trusting a
18
+ * relay-supplied party as a whitelist is exactly the trust-boundary inversion a
19
+ * compromised relay would exploit. The recipient is pinned to caller intent and
20
+ * the instrument id to this constant; the admin is validated only positionally.
21
+ */
22
+ const EXPECTED_INSTRUMENT_ID = "Amulet";
23
+ function rid(prefix) {
24
+ return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
25
+ }
26
+ /**
27
+ * prepare (relay) → VERIFY → sign hash (local key) → execute (relay) → updateId.
28
+ *
29
+ * When `verify` is supplied (any command that MOVES the agent's funds), the
30
+ * EXACT `preparedTransaction` bytes that will be submitted to `execute` are
31
+ * structurally decoded and checked to encode exactly the intended
32
+ * sender/receiver/amount/(instrument|delegate) BEFORE the agent signs its hash,
33
+ * and the hash is bound to those same bytes. This is the self-custody guarantee:
34
+ * a compromised relay cannot get the agent to sign a command it did not author —
35
+ * any tamper either fails structural validation here, or (since the participant
36
+ * recomputes the hash from the submitted bytes on execute) produces a signature
37
+ * that the participant rejects. We fail closed: if validation or hash binding
38
+ * does not pass, we never sign. See `verify-prepared.ts`.
39
+ *
40
+ * SECURITY: `verify` is REQUIRED for EVERY path — no caller can reach
41
+ * `signHashB64` without a structural gate. The claim path (accepting incoming
42
+ * transfers) is NOT exempt: it passes `kind: "accept"`, which structurally
43
+ * proves the prepared transaction is a single `TransferInstruction_Accept`
44
+ * submitted by the agent and NOT a relay-injected outbound drain. `hashBinding`
45
+ * is likewise threaded on every path and enforced fail-closed.
46
+ */
47
+ async function prepareSignExecute(relay, wallet, commands, disclosedContracts, verify, hashBinding,
48
+ /** Caller-intent synchronizer id to PREPARE on. When supplied we send it in
49
+ * the prepare body so the relay cannot silently fill its own — and the verify
50
+ * arm pins the SIGNED Metadata.synchronizer_id to it. Omitted for the claim
51
+ * (funds-in) path, whose accept carries no caller-intent domain. */
52
+ synchronizerId) {
53
+ const prep = await relay.submitPrepare({
54
+ userId: "agent", // relay overrides with the participant (m2m) user
55
+ commandId: rid("agent"),
56
+ actAs: [wallet.party],
57
+ commands,
58
+ disclosedContracts,
59
+ packageIdSelectionPreference: [],
60
+ verboseHashing: false,
61
+ // Pin the synchronizer to caller intent so the relay cannot prepare on (and
62
+ // sign the agent onto) a domain of its choosing. The verify arm additionally
63
+ // asserts the SIGNED Metadata.synchronizer_id equals this.
64
+ ...(synchronizerId !== undefined ? { synchronizerId } : {}),
65
+ });
66
+ // Bind to the EXACT bytes we will submit (single source `prep`, no TOCTOU).
67
+ const preparedTransaction = prep.preparedTransaction;
68
+ // VERIFY-BEFORE-SIGN: never sign a relay-prepared command we didn't author.
69
+ // `verify` is required on EVERY path (transfer/createTransferCommand/accept),
70
+ // so there is no branch that reaches signHashB64 ungated.
71
+ if (verify.kind === "cip56") {
72
+ assertPreparedTransferMatches(preparedTransaction, verify.expect);
73
+ }
74
+ else if (verify.kind === "v1") {
75
+ assertPreparedCreateTransferCommandMatches(preparedTransaction, verify.expect);
76
+ }
77
+ else {
78
+ // claim path: structurally prove the prepared tx is a single inbound
79
+ // TransferInstruction_Accept by the agent, not an outbound drain.
80
+ assertPreparedAcceptMatches(preparedTransaction, verify.expect);
81
+ }
82
+ // Hash binding: prove the hash we are about to sign is the hash OF THE BYTES
83
+ // we just validated, not an opaque relay-chosen value. Without this a
84
+ // compromised relay can return honest bytes + the hash of a tampered tx and
85
+ // swap the bytes on the way to the participant. Fail closed: if the binding
86
+ // cannot be established (no recompute available and no explicit opt-in to
87
+ // trust the relay hash) we never sign. See verify-prepared.ts.
88
+ await assertHashBinding(preparedTransaction, prep.hash, hashBinding ?? {});
89
+ const signature = signHashB64(prep.hash, wallet.privateKeyPkcs8Pem);
90
+ const exec = await relay.submitExecute({
91
+ submissionId: rid("agent-exec"),
92
+ preparedTransaction,
93
+ hashingSchemeVersion: "HASHING_SCHEME_VERSION_V2",
94
+ partySignatures: {
95
+ signatures: [
96
+ {
97
+ party: wallet.party,
98
+ signatures: [
99
+ {
100
+ format: "SIGNATURE_FORMAT_CONCAT",
101
+ signature,
102
+ signingAlgorithmSpec: "SIGNING_ALGORITHM_SPEC_ED25519",
103
+ signedBy: wallet.publicKeyFingerprint,
104
+ },
105
+ ],
106
+ },
107
+ ],
108
+ },
109
+ deduplicationPeriod: { Empty: {} },
110
+ });
111
+ return exec.updateId;
112
+ }
113
+ /**
114
+ * Send CC from the agent to `receiver`. Returns the ledger updateId.
115
+ *
116
+ * `opts.expectInstrumentId` overrides the asset the verifier pins the prepared
117
+ * transfer to (defaults to Canton Coin / "Amulet"). It is CALLER INTENT, never
118
+ * taken from the relay.
119
+ */
120
+ export async function transfer(relay, wallet, opts) {
121
+ const bal = await relay.balance(wallet.party);
122
+ const inputHoldingCids = bal.holdings.map((h) => h.cid);
123
+ const f = await relay.resolveTransferFactory({
124
+ sender: wallet.party,
125
+ receiver: opts.receiver,
126
+ amount: opts.amount,
127
+ ...(opts.meta ? { meta: opts.meta } : {}),
128
+ });
129
+ const now = Date.now();
130
+ const ex = {
131
+ ExerciseCommand: {
132
+ templateId: f.transferFactoryTemplateId,
133
+ contractId: f.factoryId,
134
+ choice: "TransferFactory_Transfer",
135
+ choiceArgument: {
136
+ expectedAdmin: f.instrumentId.admin,
137
+ transfer: {
138
+ sender: wallet.party,
139
+ receiver: opts.receiver,
140
+ amount: opts.amount,
141
+ instrumentId: f.instrumentId,
142
+ requestedAt: new Date(now - 2000).toISOString(),
143
+ executeBefore: new Date(now + 600_000).toISOString(),
144
+ inputHoldingCids,
145
+ meta: { values: opts.meta ?? {} },
146
+ },
147
+ extraArgs: { context: f.choiceContextData, meta: { values: {} } },
148
+ },
149
+ },
150
+ };
151
+ return prepareSignExecute(relay, wallet, [ex], f.disclosedContracts, {
152
+ kind: "cip56",
153
+ expect: {
154
+ // Trust anchors are CALLER INTENT only — never the relay's resolve response:
155
+ sender: wallet.party,
156
+ receiver: opts.receiver,
157
+ amount: opts.amount,
158
+ instrumentId: opts.expectInstrumentId ?? EXPECTED_INSTRUMENT_ID,
159
+ // Pin the exercise's target to the SAME factory cid we built the command
160
+ // against, so a relay cannot resolve one factory to us then prepare the
161
+ // exercise against another (resolve→prepare TOCTOU). Defense-in-depth on
162
+ // top of the all-nodes party backstop.
163
+ expectedContractId: f.factoryId,
164
+ // Optional caller-intent pins (off by default — the agent has no out-of-
165
+ // band DSO/domain in the base CC flow): the SIGNED synchronizer_id and
166
+ // the instrument admin (DSO). When supplied they close the relay-chosen-
167
+ // domain and unpinned-admin neutralization fully; always sanity-bound the
168
+ // SIGNED timing metadata via nowMs.
169
+ ...(opts.expectSynchronizerId !== undefined
170
+ ? { synchronizerId: opts.expectSynchronizerId }
171
+ : {}),
172
+ ...(opts.expectInstrumentAdmin !== undefined
173
+ ? { instrumentAdmin: opts.expectInstrumentAdmin }
174
+ : {}),
175
+ nowMs: Date.now(),
176
+ },
177
+ }, opts.hashBinding, opts.expectSynchronizerId);
178
+ }
179
+ /**
180
+ * v1 (external-party-amulet-rules) — create a Splice `TransferCommand` the
181
+ * facilitator will later settle (it pays the GS traffic fee). The agent signs
182
+ * only an INTENT here: no gas, no preapproval. Mirrors the cip56 `transfer`
183
+ * flow — resolve refs via relay → build the create exercise → VERIFY-before-sign
184
+ * over the EXACT prepared bytes → sign locally → execute via relay → read back
185
+ * the created cid (ACS-polled by the relay) — but produces the v1 payload the
186
+ * x402 client puts in PaymentPayload: `{transferCommandCid, payerParty, nonce}`.
187
+ *
188
+ * SECURITY: every money-critical field the verifier pins (sender == own party,
189
+ * receiver == merchant payTo, amount == required, delegate == facilitatorParty)
190
+ * is CALLER INTENT passed in `opts`, NOT taken from the relay's resolve
191
+ * response. The relay-resolved EPAR/exercise templateIds + expectedDso are used
192
+ * only to BUILD the exercise; they widen nothing the agent will sign. The cid
193
+ * returned by the relay moves no funds on its own — the facilitator independently
194
+ * re-validates sender/receiver/amount/delegate/nonce at /verify + /settle.
195
+ */
196
+ export async function createTransferCommand(relay, wallet, opts) {
197
+ // Resolve the v1 ledger refs (EPAR disclosed + exercise templateId +
198
+ // expectedDso + the agent's next nonce). NONE of these is a verify trust
199
+ // anchor — the verifier pins sender/receiver/amount/delegate to caller intent.
200
+ const r = await relay.resolveTransferCommand({ payerParty: wallet.party });
201
+ // The agent pins the DELEGATE to its OWN intent (the 402's facilitatorParty),
202
+ // not the relay's `r.delegate`. If the relay disagrees with caller intent,
203
+ // fail fast BEFORE building/prepare rather than silently using the relay's.
204
+ if (r.delegate !== opts.delegate) {
205
+ throw new Error(`relay resolve/transfer-command returned delegate ${JSON.stringify(r.delegate)} ` +
206
+ `but caller intent (extra.facilitatorParty) is ${JSON.stringify(opts.delegate)} — ` +
207
+ `refusing to build a TransferCommand with a relay-chosen delegate`);
208
+ }
209
+ // Likewise pin the synchronizer to caller intent.
210
+ if (r.synchronizerId !== opts.synchronizerId) {
211
+ throw new Error(`relay resolve/transfer-command returned synchronizerId ${JSON.stringify(r.synchronizerId)} ` +
212
+ `but caller intent (extra.synchronizerId) is ${JSON.stringify(opts.synchronizerId)} — ` +
213
+ `refusing to prepare on a relay-chosen synchronizer`);
214
+ }
215
+ const nonceStr = r.nextNonce;
216
+ const expiresAtMs = opts.expiresAtMs ?? Date.now() + 60_000;
217
+ const expiresAt = new Date(expiresAtMs).toISOString();
218
+ // Build the CreateTransferCommand exercise. Choice argument shape + the
219
+ // EPAR-only disclosure mirror the PROVEN KeyfileSigner v1 flow exactly. The
220
+ // exercise targets the resolved current-package templateId; the disclosed
221
+ // contract carries the EPAR's OWN templateId (must match its blob's package).
222
+ const ex = {
223
+ ExerciseCommand: {
224
+ templateId: r.exerciseTemplateId,
225
+ contractId: r.externalPartyAmuletRules.contractId,
226
+ choice: "ExternalPartyAmuletRules_CreateTransferCommand",
227
+ choiceArgument: {
228
+ sender: wallet.party,
229
+ receiver: opts.receiver,
230
+ delegate: opts.delegate,
231
+ amount: opts.amount,
232
+ expiresAt,
233
+ nonce: nonceStr,
234
+ description: opts.description,
235
+ expectedDso: r.expectedDso,
236
+ },
237
+ },
238
+ };
239
+ const disclosedContracts = [
240
+ {
241
+ templateId: r.externalPartyAmuletRules.templateId,
242
+ contractId: r.externalPartyAmuletRules.contractId,
243
+ createdEventBlob: r.externalPartyAmuletRules.createdEventBlob,
244
+ synchronizerId: opts.synchronizerId,
245
+ },
246
+ ];
247
+ // prepare → VERIFY-before-sign (v1 arm) → sign locally → execute. The verifier
248
+ // asserts the EXACT prepared bytes encode sender==own, receiver==payTo,
249
+ // amount==required, delegate==facilitator, nonce==expected; fail-closed.
250
+ const createUpdateId = await prepareSignExecute(relay, wallet, [ex], disclosedContracts, {
251
+ kind: "v1",
252
+ expect: {
253
+ sender: wallet.party,
254
+ receiver: opts.receiver,
255
+ amount: opts.amount,
256
+ delegate: opts.delegate,
257
+ nonce: nonceStr,
258
+ // Pin the exercise target to the SAME EPAR cid we built against (the one
259
+ // the relay resolved), so a relay cannot resolve one EPAR to us then
260
+ // prepare against another (resolve→prepare TOCTOU). Defense-in-depth on
261
+ // top of the all-nodes party backstop.
262
+ expectedContractId: r.externalPartyAmuletRules.contractId,
263
+ // Pin the SIGNED Metadata.synchronizer_id to caller intent (the merchant-
264
+ // advertised domain). The relay PREPAREs with the synchronizer it chooses
265
+ // and embeds it into the signed Metadata; without this pin the agent would
266
+ // blind-sign a relay-chosen domain even though the v1 resolve-response
267
+ // synchronizer was cross-checked (a claim-vs-signed-bytes divergence).
268
+ synchronizerId: opts.synchronizerId,
269
+ // Optional out-of-band DSO pin (off by default; never the relay's value).
270
+ ...(opts.expectedDso !== undefined ? { expectedDso: opts.expectedDso } : {}),
271
+ nowMs: Date.now(),
272
+ },
273
+ }, opts.hashBinding, opts.synchronizerId);
274
+ // interactive execute is ASYNC — the create commits after execute returns. The
275
+ // agent is relay-only (no ledger/ACS access), so the relay ACS-polls the
276
+ // payer's TransferCommand at this (sender, nonce) and returns the cid. The cid
277
+ // alone moves no funds; the facilitator re-validates every field at settle.
278
+ const cidRes = await relay.transferCommandCid(wallet.party, nonceStr);
279
+ // Nonce as a number for the x402 v1 payload (CantonPaymentPayload.nonce: number).
280
+ // Counters in practice stay well within Number.MAX_SAFE_INTEGER.
281
+ return {
282
+ transferCommandCid: cidRes.transferCommandCid,
283
+ payerParty: wallet.party,
284
+ nonce: Number(nonceStr),
285
+ // The CreateTransferCommand execute updateId (burn #1, submitted via OUR
286
+ // node). Surfaced into the x402 v1 payload so the facilitator /settle links
287
+ // it to the Send burn (#2) for the Create+Send traffic attribution (PR #22).
288
+ createUpdateId,
289
+ };
290
+ }
291
+ /**
292
+ * Accept every pending incoming transfer (e.g. the agent's initial funding).
293
+ *
294
+ * SECURITY: even though this path is funds-IN, it is NOT exempt from
295
+ * verify-before-sign. A malicious relay returning an OUTBOUND drain
296
+ * (CreateTransferCommand / TransferFactory_Transfer sending the agent's balance
297
+ * to an attacker) instead of the accept the agent built would otherwise be
298
+ * blind-signed. We pass `kind: "accept"`, which structurally proves the prepared
299
+ * transaction is a single `TransferInstruction_Accept` submitted by the agent —
300
+ * any outbound leg is rejected — and we bind the signed hash to those bytes
301
+ * (fail-closed by default, exactly like the other paths). `opts.hashBinding`
302
+ * lets a programmatic caller supply a participant-conformant recompute; the CLI
303
+ * resolves it from the environment (default fail-closed).
304
+ */
305
+ export async function claimAll(relay, wallet, opts = {}) {
306
+ const hashBinding = opts.hashBinding ?? resolveHashBinding();
307
+ const { pending } = await relay.pending(wallet.party);
308
+ const updateIds = [];
309
+ for (const p of pending) {
310
+ const ctx = await relay.resolveAccept({ instructionCid: p.cid });
311
+ const ex = {
312
+ ExerciseCommand: {
313
+ templateId: TI_IFACE,
314
+ contractId: p.cid,
315
+ choice: "TransferInstruction_Accept",
316
+ choiceArgument: {
317
+ extraArgs: { context: ctx.choiceContextData, meta: { values: {} } },
318
+ },
319
+ },
320
+ };
321
+ updateIds.push(await prepareSignExecute(relay, wallet, [ex], ctx.disclosedContracts,
322
+ // VERIFY-before-sign: the prepared tx MUST be a single inbound accept by
323
+ // the agent — never a relay-injected outbound drain.
324
+ { kind: "accept", expect: { selfParty: wallet.party, nowMs: Date.now() } }, hashBinding));
325
+ }
326
+ return { claimed: pending.length, updateIds };
327
+ }
328
+ //# sourceMappingURL=tx.js.map
package/dist/tx.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tx.js","sourceRoot":"","sources":["../src/tx.ts"],"names":[],"mappings":"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"}