@bitgo/wasm-utxo 1.42.0 → 1.44.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.
package/README.md CHANGED
@@ -31,6 +31,36 @@ Zcash support includes:
31
31
  - **Height-Based API**: Preferred `createEmpty()` method automatically selects correct consensus rules
32
32
  - **Parity Testing**: Validated against `zebra-chain` for accuracy across all network upgrades
33
33
 
34
+ ## Inspect Feature
35
+
36
+ The `inspect` feature adds PSBT and transaction parsing into hierarchical node trees,
37
+ useful for building tree-view UIs and CLI formatters.
38
+
39
+ It is behind a Cargo feature flag because it pulls in extra dependencies (`serde`, `serde_json`,
40
+ `num-bigint`, `hex`) that are not needed for core wallet operations.
41
+
42
+ ### Rust
43
+
44
+ ```rust
45
+ // Cargo.toml
46
+ wasm-utxo = { path = ".", features = ["inspect"] }
47
+
48
+ // Usage
49
+ use wasm_utxo::inspect::{parse_psbt_bytes_with_network, parse_tx_bytes_with_network, Node};
50
+ ```
51
+
52
+ ### TypeScript
53
+
54
+ Available as a separate import path, not included in the main `@bitgo/wasm-utxo` entry:
55
+
56
+ ```typescript
57
+ import { parsePsbtToNode, parseTxToNode, isInspectEnabled } from "@bitgo/wasm-utxo/inspect";
58
+ ```
59
+
60
+ The published npm package includes stub implementations that return `isInspectEnabled() === false`
61
+ and throw runtime errors from the parse functions. To get a working build, compile the WASM with
62
+ `--features inspect` (see [`packages/webui/scripts/build-wasm.sh`](../webui/scripts/build-wasm.sh)).
63
+
34
64
  ## Building
35
65
 
36
66
  ### Mac
