@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,210 +1,613 @@
1
+ /**
2
+ * Pay-to-Script-Hash (P2SH) payment class.
3
+ *
4
+ * P2SH allows spending to be based on a hash of a script, with the actual
5
+ * script revealed only at spend time. This enables complex spending conditions
6
+ * while keeping addresses short.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+
1
11
  import * as bs58check from 'bs58check';
2
12
  import * as bcrypto from '../crypto.js';
3
- import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
13
+ import { bitcoin as BITCOIN_NETWORK, type Network } from '../networks.js';
4
14
  import * as bscript from '../script.js';
5
- import { stacksEqual, typeforce as typef, type Stack, type StackFunction } from '../types.js';
6
- import { P2SHPayment, Payment, PaymentOpts, PaymentType, ScriptRedeem } from './types.js';
7
- import * as lazy from './lazy.js';
15
+ import { type Bytes20, type Script, type Stack, stacksEqual } from '../types.js';
16
+ import { alloc, equals } from '../io/index.js';
17
+ import {
18
+ type P2SHPayment,
19
+ type Payment,
20
+ type PaymentOpts,
21
+ PaymentType,
22
+ type ScriptRedeem,
23
+ } from './types.js';
8
24
 
9
25
  const OPS = bscript.opcodes;
10
26
 
11
- // input: [redeemScriptSig ...] {redeemScript}
12
- // witness: <?>
13
- // output: OP_HASH160 {hash160(redeemScript)} OP_EQUAL
14
27
  /**
15
- * Creates a Pay-to-Script-Hash (P2SH) payment object.
28
+ * Pay-to-Script-Hash (P2SH) payment class.
29
+ *
30
+ * Creates locking scripts of the form:
31
+ * `OP_HASH160 {hash160(redeemScript)} OP_EQUAL`
32
+ *
33
+ * Spending requires: `{redeemScriptSig...} {redeemScript}`
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * import { P2SH, P2MS } from '@btc-vision/bitcoin';
38
+ *
39
+ * // Wrap a multisig in P2SH
40
+ * const multisig = P2MS.fromPubkeys(2, [pubkey1, pubkey2, pubkey3]);
41
+ * const p2sh = P2SH.fromRedeem({ output: multisig.output });
42
+ * console.log(p2sh.address); // 3... address
16
43
  *
17
- * @param a - The payment object containing the necessary data.
18
- * @param opts - Optional payment options.
19
- * @returns The P2SH payment object.
20
- * @throws {TypeError} If the required data is not provided or if the data is invalid.
44
+ * // Decode an existing output
45
+ * const decoded = P2SH.fromOutput(scriptPubKey);
46
+ * console.log(decoded.hash); // 20-byte script hash
47
+ * ```
21
48
  */
