@btc-vision/bitcoin 6.5.6 → 7.0.0-alpha.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 (455) hide show
  1. package/HOW_TO_WRITE_GOOD_CODE.md +2436 -0
  2. package/benchmark/psbt-2000-inputs.bench.ts +178 -0
  3. package/benchmark/signing.bench.ts +147 -0
  4. package/browser/address.d.ts +56 -9
  5. package/browser/address.d.ts.map +1 -0
  6. package/browser/bech32utils.d.ts +9 -1
  7. package/browser/bech32utils.d.ts.map +1 -0
  8. package/browser/bip66.d.ts +11 -6
  9. package/browser/bip66.d.ts.map +1 -0
  10. package/browser/block.d.ts +117 -11
  11. package/browser/block.d.ts.map +1 -0
  12. package/browser/branded.d.ts +20 -0
  13. package/browser/branded.d.ts.map +1 -0
  14. package/browser/crypto/crypto.d.ts +1 -0
  15. package/browser/crypto/crypto.d.ts.map +1 -0
  16. package/browser/crypto.d.ts +46 -7
  17. package/browser/crypto.d.ts.map +1 -0
  18. package/browser/ecc/context.d.ts +129 -0
  19. package/browser/ecc/context.d.ts.map +1 -0
  20. package/browser/ecc/index.d.ts +11 -0
  21. package/browser/ecc/index.d.ts.map +1 -0
  22. package/browser/ecc/types.d.ts +128 -0
  23. package/browser/ecc/types.d.ts.map +1 -0
  24. package/browser/ecpair.d.ts +99 -0
  25. package/browser/errors.d.ts +124 -0
  26. package/browser/errors.d.ts.map +1 -0
  27. package/browser/index.d.ts +32 -5
  28. package/browser/index.d.ts.map +1 -0
  29. package/browser/index.js +12482 -101
  30. package/browser/io/BinaryReader.d.ts +276 -0
  31. package/browser/io/BinaryReader.d.ts.map +1 -0
  32. package/browser/io/BinaryWriter.d.ts +391 -0
  33. package/browser/io/BinaryWriter.d.ts.map +1 -0
  34. package/browser/io/MemoryPool.d.ts +220 -0
  35. package/browser/io/MemoryPool.d.ts.map +1 -0
  36. package/browser/io/base64.d.ts +13 -0
  37. package/browser/io/base64.d.ts.map +1 -0
  38. package/browser/io/hex.d.ts +67 -0
  39. package/browser/io/hex.d.ts.map +1 -0
  40. package/browser/io/index.d.ts +17 -0
  41. package/browser/io/index.d.ts.map +1 -0
  42. package/browser/io/utils.d.ts +199 -0
  43. package/browser/io/utils.d.ts.map +1 -0
  44. package/browser/merkle.d.ts +10 -1
  45. package/browser/merkle.d.ts.map +1 -0
  46. package/browser/networks.d.ts +70 -9
  47. package/browser/networks.d.ts.map +1 -0
  48. package/browser/opcodes.d.ts +1 -0
  49. package/browser/opcodes.d.ts.map +1 -0
  50. package/browser/payments/bip341.d.ts +35 -9
  51. package/browser/payments/bip341.d.ts.map +1 -0
  52. package/browser/payments/embed.d.ts +112 -1
  53. package/browser/payments/embed.d.ts.map +1 -0
  54. package/browser/payments/index.d.ts +17 -10
  55. package/browser/payments/index.d.ts.map +1 -0
  56. package/browser/payments/p2ms.d.ts +150 -0
  57. package/browser/payments/p2ms.d.ts.map +1 -0
  58. package/browser/payments/p2op.d.ts +150 -24
  59. package/browser/payments/p2op.d.ts.map +1 -0
  60. package/browser/payments/p2pk.d.ts +154 -1
  61. package/browser/payments/p2pk.d.ts.map +1 -0
  62. package/browser/payments/p2pkh.d.ts +176 -1
  63. package/browser/payments/p2pkh.d.ts.map +1 -0
  64. package/browser/payments/p2sh.d.ts +150 -1
  65. package/browser/payments/p2sh.d.ts.map +1 -0
  66. package/browser/payments/p2tr.d.ts +185 -1
  67. package/browser/payments/p2tr.d.ts.map +1 -0
  68. package/browser/payments/p2wpkh.d.ts +161 -1
  69. package/browser/payments/p2wpkh.d.ts.map +1 -0
  70. package/browser/payments/p2wsh.d.ts +146 -1
  71. package/browser/payments/p2wsh.d.ts.map +1 -0
  72. package/browser/payments/types.d.ts +94 -64
  73. package/browser/payments/types.d.ts.map +1 -0
  74. package/browser/psbt/bip371.d.ts +34 -8
  75. package/browser/psbt/bip371.d.ts.map +1 -0
  76. package/browser/psbt/psbtutils.d.ts +56 -16
  77. package/browser/psbt/psbtutils.d.ts.map +1 -0
  78. package/browser/psbt/types.d.ts +245 -0
  79. package/browser/psbt/types.d.ts.map +1 -0
  80. package/browser/psbt/utils.d.ts +64 -0
  81. package/browser/psbt/utils.d.ts.map +1 -0
  82. package/browser/psbt/validation.d.ts +84 -0
  83. package/browser/psbt/validation.d.ts.map +1 -0
  84. package/browser/psbt.d.ts +82 -118
  85. package/browser/psbt.d.ts.map +1 -0
  86. package/browser/pubkey.d.ts +27 -6
  87. package/browser/pubkey.d.ts.map +1 -0
  88. package/browser/push_data.d.ts +24 -2
  89. package/browser/push_data.d.ts.map +1 -0
  90. package/browser/script.d.ts +33 -8
  91. package/browser/script.d.ts.map +1 -0
  92. package/browser/script_number.d.ts +17 -0
  93. package/browser/script_number.d.ts.map +1 -0
  94. package/browser/script_signature.d.ts +23 -5
  95. package/browser/script_signature.d.ts.map +1 -0
  96. package/browser/transaction.d.ts +160 -18
  97. package/browser/transaction.d.ts.map +1 -0
  98. package/browser/types.d.ts +36 -38
  99. package/browser/types.d.ts.map +1 -0
  100. package/browser/workers/WorkerSigningPool.d.ts +143 -0
  101. package/browser/workers/WorkerSigningPool.d.ts.map +1 -0
  102. package/browser/workers/WorkerSigningPool.node.d.ts +116 -0
  103. package/browser/workers/WorkerSigningPool.node.d.ts.map +1 -0
  104. package/browser/workers/ecc-bundle.d.ts +25 -0
  105. package/browser/workers/ecc-bundle.d.ts.map +1 -0
  106. package/browser/workers/index.d.ts +91 -0
  107. package/browser/workers/index.d.ts.map +1 -0
  108. package/browser/workers/psbt-parallel.d.ts +88 -0
  109. package/browser/workers/psbt-parallel.d.ts.map +1 -0
  110. package/browser/workers/signing-worker.d.ts +37 -0
  111. package/browser/workers/signing-worker.d.ts.map +1 -0
  112. package/browser/workers/types.d.ts +365 -0
  113. package/browser/workers/types.d.ts.map +1 -0
  114. package/build/address.d.ts +57 -10
  115. package/build/address.d.ts.map +1 -0
  116. package/build/address.js +80 -24
  117. package/build/address.js.map +1 -0
  118. package/build/bech32utils.d.ts +9 -1
  119. package/build/bech32utils.d.ts.map +1 -0
  120. package/build/bech32utils.js +10 -2
  121. package/build/bech32utils.js.map +1 -0
  122. package/build/bip66.d.ts +11 -6
  123. package/build/bip66.d.ts.map +1 -0
  124. package/build/bip66.js +32 -3
  125. package/build/bip66.js.map +1 -0
  126. package/build/block.d.ts +117 -11
  127. package/build/block.d.ts.map +1 -0
  128. package/build/block.js +204 -72
  129. package/build/block.js.map +1 -0
  130. package/build/branded.d.ts +20 -0
  131. package/build/branded.d.ts.map +1 -0
  132. package/build/branded.js +7 -0
  133. package/build/branded.js.map +1 -0
  134. package/build/crypto/crypto.d.ts +1 -0
  135. package/build/crypto/crypto.d.ts.map +1 -0
  136. package/build/crypto/crypto.js +1 -0
  137. package/build/crypto/crypto.js.map +1 -0
  138. package/build/crypto.d.ts +46 -7
  139. package/build/crypto.d.ts.map +1 -0
  140. package/build/crypto.js +65 -20
  141. package/build/crypto.js.map +1 -0
  142. package/build/ecc/context.d.ts +135 -0
  143. package/build/ecc/context.d.ts.map +1 -0
  144. package/build/ecc/context.js +232 -0
  145. package/build/ecc/context.js.map +1 -0
  146. package/build/ecc/index.d.ts +11 -0
  147. package/build/ecc/index.d.ts.map +1 -0
  148. package/build/ecc/index.js +11 -0
  149. package/build/ecc/index.js.map +1 -0
  150. package/build/ecc/types.d.ts +134 -0
  151. package/build/ecc/types.d.ts.map +1 -0
  152. package/build/ecc/types.js +8 -0
  153. package/build/ecc/types.js.map +1 -0
  154. package/build/errors.d.ts +124 -0
  155. package/build/errors.d.ts.map +1 -0
  156. package/build/errors.js +155 -0
  157. package/build/errors.js.map +1 -0
  158. package/build/index.d.ts +32 -5
  159. package/build/index.d.ts.map +1 -0
  160. package/build/index.js +26 -3
  161. package/build/index.js.map +1 -0
  162. package/build/io/BinaryReader.d.ts +276 -0
  163. package/build/io/BinaryReader.d.ts.map +1 -0
  164. package/build/io/BinaryReader.js +425 -0
  165. package/build/io/BinaryReader.js.map +1 -0
  166. package/build/io/BinaryWriter.d.ts +391 -0
  167. package/build/io/BinaryWriter.d.ts.map +1 -0
  168. package/build/io/BinaryWriter.js +611 -0
  169. package/build/io/BinaryWriter.js.map +1 -0
  170. package/build/io/MemoryPool.d.ts +220 -0
  171. package/build/io/MemoryPool.d.ts.map +1 -0
  172. package/build/io/MemoryPool.js +309 -0
  173. package/build/io/MemoryPool.js.map +1 -0
  174. package/build/io/base64.d.ts +13 -0
  175. package/build/io/base64.d.ts.map +1 -0
  176. package/build/io/base64.js +20 -0
  177. package/build/io/base64.js.map +1 -0
  178. package/build/io/hex.d.ts +67 -0
  179. package/build/io/hex.d.ts.map +1 -0
  180. package/build/io/hex.js +138 -0
  181. package/build/io/hex.js.map +1 -0
  182. package/build/io/index.d.ts +17 -0
  183. package/build/io/index.d.ts.map +1 -0
  184. package/build/io/index.js +23 -0
  185. package/build/io/index.js.map +1 -0
  186. package/build/io/utils.d.ts +199 -0
  187. package/build/io/utils.d.ts.map +1 -0
  188. package/build/io/utils.js +271 -0
  189. package/build/io/utils.js.map +1 -0
  190. package/build/merkle.d.ts +10 -1
  191. package/build/merkle.d.ts.map +1 -0
  192. package/build/merkle.js +12 -1
  193. package/build/merkle.js.map +1 -0
  194. package/build/networks.d.ts +70 -9
  195. package/build/networks.d.ts.map +1 -0
  196. package/build/networks.js +90 -4
  197. package/build/networks.js.map +1 -0
  198. package/build/opcodes.d.ts +1 -0
  199. package/build/opcodes.d.ts.map +1 -0
  200. package/build/opcodes.js +1 -0
  201. package/build/opcodes.js.map +1 -0
  202. package/build/payments/bip341.d.ts +36 -9
  203. package/build/payments/bip341.d.ts.map +1 -0
  204. package/build/payments/bip341.js +35 -15
  205. package/build/payments/bip341.js.map +1 -0
  206. package/build/payments/embed.d.ts +120 -1
  207. package/build/payments/embed.d.ts.map +1 -0
  208. package/build/payments/embed.js +215 -34
  209. package/build/payments/embed.js.map +1 -0
  210. package/build/payments/index.d.ts +17 -10
  211. package/build/payments/index.d.ts.map +1 -0
  212. package/build/payments/index.js +20 -10
  213. package/build/payments/index.js.map +1 -0
  214. package/build/payments/p2ms.d.ts +159 -1
  215. package/build/payments/p2ms.d.ts.map +1 -0
  216. package/build/payments/p2ms.js +427 -108
  217. package/build/payments/p2ms.js.map +1 -0
  218. package/build/payments/p2op.d.ts +158 -24
  219. package/build/payments/p2op.d.ts.map +1 -0
  220. package/build/payments/p2op.js +379 -93
  221. package/build/payments/p2op.js.map +1 -0
  222. package/build/payments/p2pk.d.ts +162 -1
  223. package/build/payments/p2pk.d.ts.map +1 -0
  224. package/build/payments/p2pk.js +327 -58
  225. package/build/payments/p2pk.js.map +1 -0
  226. package/build/payments/p2pkh.d.ts +185 -1
  227. package/build/payments/p2pkh.d.ts.map +1 -0
  228. package/build/payments/p2pkh.js +467 -114
  229. package/build/payments/p2pkh.js.map +1 -0
  230. package/build/payments/p2sh.d.ts +159 -1
  231. package/build/payments/p2sh.d.ts.map +1 -0
  232. package/build/payments/p2sh.js +500 -152
  233. package/build/payments/p2sh.js.map +1 -0
  234. package/build/payments/p2tr.d.ts +193 -1
  235. package/build/payments/p2tr.d.ts.map +1 -0
  236. package/build/payments/p2tr.js +592 -174
  237. package/build/payments/p2tr.js.map +1 -0
  238. package/build/payments/p2wpkh.d.ts +170 -1
  239. package/build/payments/p2wpkh.d.ts.map +1 -0
  240. package/build/payments/p2wpkh.js +429 -104
  241. package/build/payments/p2wpkh.js.map +1 -0
  242. package/build/payments/p2wsh.d.ts +155 -1
  243. package/build/payments/p2wsh.d.ts.map +1 -0
  244. package/build/payments/p2wsh.js +466 -144
  245. package/build/payments/p2wsh.js.map +1 -0
  246. package/build/payments/types.d.ts +98 -64
  247. package/build/payments/types.d.ts.map +1 -0
  248. package/build/payments/types.js +17 -13
  249. package/build/payments/types.js.map +1 -0
  250. package/build/psbt/bip371.d.ts +35 -9
  251. package/build/psbt/bip371.d.ts.map +1 -0
  252. package/build/psbt/bip371.js +113 -28
  253. package/build/psbt/bip371.js.map +1 -0
  254. package/build/psbt/psbtutils.d.ts +56 -16
  255. package/build/psbt/psbtutils.d.ts.map +1 -0
  256. package/build/psbt/psbtutils.js +71 -16
  257. package/build/psbt/psbtutils.js.map +1 -0
  258. package/build/psbt/types.d.ts +249 -0
  259. package/build/psbt/types.d.ts.map +1 -0
  260. package/build/psbt/types.js +6 -0
  261. package/build/psbt/types.js.map +1 -0
  262. package/build/psbt/utils.d.ts +68 -0
  263. package/build/psbt/utils.d.ts.map +1 -0
  264. package/build/psbt/utils.js +171 -0
  265. package/build/psbt/utils.js.map +1 -0
  266. package/build/psbt/validation.d.ts +88 -0
  267. package/build/psbt/validation.d.ts.map +1 -0
  268. package/build/psbt/validation.js +149 -0
  269. package/build/psbt/validation.js.map +1 -0
  270. package/build/psbt.d.ts +84 -120
  271. package/build/psbt.d.ts.map +1 -0
  272. package/build/psbt.js +411 -412
  273. package/build/psbt.js.map +1 -0
  274. package/build/pubkey.d.ts +27 -6
  275. package/build/pubkey.d.ts.map +1 -0
  276. package/build/pubkey.js +36 -12
  277. package/build/pubkey.js.map +1 -0
  278. package/build/push_data.d.ts +24 -2
  279. package/build/push_data.d.ts.map +1 -0
  280. package/build/push_data.js +44 -12
  281. package/build/push_data.js.map +1 -0
  282. package/build/script.d.ts +33 -8
  283. package/build/script.d.ts.map +1 -0
  284. package/build/script.js +100 -36
  285. package/build/script.js.map +1 -0
  286. package/build/script_number.d.ts +17 -0
  287. package/build/script_number.d.ts.map +1 -0
  288. package/build/script_number.js +19 -0
  289. package/build/script_number.js.map +1 -0
  290. package/build/script_signature.d.ts +23 -5
  291. package/build/script_signature.d.ts.map +1 -0
  292. package/build/script_signature.js +48 -15
  293. package/build/script_signature.js.map +1 -0
  294. package/build/transaction.d.ts +160 -18
  295. package/build/transaction.d.ts.map +1 -0
  296. package/build/transaction.js +443 -176
  297. package/build/transaction.js.map +1 -0
  298. package/build/tsconfig.build.tsbuildinfo +1 -0
  299. package/build/types.d.ts +36 -38
  300. package/build/types.d.ts.map +1 -0
  301. package/build/types.js +175 -57
  302. package/build/types.js.map +1 -0
  303. package/build/workers/WorkerSigningPool.d.ts +174 -0
  304. package/build/workers/WorkerSigningPool.d.ts.map +1 -0
  305. package/build/workers/WorkerSigningPool.js +553 -0
  306. package/build/workers/WorkerSigningPool.js.map +1 -0
  307. package/build/workers/WorkerSigningPool.node.d.ts +124 -0
  308. package/build/workers/WorkerSigningPool.node.d.ts.map +1 -0
  309. package/build/workers/WorkerSigningPool.node.js +753 -0
  310. package/build/workers/WorkerSigningPool.node.js.map +1 -0
  311. package/build/workers/ecc-bundle.d.ts +25 -0
  312. package/build/workers/ecc-bundle.d.ts.map +1 -0
  313. package/build/workers/ecc-bundle.js +25 -0
  314. package/build/workers/ecc-bundle.js.map +1 -0
  315. package/build/workers/index.d.ts +91 -0
  316. package/build/workers/index.d.ts.map +1 -0
  317. package/build/workers/index.js +114 -0
  318. package/build/workers/index.js.map +1 -0
  319. package/build/workers/psbt-parallel.d.ts +117 -0
  320. package/build/workers/psbt-parallel.d.ts.map +1 -0
  321. package/build/workers/psbt-parallel.js +233 -0
  322. package/build/workers/psbt-parallel.js.map +1 -0
  323. package/build/workers/signing-worker.d.ts +37 -0
  324. package/build/workers/signing-worker.d.ts.map +1 -0
  325. package/build/workers/signing-worker.js +350 -0
  326. package/build/workers/signing-worker.js.map +1 -0
  327. package/build/workers/types.d.ts +365 -0
  328. package/build/workers/types.d.ts.map +1 -0
  329. package/build/workers/types.js +60 -0
  330. package/build/workers/types.js.map +1 -0
  331. package/package.json +66 -8
  332. package/scripts/bundle-ecc.ts +111 -0
  333. package/src/address.ts +81 -44
  334. package/src/bech32utils.ts +3 -3
  335. package/src/bip66.ts +34 -24
  336. package/src/block.ts +196 -84
  337. package/src/branded.ts +18 -0
  338. package/src/crypto.ts +64 -26
  339. package/src/ecc/context.ts +277 -0
  340. package/src/ecc/index.ts +14 -0
  341. package/src/ecc/types.ts +154 -0
  342. package/src/ecpair.d.ts +99 -0
  343. package/src/errors.ts +163 -0
  344. package/src/index.ts +113 -9
  345. package/src/io/BinaryReader.ts +461 -0
  346. package/src/io/BinaryWriter.ts +696 -0
  347. package/src/io/MemoryPool.ts +343 -0
  348. package/src/io/base64.ts +20 -0
  349. package/src/io/hex.ts +155 -0
  350. package/src/io/index.ts +41 -0
  351. package/src/io/utils.ts +283 -0
  352. package/src/merkle.ts +14 -9
  353. package/src/networks.ts +9 -9
  354. package/src/payments/bip341.ts +34 -33
  355. package/src/payments/embed.ts +244 -41
  356. package/src/payments/index.ts +12 -10
  357. package/src/payments/p2ms.ts +490 -118
  358. package/src/payments/p2op.ts +431 -133
  359. package/src/payments/p2pk.ts +370 -72
  360. package/src/payments/p2pkh.ts +524 -130
  361. package/src/payments/p2sh.ts +572 -172
  362. package/src/payments/p2tr.ts +686 -194
  363. package/src/payments/p2wpkh.ts +484 -107
  364. package/src/payments/p2wsh.ts +526 -164
  365. package/src/payments/types.ts +80 -66
  366. package/src/psbt/bip371.ts +68 -51
  367. package/src/psbt/psbtutils.ts +39 -40
  368. package/src/psbt/types.ts +331 -0
  369. package/src/psbt/utils.ts +188 -0
  370. package/src/psbt/validation.ts +192 -0
  371. package/src/psbt.ts +566 -809
  372. package/src/pubkey.ts +22 -23
  373. package/src/push_data.ts +18 -16
  374. package/src/script.ts +82 -64
  375. package/src/script_number.ts +6 -6
  376. package/src/script_signature.ts +33 -36
  377. package/src/transaction.ts +458 -238
  378. package/src/types.ts +231 -100
  379. package/src/workers/WorkerSigningPool.node.ts +887 -0
  380. package/src/workers/WorkerSigningPool.ts +670 -0
  381. package/src/workers/ecc-bundle.ts +26 -0
  382. package/src/workers/index.ts +165 -0
  383. package/src/workers/psbt-parallel.ts +332 -0
  384. package/src/workers/signing-worker.ts +353 -0
  385. package/src/workers/types.ts +413 -0
  386. package/test/address.spec.ts +9 -6
  387. package/test/bitcoin.core.spec.ts +16 -17
  388. package/test/block.spec.ts +8 -7
  389. package/test/bufferutils.spec.ts +228 -214
  390. package/test/crypto.spec.ts +19 -11
  391. package/test/fixtures/p2pk.json +0 -8
  392. package/test/fixtures/p2pkh.json +1 -1
  393. package/test/fixtures/p2sh.json +1 -1
  394. package/test/fixtures/script.json +1 -1
  395. package/test/fixtures/transaction.json +2 -2
  396. package/test/integration/_regtest.ts +25 -0
  397. package/test/integration/addresses.spec.ts +4 -3
  398. package/test/integration/bip32.spec.ts +2 -1
  399. package/test/integration/blocks.spec.ts +1 -1
  400. package/test/integration/cltv.spec.ts +18 -16
  401. package/test/integration/csv.spec.ts +37 -64
  402. package/test/integration/payments.spec.ts +5 -3
  403. package/test/integration/taproot.spec.ts +76 -83
  404. package/test/integration/transactions.spec.ts +38 -35
  405. package/test/payments.spec.ts +35 -13
  406. package/test/payments.utils.ts +17 -16
  407. package/test/psbt.spec.ts +111 -100
  408. package/test/script.spec.ts +11 -10
  409. package/test/script_signature.spec.ts +9 -11
  410. package/test/taproot-cache.spec.ts +694 -0
  411. package/test/transaction.spec.ts +32 -40
  412. package/test/types.spec.ts +74 -29
  413. package/test/workers-pool.spec.ts +963 -0
  414. package/test/workers-signing.spec.ts +635 -0
  415. package/test/workers.spec.ts +1390 -0
  416. package/tsconfig.base.json +34 -18
  417. package/tsconfig.browser.json +15 -0
  418. package/tsconfig.build.json +5 -0
  419. package/tsconfig.json +5 -14
  420. package/vite.config.browser.ts +3 -42
  421. package/vitest.config.integration.ts +2 -0
  422. package/browser/bufferutils.d.ts +0 -34
  423. package/browser/chunks/crypto-BhCpKpek.js +0 -2033
  424. package/browser/chunks/payments-B1wlSccx.js +0 -1089
  425. package/browser/chunks/psbt-BCNk7JUx.js +0 -4055
  426. package/browser/chunks/script-DyPItFEl.js +0 -318
  427. package/browser/chunks/transaction-C_UbhMGn.js +0 -432
  428. package/browser/chunks/utils-DNZi-T5W.js +0 -761
  429. package/browser/ecc_lib.d.ts +0 -3
  430. package/browser/hooks/AdvancedSignatureManager.d.ts +0 -16
  431. package/browser/hooks/HookedSigner.d.ts +0 -4
  432. package/browser/hooks/SignatureManager.d.ts +0 -13
  433. package/browser/payments/lazy.d.ts +0 -2
  434. package/browser/typeforce.d.ts +0 -38
  435. package/build/bufferutils.d.ts +0 -34
  436. package/build/bufferutils.js +0 -141
  437. package/build/ecc_lib.d.ts +0 -3
  438. package/build/ecc_lib.js +0 -61
  439. package/build/hooks/AdvancedSignatureManager.d.ts +0 -16
  440. package/build/hooks/AdvancedSignatureManager.js +0 -52
  441. package/build/hooks/HookedSigner.d.ts +0 -4
  442. package/build/hooks/HookedSigner.js +0 -64
  443. package/build/hooks/SignatureManager.d.ts +0 -13
  444. package/build/hooks/SignatureManager.js +0 -45
  445. package/build/payments/lazy.d.ts +0 -2
  446. package/build/payments/lazy.js +0 -28
  447. package/build/tsconfig.tsbuildinfo +0 -1
  448. package/src/bufferutils.ts +0 -188
  449. package/src/ecc_lib.ts +0 -94
  450. package/src/hooks/AdvancedSignatureManager.ts +0 -104
  451. package/src/hooks/HookedSigner.ts +0 -108
  452. package/src/hooks/SignatureManager.ts +0 -84
  453. package/src/payments/lazy.ts +0 -28
  454. package/src/typeforce.d.ts +0 -38
  455. package/tsconfig.webpack.json +0 -18
