@bitgo/wasm-utxo 1.35.0 → 1.37.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 (42) hide show
  1. package/dist/cjs/js/bip32.d.ts +19 -0
  2. package/dist/cjs/js/bip32.js +29 -0
  3. package/dist/cjs/js/index.d.ts +7 -2
  4. package/dist/cjs/js/index.js +2 -2
  5. package/dist/cjs/js/message.d.ts +36 -0
  6. package/dist/cjs/js/message.js +47 -0
  7. package/dist/cjs/js/testutils/descriptor/descriptors.d.ts +27 -0
  8. package/dist/cjs/js/testutils/descriptor/descriptors.js +163 -0
  9. package/dist/cjs/js/testutils/descriptor/index.d.ts +2 -0
  10. package/dist/cjs/js/testutils/descriptor/index.js +18 -0
  11. package/dist/cjs/js/testutils/descriptor/mockPsbt.d.ts +41 -0
  12. package/dist/cjs/js/testutils/descriptor/mockPsbt.js +62 -0
  13. package/dist/cjs/js/testutils/fixtures.d.ts +35 -0
  14. package/dist/cjs/js/testutils/fixtures.js +244 -0
  15. package/dist/cjs/js/testutils/index.d.ts +2 -0
  16. package/dist/cjs/js/testutils/index.js +25 -0
  17. package/dist/cjs/js/wasm/wasm_utxo.d.ts +33 -0
  18. package/dist/cjs/js/wasm/wasm_utxo.js +112 -0
  19. package/dist/cjs/js/wasm/wasm_utxo_bg.wasm +0 -0
  20. package/dist/cjs/js/wasm/wasm_utxo_bg.wasm.d.ts +103 -98
  21. package/dist/esm/js/bip32.d.ts +19 -0
  22. package/dist/esm/js/bip32.js +29 -0
  23. package/dist/esm/js/index.d.ts +7 -2
  24. package/dist/esm/js/index.js +1 -1
  25. package/dist/esm/js/message.d.ts +36 -0
  26. package/dist/esm/js/message.js +43 -0
  27. package/dist/esm/js/testutils/descriptor/descriptors.d.ts +27 -0
  28. package/dist/esm/js/testutils/descriptor/descriptors.js +150 -0
  29. package/dist/esm/js/testutils/descriptor/index.d.ts +2 -0
  30. package/dist/esm/js/testutils/descriptor/index.js +2 -0
  31. package/dist/esm/js/testutils/descriptor/mockPsbt.d.ts +41 -0
  32. package/dist/esm/js/testutils/descriptor/mockPsbt.js +56 -0
  33. package/dist/esm/js/testutils/fixtures.d.ts +35 -0
  34. package/dist/esm/js/testutils/fixtures.js +205 -0
  35. package/dist/esm/js/testutils/index.d.ts +2 -0
  36. package/dist/esm/js/testutils/index.js +2 -0
  37. package/dist/esm/js/wasm/wasm_utxo.d.ts +33 -0
  38. package/dist/esm/js/wasm/wasm_utxo.js +1 -1
  39. package/dist/esm/js/wasm/wasm_utxo_bg.js +111 -0
  40. package/dist/esm/js/wasm/wasm_utxo_bg.wasm +0 -0
  41. package/dist/esm/js/wasm/wasm_utxo_bg.wasm.d.ts +103 -98
  42. package/package.json +11 -1