22
- export function p2sh(a: Omit<P2SHPayment, 'name'>, opts?: PaymentOpts): P2SHPayment {
23
- if (!a.address && !a.hash && !a.output && !a.redeem && !a.input) {
24
- throw new TypeError('Not enough data');
25
- }
26
- opts = Object.assign({ validate: true }, opts || {});
49
+ export class P2SH {
50
+ // Static public fields
51
+ static readonly NAME = PaymentType.P2SH;
27
52
 
28
- typef(
29
- {
30
- network: typef.maybe(typef.Object),
31
-
32
- address: typef.maybe(typef.String),
33
- hash: typef.maybe(typef.BufferN(20)),
34
- output: typef.maybe(typef.BufferN(23)),
35
-
36
- redeem: typef.maybe({
37
- network: typef.maybe(typef.Object),
38
- output: typef.maybe(typef.Buffer),
39
- input: typef.maybe(typef.Buffer),
40
- witness: typef.maybe(typef.arrayOf(typef.Buffer)),
41
- }),
42
- input: typef.maybe(typef.Buffer),
43
- witness: typef.maybe(typef.arrayOf(typef.Buffer)),
53
+ // Private instance fields
54
+ readonly #network: Network;
55
+ readonly #opts: Required<PaymentOpts>;
56
+
57
+ // Input data (provided by user)
58
+ #inputAddress?: string | undefined;
59
+ #inputHash?: Uint8Array | undefined;
60
+ #inputOutput?: Uint8Array | undefined;
61
+ #inputInput?: Uint8Array | undefined;
62
+ #inputRedeem?: ScriptRedeem | undefined;
63
+ #inputWitness?: Uint8Array[] | undefined;
64
+
65
+ // Cached computed values
66
+ #address?: string | undefined;
67
+ #hash?: Uint8Array | undefined;
68
+ #output?: Uint8Array | undefined;
69
+ #input?: Uint8Array | undefined;
70
+ #redeem?: ScriptRedeem | undefined;
71
+ #witness?: Uint8Array[] | undefined;
72
+
73
+ // Cache flags
74
+ #addressComputed = false;
75
+ #hashComputed = false;
76
+ #outputComputed = false;
77
+ #inputComputed = false;
78
+ #redeemComputed = false;
79
+ #witnessComputed = false;
80
+
81
+ // Decoded address cache
82
+ #decodedAddress?: { version: number; hash: Uint8Array } | undefined;
83
+ #decodedAddressComputed = false;
84
+
85
+ // Decoded input chunks cache
86
+ #inputChunks?: Stack | undefined;
87
+ #inputChunksComputed = false;
88
+
89
+ // Derived redeem from input
90
+ #derivedRedeem?: ScriptRedeem | undefined;
91
+ #derivedRedeemComputed = false;
92
+
93
+ /**
94
+ * Creates a new P2SH payment instance.
95
+ *
96
+ * @param params - Payment parameters
97
+ * @param params.address - Base58Check encoded address (3...)
98
+ * @param params.hash - 20-byte script hash
99
+ * @param params.output - The scriptPubKey
100
+ * @param params.input - The scriptSig
101
+ * @param params.redeem - The redeem script information
102
+ * @param params.witness - The witness stack (for wrapped SegWit)
103
+ * @param params.network - Network parameters (defaults to mainnet)
104
+ * @param opts - Payment options
105
+ * @param opts.validate - Whether to validate inputs (default: true)
106
+ *
107
+ * @throws {TypeError} If validation is enabled and data is invalid
108
+ */
109
+ constructor(
110
+ params: {
111
+ address?: string | undefined;
112
+ hash?: Uint8Array | undefined;
113
+ output?: Uint8Array | undefined;
114
+ input?: Uint8Array | undefined;
115
+ redeem?: ScriptRedeem | undefined;
116
+ witness?: Uint8Array[] | undefined;
117
+ network?: Network | undefined;
44
118
  },
45
- a,
46
- );
119
+ opts?: PaymentOpts,
120
+ ) {
121
+ // Derive network from redeem if not specified
122
+ let network = params.network;
123
+ if (!network) {
124
+ network = (params.redeem && params.redeem.network) || BITCOIN_NETWORK;
125
+ }
126
+ this.#network = network;
127
+ this.#opts = {
128
+ validate: opts?.validate ?? true,
129
+ allowIncomplete: opts?.allowIncomplete ?? false,
130
+ };
131
+
132
+ // Store input data
133
+ this.#inputAddress = params.address;
134
+ this.#inputHash = params.hash;
135
+ this.#inputOutput = params.output;
136
+ this.#inputInput = params.input;
137
+ this.#inputRedeem = params.redeem;
138
+ this.#inputWitness = params.witness;
139
+
140
+ // Validate if requested
141
+ if (this.#opts.validate) {
142
+ this.#validate();
143
+ }
144
+ }
145
+
146
+ // Public getters
47
147
 
48
- let network = a.network;
49
- if (!network) {
50
- network = (a.redeem && a.redeem.network) || BITCOIN_NETWORK;
51
- }
52
-
53
- const o: P2SHPayment = {
54
- network,
55
- name: PaymentType.P2SH,
56
- };
57
-
58
- const _address = lazy.value(() => {
59
- const payload = Buffer.from(bs58check.default.decode(a.address!));
60
- const version = payload.readUInt8(0);
61
- const hash = payload.subarray(1);
62
- return { version, hash };
63
- });
64
- const _chunks = lazy.value(() => {
65
- return bscript.decompile(a.input!);
66
- }) as StackFunction;
67
-
68
- const _redeem = lazy.value((): ScriptRedeem => {
69
- const chunks = _chunks();
70
- const lastChunk = chunks[chunks.length - 1];
148
+ /**
149
+ * Payment type discriminant.
150
+ */
151
+ get name(): string {
152
+ const r = this.redeem;
153
+ if (r !== undefined && r.name !== undefined) {
154
+ return `p2sh-${r.name}`;
155
+ }
156
+ return PaymentType.P2SH;
157
+ }
158
+
159
+ /**
160
+ * Network parameters.
161
+ */
162
+ get network(): Network {
163
+ return this.#network;
164
+ }
165
+
166
+ /**
167
+ * Base58Check encoded address (3... for mainnet).
168
+ */
169
+ get address(): string | undefined {
170
+ if (!this.#addressComputed) {
171
+ this.#address = this.#computeAddress();
172
+ this.#addressComputed = true;
173
+ }
174
+ return this.#address;
175
+ }
176
+
177
+ /**
178
+ * 20-byte script hash (HASH160 of redeem script).
179
+ */
180
+ get hash(): Bytes20 | undefined {
181
+ if (!this.#hashComputed) {
182
+ this.#hash = this.#computeHash();
183
+ this.#hashComputed = true;
184
+ }
185
+ return this.#hash as Bytes20 | undefined;
186
+ }
187
+
188
+ /**
189
+ * The scriptPubKey: `OP_HASH160 {hash} OP_EQUAL`
190
+ */
191
+ get output(): Script | undefined {
192
+ if (!this.#outputComputed) {
193
+ this.#output = this.#computeOutput();
194
+ this.#outputComputed = true;
195
+ }
196
+ return this.#output as Script | undefined;
197
+ }
198
+
199
+ /**
200
+ * The scriptSig: `{redeemScriptSig...} {redeemScript}`
201
+ */
202
+ get input(): Script | undefined {
203
+ if (!this.#inputComputed) {
204
+ this.#input = this.#computeInput();
205
+ this.#inputComputed = true;
206
+ }
207
+ return this.#input as Script | undefined;
208
+ }
209
+
210
+ /**
211
+ * The redeem script information.
212
+ */
213
+ get redeem(): ScriptRedeem | undefined {
214
+ if (!this.#redeemComputed) {
215
+ this.#redeem = this.#computeRedeem();
216
+ this.#redeemComputed = true;
217
+ }
218
+ return this.#redeem;
219
+ }
220
+
221
+ /**
222
+ * The witness stack (for wrapped SegWit).
223
+ */
224
+ get witness(): Uint8Array[] | undefined {
225
+ if (!this.#witnessComputed) {
226
+ this.#witness = this.#computeWitness();
227
+ this.#witnessComputed = true;
228
+ }
229
+ return this.#witness;
230
+ }
231
+
232
+ // Static factory methods
233
+
234
+ /**
235
+ * Creates a P2SH payment from a redeem script.
236
+ *
237
+ * @param redeem - The redeem script information
238
+ * @param network - Network parameters (defaults to mainnet)
239
+ * @returns A new P2SH payment instance
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * const p2sh = P2SH.fromRedeem({ output: redeemScript });
244
+ * ```
245
+ */
246
+ static fromRedeem(redeem: ScriptRedeem, network?: Network): P2SH {
247
+ return new P2SH({ redeem, network });
248
+ }
249
+
250
+ /**
251
+ * Creates a P2SH payment from a Base58Check address.
252
+ *
253
+ * @param address - Base58Check encoded address
254
+ * @param network - Network parameters (defaults to mainnet)
255
+ * @returns A new P2SH payment instance
256
+ */
257
+ static fromAddress(address: string, network?: Network): P2SH {
258
+ return new P2SH({ address, network });
259
+ }
260
+
261
+ /**
262
+ * Creates a P2SH payment from a 20-byte script hash.
263
+ *
264
+ * @param hash - 20-byte script hash
265
+ * @param network - Network parameters (defaults to mainnet)
266
+ * @returns A new P2SH payment instance
267
+ */
268
+ static fromHash(hash: Bytes20, network?: Network): P2SH {
269
+ return new P2SH({ hash, network });
270
+ }
271
+
272
+ /**
273
+ * Creates a P2SH payment from a scriptPubKey.
274
+ *
275
+ * @param output - The scriptPubKey
276
+ * @param network - Network parameters (defaults to mainnet)
277
+ * @returns A new P2SH payment instance
278
+ */
279
+ static fromOutput(output: Uint8Array, network?: Network): P2SH {
280
+ return new P2SH({ output, network });
281
+ }
282
+
283
+ // Private helper methods
284
+
285
+ /**
286
+ * Converts to a plain P2SHPayment object for backwards compatibility.
287
+ *
288
+ * @returns A P2SHPayment object
289
+ */
290
+ toPayment(): P2SHPayment {
71
291
  return {
72
- network,
73
- output: lastChunk === OPS.OP_FALSE ? Buffer.from([]) : (lastChunk as Buffer),
74
- input: bscript.compile(chunks.slice(0, -1)),
75
- witness: a.witness || [],
292
+ name: this.name,
293
+ network: this.network,
294
+ address: this.address,
295
+ hash: this.hash,
296
+ output: this.output,
297
+ input: this.input,
298
+ redeem: this.redeem,
299
+ witness: this.witness,
76
300
  };
77
- });
301
+ }
302
+
303
+ #getDecodedAddress(): { version: number; hash: Uint8Array } | undefined {
304
+ if (!this.#decodedAddressComputed) {
305
+ if (this.#inputAddress) {
306
+ const payload = new Uint8Array(bs58check.default.decode(this.#inputAddress));
307
+ this.#decodedAddress = {
308
+ version: payload[0]!,
309
+ hash: payload.subarray(1),
310
+ };
311
+ }
312
+ this.#decodedAddressComputed = true;
313
+ }
314
+ return this.#decodedAddress;
315
+ }
316
+
317
+ #getInputChunks(): Stack | undefined {
318
+ if (!this.#inputChunksComputed) {
319
+ if (this.#inputInput) {
320
+ this.#inputChunks = (bscript.decompile(this.#inputInput) as Stack) ?? undefined;
321
+ }
322
+ this.#inputChunksComputed = true;
323
+ }
324
+ return this.#inputChunks;
325
+ }
326
+
327
+ // Private computation methods
328
+
329
+ #getDerivedRedeem(): ScriptRedeem | undefined {
330
+ if (!this.#derivedRedeemComputed) {
331
+ const chunks = this.#getInputChunks();
332
+ if (chunks) {
333
+ const lastChunk = chunks[chunks.length - 1];
334
+ this.#derivedRedeem = {
335
+ network: this.#network,
336
+ output: (lastChunk === OPS.OP_FALSE
337
+ ? new Uint8Array(0)
338
+ : (lastChunk as Uint8Array)) as Script,
339
+ input: bscript.compile(chunks.slice(0, -1)) as Script,
340
+ witness: this.#inputWitness || [],
341
+ };
342
+ }
343
+ this.#derivedRedeemComputed = true;
344
+ }
345
+ return this.#derivedRedeem;
346
+ }
78
347
 
