@btc-vision/bitcoin 7.0.0-alpha.8 → 7.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +22 -0
  2. package/benchmark-compare/BENCHMARK.md +144 -0
  3. package/benchmark-compare/compare.bench.ts +1024 -0
  4. package/benchmark-compare/harness.ts +220 -0
  5. package/benchmark-compare/package.json +18 -0
  6. package/browser/address.d.ts.map +1 -1
  7. package/browser/block.d.ts.map +1 -1
  8. package/browser/chunks/{psbt-parallel-PtTJ19DC.js → psbt-parallel-B-dfm5GZ.js} +2433 -2524
  9. package/browser/crypto-hashes.d.ts +4 -0
  10. package/browser/crypto-hashes.d.ts.map +1 -0
  11. package/browser/crypto-hashes.native.d.ts +4 -0
  12. package/browser/crypto-hashes.native.d.ts.map +1 -0
  13. package/browser/crypto.d.ts.map +1 -1
  14. package/browser/index.d.ts +3 -3
  15. package/browser/index.d.ts.map +1 -1
  16. package/browser/index.js +571 -547
  17. package/browser/io/base58check.d.ts +26 -0
  18. package/browser/io/base58check.d.ts.map +1 -0
  19. package/browser/io/base64.d.ts +8 -0
  20. package/browser/io/base64.d.ts.map +1 -1
  21. package/browser/io/hex.d.ts.map +1 -1
  22. package/browser/io/index.d.ts +2 -1
  23. package/browser/io/index.d.ts.map +1 -1
  24. package/browser/io/utils.d.ts.map +1 -1
  25. package/browser/payments/bip341.d.ts.map +1 -1
  26. package/browser/payments/p2op.d.ts.map +1 -1
  27. package/browser/payments/p2pkh.d.ts.map +1 -1
  28. package/browser/payments/p2sh.d.ts.map +1 -1
  29. package/browser/payments/p2tr.d.ts.map +1 -1
  30. package/browser/payments/p2wpkh.d.ts.map +1 -1
  31. package/browser/psbt/PsbtCache.d.ts.map +1 -1
  32. package/browser/psbt/PsbtSigner.d.ts.map +1 -1
  33. package/browser/psbt/PsbtTransaction.d.ts +2 -2
  34. package/browser/psbt/PsbtTransaction.d.ts.map +1 -1
  35. package/browser/psbt/bip371.d.ts.map +1 -1
  36. package/browser/psbt.d.ts +1 -1
  37. package/browser/psbt.d.ts.map +1 -1
  38. package/browser/react-native-quick-crypto.d.ts +11 -0
  39. package/browser/script.d.ts.map +1 -1
  40. package/browser/transaction.d.ts.map +1 -1
  41. package/browser/workers/WorkerSigningPool.node.d.ts.map +1 -1
  42. package/browser/workers/WorkerSigningPool.sequential.d.ts.map +1 -1
  43. package/browser/workers/index.js +5 -5
  44. package/build/address.d.ts.map +1 -1
  45. package/build/address.js +19 -12
  46. package/build/address.js.map +1 -1
  47. package/build/bech32utils.js.map +1 -1
  48. package/build/bip66.js +4 -4
  49. package/build/bip66.js.map +1 -1
  50. package/build/block.d.ts.map +1 -1
  51. package/build/block.js +9 -2
  52. package/build/block.js.map +1 -1
  53. package/build/crypto-hashes.d.ts +4 -0
  54. package/build/crypto-hashes.d.ts.map +1 -0
  55. package/build/crypto-hashes.js +4 -0
  56. package/build/crypto-hashes.js.map +1 -0
  57. package/build/crypto-hashes.native.d.ts +4 -0
  58. package/build/crypto-hashes.native.d.ts.map +1 -0
  59. package/build/crypto-hashes.native.js +15 -0
  60. package/build/crypto-hashes.native.js.map +1 -0
  61. package/build/crypto.d.ts.map +1 -1
  62. package/build/crypto.js +1 -2
  63. package/build/crypto.js.map +1 -1
  64. package/build/env.js.map +1 -1
  65. package/build/index.d.ts +3 -3
  66. package/build/index.d.ts.map +1 -1
  67. package/build/index.js +1 -1
  68. package/build/index.js.map +1 -1
  69. package/build/io/BinaryReader.js +1 -1
  70. package/build/io/BinaryReader.js.map +1 -1
  71. package/build/io/base58check.d.ts +26 -0
  72. package/build/io/base58check.d.ts.map +1 -0
  73. package/build/io/base58check.js +32 -0
  74. package/build/io/base58check.js.map +1 -0
  75. package/build/io/base64.d.ts +8 -0
  76. package/build/io/base64.d.ts.map +1 -1
  77. package/build/io/base64.js +14 -0
  78. package/build/io/base64.js.map +1 -1
  79. package/build/io/hex.d.ts.map +1 -1
  80. package/build/io/hex.js +3 -2
  81. package/build/io/hex.js.map +1 -1
  82. package/build/io/index.d.ts +2 -1
  83. package/build/io/index.d.ts.map +1 -1
  84. package/build/io/index.js +4 -2
  85. package/build/io/index.js.map +1 -1
  86. package/build/io/utils.d.ts.map +1 -1
  87. package/build/io/utils.js +3 -4
  88. package/build/io/utils.js.map +1 -1
  89. package/build/merkle.js.map +1 -1
  90. package/build/payments/bip341.d.ts.map +1 -1
  91. package/build/payments/bip341.js +4 -3
  92. package/build/payments/bip341.js.map +1 -1
  93. package/build/payments/embed.js.map +1 -1
  94. package/build/payments/p2ms.js.map +1 -1
  95. package/build/payments/p2op.d.ts.map +1 -1
  96. package/build/payments/p2op.js +6 -4
  97. package/build/payments/p2op.js.map +1 -1
  98. package/build/payments/p2pk.js.map +1 -1
  99. package/build/payments/p2pkh.d.ts.map +1 -1
  100. package/build/payments/p2pkh.js +3 -4
  101. package/build/payments/p2pkh.js.map +1 -1
  102. package/build/payments/p2sh.d.ts.map +1 -1
  103. package/build/payments/p2sh.js +3 -4
  104. package/build/payments/p2sh.js.map +1 -1
  105. package/build/payments/p2tr.d.ts.map +1 -1
  106. package/build/payments/p2tr.js +13 -6
  107. package/build/payments/p2tr.js.map +1 -1
  108. package/build/payments/p2wpkh.d.ts.map +1 -1
  109. package/build/payments/p2wpkh.js +7 -5
  110. package/build/payments/p2wpkh.js.map +1 -1
  111. package/build/payments/p2wsh.js.map +1 -1
  112. package/build/psbt/PsbtCache.d.ts.map +1 -1
  113. package/build/psbt/PsbtCache.js +8 -4
  114. package/build/psbt/PsbtCache.js.map +1 -1
  115. package/build/psbt/PsbtFinalizer.js +14 -8
  116. package/build/psbt/PsbtFinalizer.js.map +1 -1
  117. package/build/psbt/PsbtSigner.d.ts.map +1 -1
  118. package/build/psbt/PsbtSigner.js +3 -2
  119. package/build/psbt/PsbtSigner.js.map +1 -1
  120. package/build/psbt/PsbtTransaction.d.ts +2 -2
  121. package/build/psbt/PsbtTransaction.d.ts.map +1 -1
  122. package/build/psbt/PsbtTransaction.js.map +1 -1
  123. package/build/psbt/bip371.d.ts.map +1 -1
  124. package/build/psbt/bip371.js +4 -3
  125. package/build/psbt/bip371.js.map +1 -1
  126. package/build/psbt/utils.js.map +1 -1
  127. package/build/psbt.d.ts +1 -1
  128. package/build/psbt.d.ts.map +1 -1
  129. package/build/psbt.js.map +1 -1
  130. package/build/push_data.js +1 -1
  131. package/build/push_data.js.map +1 -1
  132. package/build/script.d.ts.map +1 -1
  133. package/build/script.js +4 -3
  134. package/build/script.js.map +1 -1
  135. package/build/script_number.js +1 -1
  136. package/build/script_number.js.map +1 -1
  137. package/build/script_signature.js.map +1 -1
  138. package/build/transaction.d.ts.map +1 -1
  139. package/build/transaction.js +2 -1
  140. package/build/transaction.js.map +1 -1
  141. package/build/tsconfig.build.tsbuildinfo +1 -1
  142. package/build/types.js.map +1 -1
  143. package/build/workers/WorkerSigningPool.js.map +1 -1
  144. package/build/workers/WorkerSigningPool.node.d.ts.map +1 -1
  145. package/build/workers/WorkerSigningPool.node.js +25 -3
  146. package/build/workers/WorkerSigningPool.node.js.map +1 -1
  147. package/build/workers/WorkerSigningPool.sequential.d.ts.map +1 -1
  148. package/build/workers/WorkerSigningPool.sequential.js +2 -0
  149. package/build/workers/WorkerSigningPool.sequential.js.map +1 -1
  150. package/build/workers/index.js.map +1 -1
  151. package/build/workers/psbt-parallel.js.map +1 -1
  152. package/package.json +7 -5
  153. package/src/address.ts +18 -13
  154. package/src/bech32utils.ts +3 -3
  155. package/src/bip66.ts +18 -18
  156. package/src/block.ts +8 -3
  157. package/src/crypto-hashes.native.ts +18 -0
  158. package/src/crypto-hashes.ts +3 -0
  159. package/src/crypto.ts +1 -2
  160. package/src/env.ts +10 -8
  161. package/src/index.ts +4 -0
  162. package/src/io/BinaryReader.ts +1 -1
  163. package/src/io/base58check.ts +35 -0
  164. package/src/io/base64.ts +15 -0
  165. package/src/io/hex.ts +3 -2
  166. package/src/io/index.ts +5 -2
  167. package/src/io/utils.ts +6 -7
  168. package/src/merkle.ts +3 -3
  169. package/src/payments/bip341.ts +8 -7
  170. package/src/payments/embed.ts +1 -1
  171. package/src/payments/p2ms.ts +2 -2
  172. package/src/payments/p2op.ts +6 -4
  173. package/src/payments/p2pk.ts +2 -2
  174. package/src/payments/p2pkh.ts +7 -8
  175. package/src/payments/p2sh.ts +8 -9
  176. package/src/payments/p2tr.ts +24 -17
  177. package/src/payments/p2wpkh.ts +9 -7
  178. package/src/payments/p2wsh.ts +3 -3
  179. package/src/psbt/PsbtCache.ts +14 -11
  180. package/src/psbt/PsbtFinalizer.ts +17 -11
  181. package/src/psbt/PsbtSigner.ts +7 -6
  182. package/src/psbt/PsbtTransaction.ts +2 -2
  183. package/src/psbt/bip371.ts +4 -3
  184. package/src/psbt/utils.ts +1 -1
  185. package/src/psbt.ts +11 -9
  186. package/src/push_data.ts +5 -5
  187. package/src/react-native-quick-crypto.d.ts +11 -0
  188. package/src/script.ts +5 -4
  189. package/src/script_number.ts +6 -6
  190. package/src/script_signature.ts +2 -2
  191. package/src/transaction.ts +15 -14
  192. package/src/types.ts +1 -1
  193. package/src/workers/WorkerSigningPool.node.ts +28 -4
  194. package/src/workers/WorkerSigningPool.sequential.ts +2 -1
  195. package/src/workers/WorkerSigningPool.ts +3 -3
  196. package/src/workers/index.ts +1 -1
  197. package/src/workers/psbt-parallel.ts +3 -3
  198. package/test/address.spec.ts +1 -0
  199. package/test/bitcoin.core.spec.ts +9 -2
  200. package/test/browser/psbt.spec.ts +54 -29
  201. package/test/browser/workers-signing.spec.ts +8 -8
  202. package/test/crypto.spec.ts +1 -1
  203. package/test/env.spec.ts +2 -2
  204. package/test/integration/_regtest.ts +2 -2
  205. package/test/integration/blocks.spec.ts +1 -1
  206. package/test/integration/csv.spec.ts +1 -1
  207. package/test/integration/payments.spec.ts +2 -2
  208. package/test/integration/taproot.spec.ts +3 -3
  209. package/test/integration/transactions.spec.ts +6 -5
  210. package/test/psbt.spec.ts +49 -25
  211. package/test/transaction.spec.ts +6 -3
  212. package/test/workers-pool.spec.ts +5 -5
  213. package/test/workers-signing.spec.ts +8 -8
  214. package/test/workers.spec.ts +3 -3
