@bitgo/wasm-utxo 1.34.0 → 1.36.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 (44) 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/fixedScriptWallet/BitGoPsbt.js +8 -6
  4. package/dist/cjs/js/index.d.ts +7 -1
  5. package/dist/cjs/js/index.js +2 -2
  6. package/dist/cjs/js/message.d.ts +36 -0
  7. package/dist/cjs/js/message.js +47 -0
  8. package/dist/cjs/js/testutils/descriptor/descriptors.d.ts +27 -0
  9. package/dist/cjs/js/testutils/descriptor/descriptors.js +163 -0
  10. package/dist/cjs/js/testutils/descriptor/index.d.ts +2 -0
  11. package/dist/cjs/js/testutils/descriptor/index.js +18 -0
  12. package/dist/cjs/js/testutils/descriptor/mockPsbt.d.ts +41 -0
  13. package/dist/cjs/js/testutils/descriptor/mockPsbt.js +62 -0
  14. package/dist/cjs/js/testutils/fixtures.d.ts +35 -0
  15. package/dist/cjs/js/testutils/fixtures.js +244 -0
  16. package/dist/cjs/js/testutils/index.d.ts +2 -0
  17. package/dist/cjs/js/testutils/index.js +25 -0
  18. package/dist/cjs/js/wasm/wasm_utxo.d.ts +1417 -1331
  19. package/dist/cjs/js/wasm/wasm_utxo.js +2093 -1996
  20. package/dist/cjs/js/wasm/wasm_utxo_bg.wasm +0 -0
  21. package/dist/cjs/js/wasm/wasm_utxo_bg.wasm.d.ts +114 -108
  22. package/dist/esm/js/bip32.d.ts +19 -0
  23. package/dist/esm/js/bip32.js +29 -0
  24. package/dist/esm/js/fixedScriptWallet/BitGoPsbt.js +8 -6
  25. package/dist/esm/js/index.d.ts +7 -1
  26. package/dist/esm/js/index.js +1 -1
  27. package/dist/esm/js/message.d.ts +36 -0
  28. package/dist/esm/js/message.js +43 -0
  29. package/dist/esm/js/testutils/descriptor/descriptors.d.ts +27 -0
  30. package/dist/esm/js/testutils/descriptor/descriptors.js +150 -0
  31. package/dist/esm/js/testutils/descriptor/index.d.ts +2 -0
  32. package/dist/esm/js/testutils/descriptor/index.js +2 -0
  33. package/dist/esm/js/testutils/descriptor/mockPsbt.d.ts +41 -0
  34. package/dist/esm/js/testutils/descriptor/mockPsbt.js +56 -0
  35. package/dist/esm/js/testutils/fixtures.d.ts +35 -0
  36. package/dist/esm/js/testutils/fixtures.js +205 -0
  37. package/dist/esm/js/testutils/index.d.ts +2 -0
  38. package/dist/esm/js/testutils/index.js +2 -0
  39. package/dist/esm/js/wasm/wasm_utxo.d.ts +1417 -1331
  40. package/dist/esm/js/wasm/wasm_utxo.js +7 -2
  41. package/dist/esm/js/wasm/wasm_utxo_bg.js +2096 -2008
  42. package/dist/esm/js/wasm/wasm_utxo_bg.wasm +0 -0
  43. package/dist/esm/js/wasm/wasm_utxo_bg.wasm.d.ts +114 -108
  44. package/package.json +11 -1
