@btc-vision/bitcoin 7.0.0-alpha.0 → 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 +6 -2
- package/browser/address.d.ts.map +1 -1
- package/browser/block.d.ts.map +1 -1
- package/browser/branded.d.ts +3 -14
- package/browser/branded.d.ts.map +1 -1
- package/browser/crypto.d.ts +1 -1
- package/browser/ecc/context.d.ts +4 -4
- package/browser/ecc/context.d.ts.map +1 -1
- package/browser/ecc/types.d.ts +1 -1
- package/browser/ecc/types.d.ts.map +1 -1
- package/browser/index.d.ts +3 -2
- package/browser/index.d.ts.map +1 -1
- package/browser/index.js +3579 -3539
- package/browser/io/BinaryReader.d.ts +15 -15
- package/browser/io/BinaryReader.d.ts.map +1 -1
- package/browser/io/BinaryWriter.d.ts +17 -17
- package/browser/io/BinaryWriter.d.ts.map +1 -1
- package/browser/io/MemoryPool.d.ts +20 -20
- package/browser/io/MemoryPool.d.ts.map +1 -1
- package/browser/opcodes.d.ts +11 -0
- package/browser/opcodes.d.ts.map +1 -1
- package/browser/payments/bip341.d.ts +1 -1
- package/browser/payments/bip341.d.ts.map +1 -1
- package/browser/payments/embed.d.ts +1 -1
- package/browser/payments/embed.d.ts.map +1 -1
- package/browser/payments/p2ms.d.ts.map +1 -1
- package/browser/payments/p2op.d.ts +1 -1
- package/browser/payments/p2op.d.ts.map +1 -1
- package/browser/payments/p2pk.d.ts +1 -1
- package/browser/payments/p2pk.d.ts.map +1 -1
- package/browser/payments/p2pkh.d.ts +1 -1
- package/browser/payments/p2pkh.d.ts.map +1 -1
- package/browser/payments/p2sh.d.ts.map +1 -1
- package/browser/payments/p2tr.d.ts +2 -2
- package/browser/payments/p2tr.d.ts.map +1 -1
- package/browser/payments/p2wpkh.d.ts +1 -1
- package/browser/payments/p2wpkh.d.ts.map +1 -1
- package/browser/payments/p2wsh.d.ts.map +1 -1
- package/browser/payments/types.d.ts +1 -1
- package/browser/payments/types.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/bip371.d.ts.map +1 -1
- package/browser/psbt/types.d.ts +14 -14
- 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/WorkerSigningPool.d.ts +17 -17
- package/browser/workers/WorkerSigningPool.d.ts.map +1 -1
- package/browser/workers/WorkerSigningPool.node.d.ts +12 -12
- package/browser/workers/WorkerSigningPool.node.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/browser/workers/psbt-parallel.d.ts +1 -1
- package/browser/workers/psbt-parallel.d.ts.map +1 -1
- package/browser/workers/types.d.ts.map +1 -1
- package/build/address.d.ts +6 -2
- package/build/address.d.ts.map +1 -1
- package/build/address.js +32 -19
- package/build/address.js.map +1 -1
- package/build/block.d.ts.map +1 -1
- package/build/block.js +2 -4
- package/build/block.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/crypto.d.ts +1 -1
- package/build/ecc/context.d.ts +4 -4
- package/build/ecc/context.d.ts.map +1 -1
- package/build/ecc/context.js +75 -52
- package/build/ecc/context.js.map +1 -1
- package/build/ecc/types.d.ts +1 -1
- package/build/ecc/types.d.ts.map +1 -1
- package/build/index.d.ts +3 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -3
- package/build/index.js.map +1 -1
- package/build/io/BinaryReader.d.ts +15 -15
- package/build/io/BinaryReader.d.ts.map +1 -1
- package/build/io/BinaryReader.js +17 -17
- package/build/io/BinaryReader.js.map +1 -1
- package/build/io/BinaryWriter.d.ts +17 -17
- package/build/io/BinaryWriter.d.ts.map +1 -1
- package/build/io/BinaryWriter.js +39 -39
- package/build/io/BinaryWriter.js.map +1 -1
- package/build/io/MemoryPool.d.ts +20 -20
- package/build/io/MemoryPool.d.ts.map +1 -1
- package/build/io/MemoryPool.js +28 -28
- package/build/io/MemoryPool.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/payments/bip341.d.ts +1 -2
- package/build/payments/bip341.d.ts.map +1 -1
- package/build/payments/bip341.js +1 -2
- package/build/payments/bip341.js.map +1 -1
- package/build/payments/embed.d.ts +1 -1
- package/build/payments/embed.d.ts.map +1 -1
- package/build/payments/embed.js +14 -14
- package/build/payments/embed.js.map +1 -1
- package/build/payments/p2ms.d.ts.map +1 -1
- package/build/payments/p2ms.js +21 -21
- package/build/payments/p2ms.js.map +1 -1
- package/build/payments/p2op.d.ts +1 -1
- package/build/payments/p2op.d.ts.map +1 -1
- package/build/payments/p2op.js +18 -18
- package/build/payments/p2op.js.map +1 -1
- package/build/payments/p2pk.d.ts +1 -1
- package/build/payments/p2pk.d.ts.map +1 -1
- package/build/payments/p2pk.js +17 -17
- package/build/payments/p2pk.js.map +1 -1
- package/build/payments/p2pkh.d.ts +1 -1
- package/build/payments/p2pkh.d.ts.map +1 -1
- package/build/payments/p2pkh.js +20 -20
- package/build/payments/p2pkh.js.map +1 -1
- package/build/payments/p2sh.d.ts.map +1 -1
- package/build/payments/p2sh.js +22 -20
- package/build/payments/p2sh.js.map +1 -1
- package/build/payments/p2tr.d.ts +2 -2
- package/build/payments/p2tr.d.ts.map +1 -1
- package/build/payments/p2tr.js +23 -23
- package/build/payments/p2tr.js.map +1 -1
- package/build/payments/p2wpkh.d.ts +1 -1
- package/build/payments/p2wpkh.d.ts.map +1 -1
- package/build/payments/p2wpkh.js +20 -20
- package/build/payments/p2wpkh.js.map +1 -1
- package/build/payments/p2wsh.d.ts.map +1 -1
- package/build/payments/p2wsh.js +22 -22
- package/build/payments/p2wsh.js.map +1 -1
- package/build/payments/types.d.ts +1 -1
- package/build/payments/types.d.ts.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/bip371.d.ts.map +1 -1
- package/build/psbt/bip371.js +6 -2
- package/build/psbt/bip371.js.map +1 -1
- package/build/psbt/psbtutils.js +1 -1
- package/build/psbt/psbtutils.js.map +1 -1
- package/build/psbt/types.d.ts +14 -14
- 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/validation.js +1 -1
- package/build/psbt/validation.js.map +1 -1
- package/build/psbt.d.ts +27 -39
- package/build/psbt.d.ts.map +1 -1
- package/build/psbt.js +142 -755
- package/build/psbt.js.map +1 -1
- package/build/script.d.ts.map +1 -1
- package/build/script.js +4 -4
- 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 +6 -5
- 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 +12 -9
- package/build/types.js.map +1 -1
- package/build/workers/WorkerSigningPool.d.ts +17 -17
- package/build/workers/WorkerSigningPool.d.ts.map +1 -1
- package/build/workers/WorkerSigningPool.js +25 -25
- package/build/workers/WorkerSigningPool.js.map +1 -1
- package/build/workers/WorkerSigningPool.node.d.ts +12 -12
- package/build/workers/WorkerSigningPool.node.d.ts.map +1 -1
- package/build/workers/WorkerSigningPool.node.js +23 -23
- package/build/workers/WorkerSigningPool.node.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/build/workers/psbt-parallel.d.ts +1 -1
- package/build/workers/psbt-parallel.d.ts.map +1 -1
- package/build/workers/psbt-parallel.js.map +1 -1
- package/build/workers/types.d.ts.map +1 -1
- package/build/workers/types.js.map +1 -1
- package/package.json +30 -10
- package/src/address.ts +53 -21
- package/src/block.ts +15 -8
- package/src/branded.ts +15 -13
- package/src/crypto.ts +1 -1
- package/src/ecc/context.ts +85 -64
- package/src/ecc/types.ts +1 -8
- package/src/index.ts +48 -14
- package/src/io/BinaryReader.ts +18 -18
- package/src/io/BinaryWriter.ts +43 -43
- package/src/io/MemoryPool.ts +32 -32
- package/src/opcodes.ts +21 -4
- package/src/payments/bip341.ts +2 -4
- package/src/payments/embed.ts +18 -18
- package/src/payments/p2ms.ts +32 -25
- package/src/payments/p2op.ts +22 -22
- package/src/payments/p2pk.ts +20 -20
- package/src/payments/p2pkh.ts +25 -25
- package/src/payments/p2sh.ts +30 -27
- package/src/payments/p2tr.ts +31 -31
- package/src/payments/p2wpkh.ts +25 -25
- package/src/payments/p2wsh.ts +27 -27
- package/src/payments/types.ts +1 -1
- 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/bip371.ts +7 -3
- package/src/psbt/psbtutils.ts +1 -1
- package/src/psbt/types.ts +14 -21
- package/src/psbt/validation.ts +5 -12
- package/src/psbt.ts +363 -1130
- package/src/script.ts +6 -9
- package/src/transaction.ts +18 -14
- package/src/types.ts +28 -17
- package/src/workers/WorkerSigningPool.node.ts +31 -31
- package/src/workers/WorkerSigningPool.ts +35 -39
- package/src/workers/index.node.ts +27 -0
- package/src/workers/index.ts +7 -9
- package/src/workers/psbt-parallel.ts +2 -7
- package/src/workers/types.ts +5 -1
- 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 +39 -0
- 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
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
import * as bip66 from './bip66.js';
|
|
6
|
-
import {
|
|
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';
|
|
12
|
-
import
|
|
12
|
+
import { isDefinedHashType } from './script_signature.js';
|
|
13
13
|
import type { Script, Stack } from './types.js';
|
|
14
|
+
import * as types from './types.js';
|
|
14
15
|
|
|
15
16
|
const OP_INT_BASE = opcodes.OP_RESERVED; // OP_1 - 1
|
|
16
17
|
export { opcodes };
|
|
@@ -116,9 +117,7 @@ export function compile(chunks: Uint8Array | Stack): Script {
|
|
|
116
117
|
return buffer as Script;
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
export function decompile(
|
|
120
|
-
buffer: Uint8Array | Stack,
|
|
121
|
-
): Array<number | Uint8Array> | null {
|
|
120
|
+
export function decompile(buffer: Uint8Array | Stack): Array<number | Uint8Array> | null {
|
|
122
121
|
// Already decompiled - return as-is
|
|
123
122
|
if (chunksIsArray(buffer)) return buffer as Array<number | Uint8Array>;
|
|
124
123
|
|
|
@@ -192,7 +191,7 @@ export function toASM(chunks: Uint8Array | Stack): string {
|
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
// opcode!
|
|
195
|
-
return
|
|
194
|
+
return getReverseOps()[chunk];
|
|
196
195
|
})
|
|
197
196
|
.join(' ');
|
|
198
197
|
}
|
|
@@ -247,8 +246,6 @@ export function isCanonicalPubKey(buffer: Uint8Array): boolean {
|
|
|
247
246
|
return types.isPoint(buffer);
|
|
248
247
|
}
|
|
249
248
|
|
|
250
|
-
import { isDefinedHashType } from './script_signature.js';
|
|
251
|
-
|
|
252
249
|
export function isCanonicalScriptSignature(buffer: Uint8Array): boolean {
|
|
253
250
|
if (!(buffer instanceof Uint8Array)) return false;
|
|
254
251
|
if (!isDefinedHashType(buffer[buffer.length - 1]!)) return false;
|
package/src/transaction.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { BinaryReader, BinaryWriter,
|
|
1
|
+
import { alloc, BinaryReader, BinaryWriter, fromHex, reverse, toHex, varuint } from './io/index.js';
|
|
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;
|
|
@@ -23,10 +24,8 @@ function vectorSize(someVector: Uint8Array[]): number {
|
|
|
23
24
|
|
|
24
25
|
const EMPTY_BYTES = new Uint8Array(0) as Script;
|
|
25
26
|
const EMPTY_WITNESS: Uint8Array[] = [];
|
|
26
|
-
const ZERO = fromHex(
|
|
27
|
-
|
|
28
|
-
) as Bytes32;
|
|
29
|
-
const ONE = fromHex('0000000000000000000000000000000000000000000000000000000000000001') as Bytes32;
|
|
27
|
+
const ZERO = fromHex('0000000000000000000000000000000000000000000000000000000000000000') as Bytes32;
|
|
28
|
+
const ONE: MessageHash = toMessageHash(fromHex('0000000000000000000000000000000000000000000000000000000000000001'));
|
|
30
29
|
|
|
31
30
|
/** Maximum value for SIGHASH_SINGLE blank outputs (0xFFFFFFFFFFFFFFFF) */
|
|
32
31
|
const BLANK_OUTPUT_VALUE = 0xffffffffffffffffn as Satoshi;
|
|
@@ -330,7 +329,7 @@ export class Transaction {
|
|
|
330
329
|
* @param hashType - Signature hash type
|
|
331
330
|
* @returns 32-byte hash for signing
|
|
332
331
|
*/
|
|
333
|
-
hashForSignature(inIndex: number, prevOutScript: Script, hashType: number):
|
|
332
|
+
hashForSignature(inIndex: number, prevOutScript: Script, hashType: number): MessageHash {
|
|
334
333
|
if (!Number.isInteger(inIndex) || inIndex < 0) {
|
|
335
334
|
throw new TypeError('Expected non-negative integer for inIndex');
|
|
336
335
|
}
|
|
@@ -410,7 +409,7 @@ export class Transaction {
|
|
|
410
409
|
writer.writeInt32LE(hashType);
|
|
411
410
|
txTmp.#toBuffer(buffer, 0, false);
|
|
412
411
|
|
|
413
|
-
return bcrypto.hash256(buffer)
|
|
412
|
+
return toMessageHash(bcrypto.hash256(buffer));
|
|
414
413
|
}
|
|
415
414
|
|
|
416
415
|
/**
|
|
@@ -432,7 +431,7 @@ export class Transaction {
|
|
|
432
431
|
leafHash?: Bytes32,
|
|
433
432
|
annex?: Uint8Array,
|
|
434
433
|
taprootCache?: TaprootHashCache,
|
|
435
|
-
):
|
|
434
|
+
): MessageHash {
|
|
436
435
|
// https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
|
|
437
436
|
if (!Number.isInteger(inIndex) || inIndex < 0 || inIndex > 0xffffffff) {
|
|
438
437
|
throw new TypeError('Expected unsigned 32-bit integer for inIndex');
|
|
@@ -493,7 +492,9 @@ export class Transaction {
|
|
|
493
492
|
bufferWriter = new BinaryWriter(
|
|
494
493
|
prevOutScripts.map(varSliceSize).reduce((a, b) => a + b),
|
|
495
494
|
);
|
|
496
|
-
prevOutScripts.forEach((prevOutScript) =>
|
|
495
|
+
prevOutScripts.forEach((prevOutScript) =>
|
|
496
|
+
bufferWriter.writeVarBytes(prevOutScript),
|
|
497
|
+
);
|
|
497
498
|
hashScriptPubKeys = bcrypto.sha256(bufferWriter.finish());
|
|
498
499
|
|
|
499
500
|
bufferWriter = new BinaryWriter(4 * this.ins.length);
|
|
@@ -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
|
/**
|
|
@@ -600,7 +601,10 @@ export class Transaction {
|
|
|
600
601
|
* @param values - Array of previous output values for all inputs
|
|
601
602
|
* @returns Cache object to pass to hashForWitnessV1
|
|
602
603
|
*/
|
|
603
|
-
getTaprootHashCache(
|
|
604
|
+
getTaprootHashCache(
|
|
605
|
+
prevOutScripts: readonly Script[],
|
|
606
|
+
values: readonly Satoshi[],
|
|
607
|
+
): TaprootHashCache {
|
|
604
608
|
// hashPrevouts
|
|
605
609
|
let bufferWriter = new BinaryWriter(36 * this.ins.length);
|
|
606
610
|
for (const txIn of this.ins) {
|
|
@@ -663,7 +667,7 @@ export class Transaction {
|
|
|
663
667
|
prevOutScript: Script,
|
|
664
668
|
value: Satoshi,
|
|
665
669
|
hashType: number,
|
|
666
|
-
):
|
|
670
|
+
): MessageHash {
|
|
667
671
|
if (!Number.isInteger(inIndex) || inIndex < 0 || inIndex > 0xffffffff) {
|
|
668
672
|
throw new TypeError('Expected unsigned 32-bit integer for inIndex');
|
|
669
673
|
}
|
|
@@ -754,7 +758,7 @@ export class Transaction {
|
|
|
754
758
|
bufferWriter.writeBytes(hashOutputs);
|
|
755
759
|
bufferWriter.writeUInt32LE(this.locktime);
|
|
756
760
|
bufferWriter.writeUInt32LE(hashType);
|
|
757
|
-
return bcrypto.hash256(tbuffer)
|
|
761
|
+
return toMessageHash(bcrypto.hash256(tbuffer));
|
|
758
762
|
}
|
|
759
763
|
|
|
760
764
|
/**
|
package/src/types.ts
CHANGED
|
@@ -3,7 +3,19 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { compare, equals, fromHex, isZero } from './io/index.js';
|
|
7
|
+
import type {
|
|
8
|
+
Bytes20,
|
|
9
|
+
Bytes32,
|
|
10
|
+
MessageHash,
|
|
11
|
+
PrivateKey,
|
|
12
|
+
PublicKey,
|
|
13
|
+
Satoshi,
|
|
14
|
+
SchnorrSignature,
|
|
15
|
+
Script,
|
|
16
|
+
Signature,
|
|
17
|
+
XOnlyPublicKey,
|
|
18
|
+
} from './branded.js';
|
|
7
19
|
|
|
8
20
|
// ============================================================================
|
|
9
21
|
// Branded Types (re-exported from branded.ts to avoid circular dependencies)
|
|
@@ -18,11 +30,10 @@ export type {
|
|
|
18
30
|
PrivateKey,
|
|
19
31
|
Signature,
|
|
20
32
|
SchnorrSignature,
|
|
33
|
+
MessageHash,
|
|
21
34
|
Script,
|
|
22
35
|
} from './branded.js';
|
|
23
36
|
|
|
24
|
-
import type { Bytes32, Bytes20, Satoshi, PrivateKey, XOnlyPublicKey, PublicKey, SchnorrSignature, Signature, Script } from './branded.js';
|
|
25
|
-
|
|
26
37
|
// ============================================================================
|
|
27
38
|
// Constants
|
|
28
39
|
// ============================================================================
|
|
@@ -40,20 +51,12 @@ export const TAPLEAF_VERSION_MASK = 0xfe;
|
|
|
40
51
|
// ============================================================================
|
|
41
52
|
|
|
42
53
|
export function isUInt8(value: unknown): value is number {
|
|
43
|
-
return (
|
|
44
|
-
typeof value === 'number' &&
|
|
45
|
-
Number.isInteger(value) &&
|
|
46
|
-
value >= 0 &&
|
|
47
|
-
value <= 0xff
|
|
48
|
-
);
|
|
54
|
+
return typeof value === 'number' && Number.isInteger(value) && value >= 0 && value <= 0xff;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
export function isUInt32(value: unknown): value is number {
|
|
52
58
|
return (
|
|
53
|
-
typeof value === 'number' &&
|
|
54
|
-
Number.isInteger(value) &&
|
|
55
|
-
value >= 0 &&
|
|
56
|
-
value <= 0xffffffff
|
|
59
|
+
typeof value === 'number' && Number.isInteger(value) && value >= 0 && value <= 0xffffffff
|
|
57
60
|
);
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -205,6 +208,17 @@ export function toBytes32(value: Uint8Array): Bytes32 {
|
|
|
205
208
|
return value;
|
|
206
209
|
}
|
|
207
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
|
+
|
|
208
222
|
export function toBytes20(value: Uint8Array): Bytes20 {
|
|
209
223
|
if (!isBytes20(value)) {
|
|
210
224
|
throw new TypeError(`Expected 20-byte Uint8Array, got ${value.length} bytes`);
|
|
@@ -244,10 +258,7 @@ export function assertXOnlyPublicKey(
|
|
|
244
258
|
}
|
|
245
259
|
}
|
|
246
260
|
|
|
247
|
-
export function assertPrivateKey(
|
|
248
|
-
value: unknown,
|
|
249
|
-
name: string,
|
|
250
|
-
): asserts value is PrivateKey {
|
|
261
|
+
export function assertPrivateKey(value: unknown, name: string): asserts value is PrivateKey {
|
|
251
262
|
if (!(value instanceof Uint8Array)) {
|
|
252
263
|
throw new TypeError(`${name} must be Uint8Array, got ${typeof value}`);
|
|
253
264
|
}
|
|
@@ -7,21 +7,21 @@
|
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { isMainThread, Worker } from 'worker_threads';
|
|
11
11
|
import { cpus } from 'os';
|
|
12
12
|
import type {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
BatchSigningMessage,
|
|
14
|
+
BatchSigningResultMessage,
|
|
15
|
+
BatchSigningTask,
|
|
15
16
|
ParallelSignerKeyPair,
|
|
16
17
|
ParallelSigningResult,
|
|
18
|
+
PooledWorker,
|
|
17
19
|
SigningResultMessage,
|
|
20
|
+
SigningTask,
|
|
21
|
+
WorkerPoolConfig,
|
|
18
22
|
WorkerResponse,
|
|
19
|
-
BatchSigningMessage,
|
|
20
|
-
BatchSigningTask,
|
|
21
|
-
BatchSigningResultMessage,
|
|
22
|
-
PooledWorker,
|
|
23
23
|
} from './types.js';
|
|
24
|
-
import {
|
|
24
|
+
import { isBatchResult, isWorkerReady, WorkerState } from './types.js';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* ECC library types for Node.js worker.
|
|
@@ -163,29 +163,6 @@ export class NodeWorkerSigningPool {
|
|
|
163
163
|
this.#preserveWorkers = this.#config.preserveWorkers;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
/**
|
|
167
|
-
* Gets the singleton pool instance.
|
|
168
|
-
*
|
|
169
|
-
* @param config - Optional configuration (only used on first call)
|
|
170
|
-
* @returns The singleton pool instance
|
|
171
|
-
*/
|
|
172
|
-
public static getInstance(config?: NodeWorkerPoolConfig): NodeWorkerSigningPool {
|
|
173
|
-
if (!NodeWorkerSigningPool.#instance) {
|
|
174
|
-
NodeWorkerSigningPool.#instance = new NodeWorkerSigningPool(config);
|
|
175
|
-
}
|
|
176
|
-
return NodeWorkerSigningPool.#instance;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Resets the singleton instance (for testing).
|
|
181
|
-
*/
|
|
182
|
-
public static resetInstance(): void {
|
|
183
|
-
if (NodeWorkerSigningPool.#instance) {
|
|
184
|
-
NodeWorkerSigningPool.#instance.shutdown().catch(() => {});
|
|
185
|
-
NodeWorkerSigningPool.#instance = null;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
166
|
/**
|
|
190
167
|
* Number of workers in the pool.
|
|
191
168
|
*/
|
|
@@ -214,6 +191,29 @@ export class NodeWorkerSigningPool {
|
|
|
214
191
|
return this.#preserveWorkers;
|
|
215
192
|
}
|
|
216
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Gets the singleton pool instance.
|
|
196
|
+
*
|
|
197
|
+
* @param config - Optional configuration (only used on first call)
|
|
198
|
+
* @returns The singleton pool instance
|
|
199
|
+
*/
|
|
200
|
+
public static getInstance(config?: NodeWorkerPoolConfig): NodeWorkerSigningPool {
|
|
201
|
+
if (!NodeWorkerSigningPool.#instance) {
|
|
202
|
+
NodeWorkerSigningPool.#instance = new NodeWorkerSigningPool(config);
|
|
203
|
+
}
|
|
204
|
+
return NodeWorkerSigningPool.#instance;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Resets the singleton instance (for testing).
|
|
209
|
+
*/
|
|
210
|
+
public static resetInstance(): void {
|
|
211
|
+
if (NodeWorkerSigningPool.#instance) {
|
|
212
|
+
NodeWorkerSigningPool.#instance.shutdown().catch(() => {});
|
|
213
|
+
NodeWorkerSigningPool.#instance = null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
217
|
/**
|
|
218
218
|
* Enables worker preservation between signing batches.
|
|
219
219
|
*/
|
|
@@ -31,22 +31,18 @@
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
import type {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
BatchSigningMessage,
|
|
35
|
+
BatchSigningResultMessage,
|
|
36
|
+
BatchSigningTask,
|
|
36
37
|
ParallelSignerKeyPair,
|
|
37
38
|
ParallelSigningResult,
|
|
39
|
+
PooledWorker,
|
|
38
40
|
SigningResultMessage,
|
|
41
|
+
SigningTask,
|
|
42
|
+
WorkerPoolConfig,
|
|
39
43
|
WorkerResponse,
|
|
40
|
-
BatchSigningMessage,
|
|
41
|
-
BatchSigningTask,
|
|
42
|
-
BatchSigningResultMessage,
|
|
43
|
-
PooledWorker,
|
|
44
|
-
} from './types.js';
|
|
45
|
-
import {
|
|
46
|
-
WorkerState,
|
|
47
|
-
isBatchResult,
|
|
48
|
-
isWorkerReady,
|
|
49
44
|
} from './types.js';
|
|
45
|
+
import { isBatchResult, isWorkerReady, WorkerState } from './types.js';
|
|
50
46
|
import { createWorkerBlobUrl, revokeWorkerBlobUrl } from './signing-worker.js';
|
|
51
47
|
|
|
52
48
|
/**
|
|
@@ -151,34 +147,6 @@ export class WorkerSigningPool {
|
|
|
151
147
|
this.#preserveWorkers = this.#config.preserveWorkers;
|
|
152
148
|
}
|
|
153
149
|
|
|
154
|
-
/**
|
|
155
|
-
* Gets the singleton pool instance.
|
|
156
|
-
*
|
|
157
|
-
* @param config - Optional configuration (only used on first call)
|
|
158
|
-
* @returns The singleton pool instance
|
|
159
|
-
*
|
|
160
|
-
* @example
|
|
161
|
-
* ```typescript
|
|
162
|
-
* const pool = WorkerSigningPool.getInstance({ workerCount: 8 });
|
|
163
|
-
* ```
|
|
164
|
-
*/
|
|
165
|
-
public static getInstance(config?: WorkerPoolConfig): WorkerSigningPool {
|
|
166
|
-
if (!WorkerSigningPool.#instance) {
|
|
167
|
-
WorkerSigningPool.#instance = new WorkerSigningPool(config);
|
|
168
|
-
}
|
|
169
|
-
return WorkerSigningPool.#instance;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Resets the singleton instance (for testing).
|
|
174
|
-
*/
|
|
175
|
-
public static resetInstance(): void {
|
|
176
|
-
if (WorkerSigningPool.#instance) {
|
|
177
|
-
WorkerSigningPool.#instance.shutdown().catch(() => {});
|
|
178
|
-
WorkerSigningPool.#instance = null;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
150
|
/**
|
|
183
151
|
* Number of workers in the pool.
|
|
184
152
|
*/
|
|
@@ -207,6 +175,34 @@ export class WorkerSigningPool {
|
|
|
207
175
|
return this.#preserveWorkers;
|
|
208
176
|
}
|
|
209
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Gets the singleton pool instance.
|
|
180
|
+
*
|
|
181
|
+
* @param config - Optional configuration (only used on first call)
|
|
182
|
+
* @returns The singleton pool instance
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* const pool = WorkerSigningPool.getInstance({ workerCount: 8 });
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
public static getInstance(config?: WorkerPoolConfig): WorkerSigningPool {
|
|
190
|
+
if (!WorkerSigningPool.#instance) {
|
|
191
|
+
WorkerSigningPool.#instance = new WorkerSigningPool(config);
|
|
192
|
+
}
|
|
193
|
+
return WorkerSigningPool.#instance;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Resets the singleton instance (for testing).
|
|
198
|
+
*/
|
|
199
|
+
public static resetInstance(): void {
|
|
200
|
+
if (WorkerSigningPool.#instance) {
|
|
201
|
+
WorkerSigningPool.#instance.shutdown().catch(() => {});
|
|
202
|
+
WorkerSigningPool.#instance = null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
210
206
|
/**
|
|
211
207
|
* Enables worker preservation between signing batches.
|
|
212
208
|
*
|
|
@@ -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
|
+
}
|
|
@@ -28,16 +28,11 @@
|
|
|
28
28
|
* @packageDocumentation
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
import type { PsbtInput,
|
|
31
|
+
import type { PsbtInput, TapKeySig, TapScriptSig } from 'bip174';
|
|
32
32
|
import type { PublicKey } from '../types.js';
|
|
33
33
|
import type { Psbt } from '../psbt.js';
|
|
34
34
|
import { Transaction } from '../transaction.js';
|
|
35
|
-
import type {
|
|
36
|
-
SigningTask,
|
|
37
|
-
ParallelSignerKeyPair,
|
|
38
|
-
ParallelSigningResult,
|
|
39
|
-
WorkerPoolConfig,
|
|
40
|
-
} from './types.js';
|
|
35
|
+
import type { ParallelSignerKeyPair, ParallelSigningResult, SigningTask, WorkerPoolConfig, } from './types.js';
|
|
41
36
|
import { SignatureType } from './types.js';
|
|
42
37
|
import { WorkerSigningPool } from './WorkerSigningPool.js';
|
|
43
38
|
import { toXOnly } from '../pubkey.js';
|
package/src/workers/types.ts
CHANGED
|
@@ -153,7 +153,11 @@ export interface BatchSigningResultMessage {
|
|
|
153
153
|
/**
|
|
154
154
|
* All possible messages to worker.
|
|
155
155
|
*/
|
|
156
|
-
export type WorkerMessage =
|
|
156
|
+
export type WorkerMessage =
|
|
157
|
+
| SigningTaskMessage
|
|
158
|
+
| BatchSigningMessage
|
|
159
|
+
| WorkerInitMessage
|
|
160
|
+
| WorkerShutdownMessage;
|
|
157
161
|
|
|
158
162
|
/**
|
|
159
163
|
* Result from worker after signing.
|
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
|
});
|