package/README.md CHANGED
@@ -38,6 +38,28 @@ npm install tiny-secp256k1
38
38
 
39
39
  Requires Node.js >= 24.0.0.
40
40
 
41
+ ## Performance
42
+
43
+ Benchmarked against `bitcoinjs-lib` v7.0.1 on Node.js v25.3.0 (Linux x64). The fork column uses the fastest backend for each scenario.
44
+
45
+ | Operation | Inputs | @btc-vision/bitcoin | bitcoinjs-lib | Improvement |
46
+ |-----------|-------:|--------------------:|-------------:|:-----------:|
47
+ | PSBT Creation | 100 | 2.13ms | 305ms | **143x** |
48
+ | PSBT Creation | 500 | 9.90ms | 7,020ms | **709x** |
49
+ | P2WPKH Sign | 100 | 40ms | 349ms | **8.6x** |
50
+ | P2WPKH Sign | 500 | 258ms | 7,710ms | **29.9x** |
51
+ | P2TR Sign | 100 | 22ms | 45ms | **2.1x** |
52
+ | P2TR Sign | 500 | 106ms | 575ms | **5.4x** |
53
+ | E2E P2WPKH | 100 | 44ms | 333ms | **7.6x** |
54
+ | E2E P2TR | 100 | 22ms | 56ms | **2.5x** |
55
+ | Parallel Sign (4 workers) | 500 | 106ms | 6,770ms | **63.6x** |
56
+
57
+ Parallel signing via `worker_threads` / Web Workers is exclusive to this fork. See [benchmark-compare/BENCHMARK.md](benchmark-compare/BENCHMARK.md) for detailed methodology and analysis.
58
+
59
+ ```bash
60
+ cd benchmark-compare && npm install && npm run bench
61
+ ```
62
+
41
63
  ## Quick Start
