@bitgo/wasm-utxo 1.22.0 → 1.23.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.
@@ -47,6 +47,10 @@ export declare class Dimensions {
47
47
  * Combine with another Dimensions instance
48
48
  */
49
49
  plus(other: Dimensions): Dimensions;
50
+ /**
51
+ * Multiply dimensions by a scalar
52
+ */
53
+ times(n: number): Dimensions;
50
54
  /**
51
55
  * Whether any inputs are segwit (affects overhead calculation)
52
56
  */
@@ -61,5 +65,23 @@ export declare class Dimensions {
61
65
  * @param size - "min" or "max", defaults to "max"
62
66
  */
63
67
  getVSize(size?: "min" | "max"): number;
68
+ /**
69
+ * Get input weight only (min or max)
70
+ * @param size - "min" or "max", defaults to "max"
71
+ */
72
+ getInputWeight(size?: "min" | "max"): number;
73
+ /**
74
+ * Get input virtual size (min or max)
75
+ * @param size - "min" or "max", defaults to "max"
76
+ */
77
+ getInputVSize(size?: "min" | "max"): number;
78
+ /**
79
+ * Get output weight
80
+ */
81
+ getOutputWeight(): number;
82
+ /**
83
+ * Get output virtual size
84
+ */
85
+ getOutputVSize(): number;
64
86
  }
65
87
  export {};
@@ -59,6 +59,12 @@ class Dimensions {
59
59
  plus(other) {
60
60
  return new Dimensions(this._wasm.plus(other._wasm));
61
61
  }
62
+ /**
63
+ * Multiply dimensions by a scalar
64
+ */
65
+ times(n) {
66
+ return new Dimensions(this._wasm.times(n));
67
+ }
62
68
  /**
63
69
  * Whether any inputs are segwit (affects overhead calculation)
64
70
  */
@@ -79,5 +85,31 @@ class Dimensions {
79
85
  getVSize(size = "max") {
80
86
  return this._wasm.get_vsize(size);
81
87
  }
88
+ /**
89
+ * Get input weight only (min or max)
90
+ * @param size - "min" or "max", defaults to "max"
91
+ */
92
+ getInputWeight(size = "max") {
93
+ return this._wasm.get_input_weight(size);
94
+ }
95
+ /**
96
+ * Get input virtual size (min or max)
97
+ * @param size - "min" or "max", defaults to "max"
98
+ */
99
+ getInputVSize(size = "max") {
100
+ return this._wasm.get_input_vsize(size);
101
+ }
102
+ /**
103
+ * Get output weight
104
+ */
105
+ getOutputWeight() {
106
+ return this._wasm.get_output_weight();
107
+ }
108
+ /**
109
+ * Get output virtual size
110
+ */
111
+ getOutputVSize() {
112
+ return this._wasm.get_output_vsize();
113
+ }
82
114
  }
83
115
  exports.Dimensions = Dimensions;
@@ -0,0 +1,56 @@
1
+ import type { OutputScriptType } from "./scriptType.js";
2
+ /** All valid chain codes as a const tuple */
3
+ export declare const chainCodes: readonly [0, 1, 10, 11, 20, 21, 30, 31, 40, 41];
4
+ /** A valid chain code value */
5
+ export type ChainCode = (typeof chainCodes)[number];
6
+ /** Whether a chain is for receiving (external) or change (internal) addresses */
7
+ export type Scope = "internal" | "external";
8
+ /**
9
+ * ChainCode namespace with utility functions for working with chain codes.
10
+ */
11
+ export declare const ChainCode: {
12
+ /**
13
+ * Check if a value is a valid chain code.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * if (ChainCode.is(maybeChain)) {
18
+ * // maybeChain is now typed as ChainCode
19
+ * const scope = ChainCode.scope(maybeChain);
20
+ * }
21
+ * ```
22
+ */
23
+ is(n: unknown): n is ChainCode;
24
+ /**
25
+ * Get the chain code for a script type and scope.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const externalP2wsh = ChainCode.value("p2wsh", "external"); // 20
30
+ * const internalP2tr = ChainCode.value("p2trLegacy", "internal"); // 31
31
+ * ```
32
+ */
33
+ value(scriptType: OutputScriptType | "p2tr", scope: Scope): ChainCode;
34
+ /**
35
+ * Get the scope (external/internal) for a chain code.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * ChainCode.scope(0); // "external"
40
+ * ChainCode.scope(1); // "internal"
41
+ * ChainCode.scope(20); // "external"
42
+ * ```
43
+ */
44
+ scope(chainCode: ChainCode): Scope;
45
+ /**
46
+ * Get the script type for a chain code.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * ChainCode.scriptType(0); // "p2sh"
51
+ * ChainCode.scriptType(20); // "p2wsh"
52
+ * ChainCode.scriptType(40); // "p2trMusig2"
53
+ * ```
54
+ */
55
+ scriptType(chainCode: ChainCode): OutputScriptType;
56
+ };
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChainCode = exports.chainCodes = void 0;
4
+ /**
5
+ * Chain code utilities for BitGo fixed-script wallets.
6
+ *
7
+ * Chain codes define the derivation path component for different script types
8
+ * and scopes (external/internal) in the format `m/0/0/{chain}/{index}`.
9
+ */
10
+ const wasm_utxo_js_1 = require("../wasm/wasm_utxo.js");
11
+ /** All valid chain codes as a const tuple */
12
+ exports.chainCodes = [0, 1, 10, 11, 20, 21, 30, 31, 40, 41];
13
+ // Build static lookup tables once at module load time
14
+ const chainCodeSet = new Set(exports.chainCodes);
15
+ const chainToMeta = new Map();
16
+ const scriptTypeToChain = new Map();
17
+ // Initialize from WASM (called once at load time)
18
+ function assertChainCode(n) {
19
+ if (!chainCodeSet.has(n)) {
20
+ throw new Error(`Invalid chain code from WASM: ${n}`);
21
+ }
22
+ return n;
23
+ }
24
+ function assertScope(s) {
25
+ if (s !== "internal" && s !== "external") {
26
+ throw new Error(`Invalid scope from WASM: ${s}`);
27
+ }
28
+ return s;
29
+ }
30
+ for (const tuple of wasm_utxo_js_1.FixedScriptWalletNamespace.chain_code_table()) {
31
+ if (!Array.isArray(tuple) || tuple.length !== 3) {
32
+ throw new Error(`Invalid chain_code_table entry: expected [number, string, string]`);
33
+ }
34
+ const [rawCode, rawScriptType, rawScope] = tuple;
35
+ if (typeof rawCode !== "number") {
36
+ throw new Error(`Invalid chain code type: ${typeof rawCode}`);
37
+ }
38
+ if (typeof rawScriptType !== "string") {
39
+ throw new Error(`Invalid scriptType type: ${typeof rawScriptType}`);
40
+ }
41
+ if (typeof rawScope !== "string") {
42
+ throw new Error(`Invalid scope type: ${typeof rawScope}`);
43
+ }
44
+ const code = assertChainCode(rawCode);
45
+ const scriptType = rawScriptType;
46
+ const scope = assertScope(rawScope);
47
+ chainToMeta.set(code, { scope, scriptType });
48
+ let entry = scriptTypeToChain.get(scriptType);
49
+ if (!entry) {
50
+ entry = {};
51
+ scriptTypeToChain.set(scriptType, entry);
52
+ }
53
+ entry[scope] = code;
54
+ }
55
+ /**
56
+ * ChainCode namespace with utility functions for working with chain codes.
57
+ */
58
+ exports.ChainCode = {
59
+ /**
60
+ * Check if a value is a valid chain code.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * if (ChainCode.is(maybeChain)) {
65
+ * // maybeChain is now typed as ChainCode
66
+ * const scope = ChainCode.scope(maybeChain);
67
+ * }
68
+ * ```
69
+ */
70
+ is(n) {
71
+ return typeof n === "number" && chainCodeSet.has(n);
72
+ },
73
+ /**
74
+ * Get the chain code for a script type and scope.
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const externalP2wsh = ChainCode.value("p2wsh", "external"); // 20
79
+ * const internalP2tr = ChainCode.value("p2trLegacy", "internal"); // 31
80
+ * ```
81
+ */
82
+ value(scriptType, scope) {
83
+ // legacy alias for p2trLegacy
84
+ if (scriptType === "p2tr") {
85
+ scriptType = "p2trLegacy";
86
+ }
87
+ const entry = scriptTypeToChain.get(scriptType);
88
+ if (!entry) {
89
+ throw new Error(`Invalid scriptType: ${scriptType}`);
90
+ }
91
+ return entry[scope];
92
+ },
93
+ /**
94
+ * Get the scope (external/internal) for a chain code.
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * ChainCode.scope(0); // "external"
99
+ * ChainCode.scope(1); // "internal"
100
+ * ChainCode.scope(20); // "external"
101
+ * ```
102
+ */
103
+ scope(chainCode) {
104
+ const meta = chainToMeta.get(chainCode);
105
+ if (!meta)
106
+ throw new Error(`Invalid chainCode: ${chainCode}`);
107
+ return meta.scope;
108
+ },
109
+ /**
110
+ * Get the script type for a chain code.
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * ChainCode.scriptType(0); // "p2sh"
115
+ * ChainCode.scriptType(20); // "p2wsh"
116
+ * ChainCode.scriptType(40); // "p2trMusig2"
117
+ * ```
118
+ */
119
+ scriptType(chainCode) {
120
+ const meta = chainToMeta.get(chainCode);
121
+ if (!meta)
122
+ throw new Error(`Invalid chainCode: ${chainCode}`);
123
+ return meta.scriptType;
124
+ },
125
+ };
@@ -4,6 +4,7 @@ export { ReplayProtection, type ReplayProtectionArg } from "./ReplayProtection.j
4
4
  export { outputScript, address } from "./address.js";
5
5
  export { Dimensions } from "./Dimensions.js";
6
6
  export { type OutputScriptType, type InputScriptType, type ScriptType } from "./scriptType.js";
7
+ export { ChainCode, chainCodes, type Scope } from "./chains.js";
7
8
  export { BitGoPsbt, type NetworkName, type ScriptId, type ParsedInput, type ParsedOutput, type ParsedTransaction, type SignPath, type CreateEmptyOptions, type AddInputOptions, type AddOutputOptions, type AddWalletInputOptions, type AddWalletOutputOptions, } from "./BitGoPsbt.js";
8
9
  export { ZcashBitGoPsbt, type ZcashNetworkName, type CreateEmptyZcashOptions, } from "./ZcashBitGoPsbt.js";
9
10
  import type { ScriptType } from "./scriptType.js";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ZcashBitGoPsbt = exports.BitGoPsbt = exports.Dimensions = exports.address = exports.outputScript = exports.ReplayProtection = exports.RootWalletKeys = void 0;
3
+ exports.ZcashBitGoPsbt = exports.BitGoPsbt = exports.chainCodes = exports.ChainCode = exports.Dimensions = exports.address = exports.outputScript = exports.ReplayProtection = exports.RootWalletKeys = void 0;
4
4
  exports.supportsScriptType = supportsScriptType;
5
5
  const wasm_utxo_js_1 = require("../wasm/wasm_utxo.js");
6
6
  var RootWalletKeys_js_1 = require("./RootWalletKeys.js");
@@ -12,6 +12,9 @@ Object.defineProperty(exports, "outputScript", { enumerable: true, get: function
12
12
  Object.defineProperty(exports, "address", { enumerable: true, get: function () { return address_js_1.address; } });
13
13
  var Dimensions_js_1 = require("./Dimensions.js");
14
14
  Object.defineProperty(exports, "Dimensions", { enumerable: true, get: function () { return Dimensions_js_1.Dimensions; } });
15
+ var chains_js_1 = require("./chains.js");
16
+ Object.defineProperty(exports, "ChainCode", { enumerable: true, get: function () { return chains_js_1.ChainCode; } });
17
+ Object.defineProperty(exports, "chainCodes", { enumerable: true, get: function () { return chains_js_1.chainCodes; } });
15
18
  // Bitcoin-like PSBT (for all non-Zcash networks)
16
19
  var BitGoPsbt_js_1 = require("./BitGoPsbt.js");
17
20
  Object.defineProperty(exports, "BitGoPsbt", { enumerable: true, get: function () { return BitGoPsbt_js_1.BitGoPsbt; } });
@@ -479,6 +479,15 @@ export class FixedScriptWalletNamespace {
479
479
  free(): void;
480
480
  [Symbol.dispose](): void;
481
481
  static output_script(keys: WasmRootWalletKeys, chain: number, index: number, network: any): Uint8Array;
482
+ /**
483
+ * Get all chain code metadata for building TypeScript lookup tables
484
+ *
485
+ * Returns an array of [chainCode, scriptType, scope] tuples where:
486
+ * - chainCode: u32 (0, 1, 10, 11, 20, 21, 30, 31, 40, 41)
487
+ * - scriptType: string ("p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", "p2trMusig2")
488
+ * - scope: string ("external" or "internal")
489
+ */
490
+ static chain_code_table(): any;
482
491
  /**
483
492
  * Check if a network supports a given fixed-script wallet script type
484
493
  *
@@ -653,6 +662,28 @@ export class WasmDimensions {
653
662
  * Whether any inputs are segwit (affects overhead calculation)
654
663
  */
655
664
  has_segwit(): boolean;
665
+ /**
666
+ * Get input virtual size (min or max)
667
+ *
668
+ * # Arguments
669
+ * * `size` - "min" or "max", defaults to "max"
670
+ */
671
+ get_input_vsize(size?: string | null): number;
672
+ /**
673
+ * Get input weight only (min or max)
674
+ *
675
+ * # Arguments
676
+ * * `size` - "min" or "max", defaults to "max"
677
+ */
678
+ get_input_weight(size?: string | null): number;
679
+ /**
680
+ * Get output virtual size
681
+ */
682
+ get_output_vsize(): number;
683
+ /**
684
+ * Get output weight
685
+ */
686
+ get_output_weight(): number;
656
687
  /**
657
688
  * Create dimensions for a single output from script bytes
658
689
  */
@@ -673,6 +704,10 @@ export class WasmDimensions {
673
704
  * Create empty dimensions (zero weight)
674
705
  */
675
706
  static empty(): WasmDimensions;
707
+ /**
708
+ * Multiply dimensions by a scalar
709
+ */
710
+ times(n: number): WasmDimensions;
676
711
  /**
677
712
  * Create dimensions from a BitGoPsbt
678
713
  *
@@ -1519,6 +1519,19 @@ class FixedScriptWalletNamespace {
1519
1519
  wasm.__wbindgen_add_to_stack_pointer(16);
1520
1520
  }
1521
1521
  }
1522
+ /**
1523
+ * Get all chain code metadata for building TypeScript lookup tables
1524
+ *
1525
+ * Returns an array of [chainCode, scriptType, scope] tuples where:
1526
+ * - chainCode: u32 (0, 1, 10, 11, 20, 21, 30, 31, 40, 41)
1527
+ * - scriptType: string ("p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", "p2trMusig2")
1528
+ * - scope: string ("external" or "internal")
1529
+ * @returns {any}
1530
+ */
1531
+ static chain_code_table() {
1532
+ const ret = wasm.fixedscriptwalletnamespace_chain_code_table();
1533
+ return takeObject(ret);
1534
+ }
1522
1535
  /**
1523
1536
  * Check if a network supports a given fixed-script wallet script type
1524
1537
  *
@@ -2182,6 +2195,50 @@ class WasmDimensions {
2182
2195
  const ret = wasm.wasmdimensions_has_segwit(this.__wbg_ptr);
2183
2196
  return ret !== 0;
2184
2197
  }
2198
+ /**
2199
+ * Get input virtual size (min or max)
2200
+ *
2201
+ * # Arguments
2202
+ * * `size` - "min" or "max", defaults to "max"
2203
+ * @param {string | null} [size]
2204
+ * @returns {number}
2205
+ */
2206
+ get_input_vsize(size) {
2207
+ var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2208
+ var len0 = WASM_VECTOR_LEN;
2209
+ const ret = wasm.wasmdimensions_get_input_vsize(this.__wbg_ptr, ptr0, len0);
2210
+ return ret >>> 0;
2211
+ }
2212
+ /**
2213
+ * Get input weight only (min or max)
2214
+ *
2215
+ * # Arguments
2216
+ * * `size` - "min" or "max", defaults to "max"
2217
+ * @param {string | null} [size]
2218
+ * @returns {number}
2219
+ */
2220
+ get_input_weight(size) {
2221
+ var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2222
+ var len0 = WASM_VECTOR_LEN;
2223
+ const ret = wasm.wasmdimensions_get_input_weight(this.__wbg_ptr, ptr0, len0);
2224
+ return ret >>> 0;
2225
+ }
2226
+ /**
2227
+ * Get output virtual size
2228
+ * @returns {number}
2229
+ */
2230
+ get_output_vsize() {
2231
+ const ret = wasm.wasmdimensions_get_output_vsize(this.__wbg_ptr);
2232
+ return ret >>> 0;
2233
+ }
2234
+ /**
2235
+ * Get output weight
2236
+ * @returns {number}
2237
+ */
2238
+ get_output_weight() {
2239
+ const ret = wasm.wasmdimensions_get_output_weight(this.__wbg_ptr);
2240
+ return ret >>> 0;
2241
+ }
2185
2242
  /**
2186
2243
  * Create dimensions for a single output from script bytes
2187
2244
  * @param {Uint8Array} script
@@ -2237,6 +2294,15 @@ class WasmDimensions {
2237
2294
  const ret = wasm.wasmdimensions_empty();
2238
2295
  return WasmDimensions.__wrap(ret);
2239
2296
  }
2297
+ /**
2298
+ * Multiply dimensions by a scalar
2299
+ * @param {number} n
2300
+ * @returns {WasmDimensions}
2301
+ */
2302
+ times(n) {
2303
+ const ret = wasm.wasmdimensions_times(this.__wbg_ptr, n);
2304
+ return WasmDimensions.__wrap(ret);
2305
+ }
2240
2306
  /**
2241
2307
  * Create dimensions from a BitGoPsbt
2242
2308
  *
Binary file
@@ -84,6 +84,7 @@ export const bitgopsbt_verify_signature_with_xpub: (a: number, b: number, c: num
84
84
  export const bitgopsbt_version: (a: number) => number;
85
85
  export const bitgopsbt_version_group_id: (a: number) => number;
86
86
  export const fixedscriptwalletnamespace_address: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
87
+ export const fixedscriptwalletnamespace_chain_code_table: () => number;
87
88
  export const fixedscriptwalletnamespace_output_script: (a: number, b: number, c: number, d: number, e: number) => void;
88
89
  export const fixedscriptwalletnamespace_supports_script_type: (a: number, b: number, c: number, d: number, e: number) => void;
89
90
  export const utxolibcompatnamespace_from_output_script: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
@@ -115,10 +116,15 @@ export const wasmdimensions_from_input: (a: number, b: number, c: number, d: num
115
116
  export const wasmdimensions_from_input_script_type: (a: number, b: number, c: number) => void;
116
117
  export const wasmdimensions_from_output_script: (a: number, b: number) => number;
117
118
  export const wasmdimensions_from_psbt: (a: number, b: number) => void;
119
+ export const wasmdimensions_get_input_vsize: (a: number, b: number, c: number) => number;
120
+ export const wasmdimensions_get_input_weight: (a: number, b: number, c: number) => number;
121
+ export const wasmdimensions_get_output_vsize: (a: number) => number;
122
+ export const wasmdimensions_get_output_weight: (a: number) => number;
118
123
  export const wasmdimensions_get_vsize: (a: number, b: number, c: number) => number;
119
124
  export const wasmdimensions_get_weight: (a: number, b: number, c: number) => number;
120
125
  export const wasmdimensions_has_segwit: (a: number) => number;
121
126
  export const wasmdimensions_plus: (a: number, b: number) => number;
127
+ export const wasmdimensions_times: (a: number, b: number) => number;
122
128
  export const wasmecpair_from_private_key: (a: number, b: number, c: number) => void;
123
129
  export const wasmecpair_from_public_key: (a: number, b: number, c: number) => void;
124
130
  export const wasmecpair_from_wif: (a: number, b: number, c: number) => void;
@@ -47,6 +47,10 @@ export declare class Dimensions {
47
47
  * Combine with another Dimensions instance
48
48
  */
49
49
  plus(other: Dimensions): Dimensions;
50
+ /**
51
+ * Multiply dimensions by a scalar
52
+ */
53
+ times(n: number): Dimensions;
50
54
  /**
51
55
  * Whether any inputs are segwit (affects overhead calculation)
52
56
  */
@@ -61,5 +65,23 @@ export declare class Dimensions {
61
65
  * @param size - "min" or "max", defaults to "max"
62
66
  */
63
67
  getVSize(size?: "min" | "max"): number;
68
+ /**
69
+ * Get input weight only (min or max)
70
+ * @param size - "min" or "max", defaults to "max"
71
+ */
72
+ getInputWeight(size?: "min" | "max"): number;
73
+ /**
74
+ * Get input virtual size (min or max)
75
+ * @param size - "min" or "max", defaults to "max"
76
+ */
77
+ getInputVSize(size?: "min" | "max"): number;
78
+ /**
79
+ * Get output weight
80
+ */
81
+ getOutputWeight(): number;
82
+ /**
83
+ * Get output virtual size
84
+ */
85
+ getOutputVSize(): number;
64
86
  }
65
87
  export {};
@@ -56,6 +56,12 @@ export class Dimensions {
56
56
  plus(other) {
57
57
  return new Dimensions(this._wasm.plus(other._wasm));
58
58
  }
59
+ /**
60
+ * Multiply dimensions by a scalar
61
+ */
62
+ times(n) {
63
+ return new Dimensions(this._wasm.times(n));
64
+ }
59
65
  /**
60
66
  * Whether any inputs are segwit (affects overhead calculation)
61
67
  */
@@ -76,4 +82,30 @@ export class Dimensions {
76
82
  getVSize(size = "max") {
77
83
  return this._wasm.get_vsize(size);
78
84
  }
85
+ /**
86
+ * Get input weight only (min or max)
87
+ * @param size - "min" or "max", defaults to "max"
88
+ */
89
+ getInputWeight(size = "max") {
90
+ return this._wasm.get_input_weight(size);
91
+ }
92
+ /**
93
+ * Get input virtual size (min or max)
94
+ * @param size - "min" or "max", defaults to "max"
95
+ */
96
+ getInputVSize(size = "max") {
97
+ return this._wasm.get_input_vsize(size);
98
+ }
99
+ /**
100
+ * Get output weight
101
+ */
102
+ getOutputWeight() {
103
+ return this._wasm.get_output_weight();
104
+ }
105
+ /**
106
+ * Get output virtual size
107
+ */
108
+ getOutputVSize() {
109
+ return this._wasm.get_output_vsize();
110
+ }
79
111
  }
@@ -0,0 +1,56 @@
1
+ import type { OutputScriptType } from "./scriptType.js";
2
+ /** All valid chain codes as a const tuple */
3
+ export declare const chainCodes: readonly [0, 1, 10, 11, 20, 21, 30, 31, 40, 41];
4
+ /** A valid chain code value */
5
+ export type ChainCode = (typeof chainCodes)[number];
6
+ /** Whether a chain is for receiving (external) or change (internal) addresses */
7
+ export type Scope = "internal" | "external";
8
+ /**
9
+ * ChainCode namespace with utility functions for working with chain codes.
10
+ */
11
+ export declare const ChainCode: {
12
+ /**
13
+ * Check if a value is a valid chain code.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * if (ChainCode.is(maybeChain)) {
18
+ * // maybeChain is now typed as ChainCode
19
+ * const scope = ChainCode.scope(maybeChain);
20
+ * }
21
+ * ```
22
+ */
23
+ is(n: unknown): n is ChainCode;
24
+ /**
25
+ * Get the chain code for a script type and scope.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const externalP2wsh = ChainCode.value("p2wsh", "external"); // 20
30
+ * const internalP2tr = ChainCode.value("p2trLegacy", "internal"); // 31
31
+ * ```
32
+ */
33
+ value(scriptType: OutputScriptType | "p2tr", scope: Scope): ChainCode;
34
+ /**
35
+ * Get the scope (external/internal) for a chain code.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * ChainCode.scope(0); // "external"
40
+ * ChainCode.scope(1); // "internal"
41
+ * ChainCode.scope(20); // "external"
42
+ * ```
43
+ */
44
+ scope(chainCode: ChainCode): Scope;
45
+ /**
46
+ * Get the script type for a chain code.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * ChainCode.scriptType(0); // "p2sh"
51
+ * ChainCode.scriptType(20); // "p2wsh"
52
+ * ChainCode.scriptType(40); // "p2trMusig2"
53
+ * ```
54
+ */
55
+ scriptType(chainCode: ChainCode): OutputScriptType;
56
+ };
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Chain code utilities for BitGo fixed-script wallets.
3
+ *
4
+ * Chain codes define the derivation path component for different script types
5
+ * and scopes (external/internal) in the format `m/0/0/{chain}/{index}`.
6
+ */
7
+ import { FixedScriptWalletNamespace } from "../wasm/wasm_utxo.js";
8
+ /** All valid chain codes as a const tuple */
9
+ export const chainCodes = [0, 1, 10, 11, 20, 21, 30, 31, 40, 41];
10
+ // Build static lookup tables once at module load time
11
+ const chainCodeSet = new Set(chainCodes);
12
+ const chainToMeta = new Map();
13
+ const scriptTypeToChain = new Map();
14
+ // Initialize from WASM (called once at load time)
15
+ function assertChainCode(n) {
16
+ if (!chainCodeSet.has(n)) {
17
+ throw new Error(`Invalid chain code from WASM: ${n}`);
18
+ }
19
+ return n;
20
+ }
21
+ function assertScope(s) {
22
+ if (s !== "internal" && s !== "external") {
23
+ throw new Error(`Invalid scope from WASM: ${s}`);
24
+ }
25
+ return s;
26
+ }
27
+ for (const tuple of FixedScriptWalletNamespace.chain_code_table()) {
28
+ if (!Array.isArray(tuple) || tuple.length !== 3) {
29
+ throw new Error(`Invalid chain_code_table entry: expected [number, string, string]`);
30
+ }
31
+ const [rawCode, rawScriptType, rawScope] = tuple;
32
+ if (typeof rawCode !== "number") {
33
+ throw new Error(`Invalid chain code type: ${typeof rawCode}`);
34
+ }
35
+ if (typeof rawScriptType !== "string") {
36
+ throw new Error(`Invalid scriptType type: ${typeof rawScriptType}`);
37
+ }
38
+ if (typeof rawScope !== "string") {
39
+ throw new Error(`Invalid scope type: ${typeof rawScope}`);
40
+ }
41
+ const code = assertChainCode(rawCode);
42
+ const scriptType = rawScriptType;
43
+ const scope = assertScope(rawScope);
44
+ chainToMeta.set(code, { scope, scriptType });
45
+ let entry = scriptTypeToChain.get(scriptType);
46
+ if (!entry) {
47
+ entry = {};
48
+ scriptTypeToChain.set(scriptType, entry);
49
+ }
50
+ entry[scope] = code;
51
+ }
52
+ /**
53
+ * ChainCode namespace with utility functions for working with chain codes.
54
+ */
55
+ export const ChainCode = {
56
+ /**
57
+ * Check if a value is a valid chain code.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * if (ChainCode.is(maybeChain)) {
62
+ * // maybeChain is now typed as ChainCode
63
+ * const scope = ChainCode.scope(maybeChain);
64
+ * }
65
+ * ```
66
+ */
67
+ is(n) {
68
+ return typeof n === "number" && chainCodeSet.has(n);
69
+ },
70
+ /**
71
+ * Get the chain code for a script type and scope.
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const externalP2wsh = ChainCode.value("p2wsh", "external"); // 20
76
+ * const internalP2tr = ChainCode.value("p2trLegacy", "internal"); // 31
77
+ * ```
78
+ */
79
+ value(scriptType, scope) {
80
+ // legacy alias for p2trLegacy
81
+ if (scriptType === "p2tr") {
82
+ scriptType = "p2trLegacy";
83
+ }
84
+ const entry = scriptTypeToChain.get(scriptType);
85
+ if (!entry) {
86
+ throw new Error(`Invalid scriptType: ${scriptType}`);
87
+ }
88
+ return entry[scope];
89
+ },
90
+ /**
91
+ * Get the scope (external/internal) for a chain code.
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * ChainCode.scope(0); // "external"
96
+ * ChainCode.scope(1); // "internal"
97
+ * ChainCode.scope(20); // "external"
98
+ * ```
99
+ */
100
+ scope(chainCode) {
101
+ const meta = chainToMeta.get(chainCode);
102
+ if (!meta)
103
+ throw new Error(`Invalid chainCode: ${chainCode}`);
104
+ return meta.scope;
105
+ },
106
+ /**
107
+ * Get the script type for a chain code.
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * ChainCode.scriptType(0); // "p2sh"
112
+ * ChainCode.scriptType(20); // "p2wsh"
113
+ * ChainCode.scriptType(40); // "p2trMusig2"
114
+ * ```
115
+ */
116
+ scriptType(chainCode) {
117
+ const meta = chainToMeta.get(chainCode);
118
+ if (!meta)
119
+ throw new Error(`Invalid chainCode: ${chainCode}`);
120
+ return meta.scriptType;
121
+ },
122
+ };
@@ -4,6 +4,7 @@ export { ReplayProtection, type ReplayProtectionArg } from "./ReplayProtection.j
4
4
  export { outputScript, address } from "./address.js";
5
5
  export { Dimensions } from "./Dimensions.js";
6
6
  export { type OutputScriptType, type InputScriptType, type ScriptType } from "./scriptType.js";
7
+ export { ChainCode, chainCodes, type Scope } from "./chains.js";
7
8
  export { BitGoPsbt, type NetworkName, type ScriptId, type ParsedInput, type ParsedOutput, type ParsedTransaction, type SignPath, type CreateEmptyOptions, type AddInputOptions, type AddOutputOptions, type AddWalletInputOptions, type AddWalletOutputOptions, } from "./BitGoPsbt.js";
8
9
  export { ZcashBitGoPsbt, type ZcashNetworkName, type CreateEmptyZcashOptions, } from "./ZcashBitGoPsbt.js";
9
10
  import type { ScriptType } from "./scriptType.js";
@@ -3,6 +3,7 @@ export { RootWalletKeys } from "./RootWalletKeys.js";
3
3
  export { ReplayProtection } from "./ReplayProtection.js";
4
4
  export { outputScript, address } from "./address.js";
5
5
  export { Dimensions } from "./Dimensions.js";
6
+ export { ChainCode, chainCodes } from "./chains.js";
6
7
  // Bitcoin-like PSBT (for all non-Zcash networks)
7
8
  export { BitGoPsbt, } from "./BitGoPsbt.js";
8
9
  // Zcash-specific PSBT subclass
@@ -479,6 +479,15 @@ export class FixedScriptWalletNamespace {
479
479
  free(): void;
480
480
  [Symbol.dispose](): void;
481
481
  static output_script(keys: WasmRootWalletKeys, chain: number, index: number, network: any): Uint8Array;
482
+ /**
483
+ * Get all chain code metadata for building TypeScript lookup tables
484
+ *
485
+ * Returns an array of [chainCode, scriptType, scope] tuples where:
486
+ * - chainCode: u32 (0, 1, 10, 11, 20, 21, 30, 31, 40, 41)
487
+ * - scriptType: string ("p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", "p2trMusig2")
488
+ * - scope: string ("external" or "internal")
489
+ */
490
+ static chain_code_table(): any;
482
491
  /**
483
492
  * Check if a network supports a given fixed-script wallet script type
484
493
  *
@@ -653,6 +662,28 @@ export class WasmDimensions {
653
662
  * Whether any inputs are segwit (affects overhead calculation)
654
663
  */
655
664
  has_segwit(): boolean;
665
+ /**
666
+ * Get input virtual size (min or max)
667
+ *
668
+ * # Arguments
669
+ * * `size` - "min" or "max", defaults to "max"
670
+ */
671
+ get_input_vsize(size?: string | null): number;
672
+ /**
673
+ * Get input weight only (min or max)
674
+ *
675
+ * # Arguments
676
+ * * `size` - "min" or "max", defaults to "max"
677
+ */
678
+ get_input_weight(size?: string | null): number;
679
+ /**
680
+ * Get output virtual size
681
+ */
682
+ get_output_vsize(): number;
683
+ /**
684
+ * Get output weight
685
+ */
686
+ get_output_weight(): number;
656
687
  /**
657
688
  * Create dimensions for a single output from script bytes
658
689
  */
@@ -673,6 +704,10 @@ export class WasmDimensions {
673
704
  * Create empty dimensions (zero weight)
674
705
  */
675
706
  static empty(): WasmDimensions;
707
+ /**
708
+ * Multiply dimensions by a scalar
709
+ */
710
+ times(n: number): WasmDimensions;
676
711
  /**
677
712
  * Create dimensions from a BitGoPsbt
678
713
  *
@@ -1525,6 +1525,19 @@ export class FixedScriptWalletNamespace {
1525
1525
  wasm.__wbindgen_add_to_stack_pointer(16);
1526
1526
  }
1527
1527
  }
1528
+ /**
1529
+ * Get all chain code metadata for building TypeScript lookup tables
1530
+ *
1531
+ * Returns an array of [chainCode, scriptType, scope] tuples where:
1532
+ * - chainCode: u32 (0, 1, 10, 11, 20, 21, 30, 31, 40, 41)
1533
+ * - scriptType: string ("p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", "p2trMusig2")
1534
+ * - scope: string ("external" or "internal")
1535
+ * @returns {any}
1536
+ */
1537
+ static chain_code_table() {
1538
+ const ret = wasm.fixedscriptwalletnamespace_chain_code_table();
1539
+ return takeObject(ret);
1540
+ }
1528
1541
  /**
1529
1542
  * Check if a network supports a given fixed-script wallet script type
1530
1543
  *
@@ -2184,6 +2197,50 @@ export class WasmDimensions {
2184
2197
  const ret = wasm.wasmdimensions_has_segwit(this.__wbg_ptr);
2185
2198
  return ret !== 0;
2186
2199
  }
2200
+ /**
2201
+ * Get input virtual size (min or max)
2202
+ *
2203
+ * # Arguments
2204
+ * * `size` - "min" or "max", defaults to "max"
2205
+ * @param {string | null} [size]
2206
+ * @returns {number}
2207
+ */
2208
+ get_input_vsize(size) {
2209
+ var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2210
+ var len0 = WASM_VECTOR_LEN;
2211
+ const ret = wasm.wasmdimensions_get_input_vsize(this.__wbg_ptr, ptr0, len0);
2212
+ return ret >>> 0;
2213
+ }
2214
+ /**
2215
+ * Get input weight only (min or max)
2216
+ *
2217
+ * # Arguments
2218
+ * * `size` - "min" or "max", defaults to "max"
2219
+ * @param {string | null} [size]
2220
+ * @returns {number}
2221
+ */
2222
+ get_input_weight(size) {
2223
+ var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2224
+ var len0 = WASM_VECTOR_LEN;
2225
+ const ret = wasm.wasmdimensions_get_input_weight(this.__wbg_ptr, ptr0, len0);
2226
+ return ret >>> 0;
2227
+ }
2228
+ /**
2229
+ * Get output virtual size
2230
+ * @returns {number}
2231
+ */
2232
+ get_output_vsize() {
2233
+ const ret = wasm.wasmdimensions_get_output_vsize(this.__wbg_ptr);
2234
+ return ret >>> 0;
2235
+ }
2236
+ /**
2237
+ * Get output weight
2238
+ * @returns {number}
2239
+ */
2240
+ get_output_weight() {
2241
+ const ret = wasm.wasmdimensions_get_output_weight(this.__wbg_ptr);
2242
+ return ret >>> 0;
2243
+ }
2187
2244
  /**
2188
2245
  * Create dimensions for a single output from script bytes
2189
2246
  * @param {Uint8Array} script
@@ -2239,6 +2296,15 @@ export class WasmDimensions {
2239
2296
  const ret = wasm.wasmdimensions_empty();
2240
2297
  return WasmDimensions.__wrap(ret);
2241
2298
  }
2299
+ /**
2300
+ * Multiply dimensions by a scalar
2301
+ * @param {number} n
2302
+ * @returns {WasmDimensions}
2303
+ */
2304
+ times(n) {
2305
+ const ret = wasm.wasmdimensions_times(this.__wbg_ptr, n);
2306
+ return WasmDimensions.__wrap(ret);
2307
+ }
2242
2308
  /**
2243
2309
  * Create dimensions from a BitGoPsbt
2244
2310
  *
Binary file
@@ -84,6 +84,7 @@ export const bitgopsbt_verify_signature_with_xpub: (a: number, b: number, c: num
84
84
  export const bitgopsbt_version: (a: number) => number;
85
85
  export const bitgopsbt_version_group_id: (a: number) => number;
86
86
  export const fixedscriptwalletnamespace_address: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
87
+ export const fixedscriptwalletnamespace_chain_code_table: () => number;
87
88
  export const fixedscriptwalletnamespace_output_script: (a: number, b: number, c: number, d: number, e: number) => void;
88
89
  export const fixedscriptwalletnamespace_supports_script_type: (a: number, b: number, c: number, d: number, e: number) => void;
89
90
  export const utxolibcompatnamespace_from_output_script: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
@@ -115,10 +116,15 @@ export const wasmdimensions_from_input: (a: number, b: number, c: number, d: num
115
116
  export const wasmdimensions_from_input_script_type: (a: number, b: number, c: number) => void;
116
117
  export const wasmdimensions_from_output_script: (a: number, b: number) => number;
117
118
  export const wasmdimensions_from_psbt: (a: number, b: number) => void;
119
+ export const wasmdimensions_get_input_vsize: (a: number, b: number, c: number) => number;
120
+ export const wasmdimensions_get_input_weight: (a: number, b: number, c: number) => number;
121
+ export const wasmdimensions_get_output_vsize: (a: number) => number;
122
+ export const wasmdimensions_get_output_weight: (a: number) => number;
118
123
  export const wasmdimensions_get_vsize: (a: number, b: number, c: number) => number;
119
124
  export const wasmdimensions_get_weight: (a: number, b: number, c: number) => number;
120
125
  export const wasmdimensions_has_segwit: (a: number) => number;
121
126
  export const wasmdimensions_plus: (a: number, b: number) => number;
127
+ export const wasmdimensions_times: (a: number, b: number) => number;
122
128
  export const wasmecpair_from_private_key: (a: number, b: number, c: number) => void;
123
129
  export const wasmecpair_from_public_key: (a: number, b: number, c: number) => void;
124
130
  export const wasmecpair_from_wif: (a: number, b: number, c: number) => void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitgo/wasm-utxo",
3
3
  "description": "WebAssembly wrapper for rust-bitcoin (beta)",
4
- "version": "1.22.0",
4
+ "version": "1.23.0",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",