@bitgo/wasm-utxo 5.5.0 → 5.6.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.
@@ -610,6 +610,41 @@ export declare class BitGoPsbt<TOutput extends ParsedOutput = ParsedOutput> exte
610
610
  * @returns The serialized unsigned transaction bytes (network/consensus encoding).
611
611
  */
612
612
  getUnsignedTransaction(): Uint8Array;
613
+ /**
614
+ * Returns each input's declared sighash type (BIP-174 PSBT_IN_SIGHASH_TYPE),
615
+ * in input order.
616
+ *
617
+ * Entries are `undefined` when the input does not declare a sighash type, in
618
+ * which case the signer's default sighash type applies.
619
+ */
620
+ getInputSighashTypes(): (number | undefined)[];
621
+ /**
622
+ * Asserts the sighash policy required when signing an externally supplied
623
+ * PSBT: every input must commit to the entire transaction.
624
+ *
625
+ * For every input this checks that
626
+ *
627
+ * 1. the declared sighash type (PSBT_IN_SIGHASH_TYPE), if present, commits
628
+ * to every input and every output: SIGHASH_ALL (0x01) — SIGHASH_ALL |
629
+ * SIGHASH_FORKID (0x41) on BCH-family coins — or SIGHASH_DEFAULT
630
+ * (0x00) / SIGHASH_ALL (0x01) on Taproot inputs. An absent sighash type
631
+ * is accepted: the signer then applies its default, which commits to
632
+ * the entire transaction.
633
+ * 2. every signature already present on the input (ECDSA partial
634
+ * signatures, Taproot key-path and script-path signatures) uses such a
635
+ * sighash type. MuSig2 partial signatures carry no sighash byte; the
636
+ * declared sighash type checked above governs them.
637
+ *
638
+ * SIGHASH_NONE, SIGHASH_SINGLE, SIGHASH_ANYONECANPAY, and combinations
639
+ * thereof leave outputs (or inputs) uncommitted, so a signature produced
640
+ * under one of them does not bind the signer to the transaction the signer
641
+ * reviewed. Callers that ingest foreign PSBTs must run this check before
642
+ * signing and again afterwards.
643
+ *
644
+ * @throws Error if any input declares a sighash type, or carries a
645
+ * signature, that does not commit to the entire transaction.
646
+ */
647
+ assertSighashAllPolicy(): void;
613
648
  /**
614
649
  * Get all PSBT outputs with resolved address strings
615
650
  *
@@ -626,6 +626,45 @@ class BitGoPsbt extends psbtBase_js_1.PsbtBase {
626
626
  getUnsignedTransaction() {
627
627
  return this._wasm.get_unsigned_tx();
628
628
  }
629
+ /**
630
+ * Returns each input's declared sighash type (BIP-174 PSBT_IN_SIGHASH_TYPE),
631
+ * in input order.
632
+ *
633
+ * Entries are `undefined` when the input does not declare a sighash type, in
634
+ * which case the signer's default sighash type applies.
635
+ */
636
+ getInputSighashTypes() {
637
+ return this._wasm.get_input_sighash_types().map((sighashType) => sighashType ?? undefined);
638
+ }
639
+ /**
640
+ * Asserts the sighash policy required when signing an externally supplied
641
+ * PSBT: every input must commit to the entire transaction.
642
+ *
643
+ * For every input this checks that
644
+ *
645
+ * 1. the declared sighash type (PSBT_IN_SIGHASH_TYPE), if present, commits
646
+ * to every input and every output: SIGHASH_ALL (0x01) — SIGHASH_ALL |
647
+ * SIGHASH_FORKID (0x41) on BCH-family coins — or SIGHASH_DEFAULT
648
+ * (0x00) / SIGHASH_ALL (0x01) on Taproot inputs. An absent sighash type
649
+ * is accepted: the signer then applies its default, which commits to
650
+ * the entire transaction.
651
+ * 2. every signature already present on the input (ECDSA partial
652
+ * signatures, Taproot key-path and script-path signatures) uses such a
653
+ * sighash type. MuSig2 partial signatures carry no sighash byte; the
654
+ * declared sighash type checked above governs them.
655
+ *
656
+ * SIGHASH_NONE, SIGHASH_SINGLE, SIGHASH_ANYONECANPAY, and combinations
657
+ * thereof leave outputs (or inputs) uncommitted, so a signature produced
658
+ * under one of them does not bind the signer to the transaction the signer
659
+ * reviewed. Callers that ingest foreign PSBTs must run this check before
660
+ * signing and again afterwards.
661
+ *
662
+ * @throws Error if any input declares a sighash type, or carries a
663
+ * signature, that does not commit to the entire transaction.
664
+ */
665
+ assertSighashAllPolicy() {
666
+ this._wasm.assert_sighash_all_policy();
667
+ }
629
668
  /**
630
669
  * Get all PSBT outputs with resolved address strings
631
670
  *
@@ -135,7 +135,9 @@ export declare class ZcashIronwoodBitGoPsbt extends ZcashBitGoPsbt {
135
135
  * @param amount - note value in zatoshi
136
136
  * @param options.anchor - 32-byte Ironwood note-commitment-tree root
137
137
  * @param options.memo - optional 512-byte memo (defaults to the ZIP-302 "no memo" encoding)
138
- * @param options.ovk - optional 32-byte outgoing viewing key (omit for a keyless build)
138
+ * @param options.ovk - optional 32-byte outgoing viewing key (omit for a keyless build). Has no
139
+ * effect in the normal flow: {@link sign}'s first round re-encrypts every action's
140
+ * `out_ciphertext` under the wallet `ovk`, replacing whatever this produced
139
141
  * @param options.unifiedAddress - optional full Unified Address string this output was addressed
140
142
  * to. Its Orchard receiver must equal `recipient`. The PCZT itself only carries the raw 43-byte
141
143
  * receiver — a lossy encoding for a multi-receiver UA, since any transparent/Sapling receiver
@@ -156,12 +158,14 @@ export declare class ZcashIronwoodBitGoPsbt extends ZcashBitGoPsbt {
156
158
  * {@link addShieldedOutput}).
157
159
  *
158
160
  * @param outputs - one entry per recipient; `memo` defaults per-entry to the ZIP-302 "no memo"
159
- * encoding, exactly as {@link addShieldedOutput}'s does
161
+ * encoding, exactly as {@link addShieldedOutput}'s does, and `ovk` is likewise replaced by
162
+ * {@link sign}'s first round
160
163
  * @param anchor - 32-byte Ironwood note-commitment-tree root, shared by every output
161
164
  * @returns the action index assigned to each output, in the same order as `outputs` — the
162
- * orchard builder pads/reorders actions, so a client-managed-`ovk` caller must use these
163
- * indices (not the position in `outputs`) when later calling
164
- * `setIronwoodOutCiphertext`/`setIronwoodOutCiphertextForUser` for a specific recipient.
165
+ * orchard builder pads/reorders actions, so any caller correlating per-action data (a stored
166
+ * unified address, an explicit `setShieldedOutCiphertext` call) must use these indices, not the
167
+ * position in `outputs` — though note {@link sign}'s first round already patches every action's
168
+ * `out_ciphertext` with the wallet `ovk` on its own.
165
169
  */
