@btc-vision/bitcoin 7.0.0-alpha.1 → 7.0.0-alpha.2

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 (160) hide show
  1. package/browser/address.d.ts +5 -1
  2. package/browser/address.d.ts.map +1 -1
  3. package/browser/branded.d.ts +3 -14
  4. package/browser/branded.d.ts.map +1 -1
  5. package/browser/ecc/context.d.ts.map +1 -1
  6. package/browser/index.d.ts +2 -1
  7. package/browser/index.d.ts.map +1 -1
  8. package/browser/index.js +2964 -2919
  9. package/browser/opcodes.d.ts +11 -0
  10. package/browser/opcodes.d.ts.map +1 -1
  11. package/browser/psbt/PsbtCache.d.ts +54 -0
  12. package/browser/psbt/PsbtCache.d.ts.map +1 -0
  13. package/browser/psbt/PsbtFinalizer.d.ts +21 -0
  14. package/browser/psbt/PsbtFinalizer.d.ts.map +1 -0
  15. package/browser/psbt/PsbtSigner.d.ts +32 -0
  16. package/browser/psbt/PsbtSigner.d.ts.map +1 -0
  17. package/browser/psbt/PsbtTransaction.d.ts +25 -0
  18. package/browser/psbt/PsbtTransaction.d.ts.map +1 -0
  19. package/browser/psbt/types.d.ts +13 -13
  20. package/browser/psbt/types.d.ts.map +1 -1
  21. package/browser/psbt/validation.d.ts +1 -1
  22. package/browser/psbt/validation.d.ts.map +1 -1
  23. package/browser/psbt.d.ts +27 -39
  24. package/browser/psbt.d.ts.map +1 -1
  25. package/browser/script.d.ts.map +1 -1
  26. package/browser/transaction.d.ts +4 -4
  27. package/browser/transaction.d.ts.map +1 -1
  28. package/browser/types.d.ts +4 -2
  29. package/browser/types.d.ts.map +1 -1
  30. package/browser/workers/index.d.ts +3 -50
  31. package/browser/workers/index.d.ts.map +1 -1
  32. package/browser/workers/index.node.d.ts +24 -0
  33. package/browser/workers/index.node.d.ts.map +1 -0
  34. package/build/address.d.ts +5 -1
  35. package/build/address.d.ts.map +1 -1
  36. package/build/address.js +29 -17
  37. package/build/address.js.map +1 -1
  38. package/build/branded.d.ts +3 -14
  39. package/build/branded.d.ts.map +1 -1
  40. package/build/branded.js +0 -5
  41. package/build/branded.js.map +1 -1
  42. package/build/ecc/context.d.ts.map +1 -1
  43. package/build/ecc/context.js +68 -45
  44. package/build/ecc/context.js.map +1 -1
  45. package/build/index.d.ts +2 -1
  46. package/build/index.d.ts.map +1 -1
  47. package/build/index.js +1 -1
  48. package/build/index.js.map +1 -1
  49. package/build/opcodes.d.ts +11 -0
  50. package/build/opcodes.d.ts.map +1 -1
  51. package/build/opcodes.js +19 -4
  52. package/build/opcodes.js.map +1 -1
  53. package/build/psbt/PsbtCache.d.ts +54 -0
  54. package/build/psbt/PsbtCache.d.ts.map +1 -0
  55. package/build/psbt/PsbtCache.js +249 -0
  56. package/build/psbt/PsbtCache.js.map +1 -0
  57. package/build/psbt/PsbtFinalizer.d.ts +21 -0
  58. package/build/psbt/PsbtFinalizer.d.ts.map +1 -0
  59. package/build/psbt/PsbtFinalizer.js +157 -0
  60. package/build/psbt/PsbtFinalizer.js.map +1 -0
  61. package/build/psbt/PsbtSigner.d.ts +32 -0
  62. package/build/psbt/PsbtSigner.d.ts.map +1 -0
  63. package/build/psbt/PsbtSigner.js +192 -0
  64. package/build/psbt/PsbtSigner.js.map +1 -0
  65. package/build/psbt/PsbtTransaction.d.ts +25 -0
  66. package/build/psbt/PsbtTransaction.d.ts.map +1 -0
  67. package/build/psbt/PsbtTransaction.js +61 -0
  68. package/build/psbt/PsbtTransaction.js.map +1 -0
  69. package/build/psbt/types.d.ts +13 -13
  70. package/build/psbt/types.d.ts.map +1 -1
  71. package/build/psbt/validation.d.ts +1 -1
  72. package/build/psbt/validation.d.ts.map +1 -1
  73. package/build/psbt.d.ts +27 -39
  74. package/build/psbt.d.ts.map +1 -1
  75. package/build/psbt.js +139 -746
  76. package/build/psbt.js.map +1 -1
  77. package/build/script.d.ts.map +1 -1
  78. package/build/script.js +2 -2
  79. package/build/script.js.map +1 -1
  80. package/build/transaction.d.ts +4 -4
  81. package/build/transaction.d.ts.map +1 -1
  82. package/build/transaction.js +5 -4
  83. package/build/transaction.js.map +1 -1
  84. package/build/tsconfig.build.tsbuildinfo +1 -1
  85. package/build/types.d.ts +4 -2
  86. package/build/types.d.ts.map +1 -1
  87. package/build/types.js +9 -0
  88. package/build/types.js.map +1 -1
  89. package/build/workers/WorkerSigningPool.js +1 -1
  90. package/build/workers/WorkerSigningPool.js.map +1 -1
  91. package/build/workers/index.d.ts +3 -3
  92. package/build/workers/index.d.ts.map +1 -1
  93. package/build/workers/index.js +0 -3
  94. package/build/workers/index.js.map +1 -1
  95. package/build/workers/index.node.d.ts +24 -0
  96. package/build/workers/index.node.d.ts.map +1 -0
  97. package/build/workers/index.node.js +26 -0
  98. package/build/workers/index.node.js.map +1 -0
  99. package/package.json +28 -9
  100. package/src/address.ts +41 -18
  101. package/src/branded.ts +15 -13
  102. package/src/ecc/context.ts +75 -57
  103. package/src/index.ts +36 -1
  104. package/src/opcodes.ts +21 -4
  105. package/src/psbt/PsbtCache.ts +325 -0
  106. package/src/psbt/PsbtFinalizer.ts +213 -0
  107. package/src/psbt/PsbtSigner.ts +302 -0
  108. package/src/psbt/PsbtTransaction.ts +82 -0
  109. package/src/psbt/types.ts +13 -13
  110. package/src/psbt/validation.ts +1 -1
  111. package/src/psbt.ts +299 -1090
  112. package/src/script.ts +2 -2
  113. package/src/transaction.ts +9 -8
  114. package/src/types.ts +13 -0
  115. package/src/workers/WorkerSigningPool.ts +1 -1
  116. package/src/workers/index.node.ts +27 -0
  117. package/src/workers/index.ts +7 -9
  118. package/test/address.spec.ts +2 -2
  119. package/test/bitcoin.core.spec.ts +5 -2
  120. package/test/browser/payments.spec.ts +151 -0
  121. package/test/browser/psbt.spec.ts +1510 -0
  122. package/test/browser/script.spec.ts +223 -0
  123. package/test/browser/setup.ts +13 -0
  124. package/test/browser/workers-signing.spec.ts +537 -0
  125. package/test/crypto.spec.ts +2 -2
  126. package/test/fixtures/core/base58_encode_decode.json +12 -48
  127. package/test/fixtures/core/base58_keys_invalid.json +50 -150
  128. package/test/fixtures/core/sighash.json +1 -3
  129. package/test/fixtures/core/tx_valid.json +133 -501
  130. package/test/fixtures/embed.json +3 -11
  131. package/test/fixtures/p2ms.json +21 -91
  132. package/test/fixtures/p2pk.json +5 -24
  133. package/test/fixtures/p2pkh.json +7 -36
  134. package/test/fixtures/p2sh.json +8 -54
  135. package/test/fixtures/p2tr.json +2 -6
  136. package/test/fixtures/p2wpkh.json +7 -36
  137. package/test/fixtures/p2wsh.json +14 -59
  138. package/test/fixtures/psbt.json +2 -6
  139. package/test/fixtures/script.json +12 -48
  140. package/test/integration/addresses.spec.ts +11 -5
  141. package/test/integration/bip32.spec.ts +1 -1
  142. package/test/integration/cltv.spec.ts +10 -6
  143. package/test/integration/csv.spec.ts +10 -9
  144. package/test/integration/payments.spec.ts +8 -4
  145. package/test/integration/taproot.spec.ts +26 -6
  146. package/test/integration/transactions.spec.ts +22 -8
  147. package/test/payments.spec.ts +1 -1
  148. package/test/payments.utils.ts +1 -1
  149. package/test/psbt.spec.ts +250 -64
  150. package/test/script_signature.spec.ts +1 -1
  151. package/test/transaction.spec.ts +18 -5
  152. package/test/tsconfig.json +6 -20
  153. package/test/workers-pool.spec.ts +22 -23
  154. package/test/workers-signing.spec.ts +7 -3
  155. package/test/workers.spec.ts +6 -7
  156. package/typedoc.json +11 -1
  157. package/vitest.config.browser.ts +68 -0
  158. package/browser/ecpair.d.ts +0 -99
  159. package/src/ecpair.d.ts +0 -99
  160. package/test/taproot-cache.spec.ts +0 -694
