@chironbuilder/ootle-sdk 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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -0
  3. package/dist/accountApi.d.ts +33 -0
  4. package/dist/accountApi.d.ts.map +1 -0
  5. package/dist/accountApi.js +1 -0
  6. package/dist/adapters.d.ts +13 -0
  7. package/dist/adapters.d.ts.map +1 -0
  8. package/dist/adapters.js +68 -0
  9. package/dist/componentAddress.d.ts +27 -0
  10. package/dist/componentAddress.d.ts.map +1 -0
  11. package/dist/componentAddress.js +68 -0
  12. package/dist/confidential.d.ts +50 -0
  13. package/dist/confidential.d.ts.map +1 -0
  14. package/dist/confidential.js +86 -0
  15. package/dist/derivation.d.ts +7 -0
  16. package/dist/derivation.d.ts.map +1 -0
  17. package/dist/derivation.js +47 -0
  18. package/dist/domainHash.d.ts +11 -0
  19. package/dist/domainHash.d.ts.map +1 -0
  20. package/dist/domainHash.js +44 -0
  21. package/dist/htlc.d.ts +26 -0
  22. package/dist/htlc.d.ts.map +1 -0
  23. package/dist/htlc.js +69 -0
  24. package/dist/index.d.ts +21 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +14 -0
  27. package/dist/ootleNetwork.d.ts +4 -0
  28. package/dist/ootleNetwork.d.ts.map +1 -0
  29. package/dist/ootleNetwork.js +11 -0
  30. package/dist/ownershipProof.d.ts +4 -0
  31. package/dist/ownershipProof.d.ts.map +1 -0
  32. package/dist/ownershipProof.js +53 -0
  33. package/dist/storage.d.ts +61 -0
  34. package/dist/storage.d.ts.map +1 -0
  35. package/dist/storage.js +110 -0
  36. package/dist/timeout.d.ts +2 -0
  37. package/dist/timeout.d.ts.map +1 -0
  38. package/dist/timeout.js +19 -0
  39. package/dist/vault.d.ts +12 -0
  40. package/dist/vault.d.ts.map +1 -0
  41. package/dist/vault.js +44 -0
  42. package/dist/wallet.d.ts +733 -0
  43. package/dist/wallet.d.ts.map +1 -0
  44. package/dist/wallet.js +1964 -0
  45. package/package.json +46 -0
  46. package/vendor/ootle-patched/README.md +67 -0
  47. package/vendor/ootle-patched/dist/index.d.ts +2129 -0
  48. package/vendor/ootle-patched/dist/index.js +1365 -0
  49. package/vendor/ootle-patched/package.json +23 -0
  50. package/vendor/ootle-wasm-patched/README.md +128 -0
  51. package/vendor/ootle-wasm-patched/ootle_wasm.d.ts +454 -0
  52. package/vendor/ootle-wasm-patched/ootle_wasm.js +9 -0
  53. package/vendor/ootle-wasm-patched/ootle_wasm_bg.js +1485 -0
  54. package/vendor/ootle-wasm-patched/ootle_wasm_bg.wasm +0 -0
  55. package/vendor/ootle-wasm-patched/ootle_wasm_bg.wasm.d.ts +83 -0
  56. package/vendor/ootle-wasm-patched/package.json +27 -0