166
170
  addShieldedOutputs(outputs: Array<{
167
171
  recipient: Uint8Array;
@@ -181,14 +185,16 @@ export declare class ZcashIronwoodBitGoPsbt extends ZcashBitGoPsbt {
181
185
  * `ovk` derived from those is one neither the user nor the server can reproduce, and the resulting
182
186
  * transaction would broadcast fine while leaving the shielded output permanently unrecoverable.
183
187
  *
184
- * Normally you do not call this directly: {@link sign} performs it on the first signing round.
188
+ * Normally you do not call this directly: {@link sign} performs it for **every** action on the
189
+ * first signing round (idempotently — same `ovk`, same bytes).
185
190
  *
186
191
  * Must be called **before** signing: `out_ciphertext` is committed by the ZIP-244 sighash, so
187
192
  * calling this after any transparent signature has been added (via
188
193
  * {@link addTransparentSignature}) throws rather than silently invalidating that signature.
189
194
  *
190
- * @param actionIndex - index of the Ironwood action whose output to re-encrypt (always `0`: only
191
- * one shielded output per transaction is supported, see {@link addShieldedOutput})
195
+ * @param actionIndex - index of the Ironwood action whose output to re-encrypt; use an index
196
+ * returned by {@link addShieldedOutputs} (the orchard builder may reorder actions, so it is not
197
+ * necessarily the output's position in the call)
192
198
  * @param userKey - the wallet's user root key (an xpriv)
193
199
  * @param rootWalletKeys - the wallet's root keys, supplying the BitGo cosigner pubkey
194
200
  */
@@ -220,7 +226,8 @@ export declare class ZcashIronwoodBitGoPsbt extends ZcashBitGoPsbt {
220
226
  *
221
227
  * If no transparent signature has been added to this PSBT yet, this is the first signing round and
222
228
  * `key` must be the wallet's user root key: it is used with `rootWalletKeys.bitgoKey()` to derive
223
- * this wallet's `ovk` and finalize `out_ciphertext` — the client-managed-`ovk` flow — before any
229
+ * this wallet's `ovk` and finalize **every** action's `out_ciphertext` — the client-managed-`ovk`
230
+ * flow, multi-recipient builds included — before any
224
231
  * sighash is computed. Once a signature exists, that step is a no-op, so a caller passes
225
232
  * `rootWalletKeys` on every signing round unconditionally: `psbt.sign(userXpriv, rootWalletKeys)`
226
233
  * and later `psbt.sign(bitgoXpriv, rootWalletKeys)` — only the first call actually uses it.
@@ -136,7 +136,9 @@ class ZcashIronwoodBitGoPsbt extends ZcashBitGoPsbt_js_1.ZcashBitGoPsbt {
136
136
  * @param amount - note value in zatoshi
137
137
  * @param options.anchor - 32-byte Ironwood note-commitment-tree root
138
138
  * @param options.memo - optional 512-byte memo (defaults to the ZIP-302 "no memo" encoding)
139
- * @param options.ovk - optional 32-byte outgoing viewing key (omit for a keyless build)
139
+ * @param options.ovk - optional 32-byte outgoing viewing key (omit for a keyless build). Has no
140
+ * effect in the normal flow: {@link sign}'s first round re-encrypts every action's
141
+ * `out_ciphertext` under the wallet `ovk`, replacing whatever this produced
140
142
  * @param options.unifiedAddress - optional full Unified Address string this output was addressed
141
143
  * to. Its Orchard receiver must equal `recipient`. The PCZT itself only carries the raw 43-byte
142
144
  * receiver — a lossy encoding for a multi-receiver UA, since any transparent/Sapling receiver
@@ -155,12 +157,14 @@ class ZcashIronwoodBitGoPsbt extends ZcashBitGoPsbt_js_1.ZcashBitGoPsbt {
155
157
  * {@link addShieldedOutput}).
156
158
  *
157
159
  * @param outputs - one entry per recipient; `memo` defaults per-entry to the ZIP-302 "no memo"
158
- * encoding, exactly as {@link addShieldedOutput}'s does
160
+ * encoding, exactly as {@link addShieldedOutput}'s does, and `ovk` is likewise replaced by
161
+ * {@link sign}'s first round
159
162
  * @param anchor - 32-byte Ironwood note-commitment-tree root, shared by every output
160
163
  * @returns the action index assigned to each output, in the same order as `outputs` — the
161
- * orchard builder pads/reorders actions, so a client-managed-`ovk` caller must use these
162
- * indices (not the position in `outputs`) when later calling
163
- * `setIronwoodOutCiphertext`/`setIronwoodOutCiphertextForUser` for a specific recipient.
164
+ * orchard builder pads/reorders actions, so any caller correlating per-action data (a stored
165
+ * unified address, an explicit `setShieldedOutCiphertext` call) must use these indices, not the
166
+ * position in `outputs` — though note {@link sign}'s first round already patches every action's
167
+ * `out_ciphertext` with the wallet `ovk` on its own.
164
168
  */
165
169
  addShieldedOutputs(outputs, anchor) {
166
170
  return Array.from(this.wasm.add_ironwood_outputs(outputs.map((o) => ({
@@ -182,14 +186,16 @@ class ZcashIronwoodBitGoPsbt extends ZcashBitGoPsbt_js_1.ZcashBitGoPsbt {
182
186
  * `ovk` derived from those is one neither the user nor the server can reproduce, and the resulting
183
187
  * transaction would broadcast fine while leaving the shielded output permanently unrecoverable.
184
188
  *
185
- * Normally you do not call this directly: {@link sign} performs it on the first signing round.
189
+ * Normally you do not call this directly: {@link sign} performs it for **every** action on the
190
+ * first signing round (idempotently — same `ovk`, same bytes).
186
191
  *
187
192
  * Must be called **before** signing: `out_ciphertext` is committed by the ZIP-244 sighash, so
188
193
  * calling this after any transparent signature has been added (via
189
194
  * {@link addTransparentSignature}) throws rather than silently invalidating that signature.
190
195
  *
191
- * @param actionIndex - index of the Ironwood action whose output to re-encrypt (always `0`: only
192
- * one shielded output per transaction is supported, see {@link addShieldedOutput})
196
+ * @param actionIndex - index of the Ironwood action whose output to re-encrypt; use an index
197
+ * returned by {@link addShieldedOutputs} (the orchard builder may reorder actions, so it is not
198
+ * necessarily the output's position in the call)
193
199
  * @param userKey - the wallet's user root key (an xpriv)
194
200
  * @param rootWalletKeys - the wallet's root keys, supplying the BitGo cosigner pubkey
195
201
  */
@@ -144,7 +144,9 @@ export class BitGoPsbt {
144
144
  *
145
145
  * * `recipient` - raw Orchard/Ironwood address ([`ORCHARD_ADDRESS_SIZE`] bytes)
146
146
  * * `amount` - note value in zatoshi
147
- * * `ovk` - optional outgoing viewing key ([`OVK_SIZE`] bytes; `None` for a keyless build)
147
+ * * `ovk` - optional outgoing viewing key ([`OVK_SIZE`] bytes; `None` for a keyless build).
148
+ * Has no effect in the normal flow: `sign_ironwood_v6`'s first round re-encrypts every
149
+ * action's `out_ciphertext` under the wallet `ovk`, replacing whatever this produced
148
150
  * * `anchor` - Ironwood note-commitment-tree root ([`ANCHOR_SIZE`] bytes)
149
151
  * * `memo` - ZIP-302 memo field ([`MEMO_SIZE`] bytes)
150
152
  * * `unified_address` - optional full Unified Address the output was addressed to; if given,
@@ -168,9 +170,10 @@ export class BitGoPsbt {
168
170
  * output.
169
171
  *
170
172
  * Returns the action index assigned to each output, in the same order as `outputs` — the
171
- * orchard builder pads/reorders actions, so a client-managed-`ovk` caller must use these
172
- * indices (not the position in `outputs`) when later calling `set_ironwood_out_ciphertext`
173
- * for a specific recipient.
173
+ * orchard builder pads/reorders actions, so a caller correlating per-action data (a stored
174
+ * Unified Address, an explicit `set_ironwood_out_ciphertext` call) must use these indices, not
175
+ * the position in `outputs` — though note `sign_ironwood_v6`'s first round already patches
176
+ * every action's `out_ciphertext` with the wallet `ovk` on its own.
174
177
  */
175
178
  add_ironwood_outputs(outputs: any, anchor: Uint8Array): Uint32Array;
176
179
  /**
@@ -213,6 +216,20 @@ export class BitGoPsbt {
213
216
  add_wallet_input_at_index(index: number, txid: string, vout: number, value: bigint, wallet_keys: WasmRootWalletKeys, chain: number, derivation_index: number, signer?: string | null, cosigner?: string | null, sequence?: number | null, prev_tx?: Uint8Array | null): number;
214
217
  add_wallet_output(chain: number, index: number, value: bigint, wallet_keys: WasmRootWalletKeys): number;
215
218
  add_wallet_output_at_index(index: number, chain: number, derivation_index: number, value: bigint, wallet_keys: WasmRootWalletKeys): number;
219
+ /**
220
+ * Asserts the sighash policy required when signing an externally
221
+ * supplied PSBT: every input must commit to the entire transaction.
222
+ *
223
+ * Rejects SIGHASH_NONE, SIGHASH_SINGLE, SIGHASH_ANYONECANPAY, and
224
+ * combinations thereof — in both the declared per-input sighash type
225
+ * and the signatures already present in the PSBT — because signatures
226
+ * produced under those types do not bind the signer to the outputs of
227
+ * the transaction. Accepted types are SIGHASH_ALL (0x01),
228
+ * SIGHASH_ALL | SIGHASH_FORKID (0x41) on BCH-family networks, and
229
+ * SIGHASH_DEFAULT (0x00) / SIGHASH_ALL (0x01) on Taproot inputs; an
230
+ * absent sighash type uses the signer default.
231
+ */
232
+ assert_sighash_all_policy(): void;
216
233
  /**
217
234
  * Merge all input fields from a raw PSBT (given as bytes) into this PSBT.
218
235
  *
@@ -490,6 +507,14 @@ export class BitGoPsbt {
490
507
  get_global_xpubs(): any;
491
508
  get_input_key_values(index: number): any;
492
509
  get_input_kv(index: number, key: any): Uint8Array | undefined;
510
+ /**
511
+ * Returns each input's declared sighash type (BIP-174
512
+ * `PSBT_IN_SIGHASH_TYPE`), in input order.
513
+ *
514
+ * Entries are `null` when the input does not declare a sighash type, in
515
+ * which case the signer's default sighash type applies.
516
+ */
517
+ get_input_sighash_types(): any;
493
518
  get_inputs(): any;
494
519
  get_kv(key: any): Uint8Array | undefined;
495
520
  /**
@@ -665,7 +690,8 @@ export class BitGoPsbt {
665
690
  *
666
691
  * If no transparent signature has been collected yet, this is the first signing round and
667
692
  * `xpriv` must be the wallet's user root key: it is used with `root_wallet_keys.bitgo_key()` to
668
- * derive this wallet's `ovk` and finalize `out_ciphertext` before computing any sighash (it is
693
+ * derive this wallet's `ovk` and finalize every action's `out_ciphertext` (multi-recipient
694
+ * builds included) before computing any sighash (it is
669
695
  * sighash-committed). Any other key signing first is rejected, rather than deriving an `ovk`
670
696
  * nobody can reproduce. Once a signature exists, the step is skipped and any key may sign — so
671
697
  * callers pass `root_wallet_keys` unconditionally on every signing round without needing to know
@@ -475,7 +475,9 @@ class BitGoPsbt {
475
475
  *
476
476
  * * `recipient` - raw Orchard/Ironwood address ([`ORCHARD_ADDRESS_SIZE`] bytes)
477
477
  * * `amount` - note value in zatoshi
478
- * * `ovk` - optional outgoing viewing key ([`OVK_SIZE`] bytes; `None` for a keyless build)
478
+ * * `ovk` - optional outgoing viewing key ([`OVK_SIZE`] bytes; `None` for a keyless build).
479
+ * Has no effect in the normal flow: `sign_ironwood_v6`'s first round re-encrypts every
480
+ * action's `out_ciphertext` under the wallet `ovk`, replacing whatever this produced
479
481
  * * `anchor` - Ironwood note-commitment-tree root ([`ANCHOR_SIZE`] bytes)
480
482
  * * `memo` - ZIP-302 memo field ([`MEMO_SIZE`] bytes)
481
483
  * * `unified_address` - optional full Unified Address the output was addressed to; if given,
@@ -527,9 +529,10 @@ class BitGoPsbt {
527
529
  * output.
528
530
  *
529
531
  * Returns the action index assigned to each output, in the same order as `outputs` — the
530
- * orchard builder pads/reorders actions, so a client-managed-`ovk` caller must use these
531
- * indices (not the position in `outputs`) when later calling `set_ironwood_out_ciphertext`
532
- * for a specific recipient.
532
+ * orchard builder pads/reorders actions, so a caller correlating per-action data (a stored
533
+ * Unified Address, an explicit `set_ironwood_out_ciphertext` call) must use these indices, not
534
+ * the position in `outputs` — though note `sign_ironwood_v6`'s first round already patches
535
+ * every action's `out_ciphertext` with the wallet `ovk` on its own.
533
536
  * @param {any} outputs
534
537
  * @param {Uint8Array} anchor
535
538
  * @returns {Uint32Array}
@@ -915,6 +918,32 @@ class BitGoPsbt {
915
918
  wasm.__wbindgen_add_to_stack_pointer(16);
916
919
  }
917
920
  }
921
+ /**
922
+ * Asserts the sighash policy required when signing an externally
923
+ * supplied PSBT: every input must commit to the entire transaction.
924
+ *
925
+ * Rejects SIGHASH_NONE, SIGHASH_SINGLE, SIGHASH_ANYONECANPAY, and
926
+ * combinations thereof — in both the declared per-input sighash type
927
+ * and the signatures already present in the PSBT — because signatures
928
+ * produced under those types do not bind the signer to the outputs of
929
+ * the transaction. Accepted types are SIGHASH_ALL (0x01),
930
+ * SIGHASH_ALL | SIGHASH_FORKID (0x41) on BCH-family networks, and
931
+ * SIGHASH_DEFAULT (0x00) / SIGHASH_ALL (0x01) on Taproot inputs; an
932
+ * absent sighash type uses the signer default.
933
+ */
934
+ assert_sighash_all_policy() {
935
+ try {
936
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
937
+ wasm.bitgopsbt_assert_sighash_all_policy(retptr, this.__wbg_ptr);
938
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
939
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
940
+ if (r1) {
941
+ throw takeObject(r0);
942
+ }
943
+ } finally {
944
+ wasm.__wbindgen_add_to_stack_pointer(16);
945
+ }
946
+ }
918
947
  /**
919
948
  * Merge all input fields from a raw PSBT (given as bytes) into this PSBT.
920
949
  *
@@ -1736,6 +1765,29 @@ class BitGoPsbt {
1736
1765
  wasm.__wbindgen_add_to_stack_pointer(16);
1737
1766
  }
1738
1767
  }
1768
+ /**
1769
+ * Returns each input's declared sighash type (BIP-174
1770
+ * `PSBT_IN_SIGHASH_TYPE`), in input order.
1771
+ *
1772
+ * Entries are `null` when the input does not declare a sighash type, in
1773
+ * which case the signer's default sighash type applies.
1774
+ * @returns {any}
1775
+ */
1776
+ get_input_sighash_types() {
1777
+ try {
1778
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1779
+ wasm.bitgopsbt_get_input_sighash_types(retptr, this.__wbg_ptr);
1780
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1781
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1782
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1783
+ if (r2) {
1784
+ throw takeObject(r1);
1785
+ }
1786
+ return takeObject(r0);
1787
+ } finally {
1788
+ wasm.__wbindgen_add_to_stack_pointer(16);
1789
+ }
1790
+ }
1739
1791
  /**
1740
1792
  * @returns {any}
1741
1793
  */
@@ -2369,7 +2421,8 @@ class BitGoPsbt {
2369
2421
  *
2370
2422
  * If no transparent signature has been collected yet, this is the first signing round and
2371
2423
  * `xpriv` must be the wallet's user root key: it is used with `root_wallet_keys.bitgo_key()` to
2372
- * derive this wallet's `ovk` and finalize `out_ciphertext` before computing any sighash (it is
2424
+ * derive this wallet's `ovk` and finalize every action's `out_ciphertext` (multi-recipient
2425
+ * builds included) before computing any sighash (it is
2373
2426
  * sighash-committed). Any other key signing first is rejected, rather than deriving an `ovk`
2374
2427
  * nobody can reproduce. Once a signature exists, the step is skipped and any key may sign — so
2375
2428
  * callers pass `root_wallet_keys` unconditionally on every signing round without needing to know
Binary file