package/src/script.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  import * as bip66 from './bip66.js';
6
6
  import { alloc, fromHex, toHex } from './io/index.js';
7
7
  import type { Opcodes } from './opcodes.js';
8
- import { opcodes, REVERSE_OPS } from './opcodes.js';
8
+ import { getReverseOps, opcodes } from './opcodes.js';
9
9
  import * as pushdata from './push_data.js';
10
10
  import * as scriptNumber from './script_number.js';
11
11
  import * as scriptSignature from './script_signature.js';
@@ -191,7 +191,7 @@ export function toASM(chunks: Uint8Array | Stack): string {
191
191
  }
192
192
 
193
193
  // opcode!
194
- return REVERSE_OPS[chunk];
194
+ return getReverseOps()[chunk];
195
195
  })
196
196
  .join(' ');
197
197
  }
@@ -2,7 +2,8 @@ import { alloc, BinaryReader, BinaryWriter, fromHex, reverse, toHex, varuint } f
2
2
  import * as bcrypto from './crypto.js';
3
3
  import * as bscript from './script.js';
4
4
  import { opcodes } from './script.js';
5
- import type { Bytes32, Satoshi, Script } from './types.js';
5
+ import type { Bytes32, MessageHash, Satoshi, Script } from './types.js';
6
+ import { toMessageHash } from './types.js';
6
7
 
