@btc-vision/bitcoin 7.0.0-alpha.1 → 7.0.0-alpha.10
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/README.md +455 -155
- 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/chunks/psbt-parallel-BBFlkmiv.js +10717 -0
- package/browser/ecc/context.d.ts +22 -21
- package/browser/ecc/context.d.ts.map +1 -1
- package/browser/ecc/index.d.ts +1 -1
- package/browser/ecc/index.d.ts.map +1 -1
- package/browser/ecc/types.d.ts +10 -123
- package/browser/ecc/types.d.ts.map +1 -1
- package/browser/env.d.ts +13 -0
- package/browser/env.d.ts.map +1 -0
- package/browser/index.d.ts +6 -6
- package/browser/index.d.ts.map +1 -1
- package/browser/index.js +2602 -11786
- package/browser/io/hex.d.ts.map +1 -1
- package/browser/io/index.d.ts +0 -1
- package/browser/io/index.d.ts.map +1 -1
- package/browser/opcodes.d.ts +11 -0
- package/browser/opcodes.d.ts.map +1 -1
- package/browser/payments/p2tr.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 +4 -70
- 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 +26 -40
- 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 +5 -3
- package/browser/types.d.ts.map +1 -1
- package/browser/workers/WorkerSigningPool.d.ts +7 -0
- package/browser/workers/WorkerSigningPool.d.ts.map +1 -1
- package/browser/workers/WorkerSigningPool.node.d.ts +7 -0
- package/browser/workers/WorkerSigningPool.node.d.ts.map +1 -1
- package/browser/workers/WorkerSigningPool.sequential.d.ts +67 -0
- package/browser/workers/WorkerSigningPool.sequential.d.ts.map +1 -0
- package/browser/workers/WorkerSigningPool.worklet.d.ts +64 -0
- package/browser/workers/WorkerSigningPool.worklet.d.ts.map +1 -0
- package/browser/workers/index.browser.d.ts +16 -0
- package/browser/workers/index.browser.d.ts.map +1 -0
- package/browser/workers/index.d.ts +4 -64
- package/browser/workers/index.d.ts.map +1 -1
- package/browser/workers/index.js +28 -0
- package/browser/workers/index.node.d.ts +17 -0
- package/browser/workers/index.node.d.ts.map +1 -0
- package/browser/workers/index.react-native.d.ts +28 -0
- package/browser/workers/index.react-native.d.ts.map +1 -0
- package/browser/workers/index.shared.d.ts +15 -0
- package/browser/workers/index.shared.d.ts.map +1 -0
- package/browser/workers/psbt-parallel.d.ts +2 -3
- package/browser/workers/psbt-parallel.d.ts.map +1 -1
- package/browser/workers/types.d.ts +17 -0
- package/browser/workers/types.d.ts.map +1 -1
- 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/bech32utils.js.map +1 -1
- 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/ecc/context.d.ts +22 -21
- package/build/ecc/context.d.ts.map +1 -1
- package/build/ecc/context.js +23 -95
- package/build/ecc/context.js.map +1 -1
- package/build/ecc/index.d.ts +1 -1
- package/build/ecc/index.d.ts.map +1 -1
- package/build/ecc/types.d.ts +7 -126
- package/build/ecc/types.d.ts.map +1 -1
- package/build/ecc/types.js +4 -1
- package/build/ecc/types.js.map +1 -1
- package/build/env.d.ts +13 -0
- package/build/env.d.ts.map +1 -0
- package/build/env.js +198 -0
- package/build/env.js.map +1 -0
- package/build/index.d.ts +7 -6
- package/build/index.d.ts.map +1 -1
- package/build/index.js +7 -5
- package/build/index.js.map +1 -1
- package/build/io/hex.d.ts.map +1 -1
- package/build/io/hex.js +2 -1
- package/build/io/hex.js.map +1 -1
- package/build/io/index.d.ts +0 -1
- package/build/io/index.d.ts.map +1 -1
- package/build/io/index.js +0 -2
- package/build/io/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/payments/bip341.js.map +1 -1
- package/build/payments/embed.js.map +1 -1
- package/build/payments/p2ms.js.map +1 -1
- package/build/payments/p2pk.js.map +1 -1
- package/build/payments/p2pkh.js.map +1 -1
- package/build/payments/p2sh.js.map +1 -1
- package/build/payments/p2tr.d.ts.map +1 -1
- package/build/payments/p2tr.js +2 -3
- package/build/payments/p2tr.js.map +1 -1
- package/build/payments/p2wpkh.js.map +1 -1
- package/build/payments/p2wsh.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 +4 -70
- 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 +26 -40
- package/build/psbt.d.ts.map +1 -1
- package/build/psbt.js +177 -799
- 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 +5 -3
- package/build/types.d.ts.map +1 -1
- package/build/types.js +11 -16
- package/build/types.js.map +1 -1
- package/build/workers/WorkerSigningPool.d.ts +7 -0
- package/build/workers/WorkerSigningPool.d.ts.map +1 -1
- package/build/workers/WorkerSigningPool.js +12 -1
- package/build/workers/WorkerSigningPool.js.map +1 -1
- package/build/workers/WorkerSigningPool.node.d.ts +7 -0
- package/build/workers/WorkerSigningPool.node.d.ts.map +1 -1
- package/build/workers/WorkerSigningPool.node.js +37 -5
- package/build/workers/WorkerSigningPool.node.js.map +1 -1
- package/build/workers/WorkerSigningPool.sequential.d.ts +76 -0
- package/build/workers/WorkerSigningPool.sequential.d.ts.map +1 -0
- package/build/workers/WorkerSigningPool.sequential.js +160 -0
- package/build/workers/WorkerSigningPool.sequential.js.map +1 -0
- package/build/workers/WorkerSigningPool.worklet.d.ts +79 -0
- package/build/workers/WorkerSigningPool.worklet.d.ts.map +1 -0
- package/build/workers/WorkerSigningPool.worklet.js +390 -0
- package/build/workers/WorkerSigningPool.worklet.js.map +1 -0
- package/build/workers/index.browser.d.ts +24 -0
- package/build/workers/index.browser.d.ts.map +1 -0
- package/build/workers/index.browser.js +30 -0
- package/build/workers/index.browser.js.map +1 -0
- package/build/workers/index.d.ts +6 -18
- package/build/workers/index.d.ts.map +1 -1
- package/build/workers/index.js +12 -14
- package/build/workers/index.js.map +1 -1
- package/build/workers/index.node.d.ts +38 -0
- package/build/workers/index.node.d.ts.map +1 -0
- package/build/workers/index.node.js +45 -0
- package/build/workers/index.node.js.map +1 -0
- package/build/workers/index.react-native.d.ts +28 -0
- package/build/workers/index.react-native.d.ts.map +1 -0
- package/build/workers/index.react-native.js +67 -0
- package/build/workers/index.react-native.js.map +1 -0
- package/build/workers/index.shared.d.ts +15 -0
- package/build/workers/index.shared.d.ts.map +1 -0
- package/build/workers/index.shared.js +20 -0
- package/build/workers/index.shared.js.map +1 -0
- package/build/workers/psbt-parallel.d.ts +2 -3
- package/build/workers/psbt-parallel.d.ts.map +1 -1
- package/build/workers/psbt-parallel.js +4 -4
- package/build/workers/psbt-parallel.js.map +1 -1
- package/build/workers/types.d.ts +17 -0
- package/build/workers/types.d.ts.map +1 -1
- package/package.json +46 -8
- package/src/address.ts +41 -18
- package/src/bech32utils.ts +3 -3
- package/src/block.ts +2 -2
- package/src/branded.ts +15 -13
- package/src/ecc/context.ts +30 -133
- package/src/ecc/index.ts +2 -2
- package/src/ecc/types.ts +7 -138
- package/src/env.ts +239 -0
- package/src/index.ts +45 -9
- package/src/io/hex.ts +2 -1
- package/src/io/index.ts +0 -3
- package/src/opcodes.ts +21 -4
- package/src/payments/bip341.ts +3 -3
- package/src/payments/embed.ts +1 -1
- package/src/payments/p2ms.ts +2 -2
- package/src/payments/p2pk.ts +2 -2
- package/src/payments/p2pkh.ts +3 -3
- package/src/payments/p2sh.ts +4 -4
- package/src/payments/p2tr.ts +9 -9
- package/src/payments/p2wpkh.ts +5 -5
- package/src/payments/p2wsh.ts +2 -2
- 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 +4 -86
- package/src/psbt/validation.ts +1 -1
- package/src/psbt.ts +349 -1198
- package/src/script.ts +2 -2
- package/src/transaction.ts +10 -9
- package/src/types.ts +18 -28
- package/src/workers/WorkerSigningPool.node.ts +41 -5
- package/src/workers/WorkerSigningPool.sequential.ts +191 -0
- package/src/workers/WorkerSigningPool.ts +14 -1
- package/src/workers/WorkerSigningPool.worklet.ts +522 -0
- package/src/workers/index.browser.ts +34 -0
- package/src/workers/index.node.ts +50 -0
- package/src/workers/index.react-native.ts +110 -0
- package/src/workers/index.shared.ts +58 -0
- package/src/workers/index.ts +14 -65
- package/src/workers/psbt-parallel.ts +7 -7
- package/src/workers/types.ts +21 -0
- 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/env.spec.ts +418 -0
- 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 +65 -23
- package/test/workers-sequential.spec.ts +669 -0
- package/test/workers-signing.spec.ts +7 -3
- package/test/workers-worklet.spec.ts +500 -0
- package/test/workers.spec.ts +6 -7
- package/typedoc.json +11 -1
- package/vite.config.browser.ts +31 -6
- package/vitest.config.browser.ts +68 -0
- package/browser/ecpair.d.ts +0 -99
- package/browser/io/MemoryPool.d.ts +0 -220
- package/browser/io/MemoryPool.d.ts.map +0 -1
- package/build/io/MemoryPool.d.ts +0 -220
- package/build/io/MemoryPool.d.ts.map +0 -1
- package/build/io/MemoryPool.js +0 -309
- package/build/io/MemoryPool.js.map +0 -1
- package/src/ecpair.d.ts +0 -99
- package/src/io/MemoryPool.ts +0 -343
- package/test/taproot-cache.spec.ts +0 -694
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native entry point for the workers module.
|
|
3
|
+
*
|
|
4
|
+
* Provides the same public API as the browser/Node.js workers module
|
|
5
|
+
* but uses WorkletSigningPool (parallel via react-native-worklets)
|
|
6
|
+
* when available, falling back to SequentialSigningPool (main-thread).
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Type exports (same as main index.ts)
|
|
12
|
+
export {
|
|
13
|
+
SignatureType,
|
|
14
|
+
type SigningTaskMessage,
|
|
15
|
+
type BatchSigningMessage,
|
|
16
|
+
type BatchSigningTask,
|
|
17
|
+
type BatchSigningResultMessage,
|
|
18
|
+
type BatchSigningTaskResult,
|
|
19
|
+
type BatchSigningTaskError,
|
|
20
|
+
type WorkerInitMessage,
|
|
21
|
+
type WorkerShutdownMessage,
|
|
22
|
+
type WorkerMessage,
|
|
23
|
+
type SigningResultMessage,
|
|
24
|
+
type SigningErrorMessage,
|
|
25
|
+
type WorkerReadyMessage,
|
|
26
|
+
type WorkerShutdownAckMessage,
|
|
27
|
+
type WorkerResponse,
|
|
28
|
+
isSigningError,
|
|
29
|
+
isSigningResult,
|
|
30
|
+
isBatchResult,
|
|
31
|
+
isWorkerReady,
|
|
32
|
+
type WorkerEccLib,
|
|
33
|
+
type WorkerPoolConfig,
|
|
34
|
+
type SigningTask,
|
|
35
|
+
type ParallelSignerKeyPair,
|
|
36
|
+
type ParallelSigningResult,
|
|
37
|
+
type SigningPoolLike,
|
|
38
|
+
WorkerState,
|
|
39
|
+
type PooledWorker,
|
|
40
|
+
} from './types.js';
|
|
41
|
+
|
|
42
|
+
// Sequential pool (React Native fallback)
|
|
43
|
+
export { SequentialSigningPool } from './WorkerSigningPool.sequential.js';
|
|
44
|
+
|
|
45
|
+
// Worklet pool (React Native parallel signing)
|
|
46
|
+
export { WorkletSigningPool } from './WorkerSigningPool.worklet.js';
|
|
47
|
+
|
|
48
|
+
// Alias for API compatibility — consumers using `WorkerSigningPool` get the sequential pool
|
|
49
|
+
export { SequentialSigningPool as WorkerSigningPool } from './WorkerSigningPool.sequential.js';
|
|
50
|
+
|
|
51
|
+
// PSBT parallel signing integration (works with any SigningPoolLike)
|
|
52
|
+
export {
|
|
53
|
+
signPsbtParallel,
|
|
54
|
+
prepareSigningTasks,
|
|
55
|
+
applySignaturesToPsbt,
|
|
56
|
+
type ParallelSignOptions,
|
|
57
|
+
type PsbtParallelKeyPair,
|
|
58
|
+
} from './psbt-parallel.js';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Detects the runtime environment.
|
|
62
|
+
*
|
|
63
|
+
* @returns Always 'react-native' in this entry point.
|
|
64
|
+
*/
|
|
65
|
+
export function detectRuntime(): 'node' | 'browser' | 'react-native' | 'unknown' {
|
|
66
|
+
return 'react-native';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Cached result of the worklets availability check.
|
|
71
|
+
* `null` = not yet checked, `true` = available, `false` = unavailable.
|
|
72
|
+
*/
|
|
73
|
+
let workletsAvailable: boolean | null = null;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Creates a signing pool appropriate for the React Native runtime.
|
|
77
|
+
*
|
|
78
|
+
* Tries to use WorkletSigningPool (parallel via react-native-worklets).
|
|
79
|
+
* Falls back to SequentialSigningPool if worklets are not installed.
|
|
80
|
+
*/
|
|
81
|
+
export async function createSigningPool(
|
|
82
|
+
config?: import('./types.js').WorkerPoolConfig,
|
|
83
|
+
): Promise<import('./types.js').SigningPoolLike> {
|
|
84
|
+
// Check worklets availability (cached after first probe)
|
|
85
|
+
if (workletsAvailable === null) {
|
|
86
|
+
try {
|
|
87
|
+
await import('react-native-worklets' as string);
|
|
88
|
+
workletsAvailable = true;
|
|
89
|
+
} catch {
|
|
90
|
+
workletsAvailable = false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (workletsAvailable) {
|
|
95
|
+
try {
|
|
96
|
+
const { WorkletSigningPool } = await import('./WorkerSigningPool.worklet.js');
|
|
97
|
+
const pool = WorkletSigningPool.getInstance(config);
|
|
98
|
+
await pool.initialize();
|
|
99
|
+
return pool;
|
|
100
|
+
} catch {
|
|
101
|
+
// Initialization failed (e.g. eval blocked) — fall through
|
|
102
|
+
workletsAvailable = false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const { SequentialSigningPool } = await import('./WorkerSigningPool.sequential.js');
|
|
107
|
+
const pool = SequentialSigningPool.getInstance(config);
|
|
108
|
+
await pool.initialize();
|
|
109
|
+
return pool;
|
|
110
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared worker module exports.
|
|
3
|
+
*
|
|
4
|
+
* Contains all platform-agnostic exports used by browser, Node.js, and generic
|
|
5
|
+
* entry points. Platform-specific entry points re-export from this module and
|
|
6
|
+
* add their own `detectRuntime` and `createSigningPool` implementations.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Type exports
|
|
12
|
+
export {
|
|
13
|
+
SignatureType,
|
|
14
|
+
type SigningTaskMessage,
|
|
15
|
+
type BatchSigningMessage,
|
|
16
|
+
type BatchSigningTask,
|
|
17
|
+
type BatchSigningResultMessage,
|
|
18
|
+
type BatchSigningTaskResult,
|
|
19
|
+
type BatchSigningTaskError,
|
|
20
|
+
type WorkerInitMessage,
|
|
21
|
+
type WorkerShutdownMessage,
|
|
22
|
+
type WorkerMessage,
|
|
23
|
+
type SigningResultMessage,
|
|
24
|
+
type SigningErrorMessage,
|
|
25
|
+
type WorkerReadyMessage,
|
|
26
|
+
type WorkerShutdownAckMessage,
|
|
27
|
+
type WorkerResponse,
|
|
28
|
+
isSigningError,
|
|
29
|
+
isSigningResult,
|
|
30
|
+
isBatchResult,
|
|
31
|
+
isWorkerReady,
|
|
32
|
+
type WorkerEccLib,
|
|
33
|
+
type WorkerPoolConfig,
|
|
34
|
+
type SigningTask,
|
|
35
|
+
type ParallelSignerKeyPair,
|
|
36
|
+
type ParallelSigningResult,
|
|
37
|
+
type SigningPoolLike,
|
|
38
|
+
WorkerState,
|
|
39
|
+
type PooledWorker,
|
|
40
|
+
} from './types.js';
|
|
41
|
+
|
|
42
|
+
// Browser worker pool
|
|
43
|
+
export { WorkerSigningPool, getSigningPool } from './WorkerSigningPool.js';
|
|
44
|
+
|
|
45
|
+
// Worker code generation (for custom implementations)
|
|
46
|
+
export { generateWorkerCode, createWorkerBlobUrl, revokeWorkerBlobUrl } from './signing-worker.js';
|
|
47
|
+
|
|
48
|
+
// ECC bundle (for embedding in custom workers)
|
|
49
|
+
export { ECC_BUNDLE, ECC_BUNDLE_SIZE } from './ecc-bundle.js';
|
|
50
|
+
|
|
51
|
+
// PSBT parallel signing integration
|
|
52
|
+
export {
|
|
53
|
+
signPsbtParallel,
|
|
54
|
+
prepareSigningTasks,
|
|
55
|
+
applySignaturesToPsbt,
|
|
56
|
+
type ParallelSignOptions,
|
|
57
|
+
type PsbtParallelKeyPair,
|
|
58
|
+
} from './psbt-parallel.js';
|
package/src/workers/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Worker-based parallel signing module.
|
|
2
|
+
* Worker-based parallel signing module (generic entry point).
|
|
3
3
|
*
|
|
4
4
|
* Provides secure parallel signature computation using worker threads.
|
|
5
5
|
* Works in both Node.js (worker_threads) and browsers (Web Workers).
|
|
6
|
+
* Uses runtime detection to select the appropriate pool implementation.
|
|
6
7
|
*
|
|
7
8
|
* @example
|
|
8
9
|
* ```typescript
|
|
@@ -46,63 +47,19 @@
|
|
|
46
47
|
* @packageDocumentation
|
|
47
48
|
*/
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
export {
|
|
51
|
-
SignatureType,
|
|
52
|
-
type SigningTaskMessage,
|
|
53
|
-
type BatchSigningMessage,
|
|
54
|
-
type BatchSigningTask,
|
|
55
|
-
type BatchSigningResultMessage,
|
|
56
|
-
type BatchSigningTaskResult,
|
|
57
|
-
type BatchSigningTaskError,
|
|
58
|
-
type WorkerInitMessage,
|
|
59
|
-
type WorkerShutdownMessage,
|
|
60
|
-
type WorkerMessage,
|
|
61
|
-
type SigningResultMessage,
|
|
62
|
-
type SigningErrorMessage,
|
|
63
|
-
type WorkerReadyMessage,
|
|
64
|
-
type WorkerShutdownAckMessage,
|
|
65
|
-
type WorkerResponse,
|
|
66
|
-
isSigningError,
|
|
67
|
-
isSigningResult,
|
|
68
|
-
isBatchResult,
|
|
69
|
-
isWorkerReady,
|
|
70
|
-
type WorkerEccLib,
|
|
71
|
-
type WorkerPoolConfig,
|
|
72
|
-
type SigningTask,
|
|
73
|
-
type ParallelSignerKeyPair,
|
|
74
|
-
type ParallelSigningResult,
|
|
75
|
-
WorkerState,
|
|
76
|
-
type PooledWorker,
|
|
77
|
-
} from './types.js';
|
|
50
|
+
import type { WorkerPoolConfig, SigningPoolLike } from './types.js';
|
|
78
51
|
|
|
79
|
-
|
|
80
|
-
export { WorkerSigningPool, getSigningPool } from './WorkerSigningPool.js';
|
|
81
|
-
|
|
82
|
-
// Worker code generation (for custom implementations)
|
|
83
|
-
export { generateWorkerCode, createWorkerBlobUrl, revokeWorkerBlobUrl } from './signing-worker.js';
|
|
84
|
-
|
|
85
|
-
// ECC bundle (for embedding in custom workers)
|
|
86
|
-
export { ECC_BUNDLE, ECC_BUNDLE_SIZE } from './ecc-bundle.js';
|
|
87
|
-
|
|
88
|
-
// Node.js specific exports (use dynamic import in browser builds)
|
|
89
|
-
export { type NodeWorkerPoolConfig } from './WorkerSigningPool.node.js';
|
|
90
|
-
|
|
91
|
-
// PSBT parallel signing integration
|
|
92
|
-
export {
|
|
93
|
-
signPsbtParallel,
|
|
94
|
-
prepareSigningTasks,
|
|
95
|
-
applySignaturesToPsbt,
|
|
96
|
-
type ParallelSignOptions,
|
|
97
|
-
type PsbtParallelKeyPair,
|
|
98
|
-
} from './psbt-parallel.js';
|
|
52
|
+
export * from './index.shared.js';
|
|
99
53
|
|
|
100
54
|
/**
|
|
101
55
|
* Detects the runtime environment and returns the appropriate signing pool.
|
|
102
56
|
*
|
|
103
57
|
* @returns 'node' for Node.js, 'browser' for browsers, 'unknown' otherwise
|
|
104
58
|
*/
|
|
105
|
-
export function detectRuntime(): 'node' | 'browser' | 'unknown' {
|
|
59
|
+
export function detectRuntime(): 'node' | 'browser' | 'react-native' | 'unknown' {
|
|
60
|
+
if (typeof navigator !== 'undefined' && (navigator as {product?: string}).product === 'ReactNative') {
|
|
61
|
+
return 'react-native';
|
|
62
|
+
}
|
|
106
63
|
if (typeof process !== 'undefined' && process.versions?.node) {
|
|
107
64
|
return 'node';
|
|
108
65
|
}
|
|
@@ -133,23 +90,10 @@ export function detectRuntime(): 'node' | 'browser' | 'unknown' {
|
|
|
133
90
|
* await pool.shutdown();
|
|
134
91
|
* ```
|
|
135
92
|
*/
|
|
136
|
-
export async function createSigningPool(config?:
|
|
137
|
-
signBatch: (
|
|
138
|
-
tasks: readonly import('./types.js').SigningTask[],
|
|
139
|
-
keyPair: import('./types.js').ParallelSignerKeyPair,
|
|
140
|
-
) => Promise<import('./types.js').ParallelSigningResult>;
|
|
141
|
-
preserveWorkers: () => void;
|
|
142
|
-
releaseWorkers: () => void;
|
|
143
|
-
shutdown: () => Promise<void>;
|
|
144
|
-
workerCount: number;
|
|
145
|
-
idleWorkerCount: number;
|
|
146
|
-
busyWorkerCount: number;
|
|
147
|
-
isPreservingWorkers: boolean;
|
|
148
|
-
}> {
|
|
93
|
+
export async function createSigningPool(config?: WorkerPoolConfig): Promise<SigningPoolLike> {
|
|
149
94
|
const runtime = detectRuntime();
|
|
150
95
|
|
|
151
96
|
if (runtime === 'node') {
|
|
152
|
-
// Dynamic import for Node.js to avoid bundler issues
|
|
153
97
|
const { NodeWorkerSigningPool } = await import('./WorkerSigningPool.node.js');
|
|
154
98
|
const pool = NodeWorkerSigningPool.getInstance(config);
|
|
155
99
|
await pool.initialize();
|
|
@@ -159,6 +103,11 @@ export async function createSigningPool(config?: import('./types.js').WorkerPool
|
|
|
159
103
|
const pool = WorkerSigningPool.getInstance(config);
|
|
160
104
|
await pool.initialize();
|
|
161
105
|
return pool;
|
|
106
|
+
} else if (runtime === 'react-native') {
|
|
107
|
+
const { SequentialSigningPool } = await import('./WorkerSigningPool.sequential.js');
|
|
108
|
+
const pool = SequentialSigningPool.getInstance(config);
|
|
109
|
+
await pool.initialize();
|
|
110
|
+
return pool;
|
|
162
111
|
} else {
|
|
163
112
|
throw new Error('Unsupported runtime for worker signing pool');
|
|
164
113
|
}
|
|
@@ -32,9 +32,8 @@ 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 { ParallelSignerKeyPair, ParallelSigningResult, SigningTask, WorkerPoolConfig, } from './types.js';
|
|
35
|
+
import type { ParallelSignerKeyPair, ParallelSigningResult, SigningPoolLike, SigningTask, WorkerPoolConfig, } from './types.js';
|
|
36
36
|
import { SignatureType } from './types.js';
|
|
37
|
-
import { WorkerSigningPool } from './WorkerSigningPool.js';
|
|
38
37
|
import { toXOnly } from '../pubkey.js';
|
|
39
38
|
import { isTaprootInput, serializeTaprootSignature } from '../psbt/bip371.js';
|
|
40
39
|
import * as bscript from '../script.js';
|
|
@@ -108,16 +107,17 @@ export interface PsbtParallelKeyPair extends ParallelSignerKeyPair {
|
|
|
108
107
|
export async function signPsbtParallel(
|
|
109
108
|
psbt: Psbt,
|
|
110
109
|
keyPair: PsbtParallelKeyPair,
|
|
111
|
-
poolOrConfig?:
|
|
110
|
+
poolOrConfig?: SigningPoolLike | WorkerPoolConfig,
|
|
112
111
|
options: ParallelSignOptions = {},
|
|
113
112
|
): Promise<ParallelSigningResult> {
|
|
114
113
|
// Get or create pool
|
|
115
|
-
let pool:
|
|
114
|
+
let pool: SigningPoolLike;
|
|
116
115
|
let shouldShutdown = false;
|
|
117
116
|
|
|
118
|
-
if (poolOrConfig
|
|
117
|
+
if (poolOrConfig && 'signBatch' in poolOrConfig) {
|
|
119
118
|
pool = poolOrConfig;
|
|
120
119
|
} else {
|
|
120
|
+
const { WorkerSigningPool } = await import('./WorkerSigningPool.js');
|
|
121
121
|
pool = WorkerSigningPool.getInstance(poolOrConfig);
|
|
122
122
|
if (!pool.isPreservingWorkers) {
|
|
123
123
|
shouldShutdown = true;
|
|
@@ -310,12 +310,12 @@ export function applySignaturesToPsbt(
|
|
|
310
310
|
} else {
|
|
311
311
|
// ECDSA signature
|
|
312
312
|
const encodedSig = bscript.signature.encode(
|
|
313
|
-
|
|
313
|
+
sigResult.signature,
|
|
314
314
|
input.sighashType ?? Transaction.SIGHASH_ALL,
|
|
315
315
|
);
|
|
316
316
|
const partialSig = [
|
|
317
317
|
{
|
|
318
|
-
pubkey:
|
|
318
|
+
pubkey: Uint8Array.from(pubkey),
|
|
319
319
|
signature: encodedSig,
|
|
320
320
|
},
|
|
321
321
|
];
|
package/src/workers/types.ts
CHANGED
|
@@ -400,6 +400,27 @@ export const WorkerState = {
|
|
|
400
400
|
|
|
401
401
|
export type WorkerState = (typeof WorkerState)[keyof typeof WorkerState];
|
|
402
402
|
|
|
403
|
+
/**
|
|
404
|
+
* Minimum contract for any signing pool implementation.
|
|
405
|
+
*
|
|
406
|
+
* Implemented by WorkerSigningPool (browser), NodeWorkerSigningPool (Node.js),
|
|
407
|
+
* and SequentialSigningPool (React Native / fallback).
|
|
408
|
+
*/
|
|
409
|
+
export interface SigningPoolLike extends Disposable, AsyncDisposable {
|
|
410
|
+
signBatch(
|
|
411
|
+
tasks: readonly SigningTask[],
|
|
412
|
+
keyPair: ParallelSignerKeyPair,
|
|
413
|
+
): Promise<ParallelSigningResult>;
|
|
414
|
+
preserveWorkers(): void;
|
|
415
|
+
releaseWorkers(): void;
|
|
416
|
+
initialize(): Promise<void>;
|
|
417
|
+
shutdown(): Promise<void>;
|
|
418
|
+
readonly workerCount: number;
|
|
419
|
+
readonly idleWorkerCount: number;
|
|
420
|
+
readonly busyWorkerCount: number;
|
|
421
|
+
readonly isPreservingWorkers: boolean;
|
|
422
|
+
}
|
|
423
|
+
|
|
403
424
|
/**
|
|
404
425
|
* Internal worker wrapper for pool management.
|
|
405
426
|
*/
|
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
|
+
});
|