79
- // output dependents
80
- lazy.prop(o, 'address', () => {
81
- if (!o.hash) return;
348
+ #computeAddress(): string | undefined {
349
+ if (this.#inputAddress) {
350
+ return this.#inputAddress;
351
+ }
352
+ const h = this.hash;
353
+ if (!h) return undefined;
82
354
 
83
- const payload = Buffer.allocUnsafe(21);
84
- payload.writeUInt8(o.network!.scriptHash, 0);
85
- o.hash.copy(payload, 1);
355
+ const payload = alloc(21);
356
+ payload[0] = this.#network.scriptHash;
357
+ payload.set(h, 1);
86
358
  return bs58check.default.encode(payload);
87
- });
88
- lazy.prop(o, 'hash', () => {
89
- // in order of least effort
90
- if (a.output) return a.output.subarray(2, 22);
91
- if (a.address) return _address().hash;
92
- if (o.redeem && o.redeem.output) return bcrypto.hash160(o.redeem.output);
93
- });
94
- lazy.prop(o, 'output', () => {
95
- if (!o.hash) return;
96
- return bscript.compile([OPS.OP_HASH160, o.hash, OPS.OP_EQUAL]);
97
- });
98
-
99
- // input dependents
100
- lazy.prop(o, 'redeem', () => {
101
- if (!a.input) return;
102
- return _redeem();
103
- });
104
- lazy.prop(o, 'input', () => {
105
- if (!a.redeem || !a.redeem.input || !a.redeem.output) return;
359
+ }
360
+
361
+ #computeHash(): Bytes20 | undefined {
362
+ if (this.#inputHash) {
363
+ return this.#inputHash as Bytes20;
364
+ }
365
+ if (this.#inputOutput) {
366
+ return this.#inputOutput.subarray(2, 22) as Bytes20;
367
+ }
368
+ if (this.#inputAddress) {
369
+ return this.#getDecodedAddress()?.hash as Bytes20 | undefined;
370
+ }
371
+ const r = this.redeem;
372
+ if (r && r.output) {
373
+ return bcrypto.hash160(r.output) as Bytes20;
374
+ }
375
+ return undefined;
376
+ }
377
+
378
+ #computeOutput(): Script | undefined {
379
+ if (this.#inputOutput) {
380
+ return this.#inputOutput as Script;
381
+ }
382
+ const h = this.hash;
383
+ if (!h) return undefined;
384
+
385
+ return bscript.compile([OPS.OP_HASH160, h, OPS.OP_EQUAL]) as Script;
386
+ }
387
+
388
+ #computeInput(): Script | undefined {
389
+ if (this.#inputInput) {
390
+ return this.#inputInput as Script;
391
+ }
392
+ const r = this.#inputRedeem;
393
+ if (!r || !r.input || !r.output) {
394
+ return undefined;
395
+ }
106
396
  return bscript.compile(
107
- ([] as Stack).concat(bscript.decompile(a.redeem.input) as Stack, a.redeem.output),
108
- );
109
- });
110
- lazy.prop(o, 'witness', () => {
111
- if (o.redeem && o.redeem.witness) return o.redeem.witness;
112
- if (o.input) return [];
113
- });
114
- lazy.prop(o, 'name', () => {
115
- const nameParts = ['p2sh'];
116
- if (o.redeem !== undefined && o.redeem.name !== undefined) nameParts.push(o.redeem.name);
117
- return nameParts.join('-');
118
- });
119
-
120
- if (opts.validate) {
121
- let hash: Buffer = Buffer.from([]);
122
- if (a.address) {
123
- if (_address().version !== network.scriptHash)
397
+ ([] as Stack).concat(bscript.decompile(r.input) as Stack, r.output),
398
+ ) as Script;
399
+ }
400
+
401
+ #computeRedeem(): ScriptRedeem | undefined {
402
+ if (this.#inputRedeem) {
403
+ return this.#inputRedeem;
404
+ }
405
+ if (this.#inputInput) {
406
+ return this.#getDerivedRedeem();
407
+ }
408
+ return undefined;
409
+ }
410
+
411
+ // Validation
412
+
413
+ #computeWitness(): Uint8Array[] | undefined {
414
+ if (this.#inputWitness) {
415
+ return this.#inputWitness;
416
+ }
417
+ const r = this.redeem;
418
+ if (r && r.witness) {
419
+ return r.witness;
420
+ }
421
+ if (this.input) {
422
+ return [];
423
+ }
424
+ return undefined;
425
+ }
426
+
427
+ #checkRedeem(redeem: Payment): void {
428
+ // Is the redeem output empty/invalid?
429
+ if (redeem.output) {
430
+ const decompile = bscript.decompile(redeem.output);
431
+ if (!decompile || decompile.length < 1) {
432
+ throw new TypeError('Redeem.output too short');
433
+ }
434
+ if (redeem.output.byteLength > 520) {
435
+ throw new TypeError('Redeem.output unspendable if larger than 520 bytes');
436
+ }
437
+ if (bscript.countNonPushOnlyOPs(decompile) > 201) {
438
+ throw new TypeError('Redeem.output unspendable with more than 201 non-push ops');
439
+ }
440
+ }
441
+
442
+ if (redeem.input) {
443
+ const hasInput = redeem.input.length > 0;
444
+ const hasWitness = redeem.witness && redeem.witness.length > 0;
445
+ if (!hasInput && !hasWitness) {
446
+ throw new TypeError('Empty input');
447
+ }
448
+ if (hasInput && hasWitness) {
449
+ throw new TypeError('Input and witness provided');
450
+ }
451
+ if (hasInput) {
452
+ const richunks = bscript.decompile(redeem.input) as Stack;
453
+ if (!bscript.isPushOnly(richunks)) {
454
+ throw new TypeError('Non push-only scriptSig');
455
+ }
456
+ }
457
+ }
458
+ }
459
+
460
+ #validate(): void {
461
+ let hash: Uint8Array = new Uint8Array(0);
462
+
463
+ if (this.#inputAddress) {
464
+ const addr = this.#getDecodedAddress();
465
+ if (!addr) {
466
+ throw new TypeError('Invalid address');
467
+ }
468
+ if (addr.version !== this.#network.scriptHash) {
124
469
  throw new TypeError('Invalid version or Network mismatch');
125
- if (_address().hash.length !== 20) throw new TypeError('Invalid address');
126
- hash = _address().hash;
470
+ }
471
+ if (addr.hash.length !== 20) {
472
+ throw new TypeError('Invalid address');
473
+ }
474
+ hash = addr.hash;
127
475
  }
