@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.
- package/browser/address.d.ts +5 -1
- package/browser/address.d.ts.map +1 -1
- package/browser/branded.d.ts +3 -14
- package/browser/branded.d.ts.map +1 -1
- package/browser/ecc/context.d.ts.map +1 -1
- package/browser/index.d.ts +2 -1
- package/browser/index.d.ts.map +1 -1
- package/browser/index.js +2964 -2919
- package/browser/opcodes.d.ts +11 -0
- package/browser/opcodes.d.ts.map +1 -1
- package/browser/psbt/PsbtCache.d.ts +54 -0
- package/browser/psbt/PsbtCache.d.ts.map +1 -0
- package/browser/psbt/PsbtFinalizer.d.ts +21 -0
- package/browser/psbt/PsbtFinalizer.d.ts.map +1 -0
- package/browser/psbt/PsbtSigner.d.ts +32 -0
- package/browser/psbt/PsbtSigner.d.ts.map +1 -0
- package/browser/psbt/PsbtTransaction.d.ts +25 -0
- package/browser/psbt/PsbtTransaction.d.ts.map +1 -0
- package/browser/psbt/types.d.ts +13 -13
- package/browser/psbt/types.d.ts.map +1 -1
- package/browser/psbt/validation.d.ts +1 -1
- package/browser/psbt/validation.d.ts.map +1 -1
- package/browser/psbt.d.ts +27 -39
- package/browser/psbt.d.ts.map +1 -1
- package/browser/script.d.ts.map +1 -1
- package/browser/transaction.d.ts +4 -4
- package/browser/transaction.d.ts.map +1 -1
- package/browser/types.d.ts +4 -2
- package/browser/types.d.ts.map +1 -1
- package/browser/workers/index.d.ts +3 -50
- package/browser/workers/index.d.ts.map +1 -1
- package/browser/workers/index.node.d.ts +24 -0
- package/browser/workers/index.node.d.ts.map +1 -0
- package/build/address.d.ts +5 -1
- package/build/address.d.ts.map +1 -1
- package/build/address.js +29 -17
- package/build/address.js.map +1 -1
- package/build/branded.d.ts +3 -14
- package/build/branded.d.ts.map +1 -1
- package/build/branded.js +0 -5
- package/build/branded.js.map +1 -1
- package/build/ecc/context.d.ts.map +1 -1
- package/build/ecc/context.js +68 -45
- package/build/ecc/context.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/opcodes.d.ts +11 -0
- package/build/opcodes.d.ts.map +1 -1
- package/build/opcodes.js +19 -4
- package/build/opcodes.js.map +1 -1
- package/build/psbt/PsbtCache.d.ts +54 -0
- package/build/psbt/PsbtCache.d.ts.map +1 -0
- package/build/psbt/PsbtCache.js +249 -0
- package/build/psbt/PsbtCache.js.map +1 -0
- package/build/psbt/PsbtFinalizer.d.ts +21 -0
- package/build/psbt/PsbtFinalizer.d.ts.map +1 -0
- package/build/psbt/PsbtFinalizer.js +157 -0
- package/build/psbt/PsbtFinalizer.js.map +1 -0
- package/build/psbt/PsbtSigner.d.ts +32 -0
- package/build/psbt/PsbtSigner.d.ts.map +1 -0
- package/build/psbt/PsbtSigner.js +192 -0
- package/build/psbt/PsbtSigner.js.map +1 -0
- package/build/psbt/PsbtTransaction.d.ts +25 -0
- package/build/psbt/PsbtTransaction.d.ts.map +1 -0
- package/build/psbt/PsbtTransaction.js +61 -0
- package/build/psbt/PsbtTransaction.js.map +1 -0
- package/build/psbt/types.d.ts +13 -13
- package/build/psbt/types.d.ts.map +1 -1
- package/build/psbt/validation.d.ts +1 -1
- package/build/psbt/validation.d.ts.map +1 -1
- package/build/psbt.d.ts +27 -39
- package/build/psbt.d.ts.map +1 -1
- package/build/psbt.js +139 -746
- package/build/psbt.js.map +1 -1
- package/build/script.d.ts.map +1 -1
- package/build/script.js +2 -2
- package/build/script.js.map +1 -1
- package/build/transaction.d.ts +4 -4
- package/build/transaction.d.ts.map +1 -1
- package/build/transaction.js +5 -4
- package/build/transaction.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/build/types.d.ts +4 -2
- package/build/types.d.ts.map +1 -1
- package/build/types.js +9 -0
- package/build/types.js.map +1 -1
- package/build/workers/WorkerSigningPool.js +1 -1
- package/build/workers/WorkerSigningPool.js.map +1 -1
- package/build/workers/index.d.ts +3 -3
- package/build/workers/index.d.ts.map +1 -1
- package/build/workers/index.js +0 -3
- package/build/workers/index.js.map +1 -1
- package/build/workers/index.node.d.ts +24 -0
- package/build/workers/index.node.d.ts.map +1 -0
- package/build/workers/index.node.js +26 -0
- package/build/workers/index.node.js.map +1 -0
- package/package.json +28 -9
- package/src/address.ts +41 -18
- package/src/branded.ts +15 -13
- package/src/ecc/context.ts +75 -57
- package/src/index.ts +36 -1
- package/src/opcodes.ts +21 -4
- package/src/psbt/PsbtCache.ts +325 -0
- package/src/psbt/PsbtFinalizer.ts +213 -0
- package/src/psbt/PsbtSigner.ts +302 -0
- package/src/psbt/PsbtTransaction.ts +82 -0
- package/src/psbt/types.ts +13 -13
- package/src/psbt/validation.ts +1 -1
- package/src/psbt.ts +299 -1090
- package/src/script.ts +2 -2
- package/src/transaction.ts +9 -8
- package/src/types.ts +13 -0
- package/src/workers/WorkerSigningPool.ts +1 -1
- package/src/workers/index.node.ts +27 -0
- package/src/workers/index.ts +7 -9
- package/test/address.spec.ts +2 -2
- package/test/bitcoin.core.spec.ts +5 -2
- package/test/browser/payments.spec.ts +151 -0
- package/test/browser/psbt.spec.ts +1510 -0
- package/test/browser/script.spec.ts +223 -0
- package/test/browser/setup.ts +13 -0
- package/test/browser/workers-signing.spec.ts +537 -0
- package/test/crypto.spec.ts +2 -2
- package/test/fixtures/core/base58_encode_decode.json +12 -48
- package/test/fixtures/core/base58_keys_invalid.json +50 -150
- package/test/fixtures/core/sighash.json +1 -3
- package/test/fixtures/core/tx_valid.json +133 -501
- package/test/fixtures/embed.json +3 -11
- package/test/fixtures/p2ms.json +21 -91
- package/test/fixtures/p2pk.json +5 -24
- package/test/fixtures/p2pkh.json +7 -36
- package/test/fixtures/p2sh.json +8 -54
- package/test/fixtures/p2tr.json +2 -6
- package/test/fixtures/p2wpkh.json +7 -36
- package/test/fixtures/p2wsh.json +14 -59
- package/test/fixtures/psbt.json +2 -6
- package/test/fixtures/script.json +12 -48
- package/test/integration/addresses.spec.ts +11 -5
- package/test/integration/bip32.spec.ts +1 -1
- package/test/integration/cltv.spec.ts +10 -6
- package/test/integration/csv.spec.ts +10 -9
- package/test/integration/payments.spec.ts +8 -4
- package/test/integration/taproot.spec.ts +26 -6
- package/test/integration/transactions.spec.ts +22 -8
- package/test/payments.spec.ts +1 -1
- package/test/payments.utils.ts +1 -1
- package/test/psbt.spec.ts +250 -64
- package/test/script_signature.spec.ts +1 -1
- package/test/transaction.spec.ts +18 -5
- package/test/tsconfig.json +6 -20
- package/test/workers-pool.spec.ts +22 -23
- package/test/workers-signing.spec.ts +7 -3
- package/test/workers.spec.ts +6 -7
- package/typedoc.json +11 -1
- package/vitest.config.browser.ts +68 -0
- package/browser/ecpair.d.ts +0 -99
- package/src/ecpair.d.ts +0 -99
- 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 {
|
|
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
|
|
194
|
+
return getReverseOps()[chunk];
|
|
195
195
|
})
|
|
196
196
|
.join(' ');
|
|
197
197
|
}
|
package/src/transaction.ts
CHANGED
|
@@ -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')
|
|
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):
|
|
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)
|
|
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
|
-
):
|
|
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)
|
|
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
|
-
):
|
|
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)
|
|
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
|
|
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';
|
package/src/workers/index.ts
CHANGED
|
@@ -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?:
|
|
135
|
+
export async function createSigningPool(config?: WorkerPoolConfig): Promise<{
|
|
137
136
|
signBatch: (
|
|
138
|
-
tasks: readonly
|
|
139
|
-
keyPair:
|
|
140
|
-
) => Promise<
|
|
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
|
+
}
|
package/test/address.spec.ts
CHANGED
|
@@ -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 {
|
|
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 {
|
|
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(
|
|
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
|
+
});
|