@@ -195,7 +195,7 @@ class BitGoPsbt {
195
195
  */
196
196
  addReplayProtectionInput(inputOptions, key) {
197
197
  const ecpair = ecpair_js_1.ECPair.from(key);
198
- return this._wasm.add_replay_protection_input(ecpair.wasm, inputOptions.txid, inputOptions.vout, inputOptions.value, inputOptions.sequence);
198
+ return this._wasm.add_replay_protection_input(ecpair.wasm, inputOptions.txid, inputOptions.vout, inputOptions.value, inputOptions.sequence, inputOptions.prevTx);
199
199
  }
200
200
  /**
201
201
  * Get the unsigned transaction ID
@@ -52,3 +52,10 @@ export declare function supportsScriptType(coin: CoinName, scriptType: ScriptTyp
52
52
  * ```
53
53
  */
54
54
  export declare function createOpReturnScript(data?: Uint8Array): Uint8Array;
55
+ /**
56
+ * Get the P2SH-P2PK output script for a compressed public key
57
+ *
58
+ * @param pubkey - The compressed public key bytes (33 bytes)
59
+ * @returns The P2SH-P2PK output script as a Uint8Array
60
+ */
61
+ export declare function p2shP2pkOutputScript(pubkey: Uint8Array): Uint8Array;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZcashBitGoPsbt = exports.BitGoPsbt = exports.assertChainCode = exports.chainCodes = exports.ChainCode = exports.inputScriptTypes = exports.outputScriptTypes = exports.Dimensions = exports.address = exports.outputScript = exports.ReplayProtection = exports.RootWalletKeys = void 0;
4
4
  exports.supportsScriptType = supportsScriptType;
5
5
  exports.createOpReturnScript = createOpReturnScript;
6
+ exports.p2shP2pkOutputScript = p2shP2pkOutputScript;
6
7
  const wasm_utxo_js_1 = require("../wasm/wasm_utxo.js");
7
8
  var RootWalletKeys_js_1 = require("./RootWalletKeys.js");
8
9
  Object.defineProperty(exports, "RootWalletKeys", { enumerable: true, get: function () { return RootWalletKeys_js_1.RootWalletKeys; } });
@@ -73,3 +74,12 @@ function supportsScriptType(coin, scriptType) {
73
74
  function createOpReturnScript(data) {
74
75
  return wasm_utxo_js_1.FixedScriptWalletNamespace.create_op_return_script(data);
75
76
  }
77
+ /**
78
+ * Get the P2SH-P2PK output script for a compressed public key
79
+ *
80
+ * @param pubkey - The compressed public key bytes (33 bytes)
81
+ * @returns The P2SH-P2PK output script as a Uint8Array
82
+ */
83
+ function p2shP2pkOutputScript(pubkey) {
84
+ return wasm_utxo_js_1.FixedScriptWalletNamespace.p2sh_p2pk_output_script(pubkey);
85
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Inspect - TypeScript bindings for PSBT and Transaction parsing
3
+ *
4
+ * Provides typed wrappers around the WASM inspect functions that return
5
+ * hierarchical node structures suitable for display as collapsible trees.
6
+ *
7
+ * Import via: `import { ... } from "@bitgo/wasm-utxo/inspect"`
8
+ */
9
+ import type { CoinName } from "../coinName.js";
10
+ /** Re-export CoinName for convenience */
11
+ export type { CoinName };
12
+ /** All supported networks in order of parsing priority */
13
+ export declare const allNetworks: CoinName[];
14
+ /**
15
+ * Primitive value types that can appear in a Node.
16
+ * Buffer values are hex-encoded strings, Integer is a decimal string for BigInt support.
17
+ */
18
+ export type PrimitiveType = "String" | "Buffer" | "Integer" | "U8" | "U16" | "U32" | "U64" | "I8" | "I16" | "I32" | "I64" | "Boolean" | "None";
19
+ /**
20
+ * A tagged union representing primitive values in the parse tree.
21
+ */
22
+ export interface Primitive {
23
+ type: PrimitiveType;
24
+ value?: string | number | boolean;
25
+ }
26
+ /**
27
+ * A node in the parse tree representing a PSBT or transaction element.
28
+ */
29
+ export interface Node {
30
+ label: string;
31
+ value: Primitive;
32
+ children: Node[];
33
+ }
34
+ /**
35
+ * Parse a PSBT and return a typed node tree.
36
+ *
37
+ * @param psbtBytes - The raw PSBT bytes
38
+ * @param network - The network coin name (e.g., "btc", "ltc", "bch")
39
+ * @returns A Node tree representing the parsed PSBT structure
40
+ * @throws If the PSBT bytes are invalid or network is unknown
41
+ */
42
+ export declare function parsePsbtToNode(psbtBytes: Uint8Array, network: CoinName): Node;
43
+ /**
44
+ * Parse a transaction and return a typed node tree.
45
+ *
46
+ * @param txBytes - The raw transaction bytes
47
+ * @param network - The network coin name (e.g., "btc", "ltc", "bch")
48
+ * @returns A Node tree representing the parsed transaction structure
49
+ * @throws If the transaction bytes are invalid or network is unknown
50
+ */
51
+ export declare function parseTxToNode(txBytes: Uint8Array, network: CoinName): Node;
52
+ /**
53
+ * Try to parse a PSBT with all networks and return the first one that succeeds.
54
+ *
55
+ * @param psbtBytes - The raw PSBT bytes
56
+ * @param networks - Optional list of networks to try (defaults to all networks)
57
+ * @returns An object with the parsed Node and detected network, or null if all fail
58
+ */
59
+ export declare function tryParsePsbt(psbtBytes: Uint8Array, networks?: CoinName[]): {
60
+ node: Node;
61
+ network: CoinName;
62
+ } | null;
63
+ /**
64
+ * Try to parse a transaction with all networks and return the first one that succeeds.
65
+ *
66
+ * @param txBytes - The raw transaction bytes
67
+ * @param networks - Optional list of networks to try (defaults to all networks)
68
+ * @returns An object with the parsed Node and detected network, or null if all fail
69
+ */
70
+ export declare function tryParseTx(txBytes: Uint8Array, networks?: CoinName[]): {
71
+ node: Node;
72
+ network: CoinName;
73
+ } | null;
74
+ /**
75
+ * Parse a PSBT at the raw byte level and return a typed node tree.
76
+ *
77
+ * Unlike `parsePsbtToNode`, this function exposes the raw key-value pair
78
+ * structure as defined in BIP-174, showing:
79
+ * - Raw key type IDs and their human-readable names
80
+ * - Proprietary keys with their structured format
81
+ * - Unknown/unrecognized keys that standard parsers might skip
82
+ *
83
+ * @param psbtBytes - The raw PSBT bytes
84
+ * @param network - The network coin name (e.g., "btc", "ltc", "zec")
85
+ * @returns A Node tree representing the raw PSBT key-value structure
86
+ * @throws If the PSBT bytes are invalid or network is unknown
87
+ */
88
+ export declare function parsePsbtRawToNode(psbtBytes: Uint8Array, network: CoinName): Node;
89
+ /**
90
+ * Try to parse a raw PSBT with all networks and return the first one that succeeds.
91
+ *
92
+ * @param psbtBytes - The raw PSBT bytes
93
+ * @param networks - Optional list of networks to try (defaults to all networks)
94
+ * @returns An object with the parsed Node and detected network, or null if all fail
95
+ */
96
+ export declare function tryParsePsbtRaw(psbtBytes: Uint8Array, networks?: CoinName[]): {
97
+ node: Node;
98
+ network: CoinName;
99
+ } | null;
100
+ /**
101
+ * Check if the inspect feature is enabled in the WASM build.
102
+ *
103
+ * @returns true if the feature is enabled, false otherwise
104
+ */
105
+ export declare function isInspectEnabled(): boolean;
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ /**
3
+ * Inspect - TypeScript bindings for PSBT and Transaction parsing
4
+ *
5
+ * Provides typed wrappers around the WASM inspect functions that return
6
+ * hierarchical node structures suitable for display as collapsible trees.
7
+ *
8
+ * Import via: `import { ... } from "@bitgo/wasm-utxo/inspect"`
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.allNetworks = void 0;
12
+ exports.parsePsbtToNode = parsePsbtToNode;
13
+ exports.parseTxToNode = parseTxToNode;
14
+ exports.tryParsePsbt = tryParsePsbt;
15
+ exports.tryParseTx = tryParseTx;
16
+ exports.parsePsbtRawToNode = parsePsbtRawToNode;
17
+ exports.tryParsePsbtRaw = tryParsePsbtRaw;
18
+ exports.isInspectEnabled = isInspectEnabled;
19
+ const wasm_utxo_js_1 = require("../wasm/wasm_utxo.js");
20
+ /** All supported networks in order of parsing priority */
21
+ exports.allNetworks = [
22
+ "btc",
23
+ "tbtc",
24
+ "tbtc4",
25
+ "tbtcsig",
26
+ "tbtcbgsig",
27
+ "ltc",
28
+ "tltc",
29
+ "bch",
30
+ "tbch",
31
+ "bcha",
32
+ "tbcha",
33
+ "btg",
34
+ "tbtg",
35
+ "bsv",
36
+ "tbsv",
37
+ "dash",
38
+ "tdash",
39
+ "doge",
40
+ "tdoge",
41
+ "zec",
42
+ "tzec",
43
+ ];
44
+ /**
45
+ * Parse a PSBT and return a typed node tree.
46
+ *
47
+ * @param psbtBytes - The raw PSBT bytes
48
+ * @param network - The network coin name (e.g., "btc", "ltc", "bch")
49
+ * @returns A Node tree representing the parsed PSBT structure
50
+ * @throws If the PSBT bytes are invalid or network is unknown
51
+ */
52
+ function parsePsbtToNode(psbtBytes, network) {
53
+ const json = (0, wasm_utxo_js_1.parsePsbtToJson)(psbtBytes, network);
54
+ return JSON.parse(json);
55
+ }
56
+ /**
57
+ * Parse a transaction and return a typed node tree.
58
+ *
59
+ * @param txBytes - The raw transaction bytes
60
+ * @param network - The network coin name (e.g., "btc", "ltc", "bch")
61
+ * @returns A Node tree representing the parsed transaction structure
62
+ * @throws If the transaction bytes are invalid or network is unknown
63
+ */
64
+ function parseTxToNode(txBytes, network) {
65
+ const json = (0, wasm_utxo_js_1.parseTxToJson)(txBytes, network);
66
+ return JSON.parse(json);
67
+ }
68
+ /**
69
+ * Try to parse a PSBT with all networks and return the first one that succeeds.
70
+ *
71
+ * @param psbtBytes - The raw PSBT bytes
72
+ * @param networks - Optional list of networks to try (defaults to all networks)
73
+ * @returns An object with the parsed Node and detected network, or null if all fail
74
+ */
75
+ function tryParsePsbt(psbtBytes, networks = exports.allNetworks) {
76
+ for (const network of networks) {
77
+ try {
78
+ const node = parsePsbtToNode(psbtBytes, network);
79
+ return { node, network };
80
+ }
81
+ catch {
82
+ // Try next network
83
+ }
84
+ }
85
+ return null;
86
+ }
87
+ /**
88
+ * Try to parse a transaction with all networks and return the first one that succeeds.
89
+ *
90
+ * @param txBytes - The raw transaction bytes
91
+ * @param networks - Optional list of networks to try (defaults to all networks)
92
+ * @returns An object with the parsed Node and detected network, or null if all fail
93
+ */
94
+ function tryParseTx(txBytes, networks = exports.allNetworks) {
95
+ for (const network of networks) {
96
+ try {
97
+ const node = parseTxToNode(txBytes, network);
98
+ return { node, network };
99
+ }
100
+ catch {
101
+ // Try next network
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+ /**
107
+ * Parse a PSBT at the raw byte level and return a typed node tree.
108
+ *
109
+ * Unlike `parsePsbtToNode`, this function exposes the raw key-value pair
110
+ * structure as defined in BIP-174, showing:
111
+ * - Raw key type IDs and their human-readable names
112
+ * - Proprietary keys with their structured format
113
+ * - Unknown/unrecognized keys that standard parsers might skip
114
+ *
115
+ * @param psbtBytes - The raw PSBT bytes
116
+ * @param network - The network coin name (e.g., "btc", "ltc", "zec")
117
+ * @returns A Node tree representing the raw PSBT key-value structure
118
+ * @throws If the PSBT bytes are invalid or network is unknown
119
+ */
120
+ function parsePsbtRawToNode(psbtBytes, network) {
121
+ const json = (0, wasm_utxo_js_1.parsePsbtRawToJson)(psbtBytes, network);
122
+ return JSON.parse(json);
123
+ }
124
+ /**
125
+ * Try to parse a raw PSBT with all networks and return the first one that succeeds.
126
+ *
127
+ * @param psbtBytes - The raw PSBT bytes
128
+ * @param networks - Optional list of networks to try (defaults to all networks)
129
+ * @returns An object with the parsed Node and detected network, or null if all fail
130
+ */
131
+ function tryParsePsbtRaw(psbtBytes, networks = exports.allNetworks) {
132
+ for (const network of networks) {
133
+ try {
134
+ const node = parsePsbtRawToNode(psbtBytes, network);
135
+ return { node, network };
136
+ }
137
+ catch {
138
+ // Try next network
139
+ }
140
+ }
141
+ return null;
142
+ }
143
+ /**
144
+ * Check if the inspect feature is enabled in the WASM build.
145
+ *
146
+ * @returns true if the feature is enabled, false otherwise
147
+ */
148
+ function isInspectEnabled() {
149
+ return (0, wasm_utxo_js_1.isInspectEnabled)();
150
+ }
@@ -14,11 +14,30 @@ export interface ITransaction {
14
14
  export declare class Transaction implements ITransaction {
15
15
  private _wasm;
16
16
  private constructor();
17
+ /**
18
+ * Create an empty transaction (version 1, locktime 0)
19
+ */
20
+ static create(): Transaction;
17
21
  static fromBytes(bytes: Uint8Array): Transaction;
18
22
  /**
19
23
  * @internal Create from WASM instance directly (avoids re-parsing bytes)
20
24
  */
21
25
  static fromWasm(wasm: WasmTransaction): Transaction;
26
+ /**
27
+ * Add an input to the transaction
28
+ * @param txid - Previous transaction ID (hex string)
29
+ * @param vout - Output index being spent
30
+ * @param sequence - Optional sequence number (default: 0xFFFFFFFF)
31
+ * @returns The index of the newly added input
32
+ */
33
+ addInput(txid: string, vout: number, sequence?: number): number;
34
+ /**
35
+ * Add an output to the transaction
36
+ * @param script - Output script (scriptPubKey)
37
+ * @param value - Value in satoshis
38
+ * @returns The index of the newly added output
39
+ */
40
+ addOutput(script: Uint8Array, value: bigint): number;
22
41
  toBytes(): Uint8Array;
23
42
  /**
24
43
  * Get the transaction ID (txid)
@@ -12,6 +12,12 @@ class Transaction {
12
12
  constructor(_wasm) {
13
13
  this._wasm = _wasm;
14
14
  }
15
+ /**
16
+ * Create an empty transaction (version 1, locktime 0)
17
+ */
18
+ static create() {
19
+ return new Transaction(wasm_utxo_js_1.WasmTransaction.create());
20
+ }
15
21
  static fromBytes(bytes) {
16
22
  return new Transaction(wasm_utxo_js_1.WasmTransaction.from_bytes(bytes));
17
23
  }
@@ -21,6 +27,25 @@ class Transaction {
21
27
  static fromWasm(wasm) {
22
28
  return new Transaction(wasm);
23
29
  }
30
+ /**
31
+ * Add an input to the transaction
32
+ * @param txid - Previous transaction ID (hex string)
33
+ * @param vout - Output index being spent
34
+ * @param sequence - Optional sequence number (default: 0xFFFFFFFF)
35
+ * @returns The index of the newly added input
36
+ */
37
+ addInput(txid, vout, sequence) {
38
+ return this._wasm.add_input(txid, vout, sequence);
39
+ }
40
+ /**
41
+ * Add an output to the transaction
42
+ * @param script - Output script (scriptPubKey)
43
+ * @param value - Value in satoshis
44
+ * @returns The index of the newly added output
45
+ */
46
+ addOutput(script, value) {
47
+ return this._wasm.add_output(script, value);
48
+ }
24
49
  toBytes() {
25
50
  return this._wasm.to_bytes();
26
51
  }
@@ -181,7 +181,7 @@ export class BitGoPsbt {
181
181
  * # Returns
182
182
  * The index of the newly added input
183
183
  */
184
- add_replay_protection_input(ecpair: WasmECPair, txid: string, vout: number, value: bigint, sequence?: number | null): number;
184
+ add_replay_protection_input(ecpair: WasmECPair, txid: string, vout: number, value: bigint, sequence?: number | null, prev_tx?: Uint8Array | null): number;
185
185
  /**
186
186
  * Add a wallet input with full PSBT metadata
187
187
  *
@@ -756,6 +756,16 @@ export class FixedScriptWalletNamespace {
756
756
  static create_op_return_script(data?: Uint8Array | null): Uint8Array;
757
757
  static output_script(keys: WasmRootWalletKeys, chain: number, index: number, network: any): Uint8Array;
758
758
  static output_script_with_network_str(keys: WasmRootWalletKeys, chain: number, index: number, network: string): Uint8Array;
759
+ /**
760
+ * Get the P2SH-P2PK output script for a compressed public key
761
+ *
762
+ * # Arguments
763
+ * * `pubkey` - The compressed public key bytes (33 bytes)
764
+ *
765
+ * # Returns
766
+ * The P2SH-P2PK output script as bytes
767
+ */
768
+ static p2sh_p2pk_output_script(pubkey: Uint8Array): Uint8Array;
759
769
  /**
760
770
  * Check if a network supports a given fixed-script wallet script type
761
771
  *
@@ -1220,6 +1230,33 @@ export class WasmTransaction {
1220
1230
  private constructor();
1221
1231
  free(): void;
1222
1232
  [Symbol.dispose](): void;
1233
+ /**
1234
+ * Add an input to the transaction
1235
+ *
1236
+ * # Arguments
1237
+ * * `txid` - The transaction ID (hex string) of the output being spent
1238
+ * * `vout` - The output index being spent
1239
+ * * `sequence` - Optional sequence number (default: 0xFFFFFFFF)
1240
+ *
1241
+ * # Returns
1242
+ * The index of the newly added input
1243
+ */
1244
+ add_input(txid: string, vout: number, sequence?: number | null): number;
1245
+ /**
1246
+ * Add an output to the transaction
1247
+ *
1248
+ * # Arguments
1249
+ * * `script` - The output script (scriptPubKey)
1250
+ * * `value` - The value in satoshis
1251
+ *
1252
+ * # Returns
1253
+ * The index of the newly added output
1254
+ */
1255
+ add_output(script: Uint8Array, value: bigint): number;
1256
+ /**
1257
+ * Create an empty transaction (version 1, locktime 0)
1258
+ */
1259
+ static create(): WasmTransaction;
1223
1260
  /**
1224
1261
  * Deserialize a transaction from bytes
1225
1262
  *
@@ -1497,3 +1534,74 @@ export class WrapPsbt {
1497
1534
  */
1498
1535
  version(): number;
1499
1536
  }
1537
+
1538
+ /**
1539
+ * Check if the inspect feature is enabled.
1540
+ *
1541
+ * # Returns
1542
+ * `true` if the feature is enabled, `false` otherwise
1543
+ */
1544
+ export function isInspectEnabled(): boolean;
1545
+
1546
+ /**
1547
+ * Parse a PSBT at the raw byte level and return a JSON representation.
1548
+ *
1549
+ * Unlike `parsePsbtToJson`, this function exposes the raw key-value pair
1550
+ * structure as defined in BIP-174, showing:
1551
+ * - Raw key type IDs and their human-readable names
1552
+ * - Proprietary keys with their structured format
1553
+ * - Unknown/unrecognized keys that standard parsers might skip
1554
+ *
1555
+ * # Arguments
1556
+ * * `psbt_bytes` - The raw PSBT bytes
1557
+ * * `coin_name` - The network coin name (e.g., "btc", "ltc", "zec")
1558
+ *
1559
+ * # Returns
1560
+ * A JSON string representing the raw PSBT key-value structure
1561
+ *
1562
+ * # Errors
1563
+ * Returns an error if:
1564
+ * - The `inspect` feature is not enabled
1565
+ * - The PSBT bytes are invalid
1566
+ * - The network name is unknown
1567
+ */
1568
+ export function parsePsbtRawToJson(psbt_bytes: Uint8Array, coin_name: string): string;
1569
+
1570
+ /**
1571
+ * Parse a PSBT and return a JSON representation of its structure.
1572
+ *
1573
+ * This function parses the PSBT using the standard bitcoin crate parser
1574
+ * and returns a hierarchical node structure suitable for display.
1575
+ *
1576
+ * # Arguments
1577
+ * * `psbt_bytes` - The raw PSBT bytes
1578
+ * * `coin_name` - The network coin name (e.g., "btc", "ltc", "bch")
1579
+ *
1580
+ * # Returns
1581
+ * A JSON string representing the parsed PSBT structure
1582
+ *
1583
+ * # Errors
1584
+ * Returns an error if:
1585
+ * - The `inspect` feature is not enabled
1586
+ * - The PSBT bytes are invalid
1587
+ * - The network name is unknown
1588
+ */
1589
+ export function parsePsbtToJson(psbt_bytes: Uint8Array, coin_name: string): string;
1590
+
1591
+ /**
1592
+ * Parse a transaction and return a JSON representation of its structure.
1593
+ *
1594
+ * # Arguments
1595
+ * * `tx_bytes` - The raw transaction bytes
1596
+ * * `coin_name` - The network coin name (e.g., "btc", "ltc", "bch")
1597
+ *
1598
+ * # Returns
1599
+ * A JSON string representing the parsed transaction structure
1600
+ *
1601
+ * # Errors
1602
+ * Returns an error if:
1603
+ * - The `inspect` feature is not enabled
1604
+ * - The transaction bytes are invalid
1605
+ * - The network name is unknown
1606
+ */
1607
+ export function parseTxToJson(tx_bytes: Uint8Array, coin_name: string): string;