7
8
  function varSliceSize(someScript: Uint8Array): number {
8
9
  const length = someScript.length;
@@ -24,7 +25,7 @@ function vectorSize(someVector: Uint8Array[]): number {
24
25
  const EMPTY_BYTES = new Uint8Array(0) as Script;
25
26
  const EMPTY_WITNESS: Uint8Array[] = [];
26
27
  const ZERO = fromHex('0000000000000000000000000000000000000000000000000000000000000000') as Bytes32;
27
- const ONE = fromHex('0000000000000000000000000000000000000000000000000000000000000001') as Bytes32;
28
+ const ONE: MessageHash = toMessageHash(fromHex('0000000000000000000000000000000000000000000000000000000000000001'));
28
29
 
29
30
  /** Maximum value for SIGHASH_SINGLE blank outputs (0xFFFFFFFFFFFFFFFF) */
30
31
  const BLANK_OUTPUT_VALUE = 0xffffffffffffffffn as Satoshi;
@@ -328,7 +329,7 @@ export class Transaction {
328
329
  * @param hashType - Signature hash type
329
330
  * @returns 32-byte hash for signing
330
331
  */
331
- hashForSignature(inIndex: number, prevOutScript: Script, hashType: number): Bytes32 {
332
+ hashForSignature(inIndex: number, prevOutScript: Script, hashType: number): MessageHash {
332
333
  if (!Number.isInteger(inIndex) || inIndex < 0) {
333
334
  throw new TypeError('Expected non-negative integer for inIndex');
334
335
  }
@@ -408,7 +409,7 @@ export class Transaction {
408
409
  writer.writeInt32LE(hashType);
409
410
  txTmp.#toBuffer(buffer, 0, false);
410
411
 
411
- return bcrypto.hash256(buffer) as Bytes32;
412
+ return toMessageHash(bcrypto.hash256(buffer));
412
413
  }
413
414
 
414
415
  /**
@@ -430,7 +431,7 @@ export class Transaction {
430
431
  leafHash?: Bytes32,
431
432
  annex?: Uint8Array,
432
433
  taprootCache?: TaprootHashCache,
433
- ): Bytes32 {
434
+ ): MessageHash {
434
435
  // https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
435
436
  if (!Number.isInteger(inIndex) || inIndex < 0 || inIndex > 0xffffffff) {
436
437
  throw new TypeError('Expected unsigned 32-bit integer for inIndex');
@@ -589,7 +590,7 @@ export class Transaction {
589
590
  const combined = new Uint8Array(1 + sigMsg.length);
590
591
  combined.set(prefix);
591
592
  combined.set(sigMsg, 1);
592
- return bcrypto.taggedHash('TapSighash', combined) as Bytes32;
593
+ return toMessageHash(bcrypto.taggedHash('TapSighash', combined));
593
594
  }
594
595
 
595
596
  /**
@@ -666,7 +667,7 @@ export class Transaction {
666
667
  prevOutScript: Script,
667
668
  value: Satoshi,
668
669
  hashType: number,
669
- ): Bytes32 {
670
+ ): MessageHash {
670
671
  if (!Number.isInteger(inIndex) || inIndex < 0 || inIndex > 0xffffffff) {
671
672
  throw new TypeError('Expected unsigned 32-bit integer for inIndex');
672
673
  }
@@ -757,7 +758,7 @@ export class Transaction {
757
758
  bufferWriter.writeBytes(hashOutputs);
758
759
  bufferWriter.writeUInt32LE(this.locktime);
759
760
  bufferWriter.writeUInt32LE(hashType);
760
- return bcrypto.hash256(tbuffer) as Bytes32;
761
+ return toMessageHash(bcrypto.hash256(tbuffer));
761
762
  }
762
763
 
763
764
  /**
package/src/types.ts CHANGED
@@ -7,6 +7,7 @@ import { compare, equals, fromHex, isZero } from './io/index.js';
7
7
  import type {
8
8
  Bytes20,
9
9
  Bytes32,
10
+ MessageHash,
10
11
  PrivateKey,
11
12
  PublicKey,
12
13
  Satoshi,
@@ -29,6 +30,7 @@ export type {
29
30
  PrivateKey,
30
31
  Signature,
31
32
  SchnorrSignature,
33
+ MessageHash,
32
34
  Script,
33
35
  } from './branded.js';
34
36
 
@@ -206,6 +208,17 @@ export function toBytes32(value: Uint8Array): Bytes32 {
206
208
  return value;
207
209
  }
208
210
 
211
+ export function isMessageHash(value: unknown): value is MessageHash {
212
+ return value instanceof Uint8Array && value.length === 32;
213
+ }
214
+
215
+ export function toMessageHash(value: Uint8Array): MessageHash {
216
+ if (!isMessageHash(value)) {
217
+ throw new TypeError(`Expected 32-byte Uint8Array, got ${value.length} bytes`);
218
+ }
219
+ return value;
220
+ }
221
+
209
222
  export function toBytes20(value: Uint8Array): Bytes20 {
210
223
  if (!isBytes20(value)) {
211
224
  throw new TypeError(`Expected 20-byte Uint8Array, got ${value.length} bytes`);
@@ -42,7 +42,7 @@ import type {
42
42
  WorkerPoolConfig,
43
43
  WorkerResponse,
44
44
  } from './types.js';
45
- import { isBatchResult, isWorkerReady, WorkerState, } from './types.js';
45
+ import { isBatchResult, isWorkerReady, WorkerState } from './types.js';
46
46
  import { createWorkerBlobUrl, revokeWorkerBlobUrl } from './signing-worker.js';
47
47
 
48
48
  /**
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Node.js worker pool entry point.
3
+ *
4
+ * This module provides direct access to Node.js-specific worker functionality.
5
+ * It re-exports everything from the base index plus Node.js specific exports.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { NodeWorkerSigningPool } from '@btc-vision/bitcoin/workers';
10
+ *
11
+ * const pool = NodeWorkerSigningPool.getInstance({ workerCount: 4 });
12
+ * await pool.initialize();
13
+ * pool.preserveWorkers();
14
+ *
15
+ * const result = await pool.signBatch(tasks, keyPair);
16
+ *
17
+ * await pool.shutdown();
18
+ * ```
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+
23
+ // Re-export everything from browser-safe index
24
+ export * from './index.js';
25
+
26
+ // Node.js specific exports
27
+ export { NodeWorkerSigningPool, type NodeWorkerPoolConfig } from './WorkerSigningPool.node.js';
@@ -46,6 +46,8 @@
46
46
  * @packageDocumentation
47
47
  */
48
48
 
49
+ import type { WorkerPoolConfig, SigningTask, ParallelSignerKeyPair, ParallelSigningResult } from './types.js';
50
+
49
51
  // Type exports
50
52
  export {
51
53
  SignatureType,
@@ -85,9 +87,6 @@ export { generateWorkerCode, createWorkerBlobUrl, revokeWorkerBlobUrl } from './
85
87
  // ECC bundle (for embedding in custom workers)
86
88
  export { ECC_BUNDLE, ECC_BUNDLE_SIZE } from './ecc-bundle.js';
87
89
 
88
- // Node.js specific exports (use dynamic import in browser builds)
89
- export { type NodeWorkerPoolConfig } from './WorkerSigningPool.node.js';
90
-
91
90
  // PSBT parallel signing integration
92
91
  export {
93
92
  signPsbtParallel,
@@ -133,11 +132,11 @@ export function detectRuntime(): 'node' | 'browser' | 'unknown' {
133
132
  * await pool.shutdown();
134
133
  * ```
135
134
  */
136
- export async function createSigningPool(config?: import('./types.js').WorkerPoolConfig): Promise<{
135
+ export async function createSigningPool(config?: WorkerPoolConfig): Promise<{
137
136
  signBatch: (
138
- tasks: readonly import('./types.js').SigningTask[],
139
- keyPair: import('./types.js').ParallelSignerKeyPair,
140
- ) => Promise<import('./types.js').ParallelSigningResult>;
137
+ tasks: readonly SigningTask[],
138
+ keyPair: ParallelSignerKeyPair,
139
+ ) => Promise<ParallelSigningResult>;
141
140
  preserveWorkers: () => void;
142
141
  releaseWorkers: () => void;
143
142
  shutdown: () => Promise<void>;
@@ -149,7 +148,6 @@ export async function createSigningPool(config?: import('./types.js').WorkerPool
149
148
  const runtime = detectRuntime();
150
149
 
151
150
  if (runtime === 'node') {
152
- // Dynamic import for Node.js to avoid bundler issues
153
151
  const { NodeWorkerSigningPool } = await import('./WorkerSigningPool.node.js');
154
152
  const pool = NodeWorkerSigningPool.getInstance(config);
155
153
  await pool.initialize();
@@ -162,4 +160,4 @@ export async function createSigningPool(config?: import('./types.js').WorkerPool
162
160
  } else {
163
161
  throw new Error('Unsupported runtime for worker signing pool');
164
162
  }
165
- }
163
+ }
@@ -6,11 +6,11 @@ import { fromBech32 } from '../src/bech32utils.js';
6
6
  import * as bscript from '../src/script.js';
7
7
  import fixtures from './fixtures/address.json' with { type: 'json' };
8
8
 
9
- import { initEccLib } from '../src/index.js';
10
9
  import type { EccLib } from '../src/index.js';
10
+ import { initEccLib } from '../src/index.js';
11
11
  import type { Network } from '../src/networks.js';
12
12
  import * as networks from '../src/networks.js';
13
- import { toHex, fromHex } from '../src/io/index.js';
13
+ import { fromHex, toHex } from '../src/io/index.js';
14
14
  import type { Bytes20 } from '../src/types.js';
15
15
 
16
16
  const NETWORKS: Record<string, Network> = Object.assign(
@@ -3,7 +3,7 @@ import base58 from 'bs58';
3
3
  import { describe, it } from 'vitest';
4
4
  import * as bitcoin from '../src/index.js';
5
5
  import type { Bytes20, Satoshi, Script } from '../src/types.js';
6
- import { toHex, fromHex, reverseCopy } from '../src/io/index.js';
6
+ import { fromHex, reverseCopy, toHex } from '../src/io/index.js';
7
7
  import base58EncodeDecode from './fixtures/core/base58_encode_decode.json' with { type: 'json' };
8
8
  import base58KeysInvalid from './fixtures/core/base58_keys_invalid.json' with { type: 'json' };
9
9
  import base58KeysValid from './fixtures/core/base58_keys_valid.json' with { type: 'json' };
@@ -57,7 +57,10 @@ describe('Bitcoin-core', () => {
57
57
  const version = network[typeMap[params.addrType]];
58
58
 
59
59
  it(`can export ${expected as string}`, () => {
60
- assert.strictEqual(bitcoin.address.toBase58Check(hash as Bytes20, version), expected);
60
+ assert.strictEqual(
61
+ bitcoin.address.toBase58Check(hash as Bytes20, version),
62
+ expected,
63
+ );
61
64
  });
62
65
  });
63
66
  });
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Browser-adapted version of test/payments.spec.ts
3
+ * Replaces fs.readFileSync with static JSON imports.
4
+ */
5
+ import assert from 'assert';
6
+ import * as ecc from 'tiny-secp256k1';
7
+ import { beforeEach, describe, it } from 'vitest';
8
+ import type { EccLib } from '../../src/index.js';
9
+ import { initEccLib } from '../../src/index.js';
10
+ import type { P2SHPayment, PaymentCreator } from '../../src/payments/index.js';
11
+ import { p2pk, p2wsh } from '../../src/payments/index.js';
12
+ import * as u from '../payments.utils.js';
13
+ import { fromHex } from '../../src/io/index.js';
14
+ import type { PublicKey } from '../../src/types.js';
15
+
16
+ // Pre-load all payment modules synchronously-like at import time
17
+ import * as embedModule from '../../src/payments/embed.js';
18
+ import * as p2msModule from '../../src/payments/p2ms.js';
19
+ import * as p2pkModule from '../../src/payments/p2pk.js';
20
+ import * as p2pkhModule from '../../src/payments/p2pkh.js';
21
+ import * as p2shModule from '../../src/payments/p2sh.js';
22
+ import * as p2wpkhModule from '../../src/payments/p2wpkh.js';
23
+ import * as p2wshModule from '../../src/payments/p2wsh.js';
24
+ import * as p2trModule from '../../src/payments/p2tr.js';
25
+
26
+ // Static JSON imports instead of fs.readFileSync
27
+ import embedFixtures from '../fixtures/embed.json' with { type: 'json' };
28
+ import p2msFixtures from '../fixtures/p2ms.json' with { type: 'json' };
29
+ import p2pkFixtures from '../fixtures/p2pk.json' with { type: 'json' };
30
+ import p2pkhFixtures from '../fixtures/p2pkh.json' with { type: 'json' };
31
+ import p2shFixtures from '../fixtures/p2sh.json' with { type: 'json' };
32
+ import p2wpkhFixtures from '../fixtures/p2wpkh.json' with { type: 'json' };
33
+ import p2wshFixtures from '../fixtures/p2wsh.json' with { type: 'json' };
34
+ import p2trFixtures from '../fixtures/p2tr.json' with { type: 'json' };
35
+
36
+ const fixtureMap: Record<string, any> = {
37
+ embed: embedFixtures,
38
+ p2ms: p2msFixtures,
39
+ p2pk: p2pkFixtures,
40
+ p2pkh: p2pkhFixtures,
41
+ p2sh: p2shFixtures,
42
+ p2wpkh: p2wpkhFixtures,
43
+ p2wsh: p2wshFixtures,
44
+ p2tr: p2trFixtures,
45
+ };
46
+
47
+ const paymentModules: Record<string, { [key: string]: PaymentCreator }> = {
48
+ embed: embedModule as any,
49
+ p2ms: p2msModule as any,
50
+ p2pk: p2pkModule as any,
51
+ p2pkh: p2pkhModule as any,
52
+ p2sh: p2shModule as any,
53
+ p2wpkh: p2wpkhModule as any,
54
+ p2wsh: p2wshModule as any,
55
+ p2tr: p2trModule as any,
56
+ };
57
+
58
+ // Initialize ECC library at module load time
59
+ initEccLib(ecc as unknown as EccLib);
60
+
61
+ ['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh', 'p2tr'].forEach((p) => {
62
+ describe(p, () => {
63
+ // Ensure ECC library is initialized before each test
64
+ beforeEach(() => {
65
+ initEccLib(ecc as unknown as EccLib);
66
+ });
67
+
68
+ const payment = paymentModules[p]!;
69
+ let fn: PaymentCreator;
70
+ if (p === 'embed') {
71
+ fn = payment['p2data']!;
72
+ } else {
73
+ fn = payment[p]!;
74
+ }
75
+
76
+ const fixtures = fixtureMap[p];
77
+ fixtures.valid.forEach((f: any) => {
78
+ it(f.description + ' as expected', () => {
79
+ const args = u.preform(f.arguments);
80
+ const actual = fn(args, f.options);
81
+
82
+ u.equate(actual, f.expected, f.arguments);
83
+ });
84
+
85
+ it(f.description + ' as expected (no validation)', () => {
86
+ const args = u.preform(f.arguments);
87
+ const actual = fn(
88
+ args,
89
+ Object.assign({}, f.options, {
90
+ validate: false,
91
+ }),
92
+ );
93
+
94
+ u.equate(actual, f.expected, f.arguments);
95
+ });
96
+ });
97
+
98
+ if (p === 'p2sh') {
99
+ it('properly assembles nested p2wsh with names', () => {
100
+ const actual = fn({
101
+ redeem: p2wsh({
102
+ redeem: p2pk({
103
+ pubkey: fromHex(
104
+ '03e15819590382a9dd878f01e2f0cbce541564eb415e43b440472d883ecd283058',
105
+ ) as PublicKey,
106
+ }),
107
+ }),
108
+ } as P2SHPayment);
109
+ assert.strictEqual(actual.address, '3MGbrbye4ttNUXM8WAvBFRKry4fkS9fjuw');
110
+ assert.strictEqual(actual.name, 'p2sh-p2wsh-p2pk');
111
+ assert.strictEqual(actual.redeem!.name, 'p2wsh-p2pk');
112
+ assert.strictEqual(actual.redeem!.redeem!.name, 'p2pk');
113
+ });
114
+ }
115
+
116
+ // cross-verify dynamically too
117
+ if (!fixtures.dynamic) return;
118
+ const { depends, details } = fixtures.dynamic;
119
+
120
+ details.forEach((f: any) => {
121
+ const detail = u.preform(f);
122
+ const disabled: any = {};
123
+ if (f.disabled)
124
+ f.disabled.forEach((k: string) => {
125
+ disabled[k] = true;
126
+ });
127
+
128
+ for (const key in depends) {
129
+ if (key in disabled) continue;
130
+ const dependencies = depends[key];
131
+
132
+ dependencies.forEach((dependency: any) => {
133
+ if (!Array.isArray(dependency)) dependency = [dependency];
134
+
135
+ const args = {};
136
+ dependency.forEach((d: any) => {
137
+ u.from(d, detail, args);
138
+ });
139
+ const expected = u.from(key, detail);
140
+
141
+ it(
142
+ f.description + ', ' + key + ' derives from ' + JSON.stringify(dependency),
143
+ () => {
144
+ u.equate(fn(args), expected);
145
+ },
146
+ );
147
+ });
148
+ }
149
+ });
150
+ });
151
+ });