128
476
 
129
- if (a.hash) {
130
- if (hash.length > 0 && !hash.equals(a.hash)) throw new TypeError('Hash mismatch');
131
- else hash = a.hash;
477
+ if (this.#inputHash) {
478
+ if (hash.length > 0 && !equals(hash, this.#inputHash)) {
479
+ throw new TypeError('Hash mismatch');
480
+ } else {
481
+ hash = this.#inputHash;
482
+ }
132
483
  }
133
484
 
134
- if (a.output) {
485
+ if (this.#inputOutput) {
135
486
  if (
136
- a.output.length !== 23 ||
137
- a.output[0] !== OPS.OP_HASH160 ||
138
- a.output[1] !== 0x14 ||
139
- a.output[22] !== OPS.OP_EQUAL
140
- )
487
+ this.#inputOutput.length !== 23 ||
488
+ this.#inputOutput[0] !== OPS.OP_HASH160 ||
489
+ this.#inputOutput[1] !== 0x14 ||
490
+ this.#inputOutput[22] !== OPS.OP_EQUAL
491
+ ) {
141
492
  throw new TypeError('Output is invalid');
493
+ }
142
494
 
143
- const hash2 = a.output.subarray(2, 22);
144
- if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
145
- else hash = hash2;
146
- }
147
-
148
- // inlined to prevent 'no-inner-declarations' failing
149
- const checkRedeem = (redeem: Payment): void => {
150
- // is the redeem output empty/invalid?
151
- if (redeem.output) {
152
- const decompile = bscript.decompile(redeem.output);
153
- if (!decompile || decompile.length < 1)
154
- throw new TypeError('Redeem.output too short');
155
- if (redeem.output.byteLength > 520)
156
- throw new TypeError('Redeem.output unspendable if larger than 520 bytes');
157
- if (bscript.countNonPushOnlyOPs(decompile) > 201)
158
- throw new TypeError(
159
- 'Redeem.output unspendable with more than 201 non-push ops',
160
- );
161
-
162
- // match hash against other sources
163
- const hash2 = bcrypto.hash160(redeem.output);
164
- if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
165
- else hash = hash2;
166
- }
167
-
168
- if (redeem.input) {
169
- const hasInput = redeem.input.length > 0;
170
- const hasWitness = redeem.witness && redeem.witness.length > 0;
171
- if (!hasInput && !hasWitness) throw new TypeError('Empty input');
172
- if (hasInput && hasWitness) throw new TypeError('Input and witness provided');
173
- if (hasInput) {
174
- const richunks = bscript.decompile(redeem.input) as Stack;
175
- if (!bscript.isPushOnly(richunks))
176
- throw new TypeError('Non push-only scriptSig');
177
- }
495
+ const hash2 = this.#inputOutput.subarray(2, 22);
496
+ if (hash.length > 0 && !equals(hash, hash2)) {
497
+ throw new TypeError('Hash mismatch');
498
+ } else {
499
+ hash = hash2;
178
500
  }
179
- };
501
+ }
180
502
 
181
- if (a.input) {
182
- const chunks = _chunks();
183
- if (!chunks || chunks.length < 1) throw new TypeError('Input too short');
184
- if (!Buffer.isBuffer(_redeem().output)) throw new TypeError('Input is invalid');
503
+ if (this.#inputInput) {
504
+ const chunks = this.#getInputChunks();
505
+ if (!chunks || chunks.length < 1) {
506
+ throw new TypeError('Input too short');
507
+ }
508
+ const derived = this.#getDerivedRedeem();
509
+ if (!derived || !(derived.output instanceof Uint8Array)) {
510
+ throw new TypeError('Input is invalid');
511
+ }
512
+
513
+ this.#checkRedeem(derived);
185
514
 
186
- checkRedeem(_redeem());
515
+ // Match hash against redeem output
516
+ if (derived.output) {
517
+ const hash2 = bcrypto.hash160(derived.output);
518
+ if (hash.length > 0 && !equals(hash, hash2)) {
519
+ throw new TypeError('Hash mismatch');
520
+ } else {
521
+ hash = hash2;
522
+ }
523
+ }
187
524
  }
188
525
 
189
- if (a.redeem) {
190
- if (a.redeem.network && a.redeem.network !== network)
526
+ if (this.#inputRedeem) {
527
+ if (this.#inputRedeem.network && this.#inputRedeem.network !== this.#network) {
191
528
  throw new TypeError('Network mismatch');
192
- if (a.input) {
193
- const redeem = _redeem();
194
- if (a.redeem.output && !a.redeem.output.equals(redeem.output!))
195
- throw new TypeError('Redeem.output mismatch');
196
- if (a.redeem.input && !a.redeem.input.equals(redeem.input!))
197
- throw new TypeError('Redeem.input mismatch');
198
529
  }
530
+ if (this.#inputInput) {
531
+ const derived = this.#getDerivedRedeem();
532
+ if (derived) {
533
+ if (
534
+ this.#inputRedeem.output &&
535
+ derived.output &&
536
+ !equals(this.#inputRedeem.output, derived.output)
537
+ ) {
538
+ throw new TypeError('Redeem.output mismatch');
539
+ }
540
+ if (
541
+ this.#inputRedeem.input &&
542
+ derived.input &&
543
+ !equals(this.#inputRedeem.input, derived.input)
544
+ ) {
545
+ throw new TypeError('Redeem.input mismatch');
546
+ }
547
+ }
548
+ }
549
+
550
+ this.#checkRedeem(this.#inputRedeem);
199
551
 
200
- checkRedeem(a.redeem);
552
+ // Match hash against redeem output
553
+ if (this.#inputRedeem.output) {
554
+ const hash2 = bcrypto.hash160(this.#inputRedeem.output);
555
+ if (hash.length > 0 && !equals(hash, hash2)) {
556
+ throw new TypeError('Hash mismatch');
557
+ }
558
+ }
201
559
  }
202
560
 
203
- if (a.witness) {
204
- if (a.redeem && a.redeem.witness && !stacksEqual(a.redeem.witness, a.witness))
561
+ if (this.#inputWitness) {
562
+ if (
563
+ this.#inputRedeem &&
564
+ this.#inputRedeem.witness &&
565
+ !stacksEqual(this.#inputRedeem.witness, this.#inputWitness)
566
+ ) {
205
567
  throw new TypeError('Witness and redeem.witness mismatch');
568
+ }
206
569
  }
207
570
  }
571
+ }
572
+
573
+ /**
574
+ * Creates a Pay-to-Script-Hash (P2SH) payment object.
575
+ *
576
+ * This is the legacy factory function for backwards compatibility.
577
+ * For new code, prefer using the P2SH class directly.
578
+ *
579
+ * @param a - The payment object containing the necessary data
580
+ * @param opts - Optional payment options
581
+ * @returns The P2SH payment object
582
+ * @throws {TypeError} If the required data is not provided or if the data is invalid
583
+ *
584
+ * @example
585
+ * ```typescript
586
+ * import { p2sh, p2ms } from '@btc-vision/bitcoin';
587
+ *
588
+ * // Wrap a multisig in P2SH
589
+ * const multisig = p2ms({ m: 2, pubkeys: [pk1, pk2, pk3] });
590
+ * const payment = p2sh({ redeem: multisig });
591
+ * ```
592
+ */
593
+ export function p2sh(a: Omit<P2SHPayment, 'name'>, opts?: PaymentOpts): P2SHPayment {
594
+ if (!a.address && !a.hash && !a.output && !a.redeem && !a.input) {
595
+ throw new TypeError('Not enough data');
596
+ }
597
+
598
+ const instance = new P2SH(
599
+ {
600
+ address: a.address,
601
+ hash: a.hash,
602
+ output: a.output,
603
+ input: a.input,
604
+ redeem: a.redeem,
605
+ witness: a.witness,
606
+ network: a.network,
607
+ },
608
+ opts,
609
+ );
208
610
 
209
- return Object.assign(o, a);
611
+ // Return a merged object for backwards compatibility
612
+ return Object.assign(instance.toPayment(), a);
210
613
  }