@@ -140,6 +140,25 @@ export declare class BIP32 implements BIP32Interface {
140
140
  * @returns A new BIP32 instance for the derived key
141
141
  */
142
142
  derivePath(path: string): BIP32;
143
+ /**
144
+ * Check equality with another BIP32 key.
145
+ * Two keys are equal if they have the same type (public/private) and identical
146
+ * BIP32 metadata (depth, parent fingerprint, child index, chain code, key data).
147
+ * This is a fast comparison that does not require serialization.
148
+ *
149
+ * @param other - The other key to compare with. Accepts BIP32, or any BIP32Interface.
150
+ * @returns True if the keys are equal
151
+ */
152
+ equals(other: BIP32Interface): boolean;
153
+ /**
154
+ * Custom JSON representation for debugging.
155
+ * Always serializes the public key (xpub) to avoid leaking private keys.
156
+ * Includes a `hasPrivateKey` flag to indicate whether the key is neutered.
157
+ */
158
+ toJSON(): {
159
+ xpub: string;
160
+ hasPrivateKey: boolean;
161
+ };
143
162
  /**
144
163
  * Get the underlying WASM instance (internal use only)
145
164
  * @internal
@@ -178,6 +178,35 @@ class BIP32 {
178
178
  const wasm = this._wasm.derive_path(path);
179
179
  return new BIP32(wasm);
180
180
  }
181
+ /**
182
+ * Check equality with another BIP32 key.
183
+ * Two keys are equal if they have the same type (public/private) and identical
184
+ * BIP32 metadata (depth, parent fingerprint, child index, chain code, key data).
185
+ * This is a fast comparison that does not require serialization.
186
+ *
187
+ * @param other - The other key to compare with. Accepts BIP32, or any BIP32Interface.
188
+ * @returns True if the keys are equal
189
+ */
190
+ equals(other) {
191
+ const otherWasm = other instanceof BIP32 ? other._wasm : BIP32.from(other)._wasm;
192
+ return this._wasm.equals(otherWasm);
193
+ }
194
+ /**
195
+ * Custom JSON representation for debugging.
196
+ * Always serializes the public key (xpub) to avoid leaking private keys.
197
+ * Includes a `hasPrivateKey` flag to indicate whether the key is neutered.
198
+ */
199
+ toJSON() {
200
+ return { xpub: this.neutered().toBase58(), hasPrivateKey: !this.isNeutered() };
201
+ }
202
+ /**
203
+ * Custom inspect representation for Node.js util.inspect and console.log.
204
+ * Always shows the public key (xpub) to avoid leaking private keys.
205
+ */
206
+ [Symbol.for("nodejs.util.inspect.custom")]() {
207
+ const flag = this.isNeutered() ? "" : ", hasPrivateKey";
208
+ return `BIP32(${this.neutered().toBase58()}${flag})`;
209
+ }
181
210
  /**
182
211
  * Get the underlying WASM instance (internal use only)
183
212
  * @internal
@@ -2,16 +2,16 @@ export * as address from "./address.js";
2
2
  export * as ast from "./ast/index.js";
3
3
  export * as bip322 from "./bip322/index.js";
4
4
  export * as inscriptions from "./inscriptions.js";
5
+ export * as message from "./message.js";
5
6
  export * as utxolibCompat from "./utxolibCompat.js";
6
7
  export * as fixedScriptWallet from "./fixedScriptWallet/index.js";
7
8
  export * as descriptorWallet from "./descriptorWallet/index.js";
8
9
  export * as bip32 from "./bip32.js";
9
10
  export * as ecpair from "./ecpair.js";
10
- export * as testutils from "./testutils/index.js";
11
11
  export { ECPair } from "./ecpair.js";
12
12
  export { BIP32 } from "./bip32.js";
13
13
  export { Dimensions } from "./fixedScriptWallet/Dimensions.js";
14
- export type { CoinName } from "./coinName.js";
14
+ export type { CoinName, getMainnet, isMainnet, isTestnet, isCoinName } from "./coinName.js";
15
15
  export type { Triple } from "./triple.js";
16
16
  export type { AddressFormat } from "./address.js";
17
17
  export type { TapLeafScript, PreparedInscriptionRevealData } from "./inscriptions.js";
@@ -60,6 +60,10 @@ declare module "./wasm/wasm_utxo.js" {
60
60
  bip32Derivation: PsbtBip32Derivation[];
61
61
  tapBip32Derivation: PsbtBip32Derivation[];
62
62
  }
63
+ /** PSBT output data with resolved address, returned by getOutputsWithAddress() */
64
+ interface PsbtOutputDataWithAddress extends PsbtOutputData {
65
+ address: string;
66
+ }
63
67
  interface WrapPsbt {
64
68
  signWithXprv(this: WrapPsbt, xprv: string): SignPsbtResult;
65
69
  signWithPrv(this: WrapPsbt, prv: Uint8Array): SignPsbtResult;
@@ -69,6 +73,7 @@ declare module "./wasm/wasm_utxo.js" {
69
73
  outputCount(): number;
70
74
  getInputs(): PsbtInputData[];
71
75
  getOutputs(): PsbtOutputData[];
76
+ getOutputsWithAddress(coin: import("./coinName.js").CoinName): PsbtOutputDataWithAddress[];
72
77
  getPartialSignatures(inputIndex: number): Array<{
73
78
  pubkey: Uint8Array;
74
79
  signature: Uint8Array;
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.hasPsbtMagic = exports.ZcashTransaction = exports.Transaction = exports.DashTransaction = exports.Psbt = exports.Miniscript = exports.Descriptor = exports.Dimensions = exports.BIP32 = exports.ECPair = exports.testutils = exports.ecpair = exports.bip32 = exports.descriptorWallet = exports.fixedScriptWallet = exports.utxolibCompat = exports.inscriptions = exports.bip322 = exports.ast = exports.address = void 0;
36
+ exports.hasPsbtMagic = exports.ZcashTransaction = exports.Transaction = exports.DashTransaction = exports.Psbt = exports.Miniscript = exports.Descriptor = exports.Dimensions = exports.BIP32 = exports.ECPair = exports.ecpair = exports.bip32 = exports.descriptorWallet = exports.fixedScriptWallet = exports.utxolibCompat = exports.message = exports.inscriptions = exports.bip322 = exports.ast = exports.address = void 0;
37
37
  const wasm = __importStar(require("./wasm/wasm_utxo.js"));
38
38
  // we need to access the wasm module here, otherwise webpack gets all weird
39
39
  // and forgets to include it in the bundle
@@ -44,12 +44,12 @@ exports.address = __importStar(require("./address.js"));
44
44
  exports.ast = __importStar(require("./ast/index.js"));
45
45
  exports.bip322 = __importStar(require("./bip322/index.js"));
46
46
  exports.inscriptions = __importStar(require("./inscriptions.js"));
47
+ exports.message = __importStar(require("./message.js"));
47
48
  exports.utxolibCompat = __importStar(require("./utxolibCompat.js"));
48
49
  exports.fixedScriptWallet = __importStar(require("./fixedScriptWallet/index.js"));
49
50
  exports.descriptorWallet = __importStar(require("./descriptorWallet/index.js"));
50
51
  exports.bip32 = __importStar(require("./bip32.js"));
51
52
  exports.ecpair = __importStar(require("./ecpair.js"));
52
- exports.testutils = __importStar(require("./testutils/index.js"));
53
53
  // Only the most commonly used classes and types are exported at the top level for convenience
54
54
  var ecpair_js_1 = require("./ecpair.js");
55
55
  Object.defineProperty(exports, "ECPair", { enumerable: true, get: function () { return ecpair_js_1.ECPair; } });
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Bitcoin message signing and verification (BIP-137)
3
+ *
4
+ * This module provides functions for signing and verifying Bitcoin messages
5
+ * using the standard Bitcoin Signed Message format (BIP-137).
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { message, ECPair } from '@bitgo/wasm-utxo';
10
+ *
11
+ * // Sign a message
12
+ * const key = ECPair.fromWIF('L1TnU2zbNaAqMoVh65Cyvmcjzbrj41Gs9iTLcWbpJCpV1iNMXpuR');
13
+ * const signature = message.signMessage('Hello, Bitcoin!', key);
14
+ *
15
+ * // Verify a message
16
+ * const isValid = message.verifyMessage('Hello, Bitcoin!', key, signature);
17
+ * ```
18
+ */
19
+ import { type ECPairArg } from "./ecpair.js";
20
+ /**
21
+ * Sign a message using Bitcoin message signing (BIP-137)
22
+ *
23
+ * @param message - The message to sign
24
+ * @param key - The key to sign with (must have a private key)
25
+ * @returns 65-byte signature (1-byte header + 64-byte signature)
26
+ */
27
+ export declare function signMessage(message: string, key: ECPairArg): Uint8Array;
28
+ /**
29
+ * Verify a Bitcoin message signature (BIP-137)
30
+ *
31
+ * @param message - The message that was signed
32
+ * @param key - The key to verify against
33
+ * @param signature - 65-byte signature (1-byte header + 64-byte signature)
34
+ * @returns True if the signature is valid for this key
35
+ */
36
+ export declare function verifyMessage(message: string, key: ECPairArg, signature: Uint8Array): boolean;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * Bitcoin message signing and verification (BIP-137)
4
+ *
5
+ * This module provides functions for signing and verifying Bitcoin messages
6
+ * using the standard Bitcoin Signed Message format (BIP-137).
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { message, ECPair } from '@bitgo/wasm-utxo';
11
+ *
12
+ * // Sign a message
13
+ * const key = ECPair.fromWIF('L1TnU2zbNaAqMoVh65Cyvmcjzbrj41Gs9iTLcWbpJCpV1iNMXpuR');
14
+ * const signature = message.signMessage('Hello, Bitcoin!', key);
15
+ *
16
+ * // Verify a message
17
+ * const isValid = message.verifyMessage('Hello, Bitcoin!', key, signature);
18
+ * ```
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.signMessage = signMessage;
22
+ exports.verifyMessage = verifyMessage;
23
+ const wasm_utxo_js_1 = require("./wasm/wasm_utxo.js");
24
+ const ecpair_js_1 = require("./ecpair.js");
25
+ /**
26
+ * Sign a message using Bitcoin message signing (BIP-137)
27
+ *
28
+ * @param message - The message to sign
29
+ * @param key - The key to sign with (must have a private key)
30
+ * @returns 65-byte signature (1-byte header + 64-byte signature)
31
+ */
32
+ function signMessage(message, key) {
33
+ const ecpair = ecpair_js_1.ECPair.from(key);
34
+ return new Uint8Array(wasm_utxo_js_1.MessageNamespace.sign_message(ecpair.wasm, message));
35
+ }
36
+ /**
37
+ * Verify a Bitcoin message signature (BIP-137)
38
+ *
39
+ * @param message - The message that was signed
40
+ * @param key - The key to verify against
41
+ * @param signature - 65-byte signature (1-byte header + 64-byte signature)
42
+ * @returns True if the signature is valid for this key
43
+ */
44
+ function verifyMessage(message, key, signature) {
45
+ const ecpair = ecpair_js_1.ECPair.from(key);
46
+ return wasm_utxo_js_1.MessageNamespace.verify_message(ecpair.wasm, message, signature);
47
+ }
@@ -0,0 +1,27 @@
1
+ import type { BIP32Interface } from "../../bip32.js";
2
+ import { Descriptor, Miniscript, ast } from "../../index.js";
3
+ import type { Triple } from "../../triple.js";
4
+ import { DescriptorMap, PsbtParams } from "../../descriptorWallet/index.js";
5
+ type KeyTriple = Triple<BIP32Interface>;
6
+ export type DescriptorTemplate = "Wsh2Of3" | "Tr1Of3-NoKeyPath-Tree" | "Tr1Of3-NoKeyPath-Tree-Plain" | "Tr2Of3-NoKeyPath" | "Wsh2Of2"
7
+ /**
8
+ * Wrapped segwit 2of3 multisig with a relative locktime OP_DROP
9
+ * (requiring a miniscript extension). Used in CoreDao staking transactions.
10
+ */
11
+ | "Wsh2Of3CltvDrop";
12
+ /**
13
+ * Get the BIP-341 "Nothing Up My Sleeve" (NUMS) unspendable key.
14
+ * This is the x-only public key with unknown discrete logarithm
15
+ * constructed by hashing the uncompressed secp256k1 base point G.
16
+ *
17
+ * @see https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs
18
+ */
19
+ export declare function getUnspendableKey(): string;
20
+ export declare function getDefaultXPubs(seed?: string): Triple<string>;
21
+ export declare function getPsbtParams(t: DescriptorTemplate): Partial<PsbtParams>;
22
+ export declare function getDescriptorNode(template: DescriptorTemplate, keys?: KeyTriple | string[], path?: string): ast.DescriptorNode;
23
+ export declare function containsKey(script: Miniscript | ast.MiniscriptNode, key: BIP32Interface | string): boolean;
24
+ export declare function getTapLeafScripts(d: Descriptor): string[];
25
+ export declare function getDescriptor(template: DescriptorTemplate, keys?: KeyTriple | string[], path?: string): Descriptor;
26
+ export declare function getDescriptorMap(template: DescriptorTemplate, keys?: KeyTriple | string[]): DescriptorMap;
27
+ export {};
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getUnspendableKey = getUnspendableKey;
7
+ exports.getDefaultXPubs = getDefaultXPubs;
8
+ exports.getPsbtParams = getPsbtParams;
9
+ exports.getDescriptorNode = getDescriptorNode;
10
+ exports.containsKey = containsKey;
11
+ exports.getTapLeafScripts = getTapLeafScripts;
12
+ exports.getDescriptor = getDescriptor;
13
+ exports.getDescriptorMap = getDescriptorMap;
14
+ /**
15
+ * Descriptor test utilities for building common descriptor templates.
16
+ * Ported from @bitgo/utxo-core/testutil/descriptor/descriptors.ts.
17
+ */
18
+ const assert_1 = __importDefault(require("assert"));
19
+ const bip32_js_1 = require("../../bip32.js");
20
+ const index_js_1 = require("../../index.js");
21
+ const keys_js_1 = require("../keys.js");
22
+ /**
23
+ * Get the BIP-341 "Nothing Up My Sleeve" (NUMS) unspendable key.
24
+ * This is the x-only public key with unknown discrete logarithm
25
+ * constructed by hashing the uncompressed secp256k1 base point G.
26
+ *
27
+ * @see https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs
28
+ */
29
+ function getUnspendableKey() {
30
+ return "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0";
31
+ }
32
+ function getDefaultXPubs(seed) {
33
+ return (0, keys_js_1.getKeyTriple)(seed ?? "default").map((k) => k.neutered().toBase58());
34
+ }
35
+ function toDescriptorMap(v) {
36
+ return new Map(Object.entries(v).map(([k, v]) => [k, index_js_1.Descriptor.fromString(v, "derivable")]));
37
+ }
38
+ function toXPub(k, path) {
39
+ if (typeof k === "string") {
40
+ return k + "/" + path;
41
+ }
42
+ return k.neutered().toBase58() + "/" + path;
43
+ }
44
+ function toPlain(k, { xonly = false } = {}) {
45
+ if (typeof k === "string") {
46
+ if (k.startsWith("xpub") || k.startsWith("xprv")) {
47
+ return toPlain(bip32_js_1.BIP32.fromBase58(k), { xonly });
48
+ }
49
+ return k;
50
+ }
51
+ return toHex(k.publicKey.subarray(xonly ? 1 : 0));
52
+ }
53
+ function toHex(bytes) {
54
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
55
+ }
56
+ function toXOnly(k) {
57
+ return toPlain(k, { xonly: true });
58
+ }
59
+ function multiArgs(m, n, keys, path) {
60
+ if (n < m) {
61
+ throw new Error(`Cannot create ${m} of ${n} multisig`);
62
+ }
63
+ if (keys.length < n) {
64
+ throw new Error(`Not enough keys for ${m} of ${n} multisig: keys.length=${keys.length}`);
65
+ }
66
+ keys = keys.slice(0, n);
67
+ return [m, ...keys.map((k) => toXPub(k, path))];
68
+ }
69
+ function getPsbtParams(t) {
70
+ switch (t) {
71
+ case "Wsh2Of3CltvDrop":
72
+ return { locktime: 1 };
73
+ default:
74
+ return {};
75
+ }
76
+ }
77
+ function getDescriptorNode(template, keys = getDefaultXPubs(), path = "0/*") {
78
+ switch (template) {
79
+ case "Wsh2Of3":
80
+ return {
81
+ wsh: { multi: multiArgs(2, 3, keys, path) },
82
+ };
83
+ case "Wsh2Of3CltvDrop": {
84
+ const { locktime } = getPsbtParams(template);
85
+ (0, assert_1.default)(locktime);
86
+ return {
87
+ wsh: {
88
+ and_v: [{ "r:after": locktime }, { multi: multiArgs(2, 3, keys, path) }],
89
+ },
90
+ };
91
+ }
92
+ case "Wsh2Of2":
93
+ return {
94
+ wsh: { multi: multiArgs(2, 2, keys, path) },
95
+ };
96
+ case "Tr2Of3-NoKeyPath":
97
+ return {
98
+ tr: [getUnspendableKey(), { multi_a: multiArgs(2, 3, keys, path) }],
99
+ };
100
+ case "Tr1Of3-NoKeyPath-Tree":
101
+ return {
102
+ tr: [
103
+ getUnspendableKey(),
104
+ [
105
+ { pk: toXPub(keys[0], path) },
106
+ [{ pk: toXPub(keys[1], path) }, { pk: toXPub(keys[2], path) }],
107
+ ],
108
+ ],
109
+ };
110
+ case "Tr1Of3-NoKeyPath-Tree-Plain":
111
+ return {
112
+ tr: [
113
+ getUnspendableKey(),
114
+ [{ pk: toXOnly(keys[0]) }, [{ pk: toXOnly(keys[1]) }, { pk: toXOnly(keys[2]) }]],
115
+ ],
116
+ };
117
+ }
118
+ throw new Error(`Unknown descriptor template: ${template}`);
119
+ }
120
+ function getTapLeafScriptNodes(t) {
121
+ if (Array.isArray(t)) {
122
+ if (t.length !== 2) {
123
+ throw new Error(`expected tuple, got: ${JSON.stringify(t)}`);
124
+ }
125
+ return t.map((v) => (Array.isArray(v) ? getTapLeafScriptNodes(v) : v)).flat();
126
+ }
127
+ if (typeof t === "object") {
128
+ const node = t;
129
+ if (!("tr" in node)) {
130
+ throw new Error(`TapLeafScripts are only supported for Taproot descriptors, got: ${JSON.stringify(t)}`);
131
+ }
132
+ if (!Array.isArray(node.tr) || node.tr.length !== 2) {
133
+ throw new Error(`expected tuple, got: ${JSON.stringify(node.tr)}`);
134
+ }
135
+ const tapscript = node.tr[1];
136
+ if (!Array.isArray(tapscript)) {
137
+ throw new Error(`expected tapscript to be an array, got: ${JSON.stringify(tapscript)}`);
138
+ }
139
+ return getTapLeafScriptNodes(tapscript);
140
+ }
141
+ throw new Error(`Invalid input: ${JSON.stringify(t)}`);
142
+ }
143
+ function containsKey(script, key) {
144
+ if (script instanceof index_js_1.Miniscript) {
145
+ script = index_js_1.ast.fromMiniscript(script);
146
+ }
147
+ if ("pk" in script) {
148
+ return script.pk === toXOnly(key);
149
+ }
150
+ throw new Error(`Unsupported script type: ${JSON.stringify(script)}`);
151
+ }
152
+ function getTapLeafScripts(d) {
153
+ return getTapLeafScriptNodes(index_js_1.ast.fromDescriptor(d)).map((n) => index_js_1.Miniscript.fromString(index_js_1.ast.formatNode(n), "tap").toString());
154
+ }
155
+ function getDescriptor(template, keys = getDefaultXPubs(), path = "0/*") {
156
+ return index_js_1.Descriptor.fromStringDetectType(index_js_1.ast.formatNode(getDescriptorNode(template, keys, path)));
157
+ }
158
+ function getDescriptorMap(template, keys = getDefaultXPubs()) {
159
+ return toDescriptorMap({
160
+ external: getDescriptor(template, keys, "0/*").toString(),
161
+ internal: getDescriptor(template, keys, "1/*").toString(),
162
+ });
163
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./descriptors.js";
2
+ export * from "./mockPsbt.js";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./descriptors.js"), exports);
18
+ __exportStar(require("./mockPsbt.js"), exports);
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Mock PSBT utilities for descriptor wallet testing.
3
+ * Ported from @bitgo/utxo-core/testutil/descriptor/mock.utils.ts.
4
+ *
5
+ * Key difference from utxo-core: returns wasm-utxo Psbt instances directly
6
+ * instead of utxolib.bitgo.UtxoPsbt. PsbtParams does not require a network field.
7
+ */
8
+ import { Descriptor, Miniscript, Psbt } from "../../index.js";
9
+ import { PsbtParams, DerivedDescriptorTransactionInput } from "../../descriptorWallet/index.js";
10
+ import { DescriptorTemplate } from "./descriptors.js";
11
+ type MockOutputIdParams = {
12
+ hash?: string;
13
+ vout?: number;
14
+ };
15
+ type BaseMockDescriptorOutputParams = {
16
+ id?: MockOutputIdParams;
17
+ index?: number;
18
+ value?: bigint;
19
+ sequence?: number;
20
+ selectTapLeafScript?: Miniscript;
21
+ };
22
+ export declare function mockDerivedDescriptorWalletOutput(descriptor: Descriptor, outputParams?: BaseMockDescriptorOutputParams): DerivedDescriptorTransactionInput;
23
+ type MockInput = BaseMockDescriptorOutputParams & {
24
+ index: number;
25
+ descriptor: Descriptor;
26
+ selectTapLeafScript?: Miniscript;
27
+ };
28
+ type MockOutput = {
29
+ descriptor: Descriptor;
30
+ index: number;
31
+ value: bigint;
32
+ external?: boolean;
33
+ };
34
+ export declare function mockPsbt(inputs: MockInput[], outputs: MockOutput[], params?: Partial<PsbtParams>): Psbt;
35
+ export declare function mockPsbtDefault({ descriptorSelf, descriptorOther, params, }?: {
36
+ descriptorSelf?: Descriptor;
37
+ descriptorOther?: Descriptor;
38
+ params?: Partial<PsbtParams>;
39
+ }): Psbt;
40
+ export declare function mockPsbtDefaultWithDescriptorTemplate(t: DescriptorTemplate, params?: Partial<PsbtParams>): Psbt;
41
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mockDerivedDescriptorWalletOutput = mockDerivedDescriptorWalletOutput;
4
+ exports.mockPsbt = mockPsbt;
5
+ exports.mockPsbtDefault = mockPsbtDefault;
6
+ exports.mockPsbtDefaultWithDescriptorTemplate = mockPsbtDefaultWithDescriptorTemplate;
7
+ const index_js_1 = require("../../descriptorWallet/index.js");
8
+ const descriptors_js_1 = require("./descriptors.js");
9
+ function mockOutputId(id) {
10
+ const hash = id?.hash ?? "0101010101010101010101010101010101010101010101010101010101010101";
11
+ const vout = id?.vout ?? 0;
12
+ return { hash, vout };
13
+ }
14
+ function mockDerivedDescriptorWalletOutput(descriptor, outputParams = {}) {
15
+ const { value = BigInt(1e6) } = outputParams;
16
+ const { hash, vout } = mockOutputId(outputParams.id);
17
+ return {
18
+ hash,
19
+ index: vout,
20
+ witnessUtxo: {
21
+ script: (0, index_js_1.createScriptPubKeyFromDescriptor)(descriptor, undefined),
22
+ value,
23
+ },
24
+ descriptor,
25
+ selectTapLeafScript: outputParams.selectTapLeafScript,
26
+ sequence: outputParams.sequence,
27
+ };
28
+ }
29
+ function tryDeriveAtIndex(descriptor, index) {
30
+ return descriptor.hasWildcard() ? descriptor.atDerivationIndex(index) : descriptor;
31
+ }
32
+ function mockPsbt(inputs, outputs, params = {}) {
33
+ return (0, index_js_1.createPsbt)(params, inputs.map((i) => mockDerivedDescriptorWalletOutput(tryDeriveAtIndex(i.descriptor, i.index), i)), outputs.map((o) => {
34
+ const derivedDescriptor = tryDeriveAtIndex(o.descriptor, o.index);
35
+ return {
36
+ script: (0, index_js_1.createScriptPubKeyFromDescriptor)(derivedDescriptor, undefined),
37
+ value: o.value,
38
+ descriptor: o.external ? undefined : derivedDescriptor,
39
+ };
40
+ }));
41
+ }
42
+ function mockPsbtDefault({ descriptorSelf = (0, descriptors_js_1.getDescriptor)("Wsh2Of3", (0, descriptors_js_1.getDefaultXPubs)("a")), descriptorOther = (0, descriptors_js_1.getDescriptor)("Wsh2Of3", (0, descriptors_js_1.getDefaultXPubs)("b")), params = {}, } = {}) {
43
+ return mockPsbt([
44
+ { descriptor: descriptorSelf, index: 0 },
45
+ { descriptor: descriptorSelf, index: 1, id: { vout: 1 } },
46
+ ], [
47
+ {
48
+ descriptor: descriptorOther,
49
+ index: 0,
50
+ value: BigInt(4e5),
51
+ external: true,
52
+ },
53
+ { descriptor: descriptorSelf, index: 0, value: BigInt(4e5) },
54
+ ], params);
55
+ }
56
+ function mockPsbtDefaultWithDescriptorTemplate(t, params = {}) {
57
+ return mockPsbtDefault({
58
+ descriptorSelf: (0, descriptors_js_1.getDescriptor)(t, (0, descriptors_js_1.getDefaultXPubs)("a")),
59
+ descriptorOther: (0, descriptors_js_1.getDescriptor)(t, (0, descriptors_js_1.getDefaultXPubs)("b")),
60
+ params: { ...(0, descriptors_js_1.getPsbtParams)(t), ...params },
61
+ });
62
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Return fixture described in `path`.
3
+ *
4
+ * If the file does not exist and `defaultValue` is provided,
5
+ * writes defaultValue to `path` and throws an error prompting
6
+ * the developer to inspect and re-run.
7
+ *
8
+ * @param path - Path to the fixture file (.json, .hex, or .txt)
9
+ * @param defaultValue - Default value to write if fixture is missing
10
+ * @returns The fixture content
11
+ */
12
+ export declare function getFixture<T>(path: string, defaultValue?: T | (() => Promise<T>)): Promise<T>;
13
+ /**
14
+ * JSON round-trip normalization.
15
+ * Converts a value to JSON and back, stripping non-serializable properties
16
+ * and normalizing types (e.g. undefined -> null in arrays).
17
+ */
18
+ export declare function jsonNormalize<T>(v: T): T;
19
+ export type ToPlainObjectOpts = {
20
+ propertyDescriptors?: boolean;
21
+ skipUndefinedValues?: boolean;
22
+ ignorePaths?: string[] | ((path: PathElement[]) => boolean);
23
+ apply?: (v: unknown, path: PathElement[]) => unknown;
24
+ };
25
+ export type PathElement = string | number;
26
+ export declare function matchPath(a: PathElement[], b: PathElement[]): boolean;
27
+ /**
28
+ * Recursively convert a value to a plain JSON-serializable object.
29
+ * Handles Uint8Array (to hex), bigint (to string), Buffer, and more.
30
+ *
31
+ * @param v - The value to convert
32
+ * @param opts - Options for customizing the conversion
33
+ * @param path - Current property path (used for ignorePaths)
34
+ */
35
+ export declare function toPlainObject(v: unknown, opts?: ToPlainObjectOpts, path?: PathElement[]): unknown;