42
64
 
43
65
  ### Initialize the ECC Library
@@ -0,0 +1,144 @@
1
+ # Benchmark: @btc-vision/bitcoin vs bitcoinjs-lib
2
+
3
+ Comprehensive performance comparison between `@btc-vision/bitcoin` (this fork) and the official `bitcoinjs-lib` v7.0.1.
4
+
5
+ ## Environment
6
+
7
+ | Property | Value |
8
+ |----------|-------|
9
+ | Node.js | v25.3.0 |
10
+ | OS | Linux 6.8.0-90-generic x64 |
11
+ | Libraries | `@btc-vision/bitcoin` 7.0.0-alpha.10, `bitcoinjs-lib` 7.0.1 |
12
+ | ECC backends | `@noble/secp256k1` 3.x (pure JS), `tiny-secp256k1` 2.2.4 (WASM) |
13
+
14
+ ## Methodology
15
+
16
+ - **Warmup**: 5 iterations (discarded) before each measurement
17
+ - **Iterations**: 30 for small inputs, 10 for 250 inputs, 5 for 500 inputs
18
+ - **Metric**: Median of all iterations (resistant to outlier spikes)
19
+ - **Fairness**: Both libraries use identical key material derived from the same seed. Each scenario builds its own PSBTs with the correct types for each library.
20
+ - **Cold-start**: Library initialization measured via separate Node.js subprocess per iteration for true cold-start timing.
21
+ - **ECC backends**: The fork is tested with both Noble (pure JS) and tiny-secp256k1 (WASM). The official library only supports tiny-secp256k1.
22
+
23
+ ## Results
24
+
25
+ ### 1. Library Initialization (cold-start)
26
+
27
+ | Configuration | Median |
28
+ |--------------|--------|
29
+ | Fork + Noble (pure JS) | 38.68ms |
30
+ | Fork + tiny-secp256k1 (WASM) | 6.94ms |
31
+ | Official + tiny-secp256k1 (WASM) | 7.58ms |
32
+
33
+ Both libraries have similar initialization time when using the same WASM backend. The Noble backend is ~32ms slower due to pure-JS module loading, but eliminates the WASM dependency entirely -- critical for React Native and edge runtimes without WASM support.
34
+
35
+ ### 2. PSBT Creation (addInput + addOutput)
36
+
37
+ | Inputs | Fork | Official | Speedup |
38
+ |--------|------|----------|---------|
39
+ | 10 | 0.27ms | 7.51ms | **27x** |
40
+ | 50 | 1.12ms | 85.13ms | **76x** |
41
+ | 100 | 2.13ms | 305.06ms | **143x** |
42
+ | 250 | 5.12ms | 1.79s | **350x** |
43
+ | 500 | 9.90ms | 7.02s | **709x** |
44
+
45
+ The fork's PSBT creation scales linearly (O(n)). The official library exhibits O(n^2) behavior -- each `addInput()` call triggers increasingly expensive internal validation passes over all existing inputs. At 500 inputs, the official library takes over **7 seconds** just to build the PSBT, while the fork completes in under **10 milliseconds**.
46
+
47
+ ### 3. P2WPKH Signing (create + sign, SegWit v0)
48
+
49
+ | Inputs | Fork (Noble) | Fork (tiny) | Official | Best Fork Speedup |
50
+ |--------|-------------|-------------|----------|-------------------|
51
+ | 10 | 7.01ms | 3.96ms | 9.50ms | **2.4x** |
52
+ | 50 | 31.66ms | 19.77ms | 108.04ms | **5.5x** |
53
+ | 100 | 66.03ms | 40.40ms | 349.29ms | **8.6x** |
54
+ | 250 | 174.11ms | 113.19ms | 1.91s | **16.9x** |
55
+ | 500 | 378.83ms | 257.67ms | 7.71s | **29.9x** |
56
+
57
+ This benchmark includes PSBT creation + signing. The fork's advantage compounds: faster PSBT construction plus efficient sighash caching. With tiny-secp256k1, the raw signing speed matches the official library, but the PSBT overhead dominates at scale.
58
+
59
+ ### 4. P2TR Taproot Signing (Schnorr, SegWit v1)
60
+
61
+ | Inputs | Fork (Noble) | Fork (tiny) | Official | Best Fork Speedup |
62
+ |--------|-------------|-------------|----------|-------------------|
63
+ | 10 | 22.41ms | 2.45ms | 3.63ms | **1.5x** |
64
+ | 50 | 107.09ms | 10.57ms | 19.43ms | **1.8x** |
65
+ | 100 | 216.75ms | 21.51ms | 45.38ms | **2.1x** |
66
+ | 250 | 542.47ms | 54.42ms | 174.53ms | **3.2x** |
67
+ | 500 | 1.10s | 106.43ms | 574.64ms | **5.4x** |
68
+
69
+ With tiny-secp256k1, the fork is consistently faster due to its O(n) Taproot sighash caching (the official library recomputes more per input). Noble's pure-JS Schnorr implementation is slower than WASM for raw signing, which shows at small input counts, but the fork's architectural advantages compound at scale.
70
+
71
+ ### 5. End-to-End Lifecycle (100 inputs)
72
+
73
+ Full lifecycle: create PSBT + add inputs/outputs + sign + finalize + extract + serialize.
74
+
75
+ | Type | Fork (Noble) | Fork (tiny) | Official | Best Fork Speedup |
76
+ |------|-------------|-------------|----------|-------------------|
77
+ | P2WPKH | 66.89ms | 44.04ms | 332.84ms | **7.6x** |
78
+ | P2TR | 217.06ms | 22.38ms | 55.72ms | **2.5x** |
79
+
80
+ P2WPKH end-to-end is **7.6x faster** with the fork (tiny-secp256k1 backend). P2TR end-to-end is **2.5x faster** with the fork's tiny-secp256k1 backend. Even though Noble's pure-JS Schnorr signing is slower for P2TR, the fork with the same WASM backend still decisively outperforms the official library due to O(n) PSBT construction and efficient sighash caching.
81
+
82
+ ### 6. Parallel Signing (fork-exclusive)
83
+
84
+ Worker-based parallel signing using `NodeWorkerSigningPool` with 4 `worker_threads`.
85
+
86
+ | Inputs | Fork Sequential | Fork Parallel (4w) | Official Sequential | Speedup vs Seq | Speedup vs Official |
87
+ |--------|----------------|-------------------|--------------------|----|------|
88
+ | 100 | 64.28ms | 21.06ms | 333.17ms | 3.1x | **15.8x** |
89
+ | 500 | 383.83ms | 106.38ms | 6.77s | 3.6x | **63.6x** |
90
+
91
+ Parallel signing is **exclusive to the fork**. At 500 inputs, parallel signing completes in 106ms vs the official library's 6.77s sequential signing -- a **63.6x improvement**.
92
+
93
+ ## The tiny-secp256k1 Reality
94
+
95
+ A common assumption is that `tiny-secp256k1` (WASM) is always faster. The raw signing numbers tell a nuanced story:
96
+
97
+ **Where WASM wins:**
98
+ - Raw Schnorr signing throughput is ~2x faster per operation than Noble's pure JS implementation
99
+ - For P2TR-heavy workloads with few inputs, the per-signature difference matters
100
+
101
+ **Where it doesn't matter:**
102
+ - The PSBT construction overhead completely dominates at scale. The official library's O(n^2) behavior means PSBT creation alone takes 7s at 500 inputs vs 10ms in the fork -- a difference so large that the choice of signing backend is irrelevant
103
+ - P2WPKH signing with Noble is only ~1.5x slower per operation than WASM, and the fork's PSBT improvements more than compensate
104
+
105
+ **Where WASM is a liability:**
106
+ - ~1.2MB WASM binary added to bundle size vs ~12KB for Noble
107
+ - WASM initialization requires WebAssembly support -- unavailable in some React Native runtimes and edge environments
108
+ - Cold-start adds measurable overhead in serverless / Lambda contexts
109
+
110
+ **Bottom line:** The fork with Noble (pure JS) outperforms the official library with WASM for all real-world P2WPKH workloads. For P2TR-heavy workloads, the fork with tiny-secp256k1 is the fastest option and still outperforms the official library. The Noble backend provides portability across Node.js, browsers, and React Native with no WASM dependency.
111
+
112
+ ## Summary
113
+
114
+ | Scenario | Inputs | @btc-vision/bitcoin | bitcoinjs-lib | Improvement |
115
+ |----------|--------|--------------------:|-------------:|:-----------:|
116
+ | PSBT Creation | 100 | 2.13ms | 305ms | **143x** |
117
+ | PSBT Creation | 500 | 9.90ms | 7,020ms | **709x** |
118
+ | P2WPKH Sign | 100 | 40ms | 349ms | **8.6x** |
119
+ | P2WPKH Sign | 500 | 258ms | 7,710ms | **29.9x** |
120
+ | P2TR Sign | 100 | 22ms | 45ms | **2.1x** |
121
+ | P2TR Sign | 500 | 106ms | 575ms | **5.4x** |
122
+ | E2E P2WPKH | 100 | 44ms | 333ms | **7.6x** |
123
+ | E2E P2TR | 100 | 22ms | 56ms | **2.5x** |
124
+ | Parallel (4w) | 500 | 106ms | 6,770ms | **63.6x** |
125
+
126
+ ## How to Reproduce
127
+
128
+ ```bash
129
+ cd benchmark-compare
130
+ npm install
131
+ npm run bench
132
+
133
+ # With GC control (recommended for stable results):
134
+ npm run bench:gc
135
+ ```
136
+
137
+ The benchmark requires the parent project to be built first:
138
+
139
+ ```bash
140
+ cd ..
141
+ npm run build
142
+ cd benchmark-compare
143
+ npm run bench
144
+ ```