@bitgo/wasm-utxo 1.27.0 → 1.29.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 (41) hide show
  1. package/dist/cjs/js/bip32.d.ts +7 -0
  2. package/dist/cjs/js/bip32.js +16 -0
  3. package/dist/cjs/js/fixedScriptWallet/BitGoPsbt.d.ts +60 -26
  4. package/dist/cjs/js/fixedScriptWallet/BitGoPsbt.js +56 -36
  5. package/dist/cjs/js/fixedScriptWallet/chains.d.ts +5 -0
  6. package/dist/cjs/js/fixedScriptWallet/chains.js +6 -2
  7. package/dist/cjs/js/fixedScriptWallet/index.d.ts +19 -2
  8. package/dist/cjs/js/fixedScriptWallet/index.js +25 -1
  9. package/dist/cjs/js/fixedScriptWallet/scriptType.d.ts +15 -5
  10. package/dist/cjs/js/fixedScriptWallet/scriptType.js +28 -0
  11. package/dist/cjs/js/testutils/AcidTest.d.ts +132 -0
  12. package/dist/cjs/js/testutils/AcidTest.js +306 -0
  13. package/dist/cjs/js/testutils/index.d.ts +2 -0
  14. package/dist/cjs/js/testutils/index.js +18 -0
  15. package/dist/cjs/js/testutils/keys.d.ts +76 -0
  16. package/dist/cjs/js/testutils/keys.js +154 -0
  17. package/dist/cjs/js/wasm/wasm_utxo.d.ts +183 -0
  18. package/dist/cjs/js/wasm/wasm_utxo.js +354 -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 +67 -56
  21. package/dist/esm/js/bip32.d.ts +7 -0
  22. package/dist/esm/js/bip32.js +15 -0
  23. package/dist/esm/js/fixedScriptWallet/BitGoPsbt.d.ts +60 -26
  24. package/dist/esm/js/fixedScriptWallet/BitGoPsbt.js +57 -37
  25. package/dist/esm/js/fixedScriptWallet/chains.d.ts +5 -0
  26. package/dist/esm/js/fixedScriptWallet/chains.js +6 -3
  27. package/dist/esm/js/fixedScriptWallet/index.d.ts +19 -2
  28. package/dist/esm/js/fixedScriptWallet/index.js +21 -1
  29. package/dist/esm/js/fixedScriptWallet/scriptType.d.ts +15 -5
  30. package/dist/esm/js/fixedScriptWallet/scriptType.js +27 -1
  31. package/dist/esm/js/testutils/AcidTest.d.ts +132 -0
  32. package/dist/esm/js/testutils/AcidTest.js +302 -0
  33. package/dist/esm/js/testutils/index.d.ts +2 -0
  34. package/dist/esm/js/testutils/index.js +2 -0
  35. package/dist/esm/js/testutils/keys.d.ts +76 -0
  36. package/dist/esm/js/testutils/keys.js +113 -0
  37. package/dist/esm/js/wasm/wasm_utxo.d.ts +183 -0
  38. package/dist/esm/js/wasm/wasm_utxo_bg.js +354 -0
  39. package/dist/esm/js/wasm/wasm_utxo_bg.wasm +0 -0
  40. package/dist/esm/js/wasm/wasm_utxo_bg.wasm.d.ts +67 -56
  41. package/package.json +2 -1
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AcidTest = exports.outputScriptTypes = exports.inputScriptTypes = exports.txFormats = exports.signStages = void 0;
4
+ const BitGoPsbt_js_1 = require("../fixedScriptWallet/BitGoPsbt.js");
5
+ const ZcashBitGoPsbt_js_1 = require("../fixedScriptWallet/ZcashBitGoPsbt.js");
6
+ const ecpair_js_1 = require("../ecpair.js");
7
+ const index_js_1 = require("../fixedScriptWallet/index.js");
8
+ Object.defineProperty(exports, "inputScriptTypes", { enumerable: true, get: function () { return index_js_1.inputScriptTypes; } });
9
+ Object.defineProperty(exports, "outputScriptTypes", { enumerable: true, get: function () { return index_js_1.outputScriptTypes; } });
10
+ const coinName_js_1 = require("../coinName.js");
11
+ const keys_js_1 = require("./keys.js");
12
+ exports.signStages = ["unsigned", "halfsigned", "fullsigned"];
13
+ exports.txFormats = ["psbt", "psbt-lite"];
14
+ /**
15
+ * Creates a valid PSBT with as many features as possible (kitchen sink).
16
+ *
17
+ * - Inputs:
18
+ * - All wallet script types supported by the network
19
+ * - A p2shP2pk input (for replay protection)
20
+ * - Outputs:
21
+ * - All wallet script types supported by the network
22
+ * - A p2sh output with derivation info of a different wallet
23
+ * - A p2sh output with no derivation info (external output)
24
+ * - An OP_RETURN output
25
+ *
26
+ * Signature stages:
27
+ * - unsigned: No signatures
28
+ * - halfsigned: One signature per input (user key)
29
+ * - fullsigned: Two signatures per input (user + bitgo)
30
+ *
31
+ * Transaction formats:
32
+ * - psbt: Full PSBT with non_witness_utxo
33
+ * - psbt-lite: Only witness_utxo (no non_witness_utxo)
34
+ */
35
+ class AcidTest {
36
+ network;
37
+ signStage;
38
+ txFormat;
39
+ rootWalletKeys;
40
+ otherWalletKeys;
41
+ inputs;
42
+ outputs;
43
+ // Store private keys for signing
44
+ userXprv;
45
+ backupXprv;
46
+ bitgoXprv;
47
+ constructor(network, signStage, txFormat, rootWalletKeys, otherWalletKeys, inputs, outputs, xprvTriple) {
48
+ this.network = network;
49
+ this.signStage = signStage;
50
+ this.txFormat = txFormat;
51
+ this.rootWalletKeys = rootWalletKeys;
52
+ this.otherWalletKeys = otherWalletKeys;
53
+ this.inputs = inputs;
54
+ this.outputs = outputs;
55
+ this.userXprv = xprvTriple[0];
56
+ this.backupXprv = xprvTriple[1];
57
+ this.bitgoXprv = xprvTriple[2];
58
+ }
59
+ /**
60
+ * Create an AcidTest with specific configuration
61
+ */
62
+ static withConfig(network, signStage, txFormat, suiteConfig = {}) {
63
+ const rootWalletKeys = (0, keys_js_1.getDefaultWalletKeys)();
64
+ const otherWalletKeys = (0, keys_js_1.getWalletKeysForSeed)("too many secrets");
65
+ // Filter inputs based on network support
66
+ const inputs = index_js_1.inputScriptTypes
67
+ .filter((scriptType) => {
68
+ // p2shP2pk is always supported (single-sig replay protection)
69
+ if (scriptType === "p2shP2pk")
70
+ return true;
71
+ // Map input script types to output script types for support check
72
+ if (scriptType === "p2trMusig2KeyPath" || scriptType === "p2trMusig2ScriptPath") {
73
+ return (0, index_js_1.supportsScriptType)(network, "p2trMusig2");
74
+ }
75
+ return (0, index_js_1.supportsScriptType)(network, scriptType);
76
+ })
77
+ .filter((scriptType) => (suiteConfig.includeP2trMusig2ScriptPath ?? false) ||
78
+ scriptType !== "p2trMusig2ScriptPath")
79
+ .map((scriptType, index) => ({
80
+ scriptType,
81
+ value: BigInt(10000 + index * 10000), // Deterministic amounts
82
+ }));
83
+ // Filter outputs based on network support
84
+ const outputs = index_js_1.outputScriptTypes
85
+ .filter((scriptType) => (0, index_js_1.supportsScriptType)(network, scriptType))
86
+ .map((scriptType, index) => ({
87
+ scriptType,
88
+ value: BigInt(900 + index * 100), // Deterministic amounts
89
+ }));
90
+ // Test other wallet output (with derivation info)
91
+ outputs.push({ scriptType: "p2sh", value: BigInt(800), walletKeys: otherWalletKeys });
92
+ // Test non-wallet output (no derivation info)
93
+ outputs.push({ scriptType: "p2sh", value: BigInt(700), walletKeys: null });
94
+ // Test OP_RETURN output
95
+ outputs.push({ opReturn: "setec astronomy", value: BigInt(0) });
96
+ // Get private keys for signing
97
+ const xprvTriple = (0, keys_js_1.getKeyTriple)("default");
98
+ return new AcidTest(network, signStage, txFormat, rootWalletKeys, otherWalletKeys, inputs, outputs, xprvTriple);
99
+ }
100
+ /**
101
+ * Get a human-readable name for this test configuration
102
+ */
103
+ get name() {
104
+ return `${this.network} ${this.signStage} ${this.txFormat}`;
105
+ }
106
+ /**
107
+ * Get the BIP32 user key for replay protection (p2shP2pk)
108
+ */
109
+ getReplayProtectionKey() {
110
+ return this.rootWalletKeys.userKey();
111
+ }
112
+ /**
113
+ * Create the actual PSBT with all inputs and outputs
114
+ */
115
+ createPsbt() {
116
+ // Use ZcashBitGoPsbt for Zcash networks
117
+ const isZcash = this.network === "zec" || this.network === "tzec";
118
+ const psbt = isZcash
119
+ ? ZcashBitGoPsbt_js_1.ZcashBitGoPsbt.createEmptyWithConsensusBranchId(this.network, this.rootWalletKeys, {
120
+ version: 2,
121
+ lockTime: 0,
122
+ consensusBranchId: 0xc2d6d0b4, // NU5
123
+ })
124
+ : BitGoPsbt_js_1.BitGoPsbt.createEmpty(this.network, this.rootWalletKeys, {
125
+ version: 2,
126
+ lockTime: 0,
127
+ });
128
+ // Add inputs with deterministic outpoints
129
+ this.inputs.forEach((input, index) => {
130
+ // Resolve scriptId: either from explicit scriptId or from scriptType + index
131
+ const scriptId = input.scriptId ?? {
132
+ chain: index_js_1.ChainCode.value("p2sh", "external"),
133
+ index: input.index ?? index,
134
+ };
135
+ const walletKeys = input.walletKeys ?? this.rootWalletKeys;
136
+ // Get scriptType: either explicit or derive from scriptId chain
137
+ const scriptType = input.scriptType ?? index_js_1.ChainCode.scriptType((0, index_js_1.assertChainCode)(scriptId.chain));
138
+ if (scriptType === "p2shP2pk") {
139
+ // Add replay protection input
140
+ const replayKey = this.getReplayProtectionKey();
141
+ // Convert BIP32 to ECPair using public key
142
+ const ecpair = ecpair_js_1.ECPair.fromPublicKey(replayKey.publicKey);
143
+ psbt.addReplayProtectionInput({
144
+ txid: "0".repeat(64),
145
+ vout: index,
146
+ value: input.value,
147
+ }, ecpair);
148
+ }
149
+ else {
150
+ // Determine signing path based on input type
151
+ let signPath;
152
+ if (scriptType === "p2trMusig2ScriptPath") {
153
+ // Script path uses user + backup
154
+ signPath = { signer: "user", cosigner: "backup" };
155
+ }
156
+ else {
157
+ // Default: user + bitgo
158
+ signPath = { signer: "user", cosigner: "bitgo" };
159
+ }
160
+ psbt.addWalletInput({
161
+ txid: "0".repeat(64),
162
+ vout: index,
163
+ value: input.value,
164
+ }, walletKeys, {
165
+ scriptId,
166
+ signPath,
167
+ });
168
+ }
169
+ });
170
+ // Add outputs
171
+ this.outputs.forEach((output, index) => {
172
+ if (output.opReturn !== undefined) {
173
+ // OP_RETURN output
174
+ const data = new TextEncoder().encode(output.opReturn);
175
+ const script = (0, index_js_1.createOpReturnScript)(data);
176
+ psbt.addOutput(script, output.value);
177
+ }
178
+ else if (output.address !== undefined) {
179
+ // Address-based output
180
+ psbt.addOutput(output.address, output.value);
181
+ }
182
+ else if (output.script !== undefined) {
183
+ // Raw script output
184
+ psbt.addOutput(output.script, output.value);
185
+ }
186
+ else {
187
+ // Wallet output: resolve scriptId from scriptType or explicit scriptId
188
+ const scriptId = output.scriptId ?? {
189
+ chain: output.scriptType ? index_js_1.ChainCode.value(output.scriptType, "external") : 0,
190
+ index: output.index ?? index,
191
+ };
192
+ if (output.walletKeys === null) {
193
+ // External output (no wallet keys, no bip32 derivation)
194
+ // Use high index for external outputs if not specified
195
+ const externalScriptId = output.scriptId ?? {
196
+ chain: scriptId.chain,
197
+ index: output.index ?? 1000 + index,
198
+ };
199
+ const script = (0, index_js_1.outputScript)(this.rootWalletKeys, externalScriptId.chain, externalScriptId.index, this.network);
200
+ psbt.addOutput(script, output.value);
201
+ }
202
+ else {
203
+ // Wallet output (with or without different wallet keys)
204
+ const walletKeys = output.walletKeys ?? this.rootWalletKeys;
205
+ psbt.addWalletOutput(walletKeys, {
206
+ chain: scriptId.chain,
207
+ index: scriptId.index,
208
+ value: output.value,
209
+ });
210
+ }
211
+ }
212
+ });
213
+ // Apply signing based on stage
214
+ if (this.signStage !== "unsigned") {
215
+ this.signPsbt(psbt);
216
+ }
217
+ return psbt;
218
+ }
219
+ /**
220
+ * Sign the PSBT according to the sign stage
221
+ */
222
+ signPsbt(psbt) {
223
+ // Use private keys stored in constructor
224
+ const userKey = this.userXprv;
225
+ const backupKey = this.backupXprv;
226
+ const bitgoKey = this.bitgoXprv;
227
+ // Generate MuSig2 nonces for user if needed
228
+ const hasMusig2Inputs = this.inputs.some((input) => input.scriptType === "p2trMusig2KeyPath" || input.scriptType === "p2trMusig2ScriptPath");
229
+ if (hasMusig2Inputs) {
230
+ const isZcash = this.network === "zec" || this.network === "tzec";
231
+ if (isZcash) {
232
+ throw new Error("Zcash does not support MuSig2/Taproot inputs");
233
+ }
234
+ // Generate nonces with user key
235
+ psbt.generateMusig2Nonces(userKey);
236
+ if (this.signStage === "fullsigned") {
237
+ // Create a second PSBT with cosigner nonces for combination
238
+ // For p2trMusig2ScriptPath use backup, for p2trMusig2KeyPath use bitgo
239
+ // Since we might have both types, we need to generate nonces separately
240
+ const bytes = psbt.serialize();
241
+ const hasKeyPath = this.inputs.some((input) => input.scriptType === "p2trMusig2KeyPath");
242
+ const hasScriptPath = this.inputs.some((input) => input.scriptType === "p2trMusig2ScriptPath");
243
+ if (hasKeyPath && !hasScriptPath) {
244
+ // Only key path inputs - generate bitgo nonces for all
245
+ const psbt2 = BitGoPsbt_js_1.BitGoPsbt.fromBytes(bytes, this.network);
246
+ psbt2.generateMusig2Nonces(bitgoKey);
247
+ psbt.combineMusig2Nonces(psbt2);
248
+ }
249
+ else if (hasScriptPath && !hasKeyPath) {
250
+ // Only script path inputs - generate backup nonces for all
251
+ const psbt2 = BitGoPsbt_js_1.BitGoPsbt.fromBytes(bytes, this.network);
252
+ psbt2.generateMusig2Nonces(backupKey);
253
+ psbt.combineMusig2Nonces(psbt2);
254
+ }
255
+ else {
256
+ const psbt2 = BitGoPsbt_js_1.BitGoPsbt.fromBytes(bytes, this.network);
257
+ psbt2.generateMusig2Nonces(bitgoKey);
258
+ psbt.combineMusig2Nonces(psbt2);
259
+ }
260
+ }
261
+ }
262
+ // Sign all wallet inputs with user key (bulk - more efficient)
263
+ psbt.sign(userKey);
264
+ // Sign replay protection inputs with raw private key
265
+ const hasReplayProtection = this.inputs.some((input) => input.scriptType === "p2shP2pk");
266
+ if (hasReplayProtection) {
267
+ if (!userKey.privateKey) {
268
+ throw new Error("User key must have private key for signing replay protection inputs");
269
+ }
270
+ psbt.sign(userKey.privateKey);
271
+ }
272
+ // For fullsigned, sign with cosigner
273
+ if (this.signStage === "fullsigned") {
274
+ const hasScriptPath = this.inputs.some((input) => input.scriptType === "p2trMusig2ScriptPath");
275
+ if (hasScriptPath) {
276
+ // Mixed case: script path uses backup, others use bitgo
277
+ // Need per-input signing (slow) to handle different cosigners
278
+ this.inputs.forEach((input, index) => {
279
+ if (input.scriptType === "p2shP2pk") {
280
+ // Replay protection is single-sig, already fully signed
281
+ return;
282
+ }
283
+ if (input.scriptType === "p2trMusig2ScriptPath") {
284
+ psbt.signInput(index, backupKey);
285
+ }
286
+ else {
287
+ psbt.signInput(index, bitgoKey);
288
+ }
289
+ });
290
+ }
291
+ else {
292
+ // No script path - can use bulk signing with bitgo (fast)
293
+ psbt.sign(bitgoKey);
294
+ }
295
+ }
296
+ }
297
+ /**
298
+ * Generate test suite for all networks, sign stages, and tx formats
299
+ */
300
+ static forAllNetworksSignStagesTxFormats(suiteConfig = {}) {
301
+ return coinName_js_1.coinNames
302
+ .filter((network) => (0, coinName_js_1.isMainnet)(network) && network !== "bsv") // Exclude bitcoinsv
303
+ .flatMap((network) => exports.signStages.flatMap((signStage) => exports.txFormats.map((txFormat) => AcidTest.withConfig(network, signStage, txFormat, suiteConfig))));
304
+ }
305
+ }
306
+ exports.AcidTest = AcidTest;
@@ -0,0 +1,2 @@
1
+ export * from "./keys.js";
2
+ export * from "./AcidTest.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("./keys.js"), exports);
18
+ __exportStar(require("./AcidTest.js"), exports);
@@ -0,0 +1,76 @@
1
+ import { BIP32 } from "../bip32.js";
2
+ import { RootWalletKeys } from "../fixedScriptWallet/RootWalletKeys.js";
3
+ import type { Triple } from "../triple.js";
4
+ /**
5
+ * Generate a deterministic BIP32 key from a seed string.
6
+ * Uses SHA256 hash of the seed to create the key, matching utxo-lib's implementation.
7
+ *
8
+ * @param seed - Seed string for deterministic key generation
9
+ * @returns BIP32 key derived from the seed
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const key = getKey("user");
14
+ * const xpub = key.neutered().toBase58();
15
+ * ```
16
+ */
17
+ export declare function getKey(seed: string): BIP32;
18
+ /**
19
+ * Generate a triple of BIP32 keys for a 2-of-3 multisig wallet.
20
+ * Keys are generated deterministically from the seed string with suffixes .0, .1, .2
21
+ * for user, backup, and bitgo keys respectively.
22
+ *
23
+ * @param seed - Base seed string for key generation
24
+ * @returns Triple of BIP32 keys [user, backup, bitgo]
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const keys = getKeyTriple("default");
29
+ * const [user, backup, bitgo] = keys;
30
+ * ```
31
+ */
32
+ export declare function getKeyTriple(seed: string): Triple<BIP32>;
33
+ /**
34
+ * Create RootWalletKeys from a seed string.
35
+ * Uses standard derivation prefixes ["m/0/0", "m/0/0", "m/0/0"].
36
+ *
37
+ * @param seed - Seed string for key generation
38
+ * @returns RootWalletKeys instance
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const walletKeys = getWalletKeysForSeed("default");
43
+ * ```
44
+ */
45
+ export declare function getWalletKeysForSeed(seed: string): RootWalletKeys;
46
+ /**
47
+ * Get the default wallet keys for testing.
48
+ * Equivalent to getWalletKeysForSeed("default").
49
+ *
50
+ * @returns RootWalletKeys instance with default seed
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const walletKeys = getDefaultWalletKeys();
55
+ * ```
56
+ */
57
+ export declare function getDefaultWalletKeys(): RootWalletKeys;
58
+ /**
59
+ * Get the key name (user, backup, or bitgo) for a given key in a triple.
60
+ *
61
+ * @param triple - Triple of BIP32 keys
62
+ * @param key - Key to find in the triple
63
+ * @returns "user", "backup", "bitgo", or undefined if not found
64
+ */
65
+ export declare function getKeyName(triple: Triple<BIP32>, key: BIP32): "user" | "backup" | "bitgo" | undefined;
66
+ /**
67
+ * Get the default cosigner for a given signer key.
68
+ * - If signer is user, returns bitgo
69
+ * - If signer is backup, returns bitgo
70
+ * - If signer is bitgo, returns user
71
+ *
72
+ * @param keyset - Triple of keys [user, backup, bitgo]
73
+ * @param signer - The signing key
74
+ * @returns The default cosigner key
75
+ */
76
+ export declare function getDefaultCosigner<T>(keyset: Triple<T>, signer: T): T;
@@ -0,0 +1,154 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getKey = getKey;
37
+ exports.getKeyTriple = getKeyTriple;
38
+ exports.getWalletKeysForSeed = getWalletKeysForSeed;
39
+ exports.getDefaultWalletKeys = getDefaultWalletKeys;
40
+ exports.getKeyName = getKeyName;
41
+ exports.getDefaultCosigner = getDefaultCosigner;
42
+ const crypto = __importStar(require("crypto"));
43
+ const bip32_js_1 = require("../bip32.js");
44
+ const RootWalletKeys_js_1 = require("../fixedScriptWallet/RootWalletKeys.js");
45
+ /**
46
+ * Generate a deterministic BIP32 key from a seed string.
47
+ * Uses SHA256 hash of the seed to create the key, matching utxo-lib's implementation.
48
+ *
49
+ * @param seed - Seed string for deterministic key generation
50
+ * @returns BIP32 key derived from the seed
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const key = getKey("user");
55
+ * const xpub = key.neutered().toBase58();
56
+ * ```
57
+ */
58
+ function getKey(seed) {
59
+ return bip32_js_1.BIP32.fromSeed(crypto.createHash("sha256").update(seed).digest());
60
+ }
61
+ /**
62
+ * Generate a triple of BIP32 keys for a 2-of-3 multisig wallet.
63
+ * Keys are generated deterministically from the seed string with suffixes .0, .1, .2
64
+ * for user, backup, and bitgo keys respectively.
65
+ *
66
+ * @param seed - Base seed string for key generation
67
+ * @returns Triple of BIP32 keys [user, backup, bitgo]
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const keys = getKeyTriple("default");
72
+ * const [user, backup, bitgo] = keys;
73
+ * ```
74
+ */
75
+ function getKeyTriple(seed) {
76
+ return [getKey(seed + ".0"), getKey(seed + ".1"), getKey(seed + ".2")];
77
+ }
78
+ /**
79
+ * Create RootWalletKeys from a seed string.
80
+ * Uses standard derivation prefixes ["m/0/0", "m/0/0", "m/0/0"].
81
+ *
82
+ * @param seed - Seed string for key generation
83
+ * @returns RootWalletKeys instance
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const walletKeys = getWalletKeysForSeed("default");
88
+ * ```
89
+ */
90
+ function getWalletKeysForSeed(seed) {
91
+ const triple = getKeyTriple(seed);
92
+ return RootWalletKeys_js_1.RootWalletKeys.from({
93
+ triple,
94
+ derivationPrefixes: ["m/0/0", "m/0/0", "m/0/0"],
95
+ });
96
+ }
97
+ /**
98
+ * Get the default wallet keys for testing.
99
+ * Equivalent to getWalletKeysForSeed("default").
100
+ *
101
+ * @returns RootWalletKeys instance with default seed
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const walletKeys = getDefaultWalletKeys();
106
+ * ```
107
+ */
108
+ function getDefaultWalletKeys() {
109
+ return getWalletKeysForSeed("default");
110
+ }
111
+ /**
112
+ * Get the key name (user, backup, or bitgo) for a given key in a triple.
113
+ *
114
+ * @param triple - Triple of BIP32 keys
115
+ * @param key - Key to find in the triple
116
+ * @returns "user", "backup", "bitgo", or undefined if not found
117
+ */
118
+ function getKeyName(triple, key) {
119
+ const index = triple.findIndex((k) => {
120
+ const kb58 = k.toBase58();
121
+ const keyb58 = key.toBase58();
122
+ return kb58 === keyb58;
123
+ });
124
+ if (index === 0)
125
+ return "user";
126
+ if (index === 1)
127
+ return "backup";
128
+ if (index === 2)
129
+ return "bitgo";
130
+ return undefined;
131
+ }
132
+ /**
133
+ * Get the default cosigner for a given signer key.
134
+ * - If signer is user, returns bitgo
135
+ * - If signer is backup, returns bitgo
136
+ * - If signer is bitgo, returns user
137
+ *
138
+ * @param keyset - Triple of keys [user, backup, bitgo]
139
+ * @param signer - The signing key
140
+ * @returns The default cosigner key
141
+ */
142
+ function getDefaultCosigner(keyset, signer) {
143
+ const [user, backup, bitgo] = keyset;
144
+ if (signer === user) {
145
+ return bitgo;
146
+ }
147
+ if (signer === backup) {
148
+ return bitgo;
149
+ }
150
+ if (signer === bitgo) {
151
+ return user;
152
+ }
153
+ throw new Error("signer not in keyset");
154
+ }