@@ -0,0 +1,2129 @@
1
+ import { AllocatableAddressType } from '@tari-project/ootle-ts-bindings';
2
+ import { Amount } from '@tari-project/ootle-ts-bindings';
3
+ import { ClaimBurnOutputData } from '@tari-project/ootle-ts-bindings';
4
+ import { ClaimedOutputTombstoneAddress } from '@tari-project/ootle-ts-bindings';
5
+ import { ComponentAddress } from '@tari-project/ootle-ts-bindings';
6
+ import { ConfidentialWithdrawProof } from '@tari-project/ootle-ts-bindings';
7
+ import { Decision } from '@tari-project/ootle-ts-bindings';
8
+ import { ExecuteResult } from '@tari-project/ootle-ts-bindings';
9
+ import { FinalizeOutcome } from '@tari-project/ootle-ts-bindings';
10
+ import { FinalizeResult } from '@tari-project/ootle-ts-bindings';
11
+ import { GetSubstatesRequest } from '@tari-project/ootle-ts-bindings';
12
+ import { GetSubstatesResponse } from '@tari-project/ootle-ts-bindings';
13
+ import { GetTemplateDefinitionResponse } from '@tari-project/ootle-ts-bindings';
14
+ import { IndexerGetSubstateRequest } from '@tari-project/ootle-ts-bindings';
15
+ import { IndexerGetSubstateResponse } from '@tari-project/ootle-ts-bindings';
16
+ import { IndexerGetTransactionResultResponse } from '@tari-project/ootle-ts-bindings';
17
+ import { IndexerSubmitTransactionRequest } from '@tari-project/ootle-ts-bindings';
18
+ import { IndexerSubmitTransactionResponse } from '@tari-project/ootle-ts-bindings';
19
+ import { IndexerTransactionFinalizedResult } from '@tari-project/ootle-ts-bindings';
20
+ import { Instruction } from '@tari-project/ootle-ts-bindings';
21
+ import { InstructionArg } from '@tari-project/ootle-ts-bindings';
22
+ import { ListRecentTransactionsRequest } from '@tari-project/ootle-ts-bindings';
23
+ import { ListRecentTransactionsResponse } from '@tari-project/ootle-ts-bindings';
24
+ import { MinotariBurnClaimProof } from '@tari-project/ootle-ts-bindings';
25
+ import { NonFungibleAddress } from '@tari-project/ootle-ts-bindings';
26
+ import { OutputBody } from '@tari-project/ootle-ts-bindings';
27
+ import { PublishedTemplateAddress } from '@tari-project/ootle-ts-bindings';
28
+ import { RejectReason } from '@tari-project/ootle-ts-bindings';
29
+ import { ResourceAddress } from '@tari-project/ootle-ts-bindings';
30
+ import { RistrettoPublicKeyBytes } from '@tari-project/ootle-ts-bindings';
31
+ import { StealthTransferStatement as StealthTransferStatement_2 } from '@tari-project/ootle-ts-bindings';
32
+ import { SubstateId } from '@tari-project/ootle-ts-bindings';
33
+ import { SubstateRequirement } from '@tari-project/ootle-ts-bindings';
34
+ import { Transaction } from '@tari-project/ootle-ts-bindings';
35
+ import { TransactionEnvelope } from '@tari-project/ootle-ts-bindings';
36
+ import { TransactionSignature } from '@tari-project/ootle-ts-bindings';
37
+ import { TransactionV1 } from '@tari-project/ootle-ts-bindings';
38
+ import { UnsealedTransactionV1 } from '@tari-project/ootle-ts-bindings';
39
+ import { UnsignedTransactionV1 } from '@tari-project/ootle-ts-bindings';
40
+ import { UtxoAddress } from '@tari-project/ootle-ts-bindings';
41
+ import { ValidatorFeePoolAddress } from '@tari-project/ootle-ts-bindings';
42
+ import { VaultId } from '@tari-project/ootle-ts-bindings';
43
+ import { WorkspaceOffsetId } from '@tari-project/ootle-ts-bindings';
44
+
45
+ /**
46
+ * Fluent builder for common account component invocations.
47
+ * Mirrors `AccountInvokeBuilder` from the Rust ootle-rs crate.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const tx = new AccountInvokeBuilder(network, maxEpoch)
52
+ * .feeTransactionPayFromComponent(accountAddress, 1000n)
53
+ * .publicTransfer(accountAddress, resourceAddress, 500n, recipientAddress)
54
+ * .build();
55
+ * ```
56
+ */
57
+ export declare class AccountInvokeBuilder {
58
+ private builder;
59
+ constructor(network: Network | number, maxEpoch: number);
60
+ /**
61
+ * Declares the transaction's substate inputs (e.g. the source account and its
62
+ * vaults) so the indexer resolves their versions before submission.
63
+ */
64
+ withInputs(inputs: SubstateRequirement[]): this;
65
+ /**
66
+ * Adds a fee instruction paying from the account's default vault.
67
+ */
68
+ feeTransactionPayFromComponent(componentAddress: ComponentAddress, maxFee: bigint): this;
69
+ /**
70
+ * Transfers `amount` of `resource` from `sourceAccount` to `destinationAddress`.
71
+ * Mirrors `AccountInvokeBuilder::public_transfer` from ootle-rs.
72
+ */
73
+ publicTransfer(sourceAccount: ComponentAddress, resourceAddress: ResourceAddress, amount: bigint, destinationAddress: string): this;
74
+ /**
75
+ * Publishes a compiled template WASM blob (standard-base64 encoded).
76
+ * Mirrors `AccountInvokeBuilder::publish_template` from ootle-rs.
77
+ *
78
+ * `sourceAccount` is the fee payer; declare it via {@link feeTransactionPayFromComponent}
79
+ * and {@link withInputs}. Pass `workspaceBucket` to capture the new template address
80
+ * for a follow-up instruction.
81
+ */
82
+ publishTemplate(_sourceAccount: ComponentAddress, templateBinaryBase64: string, workspaceBucket?: string): this;
83
+ build(): UnsignedTransactionV1;
84
+ }
85
+
86
+ export { Amount }
87
+
88
+ /**
89
+ * CBOR-encode an `Amount` (u128) the way the runtime's `minicbor` codec does:
90
+ * a plain CBOR unsigned integer while the value fits the CBOR integer range
91
+ * (`0..=u64::MAX`), and an RFC 8949 tag-2 unsigned bignum (minimal-length
92
+ * big-endian byte string) above it.
93
+ *
94
+ * Wire-breaking against the pre-0.39 `[lo_u64, hi_u64]` digit-array form —
95
+ * templates built against an older `tari_template_lib` cannot decode this.
96
+ *
97
+ * @throws {InvalidArgumentError} if `value` is negative or overflows u128.
98
+ */
99
+ export declare function amountLiteral(value: bigint): InstructionArg;
100
+
101
+ /**
102
+ * Asserts that `bytes` has exactly `length` bytes; otherwise throws with a
103
+ * descriptive message. Returns `bytes` so the assertion can be used inline in a
104
+ * property initialiser or destructuring expression.
105
+ *
106
+ * Message format deliberately mirrors the existing stealth-side inline checks
107
+ * (e.g. `Mask must be 32 bytes, got 31`).
108
+ *
109
+ * @throws {InvalidArgumentError} when the length does not match.
110
+ */
111
+ export declare function assertByteLength(bytes: Uint8Array, length: number, name: string): Uint8Array;
112
+
113
+ /**
114
+ * Standard TypeScript exhaustiveness helper. Use at the bottom of a `switch` over
115
+ * a discriminated union (or any branch the type system has narrowed to `never`)
116
+ * to assert at compile-time that every case is handled — and throw at runtime if
117
+ * an unhandled value sneaks past the type checker.
118
+ */
119
+ export declare function assertUnreachable(x: never, hint?: string): never;
120
+
121
+ /**
122
+ * The post-{@link WalletStealthAuthorizer.prepare} handle.
123
+ *
124
+ * Owns the hydrated spec, the resolved stealth inputs, and the single seal keypair shared
125
+ * across one-time authorizations and the seal signature. Constructed only via
126
+ * {@link WalletStealthAuthorizer.prepare} — there is no way to obtain one without preparing
127
+ * first, so {@link seal} / {@link createAuthorizations} no longer need a `prepared` guard.
128
+ */
129
+ export declare class AuthorizedTransfer {
130
+ private readonly wallet;
131
+ private readonly crypto;
132
+ private readonly spec;
133
+ private readonly resolvedInputs;
134
+ private readonly mustSignWithAccountKey;
135
+ /**
136
+ * The single seal keypair, generated once and shared across the one-time spend-key
137
+ * authorizations (which hash the tx with its public key) and the final {@link seal}. Every
138
+ * signature must be over the same tx hash, which depends on this exact seal public key.
139
+ */
140
+ private readonly sealKeypair;
141
+ /** Extra signatures appended via {@link addSignature} before sealing. */
142
+ private readonly extraSignatures;
143
+ /**
144
+ * Memoized one-time spend-key authorizations — see {@link createAuthorizations} for the
145
+ * lifecycle and why memoization (not recomputation) is required.
146
+ */
147
+ private cachedAuthorizations?;
148
+ constructor(params: AuthorizedTransferParams);
149
+ /** The shared seal signer public key (fixed for this transfer's lifetime). */
150
+ getSealPublicKey(): Uint8Array;
151
+ /** The hydrated, post-`prepare` spec (balance proof filled, instruction patched). */
152
+ getSpec(): StealthTransferSpec;
153
+ /**
154
+ * Produce the one-time spend-key authorizations for the stealth inputs (empty for a
155
+ * revealed-only transfer).
156
+ *
157
+ * For each resolved input, picks the owner's signer from the wallet and calls its
158
+ * `addStealthSignature(unsignedJson, publicNonce, sealPublicKey, { crypto })` — which
159
+ * derives the one-time spend scalar via `stealthDhSecret` and signs the tx hash. The
160
+ * secret stays in the signer (never pulled into the transfer).
161
+ *
162
+ * Uses this transfer's shared seal public key ({@link getSealPublicKey}) — the same one
163
+ * {@link seal} uses — so every signature is over the same tx hash. The tx hashed is
164
+ * `spec.unsignedTx` (already resolved by the builder); {@link seal} does not re-resolve,
165
+ * so the hashes match.
166
+ *
167
+ * **Memoized.** The authorizations are computed on the first call and cached; every
168
+ * subsequent call — including the internal one from {@link seal} — returns the *same*
169
+ * array, never re-signing with a fresh random nonce. Calling this before {@link seal}
170
+ * cannot double-count, because {@link seal} reuses the cache. Callers therefore must
171
+ * **not** feed these one-time authorizations to {@link addSignature} — they are
172
+ * auto-included exactly once at seal time.
173
+ *
174
+ * @throws {KeyProviderNotFoundError} if a stealth-input owner has no signer registered.
175
+ * @throws {SignerError} if a stealth-input owner's signer cannot produce one-time
176
+ * stealth signatures (lacks `addStealthSignature`).
177
+ */
178
+ createAuthorizations(): Promise<TransactionAuthorization[]>;
179
+ /**
180
+ * Sign each resolved stealth input with its owner's one-time spend key (fresh random
181
+ * nonce per signature). Called **once** via {@link createAuthorizations}'s memoization —
182
+ * never directly — so the random-nonce signatures are produced a single time.
183
+ */
184
+ private computeAuthorizations;
185
+ /**
186
+ * Append an extra signature for a **genuine external co-signer** to be included when
187
+ * sealing. The account-key signature is added automatically at {@link seal} unless
188
+ * `mustSignWithAccountKey` is `false`.
189
+ *
190
+ * Do **NOT** pass the per-input one-time spend-key authorizations here — they are
191
+ * produced (memoized) by {@link createAuthorizations} and auto-included by {@link seal}
192
+ * exactly once. Re-adding them via this method would double-count them in the sealed tx,
193
+ * which the engine rejects.
194
+ */
195
+ addSignature(signature: TransactionSignature): this;
196
+ /**
197
+ * Sign and seal the (prepared) transfer into a `TransactionEnvelope`.
198
+ *
199
+ * Composes, over a SINGLE shared seal keypair:
200
+ * - the account-key signature (unless `mustSignWithAccountKey` is `false`);
201
+ * - the per-input **one-time spend-key authorizations** — included **exactly once** per
202
+ * stealth input via {@link createAuthorizations}'s memoized cache, whether or not the
203
+ * caller invoked {@link createAuthorizations} first; callers must NOT also re-add them
204
+ * via {@link addSignature};
205
+ * - any {@link addSignature} extras (e.g. genuine external co-signers).
206
+ *
207
+ * All of these — and the seal signature itself — hash the tx with the same seal public
208
+ * key, so every signature verifies against the same hash. The tx is **not** re-resolved
209
+ * here (the builder already resolved it in `prepare()`); re-resolving could change the
210
+ * hash and invalidate the already-computed one-time authorizations.
211
+ *
212
+ * @throws {KeyProviderNotFoundError} when a stealth-input owner has no signer registered.
213
+ * @throws {SignerError} when a stealth-input signer cannot produce one-time signatures.
214
+ */
215
+ seal(): Promise<TransactionEnvelope>;
216
+ }
217
+
218
+ /**
219
+ * Parameters for the {@link AuthorizedTransfer} constructor. Kept internal — the only
220
+ * construction path is via {@link WalletStealthAuthorizer.prepare}.
221
+ */
222
+ declare interface AuthorizedTransferParams {
223
+ wallet: OotleWallet;
224
+ crypto: StealthCryptoProvider;
225
+ spec: StealthTransferSpec;
226
+ resolvedInputs: ResolvedStealthInput[];
227
+ mustSignWithAccountKey: boolean;
228
+ sealKeypair: SealKeypair;
229
+ }
230
+
231
+ /**
232
+ * The balance-proof Schnorr signature `(public_nonce, signature)`. For a
233
+ * fully-revealed transfer this pair is normally omitted on the envelope.
234
+ */
235
+ export declare class BalanceProofSignature {
236
+ private readonly _publicNonce;
237
+ private readonly _signature;
238
+ constructor(publicNonce: Uint8Array, signature: Uint8Array);
239
+ /** 32-byte public nonce (defensive copy). */
240
+ get publicNonce(): Uint8Array;
241
+ /** 32-byte signature scalar (defensive copy). */
242
+ get signature(): Uint8Array;
243
+ toJSON(): BalanceProofSignatureJson;
244
+ static fromJSON(json: BalanceProofSignatureJson): BalanceProofSignature;
245
+ }
246
+
247
+ /** Wire shape of a {@link BalanceProofSignature}. */
248
+ declare interface BalanceProofSignatureJson {
249
+ public_nonce: string;
250
+ signature: string;
251
+ }
252
+
253
+ /** CBOR-encode a `bool` as a CBOR boolean primitive. */
254
+ export declare function boolLiteral(value: boolean): InstructionArg;
255
+
256
+ /**
257
+ * Assemble a TransactionSignature from a 32-byte public key and a Schnorr
258
+ * `(public_nonce, signature)` pair. Asserts the 32-byte length on all three
259
+ * inputs at the trust boundary so length regressions surface here, not deeper.
260
+ */
261
+ export declare function buildTransactionSignature(publicKey: Uint8Array, sig: {
262
+ public_nonce: Uint8Array;
263
+ signature: Uint8Array;
264
+ }): TransactionSignature;
265
+
266
+ /**
267
+ * Internal base for 32-byte stealth-domain carriers (`Mask`, `StealthInput`).
268
+ * Asserts the 32-byte length at construction and defensively copies on the way
269
+ * in; subclasses inherit `toBytes()` / `toHex()` which return fresh copies.
270
+ *
271
+ * Exported for cross-file extension by `StealthInput` in `./statements`; not
272
+ * part of the public package surface (not re-exported from `./types`).
273
+ */
274
+ declare abstract class Bytes32 {
275
+ private readonly bytes;
276
+ protected constructor(bytes: Uint8Array, fieldName: string);
277
+ toBytes(): Uint8Array;
278
+ toHex(): string;
279
+ }
280
+
281
+ /** CBOR-encode a `Vec<u8>` as a CBOR byte string. */
282
+ export declare function bytesLiteral(value: Uint8Array): InstructionArg;
283
+
284
+ /**
285
+ * CBOR-encode a `ClaimedOutputTombstoneAddress` as `Tag(136, bytes(32))`.
286
+ * Accepts either the `tombstone_<hex>` form or the bare 64-hex-char tail.
287
+ *
288
+ * @throws {InvalidArgumentError} if the address body is not 32 bytes (64 hex chars).
289
+ */
290
+ export declare function claimedOutputTombstoneAddressLiteral(address: ClaimedOutputTombstoneAddress): InstructionArg;
291
+
292
+ /**
293
+ * @throws {InvalidArgumentError} if `result` carries an unrecognised `final_decision`
294
+ * variant (an indexer protocol mismatch — defence-in-depth).
295
+ */
296
+ export declare function classifyOutcome(result: IndexerTransactionFinalizedResult): {
297
+ outcome: FinalizeOutcome | "Reject";
298
+ reason?: string;
299
+ } | null;
300
+
301
+ /**
302
+ * Extract the 32-byte commitment from a UTXO substate id.
303
+ *
304
+ * A UTXO id has the form `utxo_{resourceHex}_{commitmentHex}`; the commitment is the
305
+ * **trailing** hex segment. Returns `null` if the id is not a UTXO id (wrong prefix,
306
+ * e.g. a component/vault id) or the trailing segment is not exactly 32 bytes of hex.
307
+ *
308
+ * The commitment is **never** in the output body — always derive it from the id.
309
+ *
310
+ * @param substateId - The full substate id string.
311
+ * @returns The 32-byte commitment, or `null` if `substateId` is not a valid UTXO id.
312
+ */
313
+ export declare function commitmentOf(substateId: string): Uint8Array | null;
314
+
315
+ /**
316
+ * The only outcome a `PendingTransaction.watch()` can resolve to: a successful
317
+ * commit. Every non-commit verdict (Reject, FeeIntentCommit, timeout, cancel)
318
+ * throws instead, so the return type is narrowed to this rather than the full
319
+ * {@link TransactionOutcome} union.
320
+ */
321
+ export declare interface CommitOutcome {
322
+ outcome: "Commit";
323
+ }
324
+
325
+ /**
326
+ * CBOR-encode a `ComponentAddress` as `Tag(128, bytes(32))`. Accepts either the
327
+ * `component_<hex>` form or the bare 64-hex-char tail.
328
+ *
329
+ * @throws {InvalidArgumentError} if the address body is not 32 bytes (64 hex chars).
330
+ */
331
+ export declare function componentAddressLiteral(address: ComponentAddress): InstructionArg;
332
+
333
+ /**
334
+ * Construct an {@link Output}, applying the conventional defaults and validating
335
+ * the amount.
336
+ *
337
+ * @throws {InvalidArgumentError} if `amount <= 0n`.
338
+ */
339
+ export declare function createOutput(init: OutputInit): Output;
340
+
341
+ /**
342
+ * Raised when the WASM crypto bridge fails (AEAD decryption, balance-proof
343
+ * verification, scalar parsing, …). `context` is a short label identifying which
344
+ * bridge call failed; the original bridge error chains via `cause`.
345
+ */
346
+ export declare class CryptoBridgeError extends OotleError {
347
+ readonly context?: string;
348
+ constructor(message: string, options?: ErrorOptions & {
349
+ context?: string;
350
+ });
351
+ }
352
+
353
+ export { Decision }
354
+
355
+ /**
356
+ * The result of decrypting an owned output via the AEAD path (`unblindOutput`).
357
+ *
358
+ * Maps from the WASM `DecryptedOutputResult { mask: Uint8Array, value: bigint,
359
+ * memo_json: string | undefined }`. Per the verified 0.38 ABI, `memo` is the
360
+ * **JSON-encoded `Memo` string** (`U256` / `Message` / `Bytes` / `PayRefAndBytes`),
361
+ * not raw bytes — callers parse it if needed.
362
+ */
363
+ export declare interface DecryptedData {
364
+ /** Recovered output blinding factor. */
365
+ mask: Mask;
366
+ /** Recovered µTari amount. */
367
+ value: bigint;
368
+ /** The JSON-encoded `Memo` string, if present. */
369
+ memo?: string;
370
+ }
371
+
372
+ /**
373
+ * Decrypt an output's encrypted data given its raw commitment + ciphertext bytes.
374
+ *
375
+ * Derives the AEAD key (`deriveAeadKey(viewSecret, senderPublicNonce)`) and unblinds.
376
+ * **Throws** (via `unblindOutput`) when the output is not owned — callers that scan a
377
+ * batch should prefer {@link decryptOwnedUtxo}, which swallows that throw.
378
+ *
379
+ * @param crypto - The crypto seam (real WASM or a fake).
380
+ * @param commitment - The output's 32-byte Pedersen commitment.
381
+ * @param encryptedData - The raw ciphertext bytes.
382
+ * @param options - The sender public nonce, recipient view secret, and `skipMemo` flag.
383
+ * @returns The decrypted value / mask / memo.
384
+ */
385
+ export declare function decryptInputData(crypto: StealthCryptoProvider, commitment: Uint8Array, encryptedData: Uint8Array, options: DecryptInputOptions): Promise<DecryptedData>;
386
+
387
+ /** Inputs to {@link decryptInputData}. All byte fields are raw `Uint8Array`. */
388
+ export declare interface DecryptInputOptions {
389
+ /** The output's sender public nonce (the substate body `public_nonce`, as bytes). */
390
+ senderPublicNonce: Uint8Array;
391
+ /** The recipient's 32-byte view secret. */
392
+ viewSecret: Uint8Array;
393
+ /** When `true`, the memo is not decrypted. */
394
+ skipMemo: boolean;
395
+ }
396
+
397
+ /**
398
+ * The recipient owner-read: try to decrypt a fetched UTXO substate with a view secret.
399
+ *
400
+ * Parses the substate (commitment from the id, `public_nonce` + `encrypted_data` from
401
+ * the body), derives the AEAD key, and unblinds. Returns the {@link DecryptedData} for
402
+ * an owned UTXO, or `null` when the substate is not a live stealth UTXO **or** the
403
+ * decrypt throws (the "not ours" signal). This lets a recipient scan many substates in
404
+ * a loop without a try/catch at each call site.
405
+ *
406
+ * @param crypto - The crypto seam (real WASM or a fake).
407
+ * @param viewSecret - The recipient's 32-byte view secret.
408
+ * @param substate - The fetched substate response.
409
+ * @param substateId - The substate id the response was fetched by (source of the commitment).
410
+ * @returns The decrypted output if owned, else `null`.
411
+ */
412
+ export declare function decryptOwnedUtxo(crypto: StealthCryptoProvider, viewSecret: Uint8Array, substate: IndexerGetSubstateResponse, substateId: string): Promise<DecryptedData | null>;
413
+
414
+ /**
415
+ * The validity window {@link resolveMaxEpoch} applies when the caller does not name one.
416
+ * Ten epochs is comfortably longer than a transaction takes to finalize while still
417
+ * letting a stuck transaction die on its own rather than lingering as a resubmittable
418
+ * intent.
419
+ */
420
+ export declare const DEFAULT_TRANSACTION_VALIDITY_EPOCHS = 10;
421
+
422
+ /**
423
+ * Returns a known default indexer URL for the given network.
424
+ * Mirrors `default_indexer_url()` from the Rust ootle-rs crate.
425
+ *
426
+ * @throws {InvalidArgumentError} for networks where no default URL is configured.
427
+ */
428
+ export declare function defaultIndexerUrl(network: Network): string;
429
+
430
+ /** The wallet has no default signer to sign / seal with. */
431
+ export declare class DefaultSignerNotSetError extends WalletError {
432
+ }
433
+
434
+ /**
435
+ * Opaque carrier for an output's ciphertext bytes (the AEAD-encrypted value/mask/memo
436
+ * payload). Treated as opaque here: the stealth module never inspects the plaintext
437
+ * structure, only carries the bytes across the JSON boundary.
438
+ */
439
+ export declare class EncryptedData {
440
+ private readonly bytes;
441
+ constructor(bytes: Uint8Array);
442
+ /** Parse a hex string into `EncryptedData` (variable length). */
443
+ static fromHex(hex: string): EncryptedData;
444
+ /** Raw ciphertext bytes (defensive copy). */
445
+ toBytes(): Uint8Array;
446
+ /** Hex encoding. */
447
+ toHex(): string;
448
+ }
449
+
450
+ export { ExecuteResult }
451
+
452
+ /**
453
+ * Fluent builder for common faucet component invocations.
454
+ * Mirrors `FaucetInvokeBuilder` from the Rust ootle-rs crate.
455
+ *
456
+ * @example
457
+ * ```ts
458
+ * const tx = new FaucetInvokeBuilder(network, maxEpoch, faucetAddress)
459
+ * .feeTransactionPayFromComponent(accountAddress, 1000n)
460
+ * .takeFaucetFunds(accountAddress, 10_000n)
461
+ * .build();
462
+ * ```
463
+ */
464
+ export declare class FaucetInvokeBuilder {
465
+ private builder;
466
+ private readonly faucetAddress;
467
+ constructor(network: Network | number, maxEpoch: number, faucetAddress: ComponentAddress);
468
+ feeTransactionPayFromComponent(componentAddress: ComponentAddress, maxFee: bigint): this;
469
+ /**
470
+ * Takes `amount` of funds from the faucet and deposits them into `destinationAccount`.
471
+ * Mirrors `FaucetInvokeBuilder::take_faucet_funds` from ootle-rs.
472
+ */
473
+ takeFaucetFunds(destinationAccount: ComponentAddress, amount: bigint): this;
474
+ /**
475
+ * Takes the maximum available funds from the faucet into `destinationAccount`.
476
+ * Mirrors `FaucetInvokeBuilder::take_max_faucet_funds` from ootle-rs.
477
+ */
478
+ takeMaxFaucetFunds(destinationAccount: ComponentAddress): this;
479
+ /**
480
+ * Publishes a template from the faucet component address.
481
+ * Mirrors `FaucetInvokeBuilder::publish_template` from ootle-rs.
482
+ */
483
+ publishTemplate(templateAddress: PublishedTemplateAddress, workspaceBucket?: string): this;
484
+ build(): UnsignedTransactionV1;
485
+ }
486
+
487
+ export { FinalizeOutcome }
488
+
489
+ export { FinalizeResult }
490
+
491
+ /**
492
+ * Decodes a hex string into bytes.
493
+ *
494
+ * Strict: rejects odd-length input and any character outside `[0-9a-fA-F]`.
495
+ * Returns an empty `Uint8Array` for an empty input.
496
+ *
497
+ * @throws {InvalidArgumentError} if `hex` has odd length or contains non-hex characters.
498
+ */
499
+ export declare function fromHexStr(hex: string): Uint8Array;
500
+
501
+ /**
502
+ * Faucet / public-stealth convenience: build a **complete** {@link StealthTransferStatement}
503
+ * for a transfer that has no stealth inputs (e.g. a faucet minting confidential outputs, or
504
+ * any revealed → stealth transfer that doesn't need the full {@link StealthTransfer} builder).
505
+ *
506
+ * Generates the outputs statement, uses a zero (`Mask.zero()`) input mask over an empty
507
+ * revealed-only inputs statement, signs the balance proof, and returns a ready-to-embed
508
+ * statement (`balanceProof` filled). The output mask is non-zero (there is ≥1 stealth
509
+ * output), so the proof is real — not the omitted all-zeros case.
510
+ *
511
+ * For multi-step transfers with revealed change / fee, prefer the {@link StealthTransfer}
512
+ * builder + {@link WalletStealthAuthorizer}; this is the one-shot helper.
513
+ *
514
+ * @param crypto - The crypto seam (real WASM or a fake).
515
+ * @param specs - The stealth outputs to create (must be non-empty).
516
+ * @param revealed - The revealed (un-confidential) output amount (0 for fully-stealth).
517
+ * @returns A complete transfer statement.
518
+ * @throws {InvalidArgumentError} if `specs` is empty.
519
+ */
520
+ export declare function generateOutputsStatement(crypto: StealthCryptoProvider, specs: Output[], revealed: bigint): Promise<StealthTransferStatement>;
521
+
522
+ /**
523
+ * Generate a fresh seal keypair (a thin wrapper over the WASM `generateKeypair`).
524
+ *
525
+ * Exposed so a caller that needs the seal **public key before sealing** can fix the
526
+ * keypair once and thread the same public key through other signatures that hash with
527
+ * it (the stealth one-time authorizations — see {@link signTransaction}'s `sealKeypair`
528
+ * parameter). Keeps `@tari-project/ootle-wasm` out of the `stealth/` module.
529
+ */
530
+ export declare function generateSealKeypair(): SealKeypair;
531
+
532
+ export { GetSubstatesRequest }
533
+
534
+ export { GetSubstatesResponse }
535
+
536
+ export { GetTemplateDefinitionResponse }
537
+
538
+ /**
539
+ * Fetch `account` and return the list of vault ids it references (depth-first,
540
+ * unique). Returns an empty array if the component does not exist or holds no
541
+ * vaults.
542
+ */
543
+ export declare function getVaultIdsForAccount(provider: Provider, account: ComponentAddress): Promise<string[]>;
544
+
545
+ /**
546
+ * Raised when the indexer transport fails or returns a non-success response.
547
+ *
548
+ * `status` is the HTTP status if the request reached the indexer (else `undefined`,
549
+ * e.g. a connection-layer failure). `body` is the raw response body when
550
+ * available, and `url` is the request URL. The original transport error chains via
551
+ * `cause`.
552
+ */
553
+ export declare class IndexerClientError extends OotleError {
554
+ readonly status?: number;
555
+ readonly body?: string;
556
+ readonly url?: string;
557
+ constructor(message: string, options?: ErrorOptions & {
558
+ status?: number;
559
+ body?: string;
560
+ url?: string;
561
+ });
562
+ }
563
+
564
+ export { IndexerGetSubstateRequest }
565
+
566
+ export { IndexerGetSubstateResponse }
567
+
568
+ export { IndexerGetTransactionResultResponse }
569
+
570
+ export { IndexerSubmitTransactionRequest }
571
+
572
+ export { IndexerSubmitTransactionResponse }
573
+
574
+ export { IndexerTransactionFinalizedResult }
575
+
576
+ export { Instruction }
577
+
578
+ export { InstructionArg }
579
+
580
+ /**
581
+ * CBOR-encode a plain integer (Rust `u8`…`u128` / `i8`…`i128`) as a bare CBOR
582
+ * integer. Distinct from {@link amountLiteral} only above the CBOR integer
583
+ * range, where an `Amount` becomes a tag-2 bignum and this throws instead.
584
+ *
585
+ * @throws {InvalidArgumentError} if the magnitude exceeds the 64-bit CBOR
586
+ * integer range (128-bit bignum encoding is not supported).
587
+ */
588
+ export declare function intLiteral(value: bigint): InstructionArg;
589
+
590
+ /** Raised when builder / helper inputs fail TS-side validation or state-machine checks. */
591
+ export declare class InvalidArgumentError extends OotleError {
592
+ }
593
+
594
+ /**
595
+ * Type guard for the native `StealthTransfer` {@link Instruction} variant. Used by the
596
+ * authorizer to locate the single stealth instruction it must patch.
597
+ */
598
+ export declare function isStealthTransferInstruction(instruction: Instruction): instruction is StealthTransferInstruction;
599
+
600
+ /**
601
+ * Walk the JSON-rendered `tari_bor::Value` of a component's state and yield every
602
+ * 32-byte payload of a `Tag(VAULT_ID, Bytes(..))` node — i.e. every vault id the
603
+ * component references. Depth-first, unique by hex payload.
604
+ *
605
+ * The engine emits values that don't map cleanly to JSON via a `{"@cbor": …}`
606
+ * sentinel object; this walker handles `tag`, `map`, and `bytes` sentinels and
607
+ * recurses through plain text-keyed maps and arrays.
608
+ */
609
+ export declare function iterVaultIdsInState(value: unknown): Generator<string>;
610
+
611
+ /**
612
+ * The wallet has no signer registered for the given address.
613
+ *
614
+ * `address` is intentionally typed as `unknown`: the wallet may register key
615
+ * providers under any keying shape (a `ComponentAddress`, a `ResourceAddress`, …),
616
+ * and the typed error should not pollute the consumer's downstream signature.
617
+ */
618
+ export declare class KeyProviderNotFoundError extends WalletError {
619
+ readonly address: unknown;
620
+ constructor(message: string, options: ErrorOptions & {
621
+ address: unknown;
622
+ });
623
+ }
624
+
625
+ /**
626
+ * CBOR-encode a value into an `InstructionArg::Literal` by its JavaScript type:
627
+ * `bigint` → `Amount`, `string` → CBOR text, `boolean` → CBOR bool,
628
+ * `Uint8Array` → CBOR byte string. For tagged on-chain addresses use
629
+ * {@link resourceAddressLiteral} / {@link componentAddressLiteral} instead — a
630
+ * raw address string would be encoded as plain text, not a tagged object key.
631
+ *
632
+ * @throws {InvalidArgumentError} if `value` is not one of the supported types.
633
+ */
634
+ export declare function literalArg(value: bigint | string | boolean | Uint8Array): InstructionArg;
635
+
636
+ /**
637
+ * A 32-byte blinding factor (Pedersen-commitment mask).
638
+ *
639
+ * Use {@link Mask.zero} for the faucet / revealed-only path (an all-zero scalar).
640
+ */
641
+ export declare class Mask extends Bytes32 {
642
+ constructor(bytes: Uint8Array);
643
+ /** All-zero 32-byte mask, for the faucet / revealed-only path. */
644
+ static zero(): Mask;
645
+ /** Wrap raw 32 bytes into a `Mask` (validates length, defensive copy in the ctor). */
646
+ static fromBytes(bytes: Uint8Array): Mask;
647
+ /** Parse a 64-char hex string into a `Mask` (validates length). */
648
+ static fromHex(hex: string): Mask;
649
+ }
650
+
651
+ /**
652
+ * The longest validity window any network accepts, in epochs
653
+ * (`ConsensusConstants::max_transaction_validity_epochs`, ~30 days). A transaction whose
654
+ * `max_epoch` sits further ahead of the current epoch than this is aborted with
655
+ * `AbortReason::ValidityWindowTooLong`.
656
+ */
657
+ export declare const MAX_TRANSACTION_VALIDITY_EPOCHS = 2160;
658
+
659
+ /**
660
+ * CBOR-encode a `Metadata` map as `Tag(129, Map<text, text>)`. Keys are emitted
661
+ * sorted to match the runtime's `BTreeMap` ordering.
662
+ */
663
+ export declare function metadataLiteral(entries: Record<string, string> | Map<string, string>): InstructionArg;
664
+
665
+ /**
666
+ * Encodes a µTari amount as a BOR-CBOR-encoded hex `Literal` instruction argument.
667
+ *
668
+ * Delegates to {@link amountLiteral}: the runtime's `InstructionArg::Literal` carries
669
+ * a hex string whose bytes are a `tari_bor::encode(value)` CBOR payload, **not** the
670
+ * decimal-string form. Keeping the public type as `bigint` preserves precision for
671
+ * values above `Number.MAX_SAFE_INTEGER`.
672
+ *
673
+ * @throws {InvalidArgumentError} if `amount` is negative or overflows u128.
674
+ */
675
+ export declare function microTariLiteral(amount: bigint): InstructionArg;
676
+
677
+ /**
678
+ * Canonical µTari → decimal-string encoding used wherever the bindings expect a
679
+ * string-encoded amount on the wire (e.g. structural `toJSON()` views of stealth
680
+ * statements). **Not** the BOR-CBOR `Literal` form — use {@link microTariLiteral}
681
+ * / {@link amountLiteral} for instruction arguments.
682
+ *
683
+ * @throws {InvalidArgumentError} if `amount` is negative.
684
+ */
685
+ export declare function microTariString(amount: bigint): string;
686
+
687
+ /**
688
+ * A NamedArg is either:
689
+ * - `{ Workspace: string }` — a named workspace reference resolved by the builder to a numeric ID
690
+ * - `InstructionArg` — a fully-formed `{ Workspace: WorkspaceOffsetId }` or `{ Literal: string }`
691
+ */
692
+ export declare type NamedArg = {
693
+ Workspace: string;
694
+ } | InstructionArg;
695
+
696
+ /**
697
+ * Tari network identifiers. Values match the Rust `Network` byte representation.
698
+ */
699
+ export declare enum Network {
700
+ MainNet = 0,
701
+ StageNet = 1,
702
+ NextNet = 2,
703
+ LocalNet = 16,
704
+ Igor = 36,
705
+ Esmeralda = 38
706
+ }
707
+
708
+ /**
709
+ * CBOR-encode a `NonFungibleAddress` as `Tag(130, [ResourceAddress, NonFungibleId])`.
710
+ * The inner pair is minicbor's struct-as-array layout; the `NonFungibleId` enum
711
+ * is its two-element `[variant_index, [field]]` form.
712
+ *
713
+ * @throws {InvalidArgumentError} if the resource address or id payload is malformed.
714
+ */
715
+ export declare function nonFungibleAddressLiteral(address: NonFungibleAddress): InstructionArg;
716
+
717
+ /** Base class for every exception thrown by the Ootle SDK. */
718
+ export declare abstract class OotleError extends Error {
719
+ constructor(message: string, options?: ErrorOptions);
720
+ }
721
+
722
+ /**
723
+ * A wallet that manages multiple key providers (one per component address) and
724
+ * can sign transactions on behalf of any registered signer.
725
+ *
726
+ * Mirrors `OotleWallet` from the Rust ootle-rs crate.
727
+ *
728
+ * @example
729
+ * ```ts
730
+ * const wallet = new OotleWallet();
731
+ * wallet.registerKeyProvider(myAddress, mySecretKeyWallet);
732
+ * wallet.setDefaultSigner(myAddress);
733
+ *
734
+ * const signed = await wallet.authorizeTransaction(unsignedTx);
735
+ * ```
736
+ */
737
+ export declare class OotleWallet implements Signer {
738
+ private keyProviders;
739
+ private defaultSignerAddress;
740
+ constructor();
741
+ /**
742
+ * Registers a key provider (a `Signer`) for the given component address.
743
+ *
744
+ * Stealth capabilities (`getViewSecret`/`addStealthSignature`) are optional methods on
745
+ * `Signer` (see {@link Signer}); the stealth spend authorizer uses them when present.
746
+ */
747
+ registerKeyProvider(address: string, provider: Signer): this;
748
+ /**
749
+ * Sets the address used when `signTransaction` is called without specifying a signer.
750
+ *
751
+ * @throws {KeyProviderNotFoundError} when no key provider has been registered for
752
+ * `address`.
753
+ */
754
+ setDefaultSigner(address: string): this;
755
+ /**
756
+ * Returns the default signer address, or throws if none is set.
757
+ *
758
+ * @throws {DefaultSignerNotSetError} when no default signer is configured.
759
+ */
760
+ getAddress(): Promise<string>;
761
+ /**
762
+ * @throws {DefaultSignerNotSetError} when no default signer is configured.
763
+ * @throws {KeyProviderNotFoundError} when the default address has no registered provider.
764
+ */
765
+ getPublicKey(): Promise<Uint8Array>;
766
+ /**
767
+ * Signs using the default signer.
768
+ *
769
+ * @throws {DefaultSignerNotSetError} when no default signer is configured.
770
+ * @throws {KeyProviderNotFoundError} when the default address has no registered provider.
771
+ */
772
+ signTransaction(unsignedTx: UnsignedTransactionV1, sealPublicKey: Uint8Array): Promise<TransactionSignature[]>;
773
+ /**
774
+ * Generates `TransactionAuthorization` (signatures) for a specific registered signer.
775
+ * Mirrors `OotleWallet::authorize_transaction` from ootle-rs.
776
+ *
777
+ * @throws {KeyProviderNotFoundError} when no provider is registered for `signerAddress`.
778
+ */
779
+ authorizeTransaction(signerAddress: string, unsignedTx: UnsignedTransactionV1, sealPublicKey: Uint8Array): Promise<TransactionAuthorization>;
780
+ /**
781
+ * Collects authorizations from all registered key providers.
782
+ * Useful when a transaction requires multiple signers.
783
+ */
784
+ authorizeTransactionAll(unsignedTx: UnsignedTransactionV1, sealPublicKey: Uint8Array): Promise<TransactionAuthorization[]>;
785
+ /**
786
+ * Returns the key provider for a specific address, if registered.
787
+ */
788
+ getKeyProvider(address: string): Signer | undefined;
789
+ /**
790
+ * Returns all registered signer addresses.
791
+ */
792
+ getSignerAddresses(): string[];
793
+ private getSignerOrThrow;
794
+ private requireKeyProvider;
795
+ }
796
+
797
+ /** Raised when an in-flight operation was cancelled by the caller. */
798
+ export declare class OperationCancelledError extends OotleError {
799
+ }
800
+
801
+ /**
802
+ * A stealth output to create.
803
+ *
804
+ * Use {@link createOutput} to construct one with the conventional defaults
805
+ * (`payTo = { StealthPublicKey: {} }`, `minimumValuePromise = 0n`) and
806
+ * validation (rejects `amount <= 0n`).
807
+ */
808
+ export declare interface Output {
809
+ /** Destination account address (a string component/account address). */
810
+ destination: string;
811
+ /** µTari amount to send (must be `> 0n`). */
812
+ amount: bigint;
813
+ /** Resource being transferred. */
814
+ resourceAddress: ResourceAddress;
815
+ /** Resource view key — set only for resources with a viewable balance. */
816
+ resourceViewKey?: Uint8Array;
817
+ /** Optional structured memo attached to the output. */
818
+ memo?: object;
819
+ /** Spend condition for the output; defaults to `{ StealthPublicKey: {} }`. */
820
+ payTo: object;
821
+ /** Minimum value promise (range-proof lower bound); defaults to `0n`. */
822
+ minimumValuePromise: bigint;
823
+ }
824
+
825
+ /** Fields callers supply to {@link createOutput}; `payTo` and `minimumValuePromise` are defaulted. */
826
+ export declare interface OutputInit {
827
+ destination: string;
828
+ amount: bigint;
829
+ resourceAddress: ResourceAddress;
830
+ resourceViewKey?: Uint8Array;
831
+ memo?: object;
832
+ payTo?: object;
833
+ minimumValuePromise?: bigint;
834
+ }
835
+
836
+ /** A parsed, spendable UTXO: its commitment (from the id) plus the on-chain output body. */
837
+ export declare interface ParsedUtxo {
838
+ /** 32-byte Pedersen commitment, derived from the substate id via {@link commitmentOf}. */
839
+ commitment: Uint8Array;
840
+ /** The on-chain output body (`public_nonce`, `encrypted_data`, ...). */
841
+ body: OutputBody;
842
+ }
843
+
844
+ /**
845
+ * A parsed workspace key string into an object with name and optional offset.
846
+ *
847
+ * Examples:
848
+ * "bucket" -> { name: "bucket", offset: null }
849
+ * "bucket.0" -> { name: "bucket", offset: 0 }
850
+ */
851
+ export declare interface ParsedWorkspaceKey {
852
+ name: string;
853
+ offset: number | null;
854
+ }
855
+
856
+ /**
857
+ * Parse a fetched substate into a {@link ParsedUtxo}, or `null` when it is not a
858
+ * live, spendable stealth UTXO.
859
+ *
860
+ * Returns `null` when:
861
+ * - the substate is not the `Utxo` arm of {@link SubstateValue} (e.g. a component/vault),
862
+ * - the UTXO has been spent (`output === null`),
863
+ * - the UTXO is frozen (`is_frozen === true`),
864
+ * - or the substate id does not yield a valid 32-byte commitment.
865
+ *
866
+ * @param substate - The fetched substate response.
867
+ * @param substateId - The substate id the response was fetched by (source of the commitment).
868
+ */
869
+ export declare function parseSubstateUtxo(substate: IndexerGetSubstateResponse, substateId: string): ParsedUtxo | null;
870
+
871
+ /**
872
+ * Parses a workspace key string, supporting dot-notation offsets.
873
+ *
874
+ * @example
875
+ * parseWorkspaceStringKey("bucket") // { name: "bucket", offset: null }
876
+ * parseWorkspaceStringKey("bucket.0") // { name: "bucket", offset: 0 }
877
+ * parseWorkspaceStringKey("bucket.1") // { name: "bucket", offset: 1 }
878
+ *
879
+ * @throws {InvalidArgumentError} if the key contains more than one dot, or if the
880
+ * suffix after the dot is empty / non-numeric / negative.
881
+ */
882
+ export declare function parseWorkspaceStringKey(key: string): ParsedWorkspaceKey;
883
+
884
+ /**
885
+ * Patch the single stealth instruction in `unsignedTx` with a (hydrated) statement.
886
+ *
887
+ * Locates the sole `StealthTransfer` instruction (throws if there is not exactly one) and
888
+ * replaces its `statement` field with the byte-exact compact JSON of `statement` (via the
889
+ * single encoding seam in `instruction.ts`). Returns a new `UnsignedTransactionV1` — the
890
+ * input is not mutated.
891
+ *
892
+ * @throws {InvalidArgumentError} when there is no StealthTransfer instruction (not a
893
+ * stealth tx) or more than one (malformed).
894
+ */
895
+ export declare function patchStealthStatement(unsignedTx: UnsignedTransactionV1, statement: StealthTransferStatement): UnsignedTransactionV1;
896
+
897
+ /**
898
+ * A Provider reads chain state and submits transactions. It has no signing capability.
899
+ * The canonical implementation is IndexerProvider, which talks to the indexer REST API.
900
+ */
901
+ export declare interface Provider {
902
+ /** Returns the network this provider is connected to. */
903
+ network(): Network;
904
+ /**
905
+ * Returns the epoch the network is currently on.
906
+ *
907
+ * Every transaction carries a mandatory `max_epoch`, capped at
908
+ * `MAX_TRANSACTION_VALIDITY_EPOCHS` past this value, so a builder needs the chain tip
909
+ * before it can be constructed: `TransactionBuilder.new(network, await
910
+ * provider.getCurrentEpoch() + 10)`.
911
+ */
912
+ getCurrentEpoch(): Promise<number>;
913
+ /** Fetches a single substate by ID and optional version. */
914
+ getSubstate(substateId: string, version?: number | null): Promise<IndexerGetSubstateResponse>;
915
+ /**
916
+ * Fetches a stealth UTXO substate by resource address + 32-byte commitment.
917
+ *
918
+ * The provider owns the `utxo_{resourceHex}_{commitmentHex}` id format; callers pass
919
+ * the resource and commitment and never string the id themselves. Returns `null` when
920
+ * the UTXO does not exist (already spent / never created), instead of throwing.
921
+ */
922
+ getStealthUtxo(resourceAddress: string, commitment: Uint8Array): Promise<IndexerGetSubstateResponse | null>;
923
+ /** Fetches multiple substates by ID in a single request. */
924
+ fetchSubstates(requests: SubstateId[]): Promise<GetSubstatesResponse>;
925
+ /** Returns the ABI definition for a published template. */
926
+ getTemplateDefinition(templateAddress: string): Promise<GetTemplateDefinitionResponse>;
927
+ /**
928
+ * Submits a BOR+base64-encoded transaction envelope to the network.
929
+ * Encoding is performed by `sealTransaction` in `transaction.ts`.
930
+ */
931
+ submitTransaction(envelope: TransactionEnvelope): Promise<IndexerSubmitTransactionResponse>;
932
+ /** Polls for the result of a previously submitted transaction. */
933
+ getTransactionResult(transactionId: string): Promise<IndexerGetTransactionResultResponse>;
934
+ /**
935
+ * Resolves unversioned inputs by fetching their current version from the indexer.
936
+ * Returns the same list with `version` filled in for any entry that had `version: null`.
937
+ */
938
+ resolveInputs(inputs: SubstateRequirement[]): Promise<SubstateRequirement[]>;
939
+ /** Lists recent transactions. */
940
+ listRecentTransactions(params: ListRecentTransactionsRequest): Promise<ListRecentTransactionsResponse>;
941
+ }
942
+
943
+ /**
944
+ * CBOR-encode a `RistrettoPublicKeyBytes` as a 32-byte CBOR byte string. A
945
+ * compressed Ristretto point is *not* a tagged value — it is a bare byte string,
946
+ * the same shape {@link bytesLiteral} produces. Accepts a 64-hex-char string or
947
+ * a 32-byte `Uint8Array`; this wrapper exists so the public-key intent and the
948
+ * length check are explicit at the call site.
949
+ *
950
+ * @throws {InvalidArgumentError} if the key is not exactly 32 bytes.
951
+ */
952
+ export declare function publicKeyLiteral(value: RistrettoPublicKeyBytes | Uint8Array): InstructionArg;
953
+
954
+ /**
955
+ * A stealth input resolved during {@link WalletStealthAuthorizer.prepare}: the input being
956
+ * spent, its owner address (the one-time signer), the recovered blinding mask, and the
957
+ * sender public nonce read from the fetched UTXO body (the DH counterparty for one-time
958
+ * signing). Insertion-ordered, matching `spec.inputs`.
959
+ */
960
+ declare interface ResolvedStealthInput {
961
+ ownerAddr: string;
962
+ input: StealthInput;
963
+ mask: Mask;
964
+ /** The fetched UTXO's sender public nonce (`OutputBody.public_nonce`), raw bytes. */
965
+ publicNonce: Uint8Array;
966
+ }
967
+
968
+ /**
969
+ * Reads the chain tip and returns the `max_epoch` a transaction built now should carry:
970
+ * `currentEpoch + leadEpochs`.
971
+ *
972
+ * ```ts
973
+ * const builder = TransactionBuilder.new(provider.network(), await resolveMaxEpoch(provider));
974
+ * ```
975
+ *
976
+ * @throws {InvalidArgumentError} if `leadEpochs` is not a positive integer, or exceeds
977
+ * {@link MAX_TRANSACTION_VALIDITY_EPOCHS} (which the network would reject with
978
+ * `AbortReason::ValidityWindowTooLong`).
979
+ */
980
+ export declare function resolveMaxEpoch(provider: Provider, leadEpochs?: number): Promise<number>;
981
+
982
+ /**
983
+ * Resolves unversioned inputs in the unsigned transaction by fetching their current
984
+ * version from the provider.
985
+ */
986
+ export declare function resolveTransaction(provider: Provider, unsignedTx: UnsignedTransactionV1): Promise<UnsignedTransactionV1>;
987
+
988
+ /**
989
+ * CBOR-encode a `ResourceAddress` as `Tag(131, bytes(32))`. Accepts either the
990
+ * `resource_<hex>` form or the bare 64-hex-char tail.
991
+ *
992
+ * @throws {InvalidArgumentError} if the address body is not 32 bytes (64 hex chars).
993
+ */
994
+ export declare function resourceAddressLiteral(address: ResourceAddress): InstructionArg;
995
+
996
+ /**
997
+ * A seal keypair: the throwaway key the seal signature is produced with.
998
+ *
999
+ * Both fields are expected to be exactly 32 bytes. The length invariant is
1000
+ * enforced at the trust boundary (in {@link signTransaction}) rather than via
1001
+ * a branded type — see the README scope decision on asserted-`Uint8Array` as
1002
+ * the default for non-stealth 32-byte values.
1003
+ */
1004
+ export declare interface SealKeypair {
1005
+ secret_key: Uint8Array;
1006
+ public_key: Uint8Array;
1007
+ }
1008
+
1009
+ /**
1010
+ * BOR-encodes a {@link SignedTransaction} into a TransactionEnvelope.
1011
+ *
1012
+ * Encodes the byte-exact `sealedJson` directly (never the parsed `transaction` view), so
1013
+ * u64 amounts above 2^53 are not corrupted by a `JSON.parse` → `JSON.stringify` round-trip.
1014
+ */
1015
+ export declare function sealTransaction(signed: SignedTransaction): TransactionEnvelope;
1016
+
1017
+ /**
1018
+ * Like `sendTransaction` but sets `dry_run = true` on the transaction before
1019
+ * submitting, so the network simulates execution without committing state.
1020
+ */
1021
+ export declare function sendDryRun(provider: Provider, signers: Signer | Signer[], unsignedTx: UnsignedTransactionV1, watchOpts?: WatchOptions): Promise<IndexerGetTransactionResultResponse>;
1022
+
1023
+ /**
1024
+ * All-in-one convenience function: resolve → sign → encode → submit → watch.
1025
+ */
1026
+ export declare function sendTransaction(provider: Provider, signers: Signer | Signer[], unsignedTx: UnsignedTransactionV1, watchOpts?: WatchOptions): Promise<IndexerGetTransactionResultResponse>;
1027
+
1028
+ /**
1029
+ * Serialize an unsigned transaction to the JSON string handed to WASM (`addTransactionSigner`,
1030
+ * `sealTransaction`) and to one-time stealth-signature hashing.
1031
+ *
1032
+ * Identical to `JSON.stringify(unsignedTx)` for any fragment-free transaction — so existing
1033
+ * transaction hashes do not shift — but a stealth `statement` is carried as a
1034
+ * {@link RawJsonFragment} whose byte-exact `toCompactJson()` string must survive verbatim. Its
1035
+ * u64 amounts are bare JSON numbers exceeding 2^53; `JSON.stringify` cannot emit them
1036
+ * losslessly. We therefore stringify each carrier as a unique placeholder, then splice the raw
1037
+ * fragment in place of the quoted placeholder, never round-tripping the amounts through a JS
1038
+ * number.
1039
+ *
1040
+ * Any `bigint` field (e.g. a large `nonce`) is emitted as a decimal *string*, matching the
1041
+ * Tari clients' wire encoding: every 64-bit field on these APIs accepts a string as well as a
1042
+ * number, and a string is the only lossless encoding above `Number.MAX_SAFE_INTEGER`. Plain
1043
+ * `JSON.stringify` throws on a `bigint`, and the global `BigInt.prototype.toJSON` patch the
1044
+ * client packages used to install was removed in 0.39.
1045
+ */
1046
+ export declare function serializeUnsignedTx(unsignedTx: UnsignedTransactionV1): string;
1047
+
1048
+ /**
1049
+ * Sign the balance proof over an inputs + outputs statement pair.
1050
+ *
1051
+ * A transfer with **no stealth inputs** uses `inputMask = Mask.zero()`; a
1052
+ * **fully-revealed** transfer omits the balance proof entirely (not called here).
1053
+ *
1054
+ * @returns The `(public_nonce, signature)` balance-proof signature.
1055
+ */
1056
+ export declare function signBalanceProof(crypto: StealthCryptoProvider, inputMask: Mask, outputMask: Mask, inputsStatement: StealthInputsStatement, outputsStatement: StealthOutputsStatement): Promise<BalanceProofSignature>;
1057
+
1058
+ /**
1059
+ * A signed transaction produced by {@link signTransaction}, ready to be sealed.
1060
+ *
1061
+ * Carries the byte-exact `sealedJson` string emitted by WASM **alongside** a parsed
1062
+ * {@link Transaction} view. The two are intentionally separate:
1063
+ *
1064
+ * - `sealedJson` is the **canonical artifact**. It preserves u64 amounts that exceed
1065
+ * `Number.MAX_SAFE_INTEGER` (e.g. a confidential output's `minimum_value_promise`),
1066
+ * which the engine emits as bare JSON numbers. {@link sealTransaction} BOR-encodes
1067
+ * this string directly — it never re-stringifies the parsed object.
1068
+ * - `transaction` is a **convenience view for inspection only**. It is the result of
1069
+ * `JSON.parse(sealedJson)`, so any bare integer above 2^53 has already been rounded.
1070
+ * Re-serialising it (`JSON.stringify`) and submitting that is lossy — always seal via
1071
+ * `sealedJson`.
1072
+ */
1073
+ export declare interface SignedTransaction {
1074
+ /** The byte-exact sealed-transaction JSON from WASM — the canonical bytes to BOR-encode. */
1075
+ readonly sealedJson: string;
1076
+ /**
1077
+ * Parsed view of {@link sealedJson} for inspection. Lossy for u64 amounts > 2^53 — do
1078
+ * NOT re-serialise this for submission; seal via {@link sealedJson} instead.
1079
+ */
1080
+ readonly transaction: Transaction;
1081
+ }
1082
+
1083
+ /**
1084
+ * A Signer is responsible only for signing. It has no read or submit capability.
1085
+ * Implementations include SecretKeyWallet (local WASM signing) and WalletDaemonSigner (remote daemon).
1086
+ */
1087
+ export declare interface Signer {
1088
+ /** Returns the component address derived from this signer's public key. */
1089
+ getAddress(): Promise<string>;
1090
+ /** Returns the raw public key bytes for this signer. */
1091
+ getPublicKey(): Promise<Uint8Array>;
1092
+ /**
1093
+ * Signs the given unsigned transaction and returns the collected signatures.
1094
+ *
1095
+ * `sealPublicKey` is mixed into the transaction hash
1096
+ * (`hashUnsignedTransaction(JSON.stringify(tx), sealPublicKey)`) so every signature in the
1097
+ * final envelope verifies against the SAME hash — the engine's seal verification enforces
1098
+ * this. Implementations MUST hash with the supplied `sealPublicKey`, not their own.
1099
+ */
1100
+ signTransaction(transaction: UnsignedTransactionV1, sealPublicKey: Uint8Array): Promise<TransactionSignature[]>;
1101
+ /**
1102
+ * Returns the view-only secret for stealth scanning/spending, if this signer holds one.
1103
+ *
1104
+ * **Optional** — a signer may not hold a view secret (e.g. `EphemeralKeySigner` has no
1105
+ * view key; `WalletDaemonSigner` keeps it server-side). The spend authorizer treats this
1106
+ * as a fallback: it takes the view secret explicitly from the transfer spec and only
1107
+ * calls this when the spec does not carry one.
1108
+ */
1109
+ getViewSecret?(): Promise<Uint8Array>;
1110
+ /**
1111
+ * Produces a one-time spend-key signature for a stealth input.
1112
+ *
1113
+ * The signer derives the one-time spend scalar (`c + k`) for the owned stealth UTXO via
1114
+ * `ctx.crypto.stealthDhSecret(...)` and signs the transaction hash with it.
1115
+ *
1116
+ * **Optional** — only signers that hold the owner secret (e.g. `SecretKeyWallet`) can
1117
+ * implement this. Daemon-delegated stealth is server-side and out of scope here.
1118
+ *
1119
+ * @param unsignedJson - The (compact) JSON of the unsigned transaction to hash + sign.
1120
+ * @param publicNonce - The stealth output's sender public nonce (the DH counterparty).
1121
+ * @param sealPublicKey - The seal signer's public key, mixed into the transaction hash
1122
+ * (mirrors the `hashUnsignedTransaction` arg used by {@link Signer.signTransaction}).
1123
+ * @param ctx - Injected crypto seam, so the signer never imports WASM directly.
1124
+ */
1125
+ addStealthSignature?(unsignedJson: string, publicNonce: Uint8Array, sealPublicKey: Uint8Array, ctx: {
1126
+ crypto: SignerStealthCrypto;
1127
+ }): Promise<TransactionSignature>;
1128
+ }
1129
+
1130
+ /** Raised when a {@link Signer} fails to sign, seal, or expose required material. */
1131
+ export declare class SignerError extends OotleError {
1132
+ }
1133
+
1134
+ /**
1135
+ * The exact subset of `StealthCryptoProvider` that {@link Signer.addStealthSignature} needs.
1136
+ *
1137
+ * Defined here alongside `Signer` so the stealth-agnostic core never depends on the stealth
1138
+ * module's full surface. The wider `StealthCryptoProvider` is structurally a supertype, so
1139
+ * `WasmStealthCrypto` and `FakeStealthCrypto` flow through as-is.
1140
+ */
1141
+ export declare interface SignerStealthCrypto {
1142
+ stealthDhSecret(networkByte: number, ownerSecret: Uint8Array, publicNonce: Uint8Array): Promise<Uint8Array>;
1143
+ }
1144
+
1145
+ /**
1146
+ * Collects signatures from all provided signers and assembles a signed transaction.
1147
+ *
1148
+ * Returns a {@link SignedTransaction} carrying the byte-exact `sealedJson` (the canonical
1149
+ * bytes {@link sealTransaction} BOR-encodes) plus a parsed `transaction` view for
1150
+ * inspection. The sealed JSON is **not** round-tripped through `JSON.parse`/`JSON.stringify`
1151
+ * on its way to the envelope, so u64 amounts above 2^53 (e.g. a confidential output's
1152
+ * `minimum_value_promise`) survive byte-exact.
1153
+ *
1154
+ * @param sealKeypair - Optional pre-generated seal keypair. When omitted, a fresh one is
1155
+ * generated internally (the default for the plain transaction flow). The stealth spend
1156
+ * authorizer passes one so the **same** seal public key flows into its one-time
1157
+ * spend-key authorizations (which hash the tx with the seal public key) and into this
1158
+ * final seal — otherwise those signatures would be over a different hash and fail to
1159
+ * verify.
1160
+ */
1161
+ export declare function signTransaction(signers: Signer[], unsignedTx: UnsignedTransactionV1, sealKeypair?: SealKeypair): Promise<SignedTransaction>;
1162
+
1163
+ /**
1164
+ * Carry a {@link StealthTransferStatement} into an instruction as a byte-exact raw JSON
1165
+ * fragment.
1166
+ *
1167
+ * The statement's u64 amounts are bare JSON numbers that routinely exceed 2^53; `JSON.parse`
1168
+ * would round them and break the signed proofs. We therefore embed the canonical
1169
+ * {@link StealthTransferStatement.toCompactJson} string verbatim under {@link RAW_JSON_FRAGMENT}
1170
+ * and let {@link serializeUnsignedTx} splice it into the serialized transaction at signing /
1171
+ * sealing / hashing time — never round-tripping it through a JS number. The engine still
1172
+ * deserialises `statement` as a struct (not a string); the splice produces exactly that.
1173
+ *
1174
+ * Nothing reads the statement object structurally after it is set (the serializers stringify
1175
+ * it wholesale and {@link patchStealthStatement} replaces the whole field), so the documented
1176
+ * cast to the binding's structured type is sound.
1177
+ */
1178
+ export declare function statementAsWire(statement: StealthTransferStatement): StealthTransferStatement_2;
1179
+
1180
+ /**
1181
+ * The single seam that hides all `@tari-project/ootle-wasm` crypto behind a
1182
+ * typed, byte/bigint interface returning the SDK's domain types.
1183
+ *
1184
+ * Every higher layer depends on **this interface**, never on raw WASM, so
1185
+ * tests can inject a {@link FakeStealthCrypto fake}. The only real
1186
+ * implementation is {@link WasmStealthCrypto}.
1187
+ *
1188
+ * All methods are **async even though the WASM is synchronous** to leave room
1189
+ * for a future off-thread / worker-backed provider without churning call sites.
1190
+ */
1191
+ export declare interface StealthCryptoProvider {
1192
+ /**
1193
+ * Build the outputs (sender) side of a transfer: one witness per spec, aggregated
1194
+ * into a canonical WASM outputs-statement plus the summed output mask.
1195
+ *
1196
+ * @param specs - The outputs to create (incl. change).
1197
+ * @param revealedOutputAmount - The un-confidential (revealed) µTari output amount.
1198
+ * @returns The WASM-produced {@link StealthOutputsStatement} and the aggregated
1199
+ * `outputMask` for the balance proof.
1200
+ */
1201
+ generateOutputsStatement(specs: Output[], revealedOutputAmount: bigint): Promise<{
1202
+ statement: StealthOutputsStatement;
1203
+ outputMask: Mask;
1204
+ }>;
1205
+ /**
1206
+ * Build the inputs (spend) side of a transfer as canonical WASM wire JSON.
1207
+ *
1208
+ * @param inputs - The stealth inputs being spent (empty for a revealed-only spend).
1209
+ * @param revealedAmount - The un-confidential (revealed) µTari input amount.
1210
+ * @returns A {@link StealthInputsStatement} carrying the WASM-produced `statementJson`.
1211
+ */
1212
+ buildInputsStatement(inputs: StealthInput[], revealedAmount: bigint): Promise<StealthInputsStatement>;
1213
+ /**
1214
+ * Sign the balance proof over the two statements' canonical wire JSONs.
1215
+ *
1216
+ * A transfer with **no stealth inputs** passes `inputMask = Mask.zero()`.
1217
+ *
1218
+ * @returns The `(public_nonce, signature)` balance-proof signature.
1219
+ */
1220
+ generateBalanceProofSignature(inputMask: Mask, outputMask: Mask, inputsStatementJson: string, outputsStatementJson: string): Promise<BalanceProofSignature>;
1221
+ /**
1222
+ * Optional client-side pre-flight check of a balance-proof signature. The
1223
+ * engine is authoritative at submission — implement as a cheap debug aid only.
1224
+ */
1225
+ validateBalanceProofSignature?(proof: BalanceProofSignature, inputsStatementJson: string, outputsStatementJson: string): Promise<boolean>;
1226
+ /**
1227
+ * Derive the 32-byte AEAD encryption key for an output's encrypted data via DH+KDF.
1228
+ *
1229
+ * - Receivers: `(viewSecret, sender_public_nonce)`.
1230
+ * - Senders: `(sender_secret_nonce, recipient_view_pub)`.
1231
+ *
1232
+ * Split from {@link unblindOutput} to mirror the WASM (`encryptedDataDhKdfAead` then
1233
+ * `unblindOutput`).
1234
+ */
1235
+ deriveAeadKey(privateKey: Uint8Array, publicKey: Uint8Array): Promise<Uint8Array>;
1236
+ /**
1237
+ * Decrypt an owned output using a precomputed AEAD key (from {@link deriveAeadKey}).
1238
+ *
1239
+ * **Throws** on AEAD failure / commitment mismatch — i.e. the output is *not owned*.
1240
+ * The receive helper catches this to mean "skip this UTXO".
1241
+ *
1242
+ * @param commitment - The output's 32-byte Pedersen commitment (from its substate id).
1243
+ * @param encryptedData - The raw ciphertext bytes.
1244
+ * @param aeadKey - The 32-byte AEAD key from {@link deriveAeadKey}.
1245
+ * @param skipMemo - When `true`, the memo is not decrypted.
1246
+ */
1247
+ unblindOutput(commitment: Uint8Array, encryptedData: Uint8Array, aeadKey: Uint8Array, skipMemo: boolean): Promise<DecryptedData>;
1248
+ /**
1249
+ * Aggregate input commitment masks into a single scalar. `masks` must be
1250
+ * non-empty; the revealed-only case (no stealth inputs) must short-circuit
1251
+ * to `Mask.zero()` at the caller instead of calling this method.
1252
+ */
1253
+ aggregateInputMasks(masks: Mask[]): Promise<Mask>;
1254
+ /**
1255
+ * Derive the one-time stealth spend scalar (`c + k`) via DH for an owned stealth UTXO.
1256
+ *
1257
+ * @param networkByte - The network byte (see `Network`).
1258
+ * @param ownerSecret - The owner's secret key.
1259
+ * @param publicNonce - The output's sender public nonce.
1260
+ * @returns The 32-byte spend scalar.
1261
+ */
1262
+ stealthDhSecret(networkByte: number, ownerSecret: Uint8Array, publicNonce: Uint8Array): Promise<Uint8Array>;
1263
+ /**
1264
+ * Structurally validate a complete transfer envelope (balance proof filled). **Throws**
1265
+ * on invalid. This is a client pre-flight (`view_key = null`); the engine is
1266
+ * authoritative for viewable-resource validation at submission.
1267
+ */
1268
+ validateTransfer(statement: StealthTransferStatement): Promise<void>;
1269
+ }
1270
+
1271
+ /**
1272
+ * A stealth input being spent, identified by its 32-byte Pedersen commitment.
1273
+ */
1274
+ export declare class StealthInput extends Bytes32 {
1275
+ constructor(commitment: Uint8Array);
1276
+ /** 32-byte commitment (defensive copy). */
1277
+ get commitment(): Uint8Array;
1278
+ toJSON(): StealthInputJson;
1279
+ static fromJSON(json: StealthInputJson): StealthInput;
1280
+ }
1281
+
1282
+ /** Wire shape of a {@link StealthInput}. */
1283
+ declare interface StealthInputJson {
1284
+ commitment: string;
1285
+ }
1286
+
1287
+ /**
1288
+ * The inputs side of a stealth transfer: the commitments being spent plus the
1289
+ * revealed (un-confidential) input amount.
1290
+ *
1291
+ * **The signed/wire JSON is produced by WASM**, not hand-rolled. This type
1292
+ * carries `(inputs, revealedAmount)` plus an optional cached `statementJson`
1293
+ * (the WASM-produced wire string). Its `toJSON()` is a **debug/structural**
1294
+ * view only — it is NOT the signed wire payload; the crypto seam fills and
1295
+ * reads `statementJson` for that.
1296
+ */
1297
+ export declare class StealthInputsStatement {
1298
+ readonly inputs: StealthInput[];
1299
+ readonly revealedAmount: bigint;
1300
+ /** Cached WASM-produced wire JSON (the canonical signed payload), once computed. */
1301
+ statementJson?: string;
1302
+ constructor(inputs: StealthInput[], revealedAmount: bigint, statementJson?: string);
1303
+ /** Revealed-only inputs statement (no confidential inputs). */
1304
+ static revealedOnly(amount: bigint): StealthInputsStatement;
1305
+ /**
1306
+ * Structural view (NOT the signed wire payload — see class docs). Amounts are
1307
+ * decimal strings to keep `bigint` out of JSON.
1308
+ */
1309
+ toJSON(): {
1310
+ inputs: StealthInputJson[];
1311
+ revealed_amount: string;
1312
+ };
1313
+ static fromJSON(json: {
1314
+ inputs: StealthInputJson[];
1315
+ revealed_amount: string;
1316
+ }): StealthInputsStatement;
1317
+ }
1318
+
1319
+ /**
1320
+ * The outputs side of a stealth transfer.
1321
+ *
1322
+ * Carries the **WASM-produced** wire payload verbatim. The internal field
1323
+ * names of that JSON are owned by the engine and are not modelled here.
1324
+ */
1325
+ export declare class StealthOutputsStatement {
1326
+ /** The canonical, WASM-produced outputs-statement wire JSON. */
1327
+ readonly statementJson: string;
1328
+ constructor(statementJson: string);
1329
+ /** Parse the carried JSON into a plain object view (the engine owns the shape). */
1330
+ parsed(): unknown;
1331
+ /** The carried wire JSON string is already canonical. */
1332
+ toJSON(): string;
1333
+ /** Reconstruct from a wire JSON string. */
1334
+ static fromJSON(statementJson: string): StealthOutputsStatement;
1335
+ }
1336
+
1337
+ /**
1338
+ * Fluent builder for a confidential (stealth) transfer.
1339
+ *
1340
+ * Supports the full input/output matrix: spend revealed input (withdraw from a vault)
1341
+ * and/or one or more confidential UTXOs ({@link spendStealthInput}), emit one or more
1342
+ * stealth outputs (+ optional revealed change), and a fee. The balance equation
1343
+ * (revealed-in + stealth-in == stealth-out + revealed-out) must hold; the stealth-input
1344
+ * value is carried by each input's mask, recovered by the authorizer.
1345
+ *
1346
+ * @example
1347
+ * ```ts
1348
+ * const spec = await new StealthTransfer(provider, resourceAddress)
1349
+ * .spendRevealedInput(account, 5n * TARI)
1350
+ * .toStealthOutput(createOutput({ destination, amount: 3n * TARI, resourceAddress }))
1351
+ * .toRevealedOutput(1n * TARI) // revealed change back to `account`
1352
+ * .payFeeFromRevealed(1n * TARI)
1353
+ * .prepare();
1354
+ * ```
1355
+ */
1356
+ export declare class StealthTransfer {
1357
+ private readonly provider;
1358
+ private readonly crypto;
1359
+ private builder;
1360
+ private readonly state;
1361
+ /** Set by {@link withMaxEpoch}; `null` means {@link prepare} resolves one from the chain tip. */
1362
+ private maxEpoch;
1363
+ /** Guards against a second {@link prepare} re-emitting instructions into the same builder. */
1364
+ private prepared;
1365
+ /**
1366
+ * Set by {@link toRevealedOutputAsBucket}; when non-null, {@link emitInstructions} leaves the
1367
+ * revealed-change bucket on the workspace under this name instead of auto-depositing it back
1368
+ * to the revealed source account.
1369
+ */
1370
+ private revealedOutputBucketVar;
1371
+ /**
1372
+ * @param provider - Read-only chain access (used by {@link prepare} to resolve inputs).
1373
+ * @param resourceAddress - The resource being transferred.
1374
+ * @param crypto - Injectable crypto seam; defaults to {@link WasmStealthCrypto}. Tests
1375
+ * pass a {@link FakeStealthCrypto} for WASM-free runs.
1376
+ */
1377
+ constructor(provider: Provider, resourceAddress: ResourceAddress, crypto?: StealthCryptoProvider);
1378
+ /**
1379
+ * Withdraw `amount` of the transfer's resource from `account`'s revealed vault.
1380
+ *
1381
+ * All revealed input must come from a single account (the fee/change source). Calling
1382
+ * this more than once accumulates the amount but the account must be the same.
1383
+ *
1384
+ * @throws {InvalidArgumentError} if `amount` is not `> 0`, or a different source
1385
+ * account is supplied on a second call.
1386
+ */
1387
+ spendRevealedInput(account: ComponentAddress, amount: bigint): this;
1388
+ /** Add a stealth output to create (repeatable). */
1389
+ toStealthOutput(spec: Output): this;
1390
+ /**
1391
+ * Add revealed (un-confidential) change, returned to the revealed source account.
1392
+ *
1393
+ * @throws {InvalidArgumentError} if `amount` is not `> 0`.
1394
+ */
1395
+ toRevealedOutput(amount: bigint): this;
1396
+ /**
1397
+ * Like {@link toRevealedOutput}, but leaves the revealed-change bucket on the workspace under
1398
+ * `workspaceVarName` instead of auto-depositing it back to the revealed source account. Pairs
1399
+ * with {@link andThen} so a caller can route Stealth-typed funds into its own follow-up
1400
+ * instructions in the same signed transaction — a plain `CallMethod withdraw` on a Stealth
1401
+ * vault is not a standalone-valid instruction; moving Stealth funds anywhere always requires
1402
+ * the native `StealthTransfer` instruction this builder already emits.
1403
+ *
1404
+ * Mutually exclusive with {@link toRevealedOutput} in the same builder — call one or the
1405
+ * other, not both, since they disagree on where the change bucket ends up.
1406
+ *
1407
+ * @throws {InvalidArgumentError} if `amount` is not `> 0`, or a different workspace name was
1408
+ * already set by an earlier call.
1409
+ */
1410
+ toRevealedOutputAsBucket(amount: bigint, workspaceVarName: string): this;
1411
+ /**
1412
+ * Append raw instructions to run in the same signed transaction, after the native
1413
+ * `StealthTransfer` instruction (and the revealed-change bucket save from
1414
+ * {@link toRevealedOutputAsBucket}, if any) — typically used to consume that bucket in a
1415
+ * custom contract call.
1416
+ *
1417
+ * Workspace variable ids are a single flat counter across the whole transaction:
1418
+ * `StealthTransfer` claims id `0` (and `1`, when there's a revealed input) internally via its
1419
+ * own `saveVar` calls before these run, so instructions referencing workspace variables by
1420
+ * **name** (`{ Workspace: "name" }`) resolve correctly through the builder's own name → id
1421
+ * map — but any instruction constructed with a raw numeric `WorkspaceOffsetId` by hand must
1422
+ * account for those already-claimed ids itself.
1423
+ */
1424
+ andThen(instructions: Instruction[]): this;
1425
+ /**
1426
+ * Pay the transaction fee from the revealed source account (max `amount`).
1427
+ *
1428
+ * @throws {InvalidArgumentError} if no source account is set, or `amount` is not `> 0`.
1429
+ */
1430
+ payFeeFromRevealed(amount: bigint): this;
1431
+ /**
1432
+ * Set the transaction's validity window explicitly. Without this, {@link prepare}
1433
+ * reads the current epoch from the provider and applies
1434
+ * `DEFAULT_TRANSACTION_VALIDITY_EPOCHS`.
1435
+ *
1436
+ * @throws {InvalidArgumentError} if `maxEpoch` is not a non-negative integer.
1437
+ */
1438
+ withMaxEpoch(maxEpoch: number): this;
1439
+ /** Escape hatch over the inner {@link TransactionBuilder} (e.g. extra instructions). */
1440
+ withBuilder(fn: (b: TransactionBuilder) => TransactionBuilder): this;
1441
+ /**
1442
+ * Spend a confidential UTXO owned by `ownerAddr`, identified by its 32-byte
1443
+ * `commitment`.
1444
+ *
1445
+ * Repeatable: each call adds another stealth input. Inputs are keyed by their
1446
+ * **commitment hex alone** and de-duplicated — a second call with the same commitment
1447
+ * throws, **regardless of the owner label**. A commitment uniquely identifies a UTXO
1448
+ * within the builder's single resource and a UTXO has exactly one owner, so the same
1449
+ * commitment under two different owner labels is still the same UTXO; accepting it twice
1450
+ * would register the substate id twice and emit the commitment twice in the inputs
1451
+ * statement — a self-double-spend the engine rejects. The owner address is recorded
1452
+ * alongside the input so the authorizer can pick the one-time spend signer for each.
1453
+ *
1454
+ * The input's value contributes to the balance equation via its **mask** (recovered by
1455
+ * the authorizer when it unblinds the UTXO), so the builder does not need the amount
1456
+ * here — only the commitment.
1457
+ *
1458
+ * @throws {InvalidArgumentError} if `commitment` is not 32 bytes, or the same
1459
+ * commitment is added twice (under any owner).
1460
+ */
1461
+ spendStealthInput(ownerAddr: string, commitment: Uint8Array): this;
1462
+ /**
1463
+ * Assemble the unsigned transaction and the (incomplete) transfer statement.
1464
+ *
1465
+ * 1. validate (≥1 input, ≥1 stealth output);
1466
+ * 2. generate the outputs statement (+ aggregated output mask) via the crypto seam;
1467
+ * 3. build the inputs statement (concatenated commitments + revealed input
1468
+ * amount) and assemble an incomplete {@link StealthTransferStatement}
1469
+ * (`balanceProof: undefined`);
1470
+ * 4. emit instructions: revealed `withdraw` → `saveVar` → the native
1471
+ * `StealthTransfer` instruction (+ deposit the revealed-change bucket);
1472
+ * 5. register the revealed source account + every vault it references as tx
1473
+ * inputs (otherwise the engine rejects `withdraw` / `pay_fee` with
1474
+ * `SubstateNotFound`);
1475
+ * 6. register each stealth input's UTXO substate id as a tx input so it is
1476
+ * resolved / locked alongside the revealed inputs;
1477
+ * 7. resolve substate versions via the provider;
1478
+ * 8. return the {@link StealthTransferSpec}.
1479
+ *
1480
+ * Stealth-input **values** are carried by their masks (recovered later by the
1481
+ * authorizer), not as amounts — there is no balance-equation check here when stealth
1482
+ * inputs are present, because the builder does not know their values; the balance proof
1483
+ * (which the authorizer signs over the recovered masks) is the authoritative check.
1484
+ *
1485
+ * @throws {InvalidArgumentError} if the builder is invalid (no inputs, no outputs,
1486
+ * no stealth output, unbalanced revealed-only transfer, or revealed change without
1487
+ * a revealed source) or `prepare` has already been called once.
1488
+ */
1489
+ prepare(): Promise<StealthTransferSpec>;
1490
+ /**
1491
+ * Build the ordered, de-duplicated list of addresses that must authorize the tx: the
1492
+ * revealed source account first (if any), then each distinct stealth-input owner in the
1493
+ * order it was first added.
1494
+ */
1495
+ private collectRequiredSigners;
1496
+ /**
1497
+ * Validate the builder before assembly: at least one input (revealed and/or stealth) and
1498
+ * at least one stealth output, plus — for the revealed-only path — the balance equation
1499
+ * `revealedInput.amount == stealthOut + revealedOut`.
1500
+ *
1501
+ * The fee is withdrawn separately by the fee instruction, not from the transferred
1502
+ * amount. When stealth inputs are present, the per-input values are unknown to the builder
1503
+ * (carried by masks), so the arithmetic check is **skipped** — the balance proof the
1504
+ * authorizer signs is authoritative. We still surface obvious wiring mistakes early.
1505
+ */
1506
+ private validate;
1507
+ /**
1508
+ * Emit the instruction sequence into the inner builder:
1509
+ * (revealed `withdraw` → `saveVar`)? → native `StealthTransfer` → deposit revealed change?
1510
+ *
1511
+ * The revealed `withdraw` and the `revealed_input_bucket` are emitted **only** when there
1512
+ * is a revealed input amount; a stealth-input-only transfer passes a `null` bucket. The
1513
+ * fee instruction (if any) was already added by {@link payFeeFromRevealed}.
1514
+ */
1515
+ private emitInstructions;
1516
+ }
1517
+
1518
+ /** The narrowed shape of the native `StealthTransfer` instruction variant. */
1519
+ export declare type StealthTransferInstruction = Extract<Instruction, {
1520
+ StealthTransfer: unknown;
1521
+ }>;
1522
+
1523
+ /**
1524
+ * Encode the native `StealthTransfer` instruction. See the file header for the on-chain
1525
+ * contract and the (probe-verified) statement-encoding rationale.
1526
+ *
1527
+ * The `revealed_input_bucket` references the saved withdraw bucket by name; the builder
1528
+ * declared that name via `saveVar`, so the {@link WorkspaceOffsetId} `{ id, offset: null }`
1529
+ * is resolved here against the same name → numeric id mapping the builder uses.
1530
+ *
1531
+ * @param init - The resource, revealed-input bucket name, and statement.
1532
+ * @param resolveBucket - Maps a workspace var name to its {@link WorkspaceOffsetId}. The
1533
+ * builder owns the name → id mapping; pass a resolver so this seam stays builder-agnostic.
1534
+ */
1535
+ export declare function stealthTransferInstruction(init: StealthTransferInstructionInit, resolveBucket: (name: string) => WorkspaceOffsetId): Instruction;
1536
+
1537
+ /** Inputs to {@link stealthTransferInstruction}. */
1538
+ export declare interface StealthTransferInstructionInit {
1539
+ /** The resource being transferred. */
1540
+ resourceAddress: ResourceAddress;
1541
+ /**
1542
+ * Workspace var name of the revealed-input bucket (from the `withdraw` + `saveVar`), or
1543
+ * `null`/omitted for a stealth-input-only transfer.
1544
+ */
1545
+ revealedInputBucket: string | null;
1546
+ /** The transfer statement (may be incomplete — `balanceProof` undefined — at build time). */
1547
+ statement: StealthTransferStatement;
1548
+ }
1549
+
1550
+ /**
1551
+ * The output of {@link StealthTransfer.prepare}: an unsigned transaction carrying the
1552
+ * on-chain stealth instruction and an **incomplete** statement (`balanceProof:
1553
+ * undefined`), plus the metadata the authorizer needs to finish it.
1554
+ */
1555
+ export declare interface StealthTransferSpec {
1556
+ /** The unsigned transaction with substate versions resolved. */
1557
+ unsignedTx: UnsignedTransactionV1;
1558
+ /** The (incomplete) transfer statement; the authorizer fills `balanceProof`. */
1559
+ statement: StealthTransferStatement;
1560
+ /** The aggregated output blinding mask, needed to sign the balance proof. */
1561
+ outputMask: Mask;
1562
+ /** The builder state (resource, inputs, amounts) — consumed by the authorizer. */
1563
+ state: StealthTransferState;
1564
+ /**
1565
+ * Addresses that must authorize the transaction. The revealed source account (when there
1566
+ * is revealed input) is required first, followed by each distinct stealth-input owner
1567
+ * (in first-seen order) — those owners supply the one-time spend-key authorizations.
1568
+ */
1569
+ requiredSigners: string[];
1570
+ /**
1571
+ * Ordered list of stealth inputs being spent, each paired with its owner address. Order
1572
+ * matches the order `spendStealthInput` was called — required for the input-mask
1573
+ * aggregation and inputs-statement build to agree on ordering.
1574
+ */
1575
+ inputs: Array<{
1576
+ input: StealthInput;
1577
+ owner: string;
1578
+ }>;
1579
+ }
1580
+
1581
+ /** Mutable internal state accumulated by a {@link StealthTransfer} builder. */
1582
+ export declare interface StealthTransferState {
1583
+ resource: ResourceAddress;
1584
+ /**
1585
+ * The revealed-source account and the total amount withdrawn from it, or `null` for a
1586
+ * stealth-input-only spend. Coupling the source and amount in one tagged field encodes the
1587
+ * invariant — a revealed input always has a source — in the type system, so consumers can
1588
+ * narrow without "unreachable" guards.
1589
+ */
1590
+ revealedInput: {
1591
+ source: ComponentAddress;
1592
+ amount: bigint;
1593
+ } | null;
1594
+ /**
1595
+ * Stealth UTXOs to spend, keyed by their **commitment hex alone** (insertion-ordered,
1596
+ * duplicates rejected). A commitment uniquely identifies a UTXO within the builder's
1597
+ * single resource, and a UTXO has exactly one owner — so keying by commitment (not
1598
+ * owner+commitment) prevents the same UTXO being registered twice under different owner
1599
+ * labels, which the engine would reject as a self-double-spend. Each value carries the
1600
+ * input alongside its owner address (the one-time spend signer). The `Map` preserves
1601
+ * insertion order so the masks aggregate and the inputs statement is built in the
1602
+ * **same** order — required for the balance proof to verify.
1603
+ */
1604
+ inputsToSpend: Map<string, {
1605
+ input: StealthInput;
1606
+ owner: string;
1607
+ }>;
1608
+ outputs: Output[];
1609
+ revealedOutputAmount: bigint;
1610
+ }
1611
+
1612
+ /**
1613
+ * The top-level stealth-transfer envelope assembled **in TS**.
1614
+ *
1615
+ * Combines the WASM-produced inputs/outputs statement JSONs with the balance-proof
1616
+ * `(public_nonce, signature)`. `balanceProof` is `undefined` until the authorizer
1617
+ * fills it in.
1618
+ *
1619
+ * Two distinct serialisations, intentionally separate:
1620
+ *
1621
+ * 1. **{@link toJSON} / {@link fromJSON}** — a purely *structural*, symmetric,
1622
+ * lossless round-trip used by tests and any TS-only persistence. It does NOT
1623
+ * re-parse WASM statement strings into JS numbers; the outputs side is carried as
1624
+ * its raw wire string.
1625
+ * 2. **{@link toCompactJson}** — the *signed wire form*. It embeds the
1626
+ * WASM-produced statement strings **byte-exact** by string concatenation of raw
1627
+ * canonical fragments — it **never** `JSON.parse`s a WASM string (raw u64 µTari
1628
+ * amounts routinely exceed 2^53, so parse→number→re-stringify silently corrupts
1629
+ * them and breaks the signature). This is the form fed to
1630
+ * `validateStealthTransfer` and any hashing/signing path.
1631
+ *
1632
+ * The **byte-exactness of the WASM fragments** in {@link toCompactJson} is
1633
+ * non-negotiable: the engine validates against the exact bytes signed.
1634
+ */
1635
+ export declare class StealthTransferStatement {
1636
+ readonly inputsStatement: StealthInputsStatement;
1637
+ readonly outputsStatement: StealthOutputsStatement;
1638
+ balanceProof?: BalanceProofSignature;
1639
+ constructor(inputsStatement: StealthInputsStatement, outputsStatement: StealthOutputsStatement, balanceProof?: BalanceProofSignature);
1640
+ /**
1641
+ * Structural view of the envelope (debug / lossless round-trip — NOT the signed
1642
+ * wire form; see {@link toCompactJson}). The inputs side is the inputs statement's
1643
+ * structural `toJSON()`; the outputs side is its **raw wire string**, carried
1644
+ * verbatim (never parsed). `balance_proof` is omitted when undefined.
1645
+ */
1646
+ toJSON(): StealthTransferStatementJson;
1647
+ /**
1648
+ * The **signed wire form**: a single canonical compact JSON string in which the
1649
+ * WASM-produced statement fragments are embedded byte-exact.
1650
+ *
1651
+ * Built by concatenating raw canonical fragments — it never `JSON.parse`s a WASM
1652
+ * statement string, so raw u64 µTari amounts (which can exceed 2^53) survive
1653
+ * uncorrupted. The inputs fragment prefers the cached WASM `statementJson` (the
1654
+ * canonical signed bytes); it falls back to `JSON.stringify` of the structural
1655
+ * inputs view only when no WASM string is present (the revealed-only / test case).
1656
+ * The outputs fragment is always the raw WASM `statementJson` string. The
1657
+ * balance-proof object is small, all-hex (no large integers), so it routes through
1658
+ * `JSON.stringify` safely.
1659
+ *
1660
+ * @throws {InvalidArgumentError} if either statement fragment is not a JSON object.
1661
+ */
1662
+ toCompactJson(): string;
1663
+ /** Reconstruct from the structural {@link toJSON} shape. Symmetric and lossless. */
1664
+ static fromJSON(json: StealthTransferStatementJson): StealthTransferStatement;
1665
+ }
1666
+
1667
+ /**
1668
+ * Structural wire shape of a {@link StealthTransferStatement} envelope.
1669
+ *
1670
+ * This is the **debug / round-trip** shape produced by `toJSON()` and consumed by
1671
+ * `fromJSON()` — it is symmetric and lossless for a TS-only envelope. It is **NOT**
1672
+ * the signed wire form: see {@link StealthTransferStatement.toCompactJson}.
1673
+ *
1674
+ * - `inputs` is the structural inputs-statement view (`{ inputs, revealed_amount }`).
1675
+ * - `outputs` is the **raw `StealthOutputsStatement` wire string** (carried verbatim),
1676
+ * never a parsed object — parsing-then-restringifying WASM u64 amounts is lossy.
1677
+ */
1678
+ declare interface StealthTransferStatementJson {
1679
+ inputs: {
1680
+ inputs: StealthInputJson[];
1681
+ revealed_amount: string;
1682
+ };
1683
+ outputs: string;
1684
+ balance_proof?: BalanceProofSignatureJson;
1685
+ }
1686
+
1687
+ /**
1688
+ * Compose a stealth UTXO substate id from a resource address and a 32-byte commitment.
1689
+ *
1690
+ * The id format is `utxo_{resourceHex}_{commitmentHex}`, where `resourceHex` is the
1691
+ * resource address with its `resource_` prefix stripped (a bare hex string is accepted
1692
+ * verbatim). This is the inverse of {@link commitmentOf} and matches the id the
1693
+ * `IndexerProvider.getStealthUtxo` fetch composes, so the spend builder can register a
1694
+ * stealth input as a tx input **without** reaching into the concrete indexer client.
1695
+ *
1696
+ * @param resourceAddress - The resource address (`resource_<hex>`) or a bare hex string.
1697
+ * @param commitment - The output's 32-byte Pedersen commitment.
1698
+ * @returns The `utxo_{resourceHex}_{commitmentHex}` substate id.
1699
+ */
1700
+ export declare function stealthUtxoSubstateId(resourceAddress: string, commitment: Uint8Array): string;
1701
+
1702
+ /** CBOR-encode a `String` as a CBOR text string. */
1703
+ export declare function stringLiteral(value: string): InstructionArg;
1704
+
1705
+ /**
1706
+ * Submits an encoded transaction envelope and returns the transaction ID.
1707
+ */
1708
+ export declare function submitTransaction(provider: Provider, envelope: TransactionEnvelope): Promise<string>;
1709
+
1710
+ export { SubstateId }
1711
+
1712
+ export { SubstateRequirement }
1713
+
1714
+ /**
1715
+ * Native TARI (XTR) token resource address (object key `[1u8; 32]`). Used for
1716
+ * all native-token transfers and stealth confidential outputs.
1717
+ */
1718
+ export declare const TARI_RESOURCE_ADDRESS = "resource_0101010101010101010101010101010101010101010101010101010101010101";
1719
+
1720
+ /** A function that can be called on a published template. */
1721
+ export declare interface TariFunctionDefinition {
1722
+ templateAddress: PublishedTemplateAddress;
1723
+ functionName: string;
1724
+ args?: NamedArg[];
1725
+ }
1726
+
1727
+ /** A method that can be called on a component. */
1728
+ export declare interface TariMethodDefinition {
1729
+ methodName: string;
1730
+ args?: NamedArg[];
1731
+ /** Call by component address. Mutually exclusive with `fromWorkspace`. */
1732
+ componentAddress?: ComponentAddress;
1733
+ /** Call the component stored under this workspace key. Mutually exclusive with `componentAddress`. */
1734
+ fromWorkspace?: string;
1735
+ }
1736
+
1737
+ /**
1738
+ * CBOR-encode a `PublishedTemplateAddress` as `Tag(137, bytes(32))`. Accepts
1739
+ * either the `template_<hex>` form or the bare 64-hex-char tail.
1740
+ *
1741
+ * @throws {InvalidArgumentError} if the address body is not 32 bytes (64 hex chars).
1742
+ */
1743
+ export declare function templateAddressLiteral(address: PublishedTemplateAddress): InstructionArg;
1744
+
1745
+ /**
1746
+ * Implemented by types that can produce a component address string.
1747
+ * Mirrors the `ToAccountAddress` trait from ootle-rs.
1748
+ */
1749
+ export declare interface ToAccountAddress {
1750
+ toAccountAddress(): string;
1751
+ }
1752
+
1753
+ export declare function toHexStr(uint8: Uint8Array): string;
1754
+
1755
+ export { Transaction }
1756
+
1757
+ /**
1758
+ * The result of authorizing a transaction: a set of signatures from one signer.
1759
+ * Mirrors `TransactionAuthorization` from the Rust ootle-rs crate.
1760
+ */
1761
+ export declare interface TransactionAuthorization {
1762
+ signerAddress: string;
1763
+ signatures: TransactionSignature[];
1764
+ }
1765
+
1766
+ /**
1767
+ * Fluent builder for constructing UnsignedTransactionV1 objects.
1768
+ *
1769
+ * Only `buildUnsignedTransaction()` is exposed — signing is handled separately
1770
+ * via the `Signer` interface and `signTransaction` flow function.
1771
+ */
1772
+ export declare class TransactionBuilder {
1773
+ private unsignedTransaction;
1774
+ private workspaceIds;
1775
+ private feeWorkspaceIds;
1776
+ /**
1777
+ * `maxEpoch` is required: every transaction now carries a bounded validity window
1778
+ * (`UnsignedTransactionV1.max_epoch`), so the last epoch in which it may be sequenced
1779
+ * is decided up front rather than left open. The network rejects a window longer than
1780
+ * {@link MAX_TRANSACTION_VALIDITY_EPOCHS} epochs past the current one with
1781
+ * `AbortReason::ValidityWindowTooLong`, so derive it from the chain tip — e.g.
1782
+ * `(await provider.getCurrentEpoch()) + 10`.
1783
+ *
1784
+ * @throws {InvalidArgumentError} if `maxEpoch` is not a non-negative integer.
1785
+ */
1786
+ constructor(network: Network | number, maxEpoch: number);
1787
+ static new(network: Network | number, maxEpoch: number): TransactionBuilder;
1788
+ callFunction<T extends TariFunctionDefinition>(func: T, args: Exclude<T["args"], undefined>): this;
1789
+ /**
1790
+ * @throws {InvalidArgumentError} if `method` provides neither `componentAddress`
1791
+ * nor `fromWorkspace`, or if `fromWorkspace` references an undefined variable.
1792
+ */
1793
+ callMethod<T extends TariMethodDefinition>(method: T, args: Exclude<T["args"], undefined>): this;
1794
+ createAccount(ownerPublicKey: string, workspaceBucket?: string): this;
1795
+ createProof(account: ComponentAddress, resourceAddress: ResourceAddress): this;
1796
+ claimBurn(claim: MinotariBurnClaimProof, output_data: ClaimBurnOutputData): this;
1797
+ allocateAddress(allocatableType: AllocatableAddressType, workspaceIdName: string): this;
1798
+ /**
1799
+ * Saves the last instruction output to a named workspace variable.
1800
+ * The variable can be referenced by subsequent instructions using `{ Workspace: "name" }`.
1801
+ */
1802
+ saveVar(name: string): this;
1803
+ /**
1804
+ * Adds a fee instruction that calls `pay_fee` on the given component.
1805
+ * The component must call `vault.pay_fee` and reveal enough confidential XTR.
1806
+ */
1807
+ feeTransactionPayFromComponent(componentAddress: ComponentAddress, maxFee: bigint): this;
1808
+ /**
1809
+ * NOT IMPLEMENTED — always throws. A confidential `pay_fee` needs a
1810
+ * `ConfidentialWithdrawProof` `Literal` that requires `tari_bor` struct encoding
1811
+ * the TS SDK does not yet provide. Use {@link feeTransactionPayFromComponent} for
1812
+ * revealed-fee payment.
1813
+ *
1814
+ * @throws {InvalidArgumentError} always.
1815
+ */
1816
+ feeTransactionPayFromComponentConfidential(_componentAddress: ComponentAddress, _proof: ConfidentialWithdrawProof): this;
1817
+ dropAllProofsInWorkspace(): this;
1818
+ /**
1819
+ * Publishes a compiled WASM template. The binary is stored as a transaction
1820
+ * blob and referenced by index from the `PublishTemplate` instruction.
1821
+ *
1822
+ * @param binaryBase64 the template WASM, standard-base64 encoded
1823
+ * @param metadataHash optional multihash of off-chain CBOR metadata
1824
+ */
1825
+ publishTemplate(binaryBase64: string, metadataHash?: string | null): this;
1826
+ addInstruction(instruction: Instruction): this;
1827
+ addFeeInstruction(instruction: Instruction): this;
1828
+ withInstructions(instructions: Instruction[]): this;
1829
+ withFeeInstructions(instructions: Instruction[]): this;
1830
+ /**
1831
+ * Account for slots claimed by instructions the builder did not allocate itself, so a
1832
+ * later `saveVar` cannot re-issue one. Rust does this inline in `add_instruction`.
1833
+ */
1834
+ private observeAllocations;
1835
+ /**
1836
+ * Build the fee instructions with a nested builder, mirroring the Rust builder's separate
1837
+ * fee-instruction builder. The nested builder gets its own workspace scope — correct,
1838
+ * because the engine clears the workspace between the fee and main instruction runs.
1839
+ *
1840
+ * Note this REPLACES any fee instructions already set, as it always has.
1841
+ */
1842
+ withFeeInstructionsBuilder(builder: (b: TransactionBuilder) => TransactionBuilder): this;
1843
+ addInput(input: SubstateRequirement): this;
1844
+ withInputs(inputs: SubstateRequirement[]): this;
1845
+ /** @throws {InvalidArgumentError} if `minEpoch` is not a non-negative integer. */
1846
+ withMinEpoch(minEpoch: number): this;
1847
+ /**
1848
+ * Overrides the validity window set at construction. See the constructor for the
1849
+ * network's cap on how far ahead of the current epoch this may sit.
1850
+ *
1851
+ * @throws {InvalidArgumentError} if `maxEpoch` is not a non-negative integer.
1852
+ */
1853
+ withMaxEpoch(maxEpoch: number): this;
1854
+ /**
1855
+ * Stamps the transaction nonce, which distinguishes otherwise-identical transactions.
1856
+ *
1857
+ * The transaction id excludes the seal signature's witness data, so two identical
1858
+ * bodies sealed by the same key are the *same* transaction — submitting both executes
1859
+ * once. Give each intent a distinct nonce when repeated submissions must each execute.
1860
+ * Defaults to `0`.
1861
+ *
1862
+ * @throws {InvalidArgumentError} if `nonce` is negative or overflows u64.
1863
+ */
1864
+ withNonce(nonce: number | bigint): this;
1865
+ /**
1866
+ * Adopt an existing transaction and keep building on it.
1867
+ *
1868
+ * The adopted transaction is **copied**, not aliased: subsequent builder calls must not
1869
+ * reach back into the caller's object. The manual co-signing flow ships
1870
+ * `JSON.stringify(unsigned)` across a boundary, so mutating a transaction the caller has
1871
+ * already serialized or signed makes the two sides disagree — surfacing only at submit
1872
+ * time as the opaque engine error `"Transaction has one or more invalid signature(s)"`.
1873
+ * This mirrors the copy {@link buildUnsignedTransaction} makes on the way out.
1874
+ */
1875
+ withUnsignedTransaction(unsignedTransaction: UnsignedTransactionV1): this;
1876
+ /**
1877
+ * Resolves a workspace variable name (supporting dot-notation offsets, e.g. `"bucket.0"`)
1878
+ * to its `WorkspaceOffsetId`. The variable must have been declared by a prior `saveVar`
1879
+ * (or other allocating call). Use this when constructing an `Instruction` that takes a
1880
+ * `WorkspaceOffsetId` directly (e.g. the native `StealthTransfer` variant's
1881
+ * `revealed_input_bucket`), where the builder's automatic `{ Workspace: "name" }` arg
1882
+ * resolution does not apply.
1883
+ *
1884
+ * @throws {InvalidArgumentError} if no workspace variable with that name has been defined.
1885
+ */
1886
+ resolveWorkspaceOffsetId(name: string): WorkspaceOffsetId;
1887
+ buildUnsignedTransaction(): UnsignedTransactionV1;
1888
+ private addNamedId;
1889
+ private requireNamedId;
1890
+ private getOffsetIdFromWorkspaceName;
1891
+ private resolveArgs;
1892
+ }
1893
+
1894
+ export { TransactionEnvelope }
1895
+
1896
+ /**
1897
+ * The classified result of a finalized transaction.
1898
+ *
1899
+ * - `"Commit"` — all instructions committed successfully.
1900
+ * - `"FeeIntentCommit"` — fee instructions committed but execution was aborted
1901
+ * (the network accepted the fee intent but rejected the rest).
1902
+ * - `"Reject"` — the entire transaction was rejected.
1903
+ */
1904
+ export declare interface TransactionOutcome {
1905
+ outcome: FinalizeOutcome | "Reject";
1906
+ reason?: string;
1907
+ }
1908
+
1909
+ /**
1910
+ * Raised when consensus rejects a transaction.
1911
+ *
1912
+ * `txId` is the rejected transaction's identifier; `reason` is the human-readable
1913
+ * reason (the indexer's `abort_details` string or a `JSON.stringify` of the abort
1914
+ * variant when no string was supplied). `rejectReason` is the structured engine
1915
+ * reject reason if available — currently optional because the indexer's
1916
+ * `Decision.Abort` carries the lighter `AbortReason` shape, not the full
1917
+ * `RejectReason`. Callers should branch on `reason` (string) for most cases.
1918
+ */
1919
+ export declare class TransactionRejectedError extends OotleError {
1920
+ readonly txId: string;
1921
+ readonly reason: string;
1922
+ readonly rejectReason?: RejectReason;
1923
+ constructor(message: string, options: ErrorOptions & {
1924
+ txId: string;
1925
+ reason: string;
1926
+ rejectReason?: RejectReason;
1927
+ });
1928
+ }
1929
+
1930
+ export { TransactionSignature }
1931
+
1932
+ /** Raised when polling / SSE both timed out before the transaction finalized. */
1933
+ export declare class TransactionTimeoutError extends OotleError {
1934
+ readonly txId: string;
1935
+ constructor(message: string, options: ErrorOptions & {
1936
+ txId: string;
1937
+ });
1938
+ }
1939
+
1940
+ export { TransactionV1 }
1941
+
1942
+ export { UnsealedTransactionV1 }
1943
+
1944
+ export { UnsignedTransactionV1 }
1945
+
1946
+ /**
1947
+ * `UnsignedTransactionV1` with the `blobs` list: standard-base64 payloads
1948
+ * referenced from instructions by index (see {@link TransactionBuilder.publishTemplate}).
1949
+ *
1950
+ * @deprecated `blobs` is now a field of `UnsignedTransactionV1` itself (ootle-ts-bindings
1951
+ * ≥ 1.47), so this intersection adds nothing. Kept as an alias for one release; use
1952
+ * `UnsignedTransactionV1` directly.
1953
+ */
1954
+ export declare type UnsignedTransactionWithBlobs = UnsignedTransactionV1;
1955
+
1956
+ /**
1957
+ * CBOR-encode a `UtxoAddress` as `Tag(141, [ResourceAddress, UtxoId])`, where the
1958
+ * `UtxoId` is the 32-byte commitment byte string.
1959
+ *
1960
+ * @throws {InvalidArgumentError} if the resource address or id is not 32 bytes.
1961
+ */
1962
+ export declare function utxoAddressLiteral(address: UtxoAddress): InstructionArg;
1963
+
1964
+ /**
1965
+ * CBOR-encode a `ValidatorFeePoolAddress` as `Tag(138, bytes(32))`. Accepts
1966
+ * either the `vnfp_<hex>` form or the bare 64-hex-char tail.
1967
+ *
1968
+ * @throws {InvalidArgumentError} if the address body is not 32 bytes (64 hex chars).
1969
+ */
1970
+ export declare function validatorFeePoolAddressLiteral(address: ValidatorFeePoolAddress): InstructionArg;
1971
+
1972
+ /**
1973
+ * CBOR-encode a `VaultId` as `Tag(132, bytes(32))`. Accepts either the
1974
+ * `vault_<hex>` form or the bare 64-hex-char tail.
1975
+ *
1976
+ * @throws {InvalidArgumentError} if the address body is not 32 bytes (64 hex chars).
1977
+ */
1978
+ export declare function vaultIdLiteral(address: VaultId): InstructionArg;
1979
+
1980
+ /** Base class for errors raised by {@link OotleWallet} operations. */
1981
+ export declare class WalletError extends OotleError {
1982
+ }
1983
+
1984
+ /**
1985
+ * Authorizes a {@link StealthTransferSpec} produced by {@link StealthTransfer}: unblinds any
1986
+ * stealth inputs, signs the balance proof, hydrates + patches the statement, then returns an
1987
+ * {@link AuthorizedTransfer} that produces one-time spend-key authorizations and seals the
1988
+ * envelope. Handles both the revealed-only path and the full stealth-input spend path.
1989
+ */
1990
+ export declare class WalletStealthAuthorizer {
1991
+ private readonly wallet;
1992
+ private readonly spec;
1993
+ private readonly crypto;
1994
+ private readonly mustSignWithAccountKey;
1995
+ private readonly viewSecret?;
1996
+ private constructor();
1997
+ /**
1998
+ * Build an authorizer from a builder spec.
1999
+ *
2000
+ * @param wallet - The multi-signer wallet (supplies the account-key + one-time signatures).
2001
+ * @param spec - The spec from {@link StealthTransfer.prepare}.
2002
+ * @param options - Optional `viewSecret`, account-signature toggle, crypto seam.
2003
+ */
2004
+ static fromSpec(wallet: OotleWallet, spec: StealthTransferSpec, options?: WalletStealthAuthorizerOptions): WalletStealthAuthorizer;
2005
+ /**
2006
+ * Hydrate + sign the transfer:
2007
+ * 1. resolve each stealth input — fetch its UTXO, unblind it to recover the mask, and
2008
+ * remember the sender public nonce (revealed-only → no inputs, no fetch);
2009
+ * 2. aggregate the input masks (`Mask.zero()` when there are no stealth inputs);
2010
+ * 3. sign the balance proof over the (already-canonical) inputs/outputs statement JSONs;
2011
+ * 4. build the complete (hydrated) statement and pre-flight `validateTransfer`;
2012
+ * 5. patch the unsigned tx's sole stealth instruction with the hydrated statement.
2013
+ *
2014
+ * Returns an {@link AuthorizedTransfer} that owns the hydrated state and can produce
2015
+ * one-time spend-key authorizations or seal the envelope. The authorizer is not mutated.
2016
+ *
2017
+ * @param provider - Read-only chain access (fetches the input UTXOs).
2018
+ */
2019
+ prepare(provider: Provider): Promise<AuthorizedTransfer>;
2020
+ /**
2021
+ * Resolve the view secret used to unblind stealth inputs: prefer the explicit one passed
2022
+ * to {@link fromSpec}; else fall back to the wallet's default signer `getViewSecret?.()`.
2023
+ *
2024
+ * @throws {WalletError} a clear, actionable error when neither is available **and**
2025
+ * there are stealth inputs to unblind (the revealed-only path never needs it).
2026
+ */
2027
+ private resolveViewSecret;
2028
+ /** The wallet's default signer address, or `""` if none is set (so view-secret resolution fails clearly). */
2029
+ private safeDefaultAddress;
2030
+ /**
2031
+ * Fetch + unblind each stealth input, in `spec.inputs` order.
2032
+ *
2033
+ * For each input: `getStealthUtxo` → `parseSubstateUtxo` (commitment + body) →
2034
+ * `decryptInputData(..., { senderPublicNonce, viewSecret, skipMemo: true })` to recover
2035
+ * the mask. The sender public nonce is read from the **fetched UTXO body**, not the spec
2036
+ * (the spec only carries the commitment), and kept for one-time signing.
2037
+ *
2038
+ * `skipMemo: true` — spending only needs the mask + value, not the memo (vs the
2039
+ * receive-side `decryptOwnedUtxo`, which decrypts the memo).
2040
+ */
2041
+ private resolveStealthInputs;
2042
+ }
2043
+
2044
+ /** Options for {@link WalletStealthAuthorizer.fromSpec}. */
2045
+ export declare interface WalletStealthAuthorizerOptions {
2046
+ /**
2047
+ * The owner/recipient 32-byte view secret, needed to unblind stealth inputs. **Optional**:
2048
+ * the revealed-only path never uses it; for stealth-input transfers it is taken here first,
2049
+ * else falls back to the wallet's default signer `getViewSecret?.()` (only `SecretKeyWallet`
2050
+ * supplies one). If neither is available and there are stealth inputs, `prepare` throws.
2051
+ */
2052
+ viewSecret?: Uint8Array;
2053
+ /**
2054
+ * Whether to append the account-key Schnorr signature when sealing. Defaults to `true`.
2055
+ * Set `false` to omit it (e.g. the account already authorized out-of-band).
2056
+ */
2057
+ mustSignWithAccountKey?: boolean;
2058
+ /**
2059
+ * Injectable crypto seam; defaults to {@link WasmStealthCrypto}. Tests pass a
2060
+ * {@link FakeStealthCrypto}.
2061
+ */
2062
+ crypto?: StealthCryptoProvider;
2063
+ }
2064
+
2065
+ /**
2066
+ * The real `StealthCryptoProvider`, backed by `@tari-project/ootle-wasm@0.38.0`.
2067
+ *
2068
+ * Marshals between the step-02 domain types (`Mask`, `Output`, statements) and the raw
2069
+ * WASM ABI (snake_case result fields, positional args, raw `Uint8Array`s/`bigint`s).
2070
+ * Async signatures wrap synchronous WASM calls — see {@link StealthCryptoProvider}.
2071
+ */
2072
+ export declare class WasmStealthCrypto implements StealthCryptoProvider {
2073
+ /**
2074
+ * The network byte fed to the WASM output-witness and DH calls. Defaults to
2075
+ * {@link Network.LocalNet}; pass the target network for non-local transfers.
2076
+ */
2077
+ private readonly network;
2078
+ constructor(network?: Network);
2079
+ generateOutputsStatement(specs: Output[], revealedOutputAmount: bigint): Promise<{
2080
+ statement: StealthOutputsStatement;
2081
+ outputMask: Mask;
2082
+ }>;
2083
+ /** Build a single output witness JSON via WASM, mapping an {@link Output} spec. */
2084
+ private outputWitness;
2085
+ buildInputsStatement(inputs: StealthInput[], revealedAmount: bigint): Promise<StealthInputsStatement>;
2086
+ generateBalanceProofSignature(inputMask: Mask, outputMask: Mask, inputsStatementJson: string, outputsStatementJson: string): Promise<BalanceProofSignature>;
2087
+ validateBalanceProofSignature(proof: BalanceProofSignature, inputsStatementJson: string, outputsStatementJson: string): Promise<boolean>;
2088
+ deriveAeadKey(privateKey: Uint8Array, publicKey: Uint8Array): Promise<Uint8Array>;
2089
+ unblindOutput(commitment: Uint8Array, encryptedData: Uint8Array, aeadKey: Uint8Array, skipMemo: boolean): Promise<DecryptedData>;
2090
+ aggregateInputMasks(masks: Mask[]): Promise<Mask>;
2091
+ stealthDhSecret(networkByte: number, ownerSecret: Uint8Array, publicNonce: Uint8Array): Promise<Uint8Array>;
2092
+ validateTransfer(statement: StealthTransferStatement): Promise<void>;
2093
+ }
2094
+
2095
+ export declare interface WatchOptions {
2096
+ /** How often to poll for the transaction result, in milliseconds. Defaults to 500ms. */
2097
+ pollIntervalMs?: number;
2098
+ /** Maximum time to wait before throwing a timeout error, in milliseconds. Defaults to 60000ms. */
2099
+ timeoutMs?: number;
2100
+ }
2101
+
2102
+ /**
2103
+ * Polls the provider until a transaction reaches a finalized state, then returns the result.
2104
+ *
2105
+ * Throws for `Reject` outcomes. `FeeIntentCommit` (fees paid, execution aborted) also
2106
+ * throws with a distinct message so callers can distinguish it from a full rejection.
2107
+ * Use `classifyOutcome` on the raw result for non-throwing outcome inspection.
2108
+ *
2109
+ * @throws {TransactionRejectedError} when consensus rejects the transaction, or commits
2110
+ * only the fee intent (execution aborted). The error's `.txId` and `.reason` carry the
2111
+ * structured fields; the message remains the human-readable summary.
2112
+ * @throws {TransactionTimeoutError} when the transaction did not finalize within
2113
+ * `timeoutMs`. The error's `.txId` identifies the polled transaction.
2114
+ */
2115
+ export declare function watchTransaction(provider: Provider, txId: string, opts?: WatchOptions): Promise<IndexerGetTransactionResultResponse>;
2116
+
2117
+ /** Claim resource held by the XTR faucet (object key `[1, 2, 3, 0, …, 0, 2]`). */
2118
+ export declare const XTR_FAUCET_CLAIM_RESOURCE_ADDRESS = "resource_0102030000000000000000000000000000000000000000000000000000000002";
2119
+
2120
+ /**
2121
+ * On-chain XTR faucet component address (object key `[1, 2, 3, 0, …, 0]`).
2122
+ * LocalNet scripts call this via `FaucetInvokeBuilder` to claim revealed TARI funds.
2123
+ */
2124
+ export declare const XTR_FAUCET_COMPONENT_ADDRESS = "component_0102030000000000000000000000000000000000000000000000000000000000";
2125
+
2126
+ /** Vault held by the XTR faucet (object key `[1, 2, 3, 0, …, 0, 1]`). */
2127
+ export declare const XTR_FAUCET_VAULT_ADDRESS = "vault_0102030000000000000000000000000000000000000000000000000000000001";
2128
+
2129
+ export { }