@@ -1,18 +1,16 @@
1
- import { BufferReader, BufferWriter, reverseBuffer, varuint } from './bufferutils.js';
1
+ import { BinaryReader, BinaryWriter, reverse, varuint, fromHex, toHex, alloc } 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 * as types from './types.js';
5
+ import type { Bytes32, Satoshi, Script } from './types.js';
6
6
 
7
- const { typeforce } = types;
8
-
9
- function varSliceSize(someScript: Buffer): number {
7
+ function varSliceSize(someScript: Uint8Array): number {
10
8
  const length = someScript.length;
11
9
 
12
10
  return varuint.encodingLength(length) + length;
13
11
  }
14
12
 
15
- function vectorSize(someVector: Buffer[]): number {
13
+ function vectorSize(someVector: Uint8Array[]): number {
16
14
  const length = someVector.length;
17
15
 
18
16
  return (
@@ -23,46 +21,57 @@ function vectorSize(someVector: Buffer[]): number {
23
21
  );
24
22
  }
25
23
 
26
- const EMPTY_BUFFER: Buffer = Buffer.allocUnsafe(0);
27
- const EMPTY_WITNESS: Buffer[] = [];
28
- const ZERO: Buffer = Buffer.from(
24
+ const EMPTY_BYTES = new Uint8Array(0) as Script;
25
+ const EMPTY_WITNESS: Uint8Array[] = [];
26
+ const ZERO = fromHex(
29
27
  '0000000000000000000000000000000000000000000000000000000000000000',
30
- 'hex',
31
- );
32
- const ONE: Buffer = Buffer.from(
33
- '0000000000000000000000000000000000000000000000000000000000000001',
34
- 'hex',
35
- );
36
- const VALUE_UINT64_MAX: Buffer = Buffer.from('ffffffffffffffff', 'hex');
37
- const BLANK_OUTPUT: BlankOutput = {
38
- script: EMPTY_BUFFER,
39
- valueBuffer: VALUE_UINT64_MAX,
40
- };
41
-
42
- function isOutput(out: Output | BlankOutput): out is Output {
43
- return 'value' in out;
44
- }
28
+ ) as Bytes32;
29
+ const ONE = fromHex('0000000000000000000000000000000000000000000000000000000000000001') as Bytes32;
45
30
 
46
- export interface Output {
47
- script: Buffer;
48
- value: number;
31
+ /** Maximum value for SIGHASH_SINGLE blank outputs (0xFFFFFFFFFFFFFFFF) */
32
+ const BLANK_OUTPUT_VALUE = 0xffffffffffffffffn as Satoshi;
33
+
34
+ /**
35
+ * Cache for Taproot sighash intermediate values.
36
+ * These are identical for all inputs with SIGHASH_ALL, so compute once and reuse.
37
+ */
38
+ export interface TaprootHashCache {
39
+ readonly hashPrevouts: Bytes32;
40
+ readonly hashAmounts: Bytes32;
41
+ readonly hashScriptPubKeys: Bytes32;
42
+ readonly hashSequences: Bytes32;
43
+ readonly hashOutputs: Bytes32;
49
44
  }
50
45
 
51
- interface BlankOutput {
52
- script: Buffer;
53
- valueBuffer: Buffer;
46
+ export interface Output {
47
+ readonly script: Script;
48
+ readonly value: Satoshi;
54
49
  }
55
50
 
56
51
  export interface Input {
57
- hash: Buffer;
58
- index: number;
59
- script: Buffer;
52
+ readonly hash: Bytes32;
53
+ readonly index: number;
54
+ script: Script;
60
55
  sequence: number;
61
- witness: Buffer[];
56
+ witness: Uint8Array[];
62
57
  }
63
58
 
64
59
  /**
65
60
  * Represents a Bitcoin transaction.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * import { Transaction, fromHex } from '@btc-vision/bitcoin';
65
+ *
66
+ * // Parse a transaction from hex
67
+ * const tx = Transaction.fromHex('0100000001...');
68
+ *
69
+ * // Create a new transaction
70
+ * const newTx = new Transaction();
71
+ * newTx.version = 2;
72
+ * newTx.addInput(prevTxHash, 0);
73
+ * newTx.addOutput(scriptPubKey, 50000n);
74
+ * ```
66
75
  */
67
76
  export class Transaction {
68
77
  static readonly DEFAULT_SEQUENCE = 0xffffffff;
@@ -85,10 +94,17 @@ export class Transaction {
85
94
  ins: Input[] = [];
86
95
  outs: Output[] = [];
87
96
 
88
- static fromBuffer(buffer: Buffer, _NO_STRICT?: boolean): Transaction {
89
- const bufferReader = new BufferReader(buffer);
97
+ /**
98
+ * Parse a transaction from a Uint8Array buffer.
99
+ *
100
+ * @param buffer - The raw transaction bytes
101
+ * @param _NO_STRICT - If true, allow extra data after transaction
102
+ * @returns Parsed Transaction instance
103
+ */
104
+ static fromBuffer(buffer: Uint8Array, _NO_STRICT?: boolean): Transaction {
105
+ const bufferReader = new BinaryReader(buffer);
90
106
  const tx = new Transaction();
91
- tx.version = bufferReader.readInt32();
107
+ tx.version = bufferReader.readInt32LE();
92
108
 
93
109
  const marker = bufferReader.readUInt8();
94
110
  const flag = bufferReader.readUInt8();
@@ -105,10 +121,10 @@ export class Transaction {
105
121
 
106
122
  const vinLen = bufferReader.readVarInt();
107
123
  for (let i = 0; i < vinLen; ++i) {
108
- const hash = bufferReader.readSlice(32);
109
- const index = bufferReader.readUInt32();
110
- const script = bufferReader.readVarSlice();
111
- const sequence = bufferReader.readUInt32();
124
+ const hash = bufferReader.readBytes(32) as Bytes32;
125
+ const index = bufferReader.readUInt32LE();
126
+ const script = bufferReader.readVarBytes() as Script;
127
+ const sequence = bufferReader.readUInt32LE();
112
128
 
113
129
  tx.ins.push({
114
130
  hash: hash,
@@ -122,21 +138,21 @@ export class Transaction {
122
138
  const voutLen = bufferReader.readVarInt();
123
139
  for (let i = 0; i < voutLen; ++i) {
124
140
  tx.outs.push({
125
- value: bufferReader.readUInt64(),
126
- script: bufferReader.readVarSlice(),
141
+ value: bufferReader.readUInt64LE() as Satoshi,
142
+ script: bufferReader.readVarBytes() as Script,
127
143
  });
128
144
  }
129
145
 
130
146
  if (hasWitnesses) {
131
147
  for (let i = 0; i < vinLen; ++i) {
132
- tx.ins[i].witness = bufferReader.readVector();
148
+ tx.ins[i]!.witness = bufferReader.readVector();
133
149
  }
134
150
 
135
151
  // was this pointless?
136
152
  if (!tx.hasWitnesses()) throw new Error('Transaction has superfluous witness data');
137
153
  }
138
154
 
139
- tx.locktime = bufferReader.readUInt32();
155
+ tx.locktime = bufferReader.readUInt32LE();
140
156
 
141
157
  if (_NO_STRICT) return tx;
142
158
  if (bufferReader.offset !== buffer.length)
@@ -145,34 +161,61 @@ export class Transaction {
145
161
  return tx;
146
162
  }
147
163
 
164
+ /**
165
+ * Parse a transaction from a hex string.
166
+ *
167
+ * @param hex - The transaction as a hex string
168
+ * @returns Parsed Transaction instance
169
+ */
148
170
  static fromHex(hex: string): Transaction {
149
- return Transaction.fromBuffer(Buffer.from(hex, 'hex'), false);
171
+ return Transaction.fromBuffer(fromHex(hex), false);
150
172
  }
151
173
 
152
- static isCoinbaseHash(buffer: Buffer): boolean {
153
- typeforce(types.Hash256bit, buffer);
174
+ /**
175
+ * Check if a hash is a coinbase hash (all zeros).
176
+ *
177
+ * @param hash - 32-byte hash to check
178
+ * @returns true if hash is all zeros (coinbase)
179
+ */
180
+ static isCoinbaseHash(hash: Bytes32): boolean {
181
+ if (hash.length !== 32) {
182
+ throw new TypeError('Expected 32-byte hash');
183
+ }
154
184
  for (let i = 0; i < 32; ++i) {
155
- if (buffer[i] !== 0) return false;
185
+ if (hash[i] !== 0) return false;
156
186
  }
157
187
  return true;
158
188
  }
159
189
 
160
190
  isCoinbase(): boolean {
161
- return this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash);
191
+ return this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0]!.hash);
162
192
  }
163
193
 
164
- addInput(hash: Buffer, index: number, sequence?: number, scriptSig?: Buffer): number {
165
- typeforce(
166
- types.tuple(
167
- types.Hash256bit,
168
- types.UInt32,
169
- types.maybe(types.UInt32),
170
- types.maybe(types.Buffer),
171
- ),
172
- [hash, index, sequence, scriptSig],
173
- );
194
+ /**
195
+ * Add an input to this transaction.
196
+ *
197
+ * @param hash - 32-byte hash of the previous transaction
198
+ * @param index - Output index in the previous transaction
199
+ * @param sequence - Sequence number (defaults to 0xffffffff)
200
+ * @param scriptSig - Input script (defaults to empty)
201
+ * @returns The index of the newly added input
202
+ */
203
+ addInput(hash: Bytes32, index: number, sequence?: number, scriptSig?: Script): number {
204
+ if (hash.length !== 32) {
205
+ throw new TypeError('Expected 32-byte hash');
206
+ }
207
+ if (!Number.isInteger(index) || index < 0 || index > 0xffffffff) {
208
+ throw new TypeError('Expected unsigned 32-bit integer for index');
209
+ }
210
+ if (
211
+ sequence !== undefined &&
212
+ sequence !== null &&
213
+ (!Number.isInteger(sequence) || sequence < 0 || sequence > 0xffffffff)
214
+ ) {
215
+ throw new TypeError('Expected unsigned 32-bit integer for sequence');
216
+ }
174
217
 
175
- if (types.Null(sequence)) {
218
+ if (sequence === undefined || sequence === null) {
176
219
  sequence = Transaction.DEFAULT_SEQUENCE;
177
220
  }
178
221
 
@@ -181,15 +224,27 @@ export class Transaction {
181
224
  this.ins.push({
182
225
  hash,
183
226
  index,
184
- script: scriptSig || EMPTY_BUFFER,
185
- sequence: sequence as number,
227
+ script: scriptSig || EMPTY_BYTES,
228
+ sequence: sequence,
186
229
  witness: EMPTY_WITNESS,
187
230
  }) - 1
188
231
  );
189
232
  }
190
233
 
191
- addOutput(scriptPubKey: Buffer, value: number): number {
192
- typeforce(types.tuple(types.Buffer, types.Satoshi), [scriptPubKey, value]);
234
+ /**
235
+ * Add an output to this transaction.
236
+ *
237
+ * @param scriptPubKey - Output script (locking script)
238
+ * @param value - Output value in satoshis (bigint)
239
+ * @returns The index of the newly added output
240
+ */
241
+ addOutput(scriptPubKey: Script, value: Satoshi): number {
242
+ if (!(scriptPubKey instanceof Uint8Array)) {
243
+ throw new TypeError('Expected Uint8Array for scriptPubKey');
244
+ }
245
+ if (typeof value !== 'bigint' || value < 0n || value > 0x7fffffffffffffffn) {
246
+ throw new TypeError('Expected bigint satoshi value (0 to 2^63-1)');
247
+ }
193
248
 
194
249
  // Add the output and return the output's index
195
250
  return (
@@ -269,13 +324,22 @@ export class Transaction {
269
324
  * This method copies the transaction, makes the necessary changes based on the
270
325
  * hashType, and then hashes the result.
271
326
  * This hash can then be used to sign the provided transaction input.
327
+ *
328
+ * @param inIndex - Index of the input being signed
329
+ * @param prevOutScript - The script of the output being spent
330
+ * @param hashType - Signature hash type
331
+ * @returns 32-byte hash for signing
272
332
  */
273
- hashForSignature(inIndex: number, prevOutScript: Buffer, hashType: number): Buffer {
274
- typeforce(types.tuple(types.UInt32, types.Buffer, /* types.UInt8 */ types.Number), [
275
- inIndex,
276
- prevOutScript,
277
- hashType,
278
- ]);
333
+ hashForSignature(inIndex: number, prevOutScript: Script, hashType: number): Bytes32 {
334
+ if (!Number.isInteger(inIndex) || inIndex < 0) {
335
+ throw new TypeError('Expected non-negative integer for inIndex');
336
+ }
337
+ if (!(prevOutScript instanceof Uint8Array)) {
338
+ throw new TypeError('Expected Uint8Array for prevOutScript');
339
+ }
340
+ if (!Number.isInteger(hashType)) {
341
+ throw new TypeError('Expected integer for hashType');
342
+ }
279
343
 
280
344
  // https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L29
281
345
  if (inIndex >= this.ins.length) return ONE;
@@ -310,9 +374,12 @@ export class Transaction {
310
374
  // truncate outputs after
311
375
  txTmp.outs.length = inIndex + 1;
312
376
 
313
- // "blank" outputs before
377
+ // "blank" outputs before (value = 0xFFFFFFFFFFFFFFFF, empty script)
314
378
  for (let i = 0; i < inIndex; i++) {
315
- (txTmp.outs as (Output | BlankOutput)[])[i] = BLANK_OUTPUT;
379
+ txTmp.outs[i] = {
380
+ script: EMPTY_BYTES,
381
+ value: BLANK_OUTPUT_VALUE,
382
+ };
316
383
  }
317
384
 
318
385
  // ignore sequence numbers (except at inIndex)
@@ -325,44 +392,63 @@ export class Transaction {
325
392
 
326
393
  // SIGHASH_ANYONECANPAY: ignore inputs entirely?
327
394
  if (hashType & Transaction.SIGHASH_ANYONECANPAY) {
328
- txTmp.ins = [txTmp.ins[inIndex]];
329
- txTmp.ins[0].script = ourScript;
395
+ txTmp.ins = [txTmp.ins[inIndex]!];
396
+ txTmp.ins[0]!.script = ourScript;
330
397
 
331
398
  // SIGHASH_ALL: only ignore input scripts
332
399
  } else {
333
400
  // "blank" others input scripts
334
401
  txTmp.ins.forEach((input) => {
335
- input.script = EMPTY_BUFFER;
402
+ input.script = EMPTY_BYTES;
336
403
  });
337
- txTmp.ins[inIndex].script = ourScript;
404
+ txTmp.ins[inIndex]!.script = ourScript;
338
405
  }
339
406
 
340
407
  // serialize and hash
341
- const buffer: Buffer = Buffer.allocUnsafe(txTmp.byteLength(false) + 4);
342
- buffer.writeInt32LE(hashType, buffer.length - 4);
343
- txTmp.__toBuffer(buffer, 0, false);
408
+ const buffer: Uint8Array = alloc(txTmp.byteLength(false) + 4);
409
+ const writer = new BinaryWriter(buffer, txTmp.byteLength(false));
410
+ writer.writeInt32LE(hashType);
411
+ txTmp.#toBuffer(buffer, 0, false);
344
412
 
345
- return bcrypto.hash256(buffer);
413
+ return bcrypto.hash256(buffer) as Bytes32;
346
414
  }
347
415
 
416
+ /**
417
+ * Hash transaction for signing a Taproot (witness v1) input.
418
+ *
419
+ * @param inIndex - Index of the input being signed
420
+ * @param prevOutScripts - Scripts of all inputs being spent
421
+ * @param values - Values of all inputs being spent (bigint satoshis)
422
+ * @param hashType - Signature hash type
423
+ * @param leafHash - Optional leaf hash for script path spending
424
+ * @param annex - Optional annex data
425
+ * @returns 32-byte hash for signing
426
+ */
348
427
  hashForWitnessV1(
349
428
  inIndex: number,
350
- prevOutScripts: Buffer[],
351
- values: number[],
429
+ prevOutScripts: readonly Script[],
430
+ values: readonly Satoshi[],
352
431
  hashType: number,
353
- leafHash?: Buffer,
354
- annex?: Buffer,
355
- ): Buffer {
432
+ leafHash?: Bytes32,
433
+ annex?: Uint8Array,
434
+ taprootCache?: TaprootHashCache,
435
+ ): Bytes32 {
356
436
  // https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
357
- typeforce(
358
- types.tuple(
359
- types.UInt32,
360
- typeforce.arrayOf(types.Buffer),
361
- typeforce.arrayOf(types.Satoshi),
362
- types.UInt32,
363
- ),
364
- [inIndex, prevOutScripts, values, hashType],
365
- );
437
+ if (!Number.isInteger(inIndex) || inIndex < 0 || inIndex > 0xffffffff) {
438
+ throw new TypeError('Expected unsigned 32-bit integer for inIndex');
439
+ }
440
+ if (
441
+ !Array.isArray(prevOutScripts) ||
442
+ !prevOutScripts.every((s) => s instanceof Uint8Array)
443
+ ) {
444
+ throw new TypeError('Expected array of Uint8Array for prevOutScripts');
445
+ }
446
+ if (!Array.isArray(values) || !values.every((v) => typeof v === 'bigint')) {
447
+ throw new TypeError('Expected array of bigint for values');
448
+ }
449
+ if (!Number.isInteger(hashType) || hashType < 0 || hashType > 0xffffffff) {
450
+ throw new TypeError('Expected unsigned 32-bit integer for hashType');
451
+ }
366
452
 
367
453
  if (values.length !== this.ins.length || prevOutScripts.length !== this.ins.length) {
368
454
  throw new Error('Must supply prevout script and value for all inputs');
@@ -379,56 +465,68 @@ export class Transaction {
379
465
  const isNone = outputType === Transaction.SIGHASH_NONE;
380
466
  const isSingle = outputType === Transaction.SIGHASH_SINGLE;
381
467
 
382
- let hashPrevouts = EMPTY_BUFFER;
383
- let hashAmounts = EMPTY_BUFFER;
384
- let hashScriptPubKeys = EMPTY_BUFFER;
385
- let hashSequences = EMPTY_BUFFER;
386
- let hashOutputs = EMPTY_BUFFER;
468
+ let hashPrevouts: Uint8Array = EMPTY_BYTES;
469
+ let hashAmounts: Uint8Array = EMPTY_BYTES;
470
+ let hashScriptPubKeys: Uint8Array = EMPTY_BYTES;
471
+ let hashSequences: Uint8Array = EMPTY_BYTES;
472
+ let hashOutputs: Uint8Array = EMPTY_BYTES;
387
473
 
474
+ // Use cache if provided (for SIGHASH_ALL, these are identical for all inputs)
388
475
  if (!isAnyoneCanPay) {
389
- let bufferWriter = BufferWriter.withCapacity(36 * this.ins.length);
390
- this.ins.forEach((txIn) => {
391
- bufferWriter.writeSlice(txIn.hash);
392
- bufferWriter.writeUInt32(txIn.index);
393
- });
394
- hashPrevouts = bcrypto.sha256(bufferWriter.end());
395
-
396
- bufferWriter = BufferWriter.withCapacity(8 * this.ins.length);
397
- values.forEach((value) => bufferWriter.writeUInt64(value));
398
- hashAmounts = bcrypto.sha256(bufferWriter.end());
399
-
400
- bufferWriter = BufferWriter.withCapacity(
401
- prevOutScripts.map(varSliceSize).reduce((a, b) => a + b),
402
- );
403
- prevOutScripts.forEach((prevOutScript) => bufferWriter.writeVarSlice(prevOutScript));
404
- hashScriptPubKeys = bcrypto.sha256(bufferWriter.end());
405
-
406
- bufferWriter = BufferWriter.withCapacity(4 * this.ins.length);
407
- this.ins.forEach((txIn) => bufferWriter.writeUInt32(txIn.sequence));
408
- hashSequences = bcrypto.sha256(bufferWriter.end());
476
+ if (taprootCache) {
477
+ hashPrevouts = taprootCache.hashPrevouts;
478
+ hashAmounts = taprootCache.hashAmounts;
479
+ hashScriptPubKeys = taprootCache.hashScriptPubKeys;
480
+ hashSequences = taprootCache.hashSequences;
481
+ } else {
482
+ let bufferWriter = new BinaryWriter(36 * this.ins.length);
483
+ this.ins.forEach((txIn) => {
484
+ bufferWriter.writeBytes(txIn.hash);
485
+ bufferWriter.writeUInt32LE(txIn.index);
486
+ });
487
+ hashPrevouts = bcrypto.sha256(bufferWriter.finish());
488
+
489
+ bufferWriter = new BinaryWriter(8 * this.ins.length);
490
+ values.forEach((value) => bufferWriter.writeUInt64LE(value));
491
+ hashAmounts = bcrypto.sha256(bufferWriter.finish());
492
+
493
+ bufferWriter = new BinaryWriter(
494
+ prevOutScripts.map(varSliceSize).reduce((a, b) => a + b),
495
+ );
496
+ prevOutScripts.forEach((prevOutScript) => bufferWriter.writeVarBytes(prevOutScript));
497
+ hashScriptPubKeys = bcrypto.sha256(bufferWriter.finish());
498
+
499
+ bufferWriter = new BinaryWriter(4 * this.ins.length);
500
+ this.ins.forEach((txIn) => bufferWriter.writeUInt32LE(txIn.sequence));
501
+ hashSequences = bcrypto.sha256(bufferWriter.finish());
502
+ }
409
503
  }
410
504
 
411
505
  if (!(isNone || isSingle)) {
412
- if (!this.outs.length)
413
- throw new Error('Add outputs to the transaction before signing.');
414
- const txOutsSize = this.outs
415
- .map((output) => 8 + varSliceSize(output.script))
416
- .reduce((a, b) => a + b);
417
- const bufferWriter = BufferWriter.withCapacity(txOutsSize);
418
-
419
- this.outs.forEach((out) => {
420
- bufferWriter.writeUInt64(out.value);
421
- bufferWriter.writeVarSlice(out.script);
422
- });
423
-
424
- hashOutputs = bcrypto.sha256(bufferWriter.end());
506
+ if (taprootCache) {
507
+ hashOutputs = taprootCache.hashOutputs;
508
+ } else {
509
+ if (!this.outs.length)
510
+ throw new Error('Add outputs to the transaction before signing.');
511
+ const txOutsSize = this.outs
512
+ .map((output) => 8 + varSliceSize(output.script))
513
+ .reduce((a, b) => a + b);
514
+ const bufferWriter = new BinaryWriter(txOutsSize);
515
+
516
+ this.outs.forEach((out) => {
517
+ bufferWriter.writeUInt64LE(out.value);
518
+ bufferWriter.writeVarBytes(out.script);
519
+ });
520
+
521
+ hashOutputs = bcrypto.sha256(bufferWriter.finish());
522
+ }
425
523
  } else if (isSingle && inIndex < this.outs.length) {
426
- const output = this.outs[inIndex];
524
+ const output = this.outs[inIndex]!;
427
525
 
428
- const bufferWriter = BufferWriter.withCapacity(8 + varSliceSize(output.script));
429
- bufferWriter.writeUInt64(output.value);
430
- bufferWriter.writeVarSlice(output.script);
431
- hashOutputs = bcrypto.sha256(bufferWriter.end());
526
+ const bufferWriter = new BinaryWriter(8 + varSliceSize(output.script));
527
+ bufferWriter.writeUInt64LE(output.value);
528
+ bufferWriter.writeVarBytes(output.script);
529
+ hashOutputs = bcrypto.sha256(bufferWriter.finish());
432
530
  }
433
531
 
434
532
  const spendType = (leafHash ? 2 : 0) + (annex ? 1 : 0);
@@ -443,82 +541,156 @@ export class Transaction {
443
541
  (isNone ? 32 : 0) +
444
542
  (annex ? 32 : 0) +
445
543
  (leafHash ? 37 : 0);
446
- const sigMsgWriter = BufferWriter.withCapacity(sigMsgSize);
544
+ const sigMsgWriter = new BinaryWriter(sigMsgSize);
447
545
 
448
546
  sigMsgWriter.writeUInt8(hashType);
449
547
  // Transaction
450
- sigMsgWriter.writeInt32(this.version);
451
- sigMsgWriter.writeUInt32(this.locktime);
452
- sigMsgWriter.writeSlice(hashPrevouts);
453
- sigMsgWriter.writeSlice(hashAmounts);
454
- sigMsgWriter.writeSlice(hashScriptPubKeys);
455
- sigMsgWriter.writeSlice(hashSequences);
548
+ sigMsgWriter.writeInt32LE(this.version);
549
+ sigMsgWriter.writeUInt32LE(this.locktime);
550
+ sigMsgWriter.writeBytes(hashPrevouts);
551
+ sigMsgWriter.writeBytes(hashAmounts);
552
+ sigMsgWriter.writeBytes(hashScriptPubKeys);
553
+ sigMsgWriter.writeBytes(hashSequences);
456
554
  if (!(isNone || isSingle)) {
457
- sigMsgWriter.writeSlice(hashOutputs);
555
+ sigMsgWriter.writeBytes(hashOutputs);
458
556
  }
459
557
  // Input
460
558
  sigMsgWriter.writeUInt8(spendType);
461
559
  if (isAnyoneCanPay) {
462
- const input = this.ins[inIndex];
463
- sigMsgWriter.writeSlice(input.hash);
464
- sigMsgWriter.writeUInt32(input.index);
465
- sigMsgWriter.writeUInt64(values[inIndex]);
466
- sigMsgWriter.writeVarSlice(prevOutScripts[inIndex]);
467
- sigMsgWriter.writeUInt32(input.sequence);
560
+ const input = this.ins[inIndex]!;
561
+ sigMsgWriter.writeBytes(input.hash);
562
+ sigMsgWriter.writeUInt32LE(input.index);
563
+ sigMsgWriter.writeUInt64LE(values[inIndex]!);
564
+ sigMsgWriter.writeVarBytes(prevOutScripts[inIndex]!);
565
+ sigMsgWriter.writeUInt32LE(input.sequence);
468
566
  } else {
469
- sigMsgWriter.writeUInt32(inIndex);
567
+ sigMsgWriter.writeUInt32LE(inIndex);
470
568
  }
471
569
  if (annex) {
472
- const bufferWriter = BufferWriter.withCapacity(varSliceSize(annex));
473
- bufferWriter.writeVarSlice(annex);
474
- sigMsgWriter.writeSlice(bcrypto.sha256(bufferWriter.end()));
570
+ const bufferWriter = new BinaryWriter(varSliceSize(annex));
571
+ bufferWriter.writeVarBytes(annex);
572
+ sigMsgWriter.writeBytes(bcrypto.sha256(bufferWriter.finish()));
475
573
  }
476
574
  // Output
477
575
  if (isSingle) {
478
- sigMsgWriter.writeSlice(hashOutputs);
576
+ sigMsgWriter.writeBytes(hashOutputs);
479
577
  }
480
578
  // BIP342 extension
481
579
  if (leafHash) {
482
- sigMsgWriter.writeSlice(leafHash);
580
+ sigMsgWriter.writeBytes(leafHash);
483
581
  sigMsgWriter.writeUInt8(0);
484
- sigMsgWriter.writeUInt32(0xffffffff);
582
+ sigMsgWriter.writeUInt32LE(0xffffffff);
485
583
  }
486
584
 
487
585
  // Extra zero byte because:
488
586
  // https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-19
489
- return bcrypto.taggedHash(
490
- 'TapSighash',
491
- Buffer.concat([Buffer.from([0x00]), sigMsgWriter.end()]),
492
- );
587
+ const prefix = new Uint8Array([0x00]);
588
+ const sigMsg = sigMsgWriter.finish();
589
+ const combined = new Uint8Array(1 + sigMsg.length);
590
+ combined.set(prefix);
591
+ combined.set(sigMsg, 1);
592
+ return bcrypto.taggedHash('TapSighash', combined) as Bytes32;
593
+ }
594
+
595
+ /**
596
+ * Pre-compute intermediate hashes for Taproot signing.
597
+ * Call this once before signing multiple inputs to avoid O(n^2) performance.
598
+ *
599
+ * @param prevOutScripts - Array of previous output scripts for all inputs
600
+ * @param values - Array of previous output values for all inputs
601
+ * @returns Cache object to pass to hashForWitnessV1
602
+ */
603
+ getTaprootHashCache(prevOutScripts: readonly Script[], values: readonly Satoshi[]): TaprootHashCache {
604
+ // hashPrevouts
605
+ let bufferWriter = new BinaryWriter(36 * this.ins.length);
606
+ for (const txIn of this.ins) {
607
+ bufferWriter.writeBytes(txIn.hash);
608
+ bufferWriter.writeUInt32LE(txIn.index);
609
+ }
610
+ const hashPrevouts = bcrypto.sha256(bufferWriter.finish());
611
+
612
+ // hashAmounts
613
+ bufferWriter = new BinaryWriter(8 * values.length);
614
+ for (const value of values) {
615
+ bufferWriter.writeUInt64LE(value);
616
+ }
617
+ const hashAmounts = bcrypto.sha256(bufferWriter.finish());
618
+
619
+ // hashScriptPubKeys - compute size without intermediate array
620
+ let scriptPubKeysSize = 0;
621
+ for (const script of prevOutScripts) {
622
+ scriptPubKeysSize += varSliceSize(script);
623
+ }
624
+ bufferWriter = new BinaryWriter(scriptPubKeysSize);
625
+ for (const script of prevOutScripts) {
626
+ bufferWriter.writeVarBytes(script);
627
+ }
628
+ const hashScriptPubKeys = bcrypto.sha256(bufferWriter.finish());
629
+
630
+ // hashSequences
631
+ bufferWriter = new BinaryWriter(4 * this.ins.length);
632
+ for (const txIn of this.ins) {
633
+ bufferWriter.writeUInt32LE(txIn.sequence);
634
+ }
635
+ const hashSequences = bcrypto.sha256(bufferWriter.finish());
636
+
637
+ // hashOutputs - compute size without intermediate array
638
+ let txOutsSize = 0;
639
+ for (const out of this.outs) {
640
+ txOutsSize += 8 + varSliceSize(out.script);
641
+ }
642
+ bufferWriter = new BinaryWriter(txOutsSize);
643
+ for (const out of this.outs) {
644
+ bufferWriter.writeUInt64LE(out.value);
645
+ bufferWriter.writeVarBytes(out.script);
646
+ }
647
+ const hashOutputs = this.outs.length ? bcrypto.sha256(bufferWriter.finish()) : ZERO;
648
+
649
+ return { hashPrevouts, hashAmounts, hashScriptPubKeys, hashSequences, hashOutputs };
493
650
  }
494
651
 
652
+ /**
653
+ * Hash transaction for signing a SegWit v0 (P2WPKH/P2WSH) input.
654
+ *
655
+ * @param inIndex - Index of the input being signed
656
+ * @param prevOutScript - The script of the output being spent
657
+ * @param value - Value of the output being spent (bigint satoshis)
658
+ * @param hashType - Signature hash type
659
+ * @returns 32-byte hash for signing
660
+ */
495
661
  hashForWitnessV0(
496
662
  inIndex: number,
497
- prevOutScript: Buffer,
498
- value: number,
663
+ prevOutScript: Script,
664
+ value: Satoshi,
499
665
  hashType: number,
500
- ): Buffer {
501
- typeforce(types.tuple(types.UInt32, types.Buffer, types.Satoshi, types.UInt32), [
502
- inIndex,
503
- prevOutScript,
504
- value,
505
- hashType,
506
- ]);
666
+ ): Bytes32 {
667
+ if (!Number.isInteger(inIndex) || inIndex < 0 || inIndex > 0xffffffff) {
668
+ throw new TypeError('Expected unsigned 32-bit integer for inIndex');
669
+ }
670
+ if (!(prevOutScript instanceof Uint8Array)) {
671
+ throw new TypeError('Expected Uint8Array for prevOutScript');
672
+ }
673
+ if (typeof value !== 'bigint') {
674
+ throw new TypeError('Expected bigint for value');
675
+ }
676
+ if (!Number.isInteger(hashType) || hashType < 0 || hashType > 0xffffffff) {
677
+ throw new TypeError('Expected unsigned 32-bit integer for hashType');
678
+ }
507
679
 
508
- let tbuffer: Buffer = Buffer.from([]);
509
- let bufferWriter: BufferWriter;
680
+ let tbuffer: Uint8Array;
681
+ let bufferWriter: BinaryWriter;
510
682
 
511
683
  let hashOutputs = ZERO;
512
684
  let hashPrevouts = ZERO;
513
685
  let hashSequence = ZERO;
514
686
 
515
687
  if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) {
516
- tbuffer = Buffer.allocUnsafe(36 * this.ins.length);
517
- bufferWriter = new BufferWriter(tbuffer, 0);
688
+ tbuffer = alloc(36 * this.ins.length);
689
+ bufferWriter = new BinaryWriter(tbuffer, 0);
518
690
 
519
691
  this.ins.forEach((txIn) => {
520
- bufferWriter.writeSlice(txIn.hash);
521
- bufferWriter.writeUInt32(txIn.index);
692
+ bufferWriter.writeBytes(txIn.hash);
693
+ bufferWriter.writeUInt32LE(txIn.index);
522
694
  });
523
695
 
524
696
  hashPrevouts = bcrypto.hash256(tbuffer);
@@ -529,11 +701,11 @@ export class Transaction {
529
701
  (hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
530
702
  (hashType & 0x1f) !== Transaction.SIGHASH_NONE
531
703
  ) {
532
- tbuffer = Buffer.allocUnsafe(4 * this.ins.length);
533
- bufferWriter = new BufferWriter(tbuffer, 0);
704
+ tbuffer = alloc(4 * this.ins.length);
705
+ bufferWriter = new BinaryWriter(tbuffer, 0);
534
706
 
535
707
  this.ins.forEach((txIn) => {
536
- bufferWriter.writeUInt32(txIn.sequence);
708
+ bufferWriter.writeUInt32LE(txIn.sequence);
537
709
  });
538
710
 
539
711
  hashSequence = bcrypto.hash256(tbuffer);
@@ -547,85 +719,138 @@ export class Transaction {
547
719
  return sum + 8 + varSliceSize(output.script);
548
720
  }, 0);
549
721
 
550
- tbuffer = Buffer.allocUnsafe(txOutsSize);
551
- bufferWriter = new BufferWriter(tbuffer, 0);
722
+ tbuffer = alloc(txOutsSize);
723
+ bufferWriter = new BinaryWriter(tbuffer, 0);
552
724
 
553
725
  this.outs.forEach((out) => {
554
- bufferWriter.writeUInt64(out.value);
555
- bufferWriter.writeVarSlice(out.script);
726
+ bufferWriter.writeUInt64LE(out.value);
727
+ bufferWriter.writeVarBytes(out.script);
556
728
  });
557
729
 
558
730
  hashOutputs = bcrypto.hash256(tbuffer);
559
731
  } else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && inIndex < this.outs.length) {
560
- const output = this.outs[inIndex];
732
+ const output = this.outs[inIndex]!;
561
733
 
562
- tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script));
563
- bufferWriter = new BufferWriter(tbuffer, 0);
564
- bufferWriter.writeUInt64(output.value);
565
- bufferWriter.writeVarSlice(output.script);
734
+ tbuffer = alloc(8 + varSliceSize(output.script));
735
+ bufferWriter = new BinaryWriter(tbuffer, 0);
736
+ bufferWriter.writeUInt64LE(output.value);
737
+ bufferWriter.writeVarBytes(output.script);
566
738
 
567
739
  hashOutputs = bcrypto.hash256(tbuffer);
568
740
  }
569
741
 
570
- tbuffer = Buffer.allocUnsafe(156 + varSliceSize(prevOutScript));
571
- bufferWriter = new BufferWriter(tbuffer, 0);
572
-
573
- const input = this.ins[inIndex];
574
- bufferWriter.writeInt32(this.version);
575
- bufferWriter.writeSlice(hashPrevouts);
576
- bufferWriter.writeSlice(hashSequence);
577
- bufferWriter.writeSlice(input.hash);
578
- bufferWriter.writeUInt32(input.index);
579
- bufferWriter.writeVarSlice(prevOutScript);
580
- bufferWriter.writeUInt64(value);
581
- bufferWriter.writeUInt32(input.sequence);
582
- bufferWriter.writeSlice(hashOutputs);
583
- bufferWriter.writeUInt32(this.locktime);
584
- bufferWriter.writeUInt32(hashType);
585
- return bcrypto.hash256(tbuffer);
742
+ tbuffer = alloc(156 + varSliceSize(prevOutScript));
743
+ bufferWriter = new BinaryWriter(tbuffer, 0);
744
+
745
+ const input = this.ins[inIndex]!;
746
+ bufferWriter.writeInt32LE(this.version);
747
+ bufferWriter.writeBytes(hashPrevouts);
748
+ bufferWriter.writeBytes(hashSequence);
749
+ bufferWriter.writeBytes(input.hash);
750
+ bufferWriter.writeUInt32LE(input.index);
751
+ bufferWriter.writeVarBytes(prevOutScript);
752
+ bufferWriter.writeUInt64LE(value);
753
+ bufferWriter.writeUInt32LE(input.sequence);
754
+ bufferWriter.writeBytes(hashOutputs);
755
+ bufferWriter.writeUInt32LE(this.locktime);
756
+ bufferWriter.writeUInt32LE(hashType);
757
+ return bcrypto.hash256(tbuffer) as Bytes32;
586
758
  }
587
759
 
588
- getHash(forWitness?: boolean): Buffer {
760
+ /**
761
+ * Get the transaction hash.
762
+ *
763
+ * @param forWitness - If true, include witness data (wtxid)
764
+ * @returns 32-byte transaction hash
765
+ */
766
+ getHash(forWitness?: boolean): Bytes32 {
589
767
  // wtxid for coinbase is always 32 bytes of 0x00
590
- if (forWitness && this.isCoinbase()) return Buffer.alloc(32, 0);
591
- return bcrypto.hash256(this.__toBuffer(undefined, undefined, forWitness));
768
+ if (forWitness && this.isCoinbase()) return new Uint8Array(32) as Bytes32;
769
+ return bcrypto.hash256(this.#toBuffer(undefined, undefined, forWitness)) as Bytes32;
592
770
  }
593
771
 
772
+ /**
773
+ * Get the transaction ID (txid) as a hex string.
774
+ *
775
+ * @returns Transaction ID in reversed hex format
776
+ */
594
777
  getId(): string {
595
778
  // transaction hash's are displayed in reverse order
596
- return reverseBuffer(this.getHash(false)).toString('hex');
779
+ return toHex(reverse(this.getHash(false)));
597
780
  }
598
781
 
599
- toBuffer(buffer?: Buffer, initialOffset?: number): Buffer {
600
- return this.__toBuffer(buffer, initialOffset, true);
782
+ /**
783
+ * Serialize the transaction to a Uint8Array buffer.
784
+ *
785
+ * @param buffer - Optional pre-allocated buffer
786
+ * @param initialOffset - Optional starting offset in buffer
787
+ * @returns Serialized transaction bytes
788
+ */
789
+ toBuffer(buffer?: Uint8Array, initialOffset?: number): Uint8Array {
790
+ return this.#toBuffer(buffer, initialOffset, true);
601
791
  }
602
792
 
793
+ /**
794
+ * Serialize the transaction to a hex string.
795
+ *
796
+ * @returns Transaction as hex string
797
+ */
603
798
  toHex(): string {
604
- return this.toBuffer(undefined, undefined).toString('hex');
799
+ return toHex(this.toBuffer(undefined, undefined));
605
800
  }
606
801
 
607
- setInputScript(index: number, scriptSig: Buffer): void {
608
- typeforce(types.tuple(types.Number, types.Buffer), [index, scriptSig]);
802
+ /**
803
+ * Set the input script for a specific input.
804
+ *
805
+ * @param index - Input index
806
+ * @param scriptSig - The script to set
807
+ */
808
+ setInputScript(index: number, scriptSig: Script): void {
809
+ if (!Number.isInteger(index) || index < 0) {
810
+ throw new TypeError('Expected non-negative integer for index');
811
+ }
812
+ if (!(scriptSig instanceof Uint8Array)) {
813
+ throw new TypeError('Expected Uint8Array for scriptSig');
814
+ }
609
815
 
610
- this.ins[index].script = scriptSig;
816
+ this.ins[index]!.script = scriptSig;
611
817
  }
612
818
 
613
- setWitness(index: number, witness: Buffer[]): void {
614
- typeforce(types.tuple(types.Number, [types.Buffer]), [index, witness]);
819
+ /**
820
+ * Set the witness data for a specific input.
821
+ *
822
+ * @param index - Input index
823
+ * @param witness - Array of witness elements
824
+ */
825
+ setWitness(index: number, witness: Uint8Array[]): void {
826
+ if (!Number.isInteger(index) || index < 0) {
827
+ throw new TypeError('Expected non-negative integer for index');
828
+ }
829
+ if (!Array.isArray(witness) || !witness.every((w) => w instanceof Uint8Array)) {
830
+ throw new TypeError('Expected array of Uint8Array for witness');
831
+ }
615
832
 
616
- this.ins[index].witness = witness;
833
+ this.ins[index]!.witness = witness;
617
834
  }
618
835
 
619
- private __toBuffer(
620
- buffer?: Buffer,
836
+ /**
837
+ * Internal method to serialize the transaction.
838
+ *
839
+ * @param buffer - Optional pre-allocated buffer
840
+ * @param initialOffset - Optional starting offset
841
+ * @param _ALLOW_WITNESS - Whether to include witness data
842
+ * @returns Serialized transaction bytes
843
+ */
844
+ #toBuffer(
845
+ buffer?: Uint8Array,
621
846
  initialOffset?: number,
622
847
  _ALLOW_WITNESS: boolean = false,
623
- ): Buffer {
624
- if (!buffer) buffer = Buffer.allocUnsafe(this.byteLength(_ALLOW_WITNESS)) as Buffer;
848
+ ): Uint8Array {
849
+ if (!buffer) buffer = alloc(this.byteLength(_ALLOW_WITNESS));
625
850
 
626
- const bufferWriter = new BufferWriter(buffer, initialOffset || 0);
851
+ const bufferWriter = new BinaryWriter(buffer, initialOffset || 0);
627
852
 
628
- bufferWriter.writeInt32(this.version);
853
+ bufferWriter.writeInt32LE(this.version);
629
854
 
630
855
  const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses();
631
856
 
@@ -637,21 +862,16 @@ export class Transaction {
637
862
  bufferWriter.writeVarInt(this.ins.length);
638
863
 
639
864
  this.ins.forEach((txIn) => {
640
- bufferWriter.writeSlice(txIn.hash);
641
- bufferWriter.writeUInt32(txIn.index);
642
- bufferWriter.writeVarSlice(txIn.script);
643
- bufferWriter.writeUInt32(txIn.sequence);
865
+ bufferWriter.writeBytes(txIn.hash);
866
+ bufferWriter.writeUInt32LE(txIn.index);
867
+ bufferWriter.writeVarBytes(txIn.script);
868
+ bufferWriter.writeUInt32LE(txIn.sequence);
644
869
  });
645
870
 
646
871
  bufferWriter.writeVarInt(this.outs.length);
647
- (this.outs as (Output | BlankOutput)[]).forEach((txOut) => {
648
- if (isOutput(txOut)) {
649
- bufferWriter.writeUInt64(txOut.value);
650
- } else {
651
- bufferWriter.writeSlice(txOut.valueBuffer);
652
- }
653
-
654
- bufferWriter.writeVarSlice(txOut.script);
872
+ this.outs.forEach((txOut) => {
873
+ bufferWriter.writeUInt64LE(txOut.value);
874
+ bufferWriter.writeVarBytes(txOut.script);
655
875
  });
656
876
 
657
877
  if (hasWitnesses) {
@@ -660,7 +880,7 @@ export class Transaction {
660
880
  });
661
881
  }
662
882
 
663
- bufferWriter.writeUInt32(this.locktime);
883
+ bufferWriter.writeUInt32LE(this.locktime);
664
884
 
665
885
  // avoid slicing unless necessary
666
886
  if (initialOffset !== undefined) return buffer.subarray(initialOffset, bufferWriter.offset);