@@ -0,0 +1,2 @@
1
+ export * from "./descriptors.js";
2
+ export * from "./mockPsbt.js";
@@ -0,0 +1,2 @@
1
+ export * from "./descriptors.js";
2
+ export * from "./mockPsbt.js";
@@ -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,56 @@
1
+ import { createPsbt, createScriptPubKeyFromDescriptor, } from "../../descriptorWallet/index.js";
2
+ import { getDefaultXPubs, getDescriptor, getPsbtParams, } from "./descriptors.js";
3
+ function mockOutputId(id) {
4
+ const hash = id?.hash ?? "0101010101010101010101010101010101010101010101010101010101010101";
5
+ const vout = id?.vout ?? 0;
6
+ return { hash, vout };
7
+ }
8
+ export function mockDerivedDescriptorWalletOutput(descriptor, outputParams = {}) {
9
+ const { value = BigInt(1e6) } = outputParams;
10
+ const { hash, vout } = mockOutputId(outputParams.id);
11
+ return {
12
+ hash,
13
+ index: vout,
14
+ witnessUtxo: {
15
+ script: createScriptPubKeyFromDescriptor(descriptor, undefined),
16
+ value,
17
+ },
18
+ descriptor,
19
+ selectTapLeafScript: outputParams.selectTapLeafScript,
20
+ sequence: outputParams.sequence,
21
+ };
22
+ }
23
+ function tryDeriveAtIndex(descriptor, index) {
24
+ return descriptor.hasWildcard() ? descriptor.atDerivationIndex(index) : descriptor;
25
+ }
26
+ export function mockPsbt(inputs, outputs, params = {}) {
27
+ return createPsbt(params, inputs.map((i) => mockDerivedDescriptorWalletOutput(tryDeriveAtIndex(i.descriptor, i.index), i)), outputs.map((o) => {
28
+ const derivedDescriptor = tryDeriveAtIndex(o.descriptor, o.index);
29
+ return {
30
+ script: createScriptPubKeyFromDescriptor(derivedDescriptor, undefined),
31
+ value: o.value,
32
+ descriptor: o.external ? undefined : derivedDescriptor,
33
+ };
34
+ }));
35
+ }
36
+ export function mockPsbtDefault({ descriptorSelf = getDescriptor("Wsh2Of3", getDefaultXPubs("a")), descriptorOther = getDescriptor("Wsh2Of3", getDefaultXPubs("b")), params = {}, } = {}) {
37
+ return mockPsbt([
38
+ { descriptor: descriptorSelf, index: 0 },
39
+ { descriptor: descriptorSelf, index: 1, id: { vout: 1 } },
40
+ ], [
41
+ {
42
+ descriptor: descriptorOther,
43
+ index: 0,
44
+ value: BigInt(4e5),
45
+ external: true,
46
+ },
47
+ { descriptor: descriptorSelf, index: 0, value: BigInt(4e5) },
48
+ ], params);
49
+ }
50
+ export function mockPsbtDefaultWithDescriptorTemplate(t, params = {}) {
51
+ return mockPsbtDefault({
52
+ descriptorSelf: getDescriptor(t, getDefaultXPubs("a")),
53
+ descriptorOther: getDescriptor(t, getDefaultXPubs("b")),
54
+ params: { ...getPsbtParams(t), ...params },
55
+ });
56
+ }
@@ -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;
@@ -0,0 +1,205 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * Generic test fixture and serialization utilities.
4
+ * Ported from @bitgo/utxo-core/testutil/fixtures.utils.ts
5
+ * and @bitgo/utxo-core/testutil/toPlainObject.utils.ts.
6
+ *
7
+ * NOTE: getFixture requires Node.js (fs, process.env).
8
+ * The toPlainObject / jsonNormalize utilities are platform-independent.
9
+ */
10
+ import * as fs from "fs";
11
+ import * as mpath from "path";
12
+ function isNodeJsError(e) {
13
+ return e instanceof Error && typeof e.code === "string";
14
+ }
15
+ function fixtureEncoding(path) {
16
+ if (path.endsWith(".json")) {
17
+ return "json";
18
+ }
19
+ if (path.endsWith(".hex")) {
20
+ return "hex";
21
+ }
22
+ if (path.endsWith(".txt")) {
23
+ return "txt";
24
+ }
25
+ throw new Error(`unknown fixture encoding for ${path}`);
26
+ }
27
+ function hexToBytes(hex) {
28
+ const bytes = new Uint8Array(hex.length / 2);
29
+ for (let i = 0; i < hex.length; i += 2) {
30
+ bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
31
+ }
32
+ return bytes;
33
+ }
34
+ function bytesToHex(bytes) {
35
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
36
+ }
37
+ function decodeFixture(raw, encoding) {
38
+ switch (encoding) {
39
+ case "json":
40
+ return JSON.parse(raw);
41
+ case "hex":
42
+ return hexToBytes(raw);
43
+ case "txt":
44
+ return raw;
45
+ }
46
+ }
47
+ function encodeFixture(value, encoding) {
48
+ switch (encoding) {
49
+ case "json":
50
+ return JSON.stringify(value, null, 2) + "\n";
51
+ case "hex":
52
+ if (!(value instanceof Uint8Array)) {
53
+ throw new Error(`expected Uint8Array, got ${typeof value}`);
54
+ }
55
+ return bytesToHex(value);
56
+ case "txt":
57
+ if (typeof value !== "string") {
58
+ throw new Error(`expected string, got ${typeof value}`);
59
+ }
60
+ return value;
61
+ }
62
+ }
63
+ /**
64
+ * Return fixture described in `path`.
65
+ *
66
+ * If the file does not exist and `defaultValue` is provided,
67
+ * writes defaultValue to `path` and throws an error prompting
68
+ * the developer to inspect and re-run.
69
+ *
70
+ * @param path - Path to the fixture file (.json, .hex, or .txt)
71
+ * @param defaultValue - Default value to write if fixture is missing
72
+ * @returns The fixture content
73
+ */
74
+ export async function getFixture(path, defaultValue) {
75
+ try {
76
+ await fs.promises.stat(mpath.dirname(path));
77
+ }
78
+ catch (e) {
79
+ if (isNodeJsError(e) && e.code === "ENOENT") {
80
+ throw new Error(`fixture directory ${mpath.dirname(path)} not found, please create it first`);
81
+ }
82
+ throw e;
83
+ }
84
+ const encoding = fixtureEncoding(path);
85
+ try {
86
+ return decodeFixture(await fs.promises.readFile(path, "utf8"), encoding);
87
+ }
88
+ catch (e) {
89
+ if (isNodeJsError(e) && e.code === "ENOENT") {
90
+ // eslint-disable-next-line no-restricted-globals
91
+ if (process.env.WRITE_FIXTURES === "0") {
92
+ throw new Error(`fixture ${path} not found, WRITE_FIXTURES=0`);
93
+ }
94
+ if (defaultValue === undefined) {
95
+ throw new Error(`fixture ${path} not found and no default value given`);
96
+ }
97
+ if (typeof defaultValue === "function") {
98
+ defaultValue = await defaultValue();
99
+ }
100
+ await fs.promises.writeFile(path, encodeFixture(defaultValue, encoding));
101
+ throw new Error(`wrote default value for ${path}, please inspect and restart test`);
102
+ }
103
+ throw e;
104
+ }
105
+ }
106
+ /**
107
+ * JSON round-trip normalization.
108
+ * Converts a value to JSON and back, stripping non-serializable properties
109
+ * and normalizing types (e.g. undefined -> null in arrays).
110
+ */
111
+ export function jsonNormalize(v) {
112
+ return JSON.parse(JSON.stringify(v));
113
+ }
114
+ export function matchPath(a, b) {
115
+ return a.length === b.length && a.every((e, i) => e === b[i]);
116
+ }
117
+ function includePath(opts, path) {
118
+ if (!opts.ignorePaths) {
119
+ return true;
120
+ }
121
+ if (typeof opts.ignorePaths === "function") {
122
+ return !opts.ignorePaths(path);
123
+ }
124
+ return !opts.ignorePaths.some((ignorePath) => matchPath(path, ignorePath.split(".")));
125
+ }
126
+ function toPlainEntries(key, value, opts, path) {
127
+ if (!includePath(opts, [...path, key])) {
128
+ return [];
129
+ }
130
+ if (value === undefined && (opts.skipUndefinedValues ?? true)) {
131
+ return [];
132
+ }
133
+ return [[key, toPlainObject(value, opts, [...path, key])]];
134
+ }
135
+ function getAllPropertyDescriptors(v) {
136
+ if (v === null || typeof v !== "object") {
137
+ return {};
138
+ }
139
+ const descriptors = Object.getOwnPropertyDescriptors(v);
140
+ const proto = Object.getPrototypeOf(v);
141
+ if (proto) {
142
+ Object.assign(descriptors, getAllPropertyDescriptors(proto));
143
+ }
144
+ return descriptors;
145
+ }
146
+ function toPlainObjectFromPropertyDescriptors(v, opts, path) {
147
+ const descriptors = getAllPropertyDescriptors(v);
148
+ return Object.fromEntries(Object.entries(descriptors).flatMap(([key, descriptor]) => {
149
+ if (typeof descriptor.value === "function") {
150
+ return [];
151
+ }
152
+ if (descriptor.value !== undefined) {
153
+ return toPlainEntries(key, descriptor.value, opts, path);
154
+ }
155
+ if (typeof descriptor.get === "function") {
156
+ return toPlainEntries(key, descriptor.get.call(v), opts, path);
157
+ }
158
+ return [];
159
+ }));
160
+ }
161
+ /**
162
+ * Recursively convert a value to a plain JSON-serializable object.
163
+ * Handles Uint8Array (to hex), bigint (to string), Buffer, and more.
164
+ *
165
+ * @param v - The value to convert
166
+ * @param opts - Options for customizing the conversion
167
+ * @param path - Current property path (used for ignorePaths)
168
+ */
169
+ export function toPlainObject(v, opts = {}, path = []) {
170
+ if (opts.apply) {
171
+ const result = opts.apply(v, path);
172
+ if (result !== undefined) {
173
+ return result;
174
+ }
175
+ }
176
+ switch (typeof v) {
177
+ case "string":
178
+ case "number":
179
+ case "boolean":
180
+ case "undefined":
181
+ return v;
182
+ case "bigint":
183
+ return v.toString();
184
+ case "function":
185
+ case "symbol":
186
+ return undefined;
187
+ }
188
+ if (v === null) {
189
+ return v;
190
+ }
191
+ if (v instanceof Uint8Array) {
192
+ return Array.from(v, (b) => b.toString(16).padStart(2, "0")).join("");
193
+ }
194
+ if (Array.isArray(v)) {
195
+ return v.map((e, i) => toPlainObject(e, opts, [...path, i]));
196
+ }
197
+ if (typeof v === "object") {
198
+ const result = Object.fromEntries(Object.entries(v).flatMap(([key, value]) => toPlainEntries(key, value, opts, path)));
199
+ if (opts.propertyDescriptors) {
200
+ Object.assign(result, toPlainObjectFromPropertyDescriptors(v, opts, path));
201
+ }
202
+ return result;
203
+ }
204
+ throw new Error(`unknown v ${typeof v}`);
205
+ }
@@ -1,2 +1,4 @@
1
1
  export * from "./keys.js";
2
2
  export * from "./AcidTest.js";
3
+ export * from "./fixtures.js";
4
+ export * as descriptor from "./descriptor/index.js";
@@ -1,2 +1,4 @@
1
1
  export * from "./keys.js";
2
2
  export * from "./AcidTest.js";
3
+ export * from "./fixtures.js";
4
+ export * as descriptor from "./descriptor/index.js";