@btc-vision/bitcoin 6.5.6 → 7.0.0-alpha.1

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