@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
@@ -0,0 +1,361 @@
1
+ interface DecodedExercise {
2
+ choiceId: string;
3
+ chosenValue: Uint8Array;
4
+ /** The exercised contract id (Exercise.contract_id, field 2), UTF-8 decoded.
5
+ * Pinned by the arms ONLY when the caller supplies an expected value
6
+ * (defense-in-depth: closes the resolve→prepare TOCTOU where a relay points
7
+ * the choice at a contract other than the one it resolved to the agent).
8
+ * undefined if the node carried no decodable contract_id. */
9
+ contractId?: string | undefined;
10
+ /** The exercised contract's template, as a `module:entity` qualified name (the
11
+ * package id is dropped because it changes across package upgrades). Used to
12
+ * pin WHICH template the validated choice runs against, so a relay cannot
13
+ * point a same-named choice at a confusable/attacker template. undefined if
14
+ * the node carried no decodable template_id. */
15
+ templateQualifiedName?: string | undefined;
16
+ }
17
+ /** The recognized `transaction.v1.Node` node-type oneof members. Anything not
18
+ * in this set is treated as PRESENT-AND-UNVALIDATED (reject), never skipped. */
19
+ type NodeKind = "create" | "fetch" | "exercise" | "rollback" | "query_by_key";
20
+ /**
21
+ * One fully-accounted node of the prepared transaction. EVERY entry in
22
+ * DamlTransaction.nodes produces exactly one of these — a node we cannot fully
23
+ * recognize is recorded with `recognized=false` rather than silently dropped, so
24
+ * the invariant layer can fail closed on it (this is the fix for the bypass
25
+ * where a sibling node carried under a non-1000 node version, or as a
26
+ * non-exercise node type, was invisible to verify).
27
+ */
28
+ interface DecodedNode {
29
+ /** DamlTransaction.Node.node_id (the id `roots`/`children` reference). */
30
+ nodeId: string;
31
+ /** False ⇒ the node version was not the known `v1` (1000) oneof member, or it
32
+ * set an unknown/extra versioned_node member. Such a node is opaque: a
33
+ * participant understanding that version could execute it under our signature,
34
+ * so we must refuse to sign. */
35
+ recognizedVersion: boolean;
36
+ /** The v1 node-type oneof member, or undefined if !recognizedVersion or the
37
+ * inner node set no/unknown node_type member. undefined ⇒ reject. */
38
+ kind?: NodeKind | undefined;
39
+ /** For exercise nodes: the choice id + chosen value (money-critical args). */
40
+ exercise?: DecodedExercise | undefined;
41
+ /** node_id references this node declares as its children (Exercise.children /
42
+ * Rollback.children). Used to prove reachability from the single root so no
43
+ * orphan (extra-leg) node can hide in DamlTransaction.nodes. */
44
+ children: string[];
45
+ /** Every `Value`-typed payload this node introduces (exercise chosen_value &
46
+ * exercise_result, create argument). The foreign-party backstop scans the
47
+ * UNION of these across ALL nodes, not just the matched root exercise — so a
48
+ * party/recipient introduced by ANY sibling/consequence node surfaces. */
49
+ values: Uint8Array[];
50
+ /** Node-level `repeated string party` fields that are NOT carried inside a
51
+ * Daml `Value` tree: Create.signatories/stakeholders,
52
+ * Exercise.signatories/stakeholders/acting_parties/choice_observers,
53
+ * Fetch.signatories/stakeholders/acting_parties, and a QueryByKey's key
54
+ * maintainers. The foreign-party backstop scans these too, so an attacker
55
+ * party placed as e.g. a consequence contract's stakeholder/observer (a
56
+ * position invisible to the Value-leaf walk) still surfaces. */
57
+ partyMeta: string[];
58
+ }
59
+ interface DecodedPrepared {
60
+ /** `act_as` parties from Metadata.submitter_info (authoritative submitter). */
61
+ actAs: string[];
62
+ /** DamlTransaction.roots — node_ids declared as transaction roots. */
63
+ roots: string[];
64
+ /** EVERY node in DamlTransaction.nodes, fully accounted (recognized or not). */
65
+ nodes: DecodedNode[];
66
+ /** Convenience view: every recognized Exercise node's choice id + chosen value
67
+ * (backwards-compatible with callers that only inspected exercises). */
68
+ exercises: DecodedExercise[];
69
+ /** Metadata.synchronizer_id (proto field 3, in the SIGNED block). undefined if
70
+ * absent. Pinned to caller intent by the arms when supplied. */
71
+ synchronizerId?: string | undefined;
72
+ /** SIGNED Metadata timing fields, microseconds since the Unix epoch, as
73
+ * BigInts (undefined if absent). All in the proto's "needs to be signed"
74
+ * block, so the agent's signature covers them; the arms sanity-bound them. */
75
+ preparationTime?: bigint | undefined;
76
+ minLedgerEffectiveTime?: bigint | undefined;
77
+ maxLedgerEffectiveTime?: bigint | undefined;
78
+ maxRecordTime?: bigint | undefined;
79
+ /** Every Create `argument` Value carried in Metadata.input_contracts (proto
80
+ * field 7, SIGNED): the authenticated input-contract set. Scanned by the
81
+ * foreign-party backstop so a party that appears ONLY inside an input
82
+ * contract's payload (never in a transaction node) still surfaces. */
83
+ inputContractValues: Uint8Array[];
84
+ /** The node-level `repeated string party` fields of each Metadata.input_contracts
85
+ * Create — signatories (field 6) + stakeholders (field 7) + any contract-key
86
+ * parties (field 8). The V2 metadata hasher binds disclosed/input contracts via
87
+ * `hashNode(toCreateNode)` → addCreateNode, which hashes argument + signatories
88
+ * + stakeholders, so these party fields ARE covered by the agent's signature;
89
+ * the backstop scans them so a foreign party placed ONLY as an input-contract
90
+ * signatory/stakeholder (not in its argument) still surfaces. */
91
+ inputContractPartyMeta: string[];
92
+ }
93
+ /**
94
+ * Decode a base64 `PreparedTransaction` into the bits we validate.
95
+ *
96
+ * Enumerates EVERY node in DamlTransaction.nodes — every node-version member and
97
+ * every node-type oneof member — recording unrecognized ones as
98
+ * present-but-unvalidated (never silently skipping them). The single allowed
99
+ * root exercise, no-orphan reachability, and the all-nodes value backstop are
100
+ * enforced by the per-arm invariant (`assertSingleAllowedRootExercise`).
101
+ */
102
+ export declare function decodePrepared(preparedTransactionB64: string): DecodedPrepared;
103
+ interface ExtractedTransfer {
104
+ sender: string;
105
+ receiver: string;
106
+ amount: string;
107
+ instrumentAdmin: string;
108
+ instrumentId: string;
109
+ }
110
+ /**
111
+ * Extract the transfer body (sender/receiver/amount/instrument) from a
112
+ * TransferFactory_Transfer choice argument, BY TYPE at its structural position.
113
+ */
114
+ export declare function extractTransfer(chosenValue: Uint8Array): ExtractedTransfer;
115
+ export interface PreparedTransferExpectation {
116
+ /** The agent's own party — must be the transfer sender (caller intent). */
117
+ sender: string;
118
+ /** The intended recipient (merchant payTo / withdraw target) — caller intent. */
119
+ receiver: string;
120
+ /** The EXACT amount string the agent asked to transfer — caller intent. */
121
+ amount: string;
122
+ /**
123
+ * The instrument id the agent expects (e.g. "Amulet"). Caller intent — the
124
+ * agent chooses what asset to pay in. The instrument ADMIN (DSO party) is
125
+ * resolved by the relay and is deliberately NOT used as a trust anchor: we
126
+ * never whitelist a relay-supplied party. Pass it only if you have an
127
+ * independently-trusted value to additionally pin.
128
+ */
129
+ instrumentId: string;
130
+ /** Optional, independently-trusted instrument admin (the DSO party) to pin. When
131
+ * supplied it is pinned by exact equality AND becomes the ONLY admin/dso value
132
+ * the foreign-party backstop excludes outside its root position — closing the
133
+ * "alias the unpinned admin to the attacker and inject it as a consequence
134
+ * recipient" neutralization. Pass it whenever you have an out-of-band DSO. */
135
+ instrumentAdmin?: string;
136
+ /** Optional, caller-intent synchronizer id (the merchant-advertised domain).
137
+ * When supplied, the SIGNED Metadata.synchronizer_id is pinned to it (fail-
138
+ * closed if absent/different) so a relay cannot land the agent's signature on a
139
+ * domain of its choosing. */
140
+ synchronizerId?: string;
141
+ /** Optional, caller-intent template `module:entity` qualified name of the
142
+ * TransferFactory the choice runs against (e.g. the token-standard transfer
143
+ * factory). When supplied, the exercise's template_id is pinned, closing the
144
+ * template/contract-confusion surface. */
145
+ templateQualifiedName?: string;
146
+ /** Optional, caller-intent contract id of the factory the exercise targets.
147
+ * When supplied, Exercise.contract_id is pinned by exact equality (fail-closed
148
+ * on divergence) — defense-in-depth closing the resolve→prepare TOCTOU. No-op
149
+ * when omitted (the all-nodes party backstop still contains any redirect). */
150
+ expectedContractId?: string;
151
+ /** Inject Date.now() for testability of the timing sanity checks. */
152
+ nowMs?: number;
153
+ }
154
+ export declare class PreparedDecodeError extends Error {
155
+ constructor(message: string);
156
+ }
157
+ export declare class PreparedTransferMismatchError extends Error {
158
+ constructor(message: string);
159
+ }
160
+ /**
161
+ * Assert the relay-returned `preparedTransaction` encodes EXACTLY the transfer
162
+ * the agent intended. Throws `PreparedTransferMismatchError` on any mismatch
163
+ * and `PreparedDecodeError` if the bytes are not a decodable PreparedTransaction
164
+ * carrying a single transfer exercise. Call this BEFORE signing `hash`.
165
+ *
166
+ * Fail-closed: anything we cannot positively prove matches the intent throws.
167
+ */
168
+ export declare function assertPreparedTransferMatches(preparedTransactionB64: string, expect: PreparedTransferExpectation): void;
169
+ interface ExtractedCreateTransferCommand {
170
+ sender: string;
171
+ receiver: string;
172
+ delegate: string;
173
+ amount: string;
174
+ nonce: string;
175
+ /** Decimal-string of the Value.timestamp varint, or undefined if not present
176
+ * as a timestamp leaf (some encodings serialize Time differently); the
177
+ * caller only sanity-checks it, never pins it to money. */
178
+ expiresAt?: string;
179
+ /** The expectedDso party AS it appears at its own position, used ONLY to
180
+ * exclude it from the foreign-recipient backstop (never as an allowlist). */
181
+ expectedDso?: string;
182
+ }
183
+ /**
184
+ * Extract the v1 create-command fields from its (flat) choice-argument record,
185
+ * BY TYPE at its DAML DECLARATION-ORDER POSITION (what the participant binds),
186
+ * NOT by label — and fail closed on any label/position divergence (the
187
+ * amount-inflation / receiver-swap vector). Declaration order:
188
+ * [0] sender:Party [1] receiver:Party [2] delegate:Party [3] amount:Numeric
189
+ * [4] expiresAt:Time [5] nonce:Int [6] description:Optional Text [7] expectedDso:Party
190
+ * Honest encodings — fully labelled in order OR label-free (normalized) — both
191
+ * pass; a record whose labels disagree with declaration order (a decoy field
192
+ * re-using a money-critical label, or a mislabeled value at a money position) is
193
+ * rejected. Fails closed if a money-critical field is the wrong type / missing.
194
+ */
195
+ export declare function extractCreateTransferCommand(chosenValue: Uint8Array): ExtractedCreateTransferCommand;
196
+ /** Caller-intent expectation for a v1 `CreateTransferCommand`. Every field is
197
+ * CALLER INTENT — none is taken from the relay's resolve response. */
198
+ export interface PreparedCreateTransferCommandExpectation {
199
+ /** The agent's own party — must be the command sender. */
200
+ sender: string;
201
+ /** The intended recipient (merchant payTo from the 402). */
202
+ receiver: string;
203
+ /** The facilitator/delegate party (from the 402 `extra.facilitatorParty`). */
204
+ delegate: string;
205
+ /** The EXACT amount string the agent asked to pay. */
206
+ amount: string;
207
+ /** Optional: the exact nonce the agent built the command with. When supplied
208
+ * it is pinned by exact equality; always sanity-checked (>= 0) regardless. */
209
+ nonce?: string;
210
+ /** Optional, independently-trusted DSO party. When supplied it is pinned by
211
+ * exact equality to the command's expectedDso AND becomes the ONLY dso value
212
+ * the foreign-party backstop excludes outside its root position — closing the
213
+ * "alias the unpinned expectedDso to the attacker and inject it as a
214
+ * consequence recipient" neutralization. Pass it whenever an out-of-band DSO
215
+ * is available; without it the backstop still closes the root-extra-leaf and
216
+ * money-role aliasing vectors. */
217
+ expectedDso?: string;
218
+ /** Optional, caller-intent synchronizer id (merchant-advertised domain). When
219
+ * supplied, the SIGNED Metadata.synchronizer_id is pinned to it (fail-closed
220
+ * if absent/different) so a relay cannot land the signature on its own domain. */
221
+ synchronizerId?: string;
222
+ /** Optional, caller-intent template `module:entity` of the ExternalPartyAmulet-
223
+ * Rules contract the choice runs against. When supplied, the exercise's
224
+ * template_id is pinned (template/contract-confusion). */
225
+ templateQualifiedName?: string;
226
+ /** Optional, caller-intent contract id of the ExternalPartyAmuletRules contract
227
+ * the exercise targets. When supplied, Exercise.contract_id is pinned by exact
228
+ * equality (fail-closed on divergence) — defense-in-depth closing the
229
+ * resolve→prepare TOCTOU. No-op when omitted. */
230
+ expectedContractId?: string;
231
+ /** Inject Date.now() for testability of the expiresAt / timing sanity checks. */
232
+ nowMs?: number;
233
+ }
234
+ /**
235
+ * Assert the relay-returned `preparedTransaction` encodes EXACTLY the v1
236
+ * `ExternalPartyAmuletRules_CreateTransferCommand` the agent intended. Throws
237
+ * `PreparedTransferMismatchError` on any mismatch and `PreparedDecodeError` if
238
+ * the bytes are not a decodable PreparedTransaction carrying a single
239
+ * create-command exercise. Call BEFORE signing the hash. Fail-closed: anything
240
+ * not positively proven to match the intent throws.
241
+ */
242
+ export declare function assertPreparedCreateTransferCommandMatches(preparedTransactionB64: string, expect: PreparedCreateTransferCommandExpectation): void;
243
+ /** Caller-intent expectation for a `TransferInstruction_Accept` (claim) prepare. */
244
+ export interface PreparedAcceptExpectation {
245
+ /** The agent's own party — must be the authoritative submitter (act_as). */
246
+ selfParty: string;
247
+ /** Inject Date.now() for testability of the timing sanity checks. */
248
+ nowMs?: number;
249
+ }
250
+ /**
251
+ * Assert the relay-returned `preparedTransaction` for the claim path encodes
252
+ * EXACTLY a single `TransferInstruction_Accept` exercise submitted by the agent —
253
+ * and is NOT an outbound transfer/create-transfer-command drain. Throws
254
+ * `PreparedTransferMismatchError` on any mismatch and `PreparedDecodeError` if
255
+ * the bytes are not a decodable PreparedTransaction. Call BEFORE signing the
256
+ * hash. Fail-closed: anything not positively proven to be an inbound accept by
257
+ * the agent throws.
258
+ */
259
+ export declare function assertPreparedAcceptMatches(preparedTransactionB64: string, expect: PreparedAcceptExpectation): void;
260
+ /**
261
+ * How to bind the relay-returned `hash` to the `preparedTransaction` bytes the
262
+ * agent just structurally validated. Exactly one of these must hold for a
263
+ * value-moving transfer, or we refuse to sign (fail-closed).
264
+ */
265
+ export interface HashBindingOptions {
266
+ /**
267
+ * A function that recomputes the signing hash from the prepared-transaction
268
+ * bytes EXACTLY as Canton's participant does on `execute`
269
+ * (HASHING_SCHEME_VERSION_V2), returning it base64-encoded. When supplied,
270
+ * `assertHashBinding` requires `recomputeHash(prepared) === hash`
271
+ * (constant-time) and throws otherwise — this is the real cryptographic
272
+ * binding and the only thing that defeats a relay returning honest bytes with
273
+ * the hash of a DIFFERENT (tampered) transaction.
274
+ *
275
+ * It MUST be a deterministic function of the bytes alone and MUST match the
276
+ * participant's algorithm; if it does not, honest transfers fail closed
277
+ * (refused), never silently mis-bound.
278
+ *
279
+ * May be async: the conformant implementation (`recomputeHash` in
280
+ * `canton-hash.ts`, backed by `@canton-network/core-tx-visualizer`) uses
281
+ * WebCrypto and returns a Promise. `assertHashBinding` awaits the result, so a
282
+ * sync `=> string` recompute is also accepted.
283
+ */
284
+ recomputeHash?: (preparedTransactionB64: string) => Promise<string> | string;
285
+ /**
286
+ * DANGEROUS, OFF BY DEFAULT. Sign the relay-returned hash WITHOUT recomputing
287
+ * it. The Canton Ledger API proto is explicit: "clients MUST recompute the
288
+ * hash from the raw transaction if the preparing participant is not trusted"
289
+ * and the hash field is "provided for convenience [and] may be removed". A
290
+ * compromised relay can return structurally-honest bytes paired with the hash
291
+ * of a tampered transaction; if it then swaps the bytes it forwards to the
292
+ * participant, the agent's signature authorizes the attacker's transfer.
293
+ *
294
+ * Only set this true if you independently display the decoded transfer to a
295
+ * human for approval before signing, OR you fully trust the relay. Never the
296
+ * default for autonomous agents.
297
+ */
298
+ trustRelayHash?: boolean;
299
+ }
300
+ /** Thrown when a supplied `recomputeHash` cannot faithfully encode the bytes. */
301
+ export declare class PreparedHashUnavailableError extends Error {
302
+ constructor(message: string);
303
+ }
304
+ /**
305
+ * Bind the `hash` the relay told us to sign to the `preparedTransaction` bytes
306
+ * we just structurally validated. Call this BEFORE signing `hash`.
307
+ *
308
+ * THE BINDING (why blind-signing breaks self-custody)
309
+ * ---------------------------------------------------
310
+ * The signed artifact is `hash`. The participant, on `execute`, recomputes the
311
+ * V2 hash from whatever bytes reach it and accepts the signature only if it
312
+ * matches. A compromised relay (the participant proxy) can therefore return
313
+ * structurally-HONEST `preparedTransaction` bytes (which sail through
314
+ * `assertPreparedTransferMatches`) paired with `hash = V2(PT_evil)` for a
315
+ * DIFFERENT transfer, then forward `PT_evil` instead of the honest bytes to the
316
+ * participant: V2(PT_evil) == hash, signature valid, attacker paid. Validating
317
+ * the bytes is therefore necessary but NOT sufficient — the agent must also
318
+ * prove the hash it signs is the hash OF THOSE validated bytes. That requires
319
+ * recomputing the hash locally; the relay-supplied hash is untrusted input.
320
+ *
321
+ * This function enforces, fail-closed:
322
+ * 1. shape: `hash` is a present, well-formed, non-empty base64 digest, and the
323
+ * `preparedTransaction` is a decodable PreparedTransaction with exactly the
324
+ * one transfer exercise (so we are signing a transfer we understood);
325
+ * 2. binding: EITHER `opts.recomputeHash` is supplied and
326
+ * `recomputeHash(prepared) === hash` (constant-time) — the real binding —
327
+ * OR `opts.trustRelayHash === true` is explicitly set (the documented,
328
+ * off-by-default escape hatch for human-in-the-loop / trusted-relay use).
329
+ * If neither holds, we REFUSE to sign rather than blind-sign an unbound,
330
+ * relay-chosen hash.
331
+ */
332
+ export declare function assertHashBinding(preparedTransactionB64: string, hashB64: string, opts?: HashBindingOptions): Promise<void>;
333
+ /**
334
+ * Returns true iff `hash` is the plain SHA-256 of the `preparedTransaction`
335
+ * bytes. NOTE: Canton V2 does NOT hash this way (see `assertHashBinding`), so
336
+ * this is advisory only and is NEVER used to accept or reject a submission.
337
+ * Retained for diagnostics / future schemes.
338
+ */
339
+ export declare function hashMatchesPreparedPlain(preparedTransactionB64: string, hashB64: string): boolean;
340
+ /** Thrown when relay-returned onboarding topology cannot be proven to bind the
341
+ * agent's own key + namespace. Onboarding refuses to sign the multiHash. */
342
+ export declare class OnboardingTopologyMismatchError extends Error {
343
+ constructor(message: string);
344
+ }
345
+ /** What the agent independently knows/expects about its onboarding. */
346
+ export interface OnboardingTopologyExpectation {
347
+ /** The agent's OWN freshly-generated public key, base64 SPKI/DER (keys.ts). */
348
+ publicKeySpkiB64: string;
349
+ /** The relay-returned party id, expected `name::fingerprint`. */
350
+ party: string;
351
+ /** The relay-returned canonical key fingerprint (the party's namespace). */
352
+ publicKeyFingerprint: string;
353
+ }
354
+ /**
355
+ * Assert the relay-returned onboarding topology binds the agent's OWN key and
356
+ * namespace. Call this BEFORE signing the onboarding `multiHash`. Fail-closed:
357
+ * anything not positively proven throws `OnboardingTopologyMismatchError`.
358
+ */
359
+ export declare function assertOnboardingTopologyBindsKey(onboardingTransactionsB64: string[], expect: OnboardingTopologyExpectation): void;
360
+ export {};
361
+ //# sourceMappingURL=verify-prepared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-prepared.d.ts","sourceRoot":"","sources":["../src/verify-prepared.ts"],"names":[],"mappings":"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"}