@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
package/build/psbt.js CHANGED
@@ -1,94 +1,156 @@
1
- import { Psbt as PsbtBase } from 'bip174';
2
- import * as varuint from 'bip174/src/lib/converter/varint.js';
3
- const varuintDecode = varuint.decode;
4
- import { checkForInput, checkForOutput } from 'bip174/src/lib/utils.js';
1
+ import { checkForInput, checkForOutput, Psbt as PsbtBase } from 'bip174';
2
+ import { clone, equals, fromBase64, fromHex, reverse, toHex } from './io/index.js';
5
3
  import { fromOutputScript, isUnknownSegwitVersion, toOutputScript } from './address.js';
6
- import { cloneBuffer, reverseBuffer } from './bufferutils.js';
7
4
  import { bitcoin as btcNetwork } from './networks.js';
8
5
  import * as payments from './payments/index.js';
9
6
  import { tapleafHash } from './payments/bip341.js';
10
- import { checkTaprootInputFields, checkTaprootInputForSigs, checkTaprootOutputFields, isTaprootInput, serializeTaprootSignature, tapScriptFinalizer, } from './psbt/bip371.js';
7
+ import { checkTaprootInputFields, checkTaprootOutputFields, isTaprootInput, serializeTaprootSignature, tapScriptFinalizer, } from './psbt/bip371.js';
11
8
  import { toXOnly } from './pubkey.js';
12
- import { checkInputForSig, isP2MS, isP2PK, isP2PKH, isP2SHScript, isP2TR, isP2WPKH, isP2WSHScript, pubkeyInScript, witnessStackToScriptWitness, } from './psbt/psbtutils.js';
9
+ import { isP2TR, isP2WPKH, pubkeyInScript, witnessStackToScriptWitness } from './psbt/psbtutils.js';
10
+ import { check32Bit, checkCache, checkInputsForPartialSig, checkPartialSigSighashes, checkScriptForPubkey, checkTxEmpty, checkTxForDupeIns, checkTxInputCache, isFinalized, } from './psbt/validation.js';
11
+ import { checkInvalidP2WSH, classifyScript, compressPubkey, getMeaningfulScript, isPubkeyLike, isSigLike, range, scriptWitnessToWitnessStack, sighashTypeToString, } from './psbt/utils.js';
13
12
  import * as bscript from './script.js';
14
13
  import { Transaction } from './transaction.js';
14
+ /**
15
+ * These are the default arguments for a Psbt instance.
16
+ */
15
17
  const DEFAULT_OPTS = {
18
+ /**
19
+ * A bitcoinjs Network object. This is only used if you pass an `address`
20
+ * parameter to addOutput. Otherwise it is not needed and can be left default.
21
+ */
16
22
  network: btcNetwork,
17
- maximumFeeRate: 5000,
23
+ /**
24
+ * When extractTransaction is called, the fee rate is checked.
25
+ * THIS IS NOT TO BE RELIED ON.
26
+ * It is only here as a last ditch effort to prevent sending a 500 BTC fee etc.
27
+ */
28
+ maximumFeeRate: 5000, // satoshi per byte
18
29
  };
30
+ /**
31
+ * Psbt class can parse and generate a PSBT binary based off of the BIP174.
32
+ * There are 6 roles that this class fulfills. (Explained in BIP174)
33
+ *
34
+ * Creator: This can be done with `new Psbt()`
35
+ *
36
+ * Updater: This can be done with `psbt.addInput(input)`, `psbt.addInputs(inputs)`,
37
+ * `psbt.addOutput(output)`, `psbt.addOutputs(outputs)` when you are looking to
38
+ * add new inputs and outputs to the PSBT, and `psbt.updateGlobal(itemObject)`,
39
+ * `psbt.updateInput(itemObject)`, `psbt.updateOutput(itemObject)`
40
+ * addInput requires hash: Uint8Array | string; and index: number; as attributes
41
+ * and can also include any attributes that are used in updateInput method.
42
+ * addOutput requires script: Uint8Array; and value: bigint; and likewise can include
43
+ * data for updateOutput.
44
+ * For a list of what attributes should be what types. Check the bip174 library.
45
+ * Also, check the integration tests for some examples of usage.
46
+ *
47
+ * Signer: There are a few methods. signAllInputs and signAllInputsAsync, which will search all input
48
+ * information for your pubkey or pubkeyhash, and only sign inputs where it finds
49
+ * your info. Or you can explicitly sign a specific input with signInput and
50
+ * signInputAsync. For the async methods you can create a SignerAsync object
51
+ * and use something like a hardware wallet to sign with. (You must implement this)
52
+ *
53
+ * Combiner: psbts can be combined easily with `psbt.combine(psbt2, psbt3, psbt4 ...)`
54
+ * the psbt calling combine will always have precedence when a conflict occurs.
55
+ * Combine checks if the internal bitcoin transaction is the same, so be sure that
56
+ * all sequences, version, locktime, etc. are the same before combining.
57
+ *
58
+ * Input Finalizer: This role is fairly important. Not only does it need to construct
59
+ * the input scriptSigs and witnesses, but it SHOULD verify the signatures etc.
60
+ * Before running `psbt.finalizeAllInputs()` please run `psbt.validateSignaturesOfAllInputs()`
61
+ * Running any finalize method will delete any data in the input(s) that are no longer
62
+ * needed due to the finalized scripts containing the information.
63
+ *
64
+ * Transaction Extractor: This role will perform some checks before returning a
65
+ * Transaction object. Such as fee rate not being larger than maximumFeeRate etc.
66
+ */
67
+ /**
68
+ * Psbt class can parse and generate a PSBT binary based off of the BIP174.
69
+ */
19
70
  export class Psbt {
71
+ data;
72
+ #cache;
73
+ #opts;
20
74
  constructor(opts = {}, data = new PsbtBase(new PsbtTransaction())) {
21
75
  this.data = data;
22
- this.opts = Object.assign({}, DEFAULT_OPTS, opts);
23
- this.__CACHE = {
24
- __NON_WITNESS_UTXO_TX_CACHE: [],
25
- __NON_WITNESS_UTXO_BUF_CACHE: [],
26
- __TX_IN_CACHE: {},
27
- __TX: this.data.globalMap.unsignedTx.tx,
28
- __UNSAFE_SIGN_NONSEGWIT: false,
76
+ this.#opts = Object.assign({}, DEFAULT_OPTS, opts);
77
+ this.#cache = {
78
+ nonWitnessUtxoTxCache: [],
79
+ nonWitnessUtxoBufCache: [],
80
+ txInCache: {},
81
+ // unsignedTx.tx property is dynamically added by PsbtBase
82
+ tx: this.data.globalMap.unsignedTx.tx,
83
+ unsafeSignNonSegwit: false,
84
+ hasSignatures: false,
29
85
  };
30
86
  if (opts.version === 3) {
31
87
  this.setVersionTRUC();
32
88
  }
33
89
  else if (this.data.inputs.length === 0)
34
90
  this.setVersion(2);
35
- const dpew = (obj, attr, enumerable, writable) => {
36
- Object.defineProperty(obj, attr, {
37
- enumerable,
38
- writable,
39
- });
40
- };
41
- dpew(this, '__CACHE', false, true);
42
- dpew(this, 'opts', false, true);
91
+ }
92
+ /** @internal - Exposed for testing. Do not use in production code. */
93
+ get __CACHE() {
94
+ return this.#cache;
95
+ }
96
+ /** @internal - Exposed for testing. Do not use in production code. */
97
+ get opts() {
98
+ return this.#opts;
43
99
  }
44
100
  get inputCount() {
45
101
  return this.data.inputs.length;
46
102
  }
47
103
  get version() {
48
- return this.__CACHE.__TX.version;
104
+ return this.#cache.tx.version;
49
105
  }
50
106
  set version(version) {
51
107
  this.setVersion(version);
52
108
  }
53
109
  get locktime() {
54
- return this.__CACHE.__TX.locktime;
110
+ return this.#cache.tx.locktime;
55
111
  }
56
112
  set locktime(locktime) {
57
113
  this.setLocktime(locktime);
58
114
  }
59
115
  get txInputs() {
60
- return this.__CACHE.__TX.ins.map((input) => ({
61
- hash: cloneBuffer(input.hash),
116
+ return this.#cache.tx.ins.map((input) => ({
117
+ hash: clone(input.hash),
62
118
  index: input.index,
63
119
  sequence: input.sequence,
64
120
  }));
65
121
  }
66
122
  get txOutputs() {
67
- return this.__CACHE.__TX.outs.map((output) => {
123
+ return this.#cache.tx.outs.map((output) => {
68
124
  let address;
69
125
  try {
70
- address = fromOutputScript(output.script, this.opts.network);
126
+ address = fromOutputScript(output.script, this.#opts.network);
71
127
  }
72
128
  catch (_) { }
73
129
  return {
74
- script: cloneBuffer(output.script),
130
+ script: clone(output.script),
75
131
  value: output.value,
76
132
  address,
77
133
  };
78
134
  });
79
135
  }
80
136
  static fromBase64(data, opts = {}) {
81
- const buffer = Buffer.from(data, 'base64');
137
+ const buffer = fromBase64(data);
82
138
  return this.fromBuffer(buffer, opts);
83
139
  }
84
140
  static fromHex(data, opts = {}) {
85
- const buffer = Buffer.from(data, 'hex');
141
+ const buffer = fromHex(data);
86
142
  return this.fromBuffer(buffer, opts);
87
143
  }
88
144
  static fromBuffer(buffer, opts = {}) {
89
145
  const psbtBase = PsbtBase.fromBuffer(buffer, transactionFromBuffer);
90
146
  const psbt = new Psbt(opts, psbtBase);
91
- checkTxForDupeIns(psbt.__CACHE.__TX, psbt.__CACHE);
147
+ checkTxForDupeIns(psbt.#cache.tx, psbt.#cache);
148
+ // Check if restored PSBT has any signatures (partial or finalized)
149
+ psbt.#cache.hasSignatures = psbt.data.inputs.some((input) => input.partialSig?.length ||
150
+ input.tapKeySig ||
151
+ input.tapScriptSig?.length ||
152
+ input.finalScriptSig ||
153
+ input.finalScriptWitness);
92
154
  return psbt;
93
155
  }
94
156
  combine(...those) {
@@ -96,19 +158,20 @@ export class Psbt {
96
158
  return this;
97
159
  }
98
160
  clone() {
99
- const clonedOpts = JSON.parse(JSON.stringify(this.opts));
100
- return Psbt.fromBuffer(this.data.toBuffer(), clonedOpts);
161
+ // TODO: more efficient cloning
162
+ const clonedOpts = JSON.parse(JSON.stringify(this.#opts));
163
+ return Psbt.fromBuffer(new Uint8Array(this.data.toBuffer()), clonedOpts);
101
164
  }
102
165
  setMaximumFeeRate(satoshiPerByte) {
103
- check32Bit(satoshiPerByte);
104
- this.opts.maximumFeeRate = satoshiPerByte;
166
+ check32Bit(satoshiPerByte); // 42.9 BTC per byte IS excessive... so throw
167
+ this.#opts.maximumFeeRate = satoshiPerByte;
105
168
  }
106
169
  setVersion(version) {
107
170
  check32Bit(version);
108
- checkInputsForPartialSig(this.data.inputs, 'setVersion');
109
- const c = this.__CACHE;
110
- c.__TX.version = version;
111
- c.__EXTRACTED_TX = undefined;
171
+ checkInputsForPartialSig(this.data.inputs, 'setVersion', this.#cache.hasSignatures);
172
+ const c = this.#cache;
173
+ c.tx.version = version;
174
+ c.extractedTx = undefined;
112
175
  return this;
113
176
  }
114
177
  setVersionTRUC() {
@@ -116,21 +179,21 @@ export class Psbt {
116
179
  }
117
180
  setLocktime(locktime) {
118
181
  check32Bit(locktime);
119
- checkInputsForPartialSig(this.data.inputs, 'setLocktime');
120
- const c = this.__CACHE;
121
- c.__TX.locktime = locktime;
122
- c.__EXTRACTED_TX = undefined;
182
+ checkInputsForPartialSig(this.data.inputs, 'setLocktime', this.#cache.hasSignatures);
183
+ const c = this.#cache;
184
+ c.tx.locktime = locktime;
185
+ c.extractedTx = undefined;
123
186
  return this;
124
187
  }
125
188
  setInputSequence(inputIndex, sequence) {
126
189
  check32Bit(sequence);
127
- checkInputsForPartialSig(this.data.inputs, 'setInputSequence');
128
- const c = this.__CACHE;
129
- if (c.__TX.ins.length <= inputIndex) {
190
+ checkInputsForPartialSig(this.data.inputs, 'setInputSequence', this.#cache.hasSignatures);
191
+ const c = this.#cache;
192
+ if (c.tx.ins.length <= inputIndex) {
130
193
  throw new Error('Input index too high');
131
194
  }
132
- c.__TX.ins[inputIndex].sequence = sequence;
133
- c.__EXTRACTED_TX = undefined;
195
+ c.tx.ins[inputIndex].sequence = sequence;
196
+ c.extractedTx = undefined;
134
197
  return this;
135
198
  }
136
199
  addInputs(inputDatas, checkPartialSigs = true) {
@@ -144,51 +207,78 @@ export class Psbt {
144
207
  }
145
208
  checkTaprootInputFields(inputData, inputData, 'addInput');
146
209
  if (checkPartialSigs) {
147
- checkInputsForPartialSig(this.data.inputs, 'addInput');
210
+ checkInputsForPartialSig(this.data.inputs, 'addInput', this.#cache.hasSignatures);
148
211
  }
149
212
  if (inputData.witnessScript)
150
213
  checkInvalidP2WSH(inputData.witnessScript);
151
- const c = this.__CACHE;
152
- this.data.addInput(inputData);
153
- const txIn = c.__TX.ins[c.__TX.ins.length - 1];
214
+ // Convert witnessUtxo for bip174 v3 compatibility (value: bigint, script: Uint8Array)
215
+ const normalizedInputData = inputData.witnessUtxo
216
+ ? {
217
+ ...inputData,
218
+ witnessUtxo: {
219
+ script: inputData.witnessUtxo.script,
220
+ value: typeof inputData.witnessUtxo.value === 'bigint'
221
+ ? inputData.witnessUtxo.value
222
+ : BigInt(inputData.witnessUtxo.value),
223
+ },
224
+ }
225
+ : inputData;
226
+ const c = this.#cache;
227
+ this.data.addInput(normalizedInputData);
228
+ const txIn = c.tx.ins[c.tx.ins.length - 1];
154
229
  checkTxInputCache(c, txIn);
155
230
  const inputIndex = this.data.inputs.length - 1;
156
231
  const input = this.data.inputs[inputIndex];
157
232
  if (input.nonWitnessUtxo) {
158
- addNonWitnessTxCache(this.__CACHE, input, inputIndex);
233
+ addNonWitnessTxCache(this.#cache, input, inputIndex);
159
234
  }
160
- c.__FEE = undefined;
161
- c.__FEE_RATE = undefined;
162
- c.__EXTRACTED_TX = undefined;
235
+ c.fee = undefined;
236
+ c.feeRate = undefined;
237
+ c.extractedTx = undefined;
238
+ c.prevOuts = undefined;
239
+ c.signingScripts = undefined;
240
+ c.values = undefined;
241
+ c.taprootHashCache = undefined;
163
242
  return this;
164
243
  }
165
- addOutputs(outputDatas) {
166
- outputDatas.forEach((outputData) => this.addOutput(outputData));
244
+ addOutputs(outputDatas, checkPartialSigs = true) {
245
+ outputDatas.forEach((outputData) => this.addOutput(outputData, checkPartialSigs));
167
246
  return this;
168
247
  }
169
- addOutput(outputData) {
248
+ /**
249
+ * Add an output to the PSBT.
250
+ *
251
+ * **PERFORMANCE WARNING:** Passing an `address` string is ~10x slower than passing
252
+ * a `script` directly due to address parsing overhead (bech32 decode, etc.).
253
+ * For high-performance use cases with many outputs, pre-compute the script using
254
+ * `toOutputScript(address, network)` and pass `{ script, value }` instead.
255
+ *
256
+ * @param outputData - Output data with either `address` or `script`, and `value`
257
+ * @param checkPartialSigs - Whether to check for existing signatures (default: true)
258
+ */
259
+ addOutput(outputData, checkPartialSigs = true) {
170
260
  const hasAddress = 'address' in outputData;
171
261
  const hasScript = 'script' in outputData;
172
- if (arguments.length > 1 ||
173
- !outputData ||
174
- outputData.value === undefined ||
175
- (!hasAddress && !hasScript)) {
262
+ if (!outputData || outputData.value === undefined || (!hasAddress && !hasScript)) {
176
263
  throw new Error(`Invalid arguments for Psbt.addOutput. ` +
177
264
  `Requires single object with at least [script or address] and [value]`);
178
265
  }
179
- checkInputsForPartialSig(this.data.inputs, 'addOutput');
266
+ if (checkPartialSigs) {
267
+ checkInputsForPartialSig(this.data.inputs, 'addOutput', this.#cache.hasSignatures);
268
+ }
180
269
  if (hasAddress) {
181
270
  const { address } = outputData;
182
- const { network } = this.opts;
271
+ const { network } = this.#opts;
183
272
  const script = toOutputScript(address, network);
184
273
  outputData = Object.assign({}, outputData, { script });
185
274
  }
186
275
  checkTaprootOutputFields(outputData, outputData, 'addOutput');
187
- const c = this.__CACHE;
276
+ const c = this.#cache;
188
277
  this.data.addOutput(outputData);
189
- c.__FEE = undefined;
190
- c.__FEE_RATE = undefined;
191
- c.__EXTRACTED_TX = undefined;
278
+ c.fee = undefined;
279
+ c.feeRate = undefined;
280
+ c.extractedTx = undefined;
281
+ c.taprootHashCache = undefined;
192
282
  return this;
193
283
  }
194
284
  extractTransaction(disableFeeCheck, disableOutputChecks) {
@@ -197,43 +287,43 @@ export class Psbt {
197
287
  }
198
288
  if (!this.data.inputs.every(isFinalized))
199
289
  throw new Error('Not finalized');
200
- const c = this.__CACHE;
290
+ const c = this.#cache;
201
291
  if (!disableFeeCheck) {
202
- checkFees(this, c, this.opts);
292
+ checkFees(this, c, this.#opts);
203
293
  }
204
- if (c.__EXTRACTED_TX)
205
- return c.__EXTRACTED_TX;
206
- const tx = c.__TX.clone();
294
+ if (c.extractedTx)
295
+ return c.extractedTx;
296
+ const tx = c.tx.clone();
207
297
  inputFinalizeGetAmts(this.data.inputs, tx, c, true, disableOutputChecks);
208
298
  return tx;
209
299
  }
210
300
  getFeeRate(disableOutputChecks = false) {
211
- return getTxCacheValue('__FEE_RATE', 'fee rate', this.data.inputs, this.__CACHE, disableOutputChecks);
301
+ return getTxCacheValue('feeRate', 'fee rate', this.data.inputs, this.#cache, disableOutputChecks);
212
302
  }
213
303
  getFee(disableOutputChecks = false) {
214
- return getTxCacheValue('__FEE', 'fee', this.data.inputs, this.__CACHE, disableOutputChecks);
304
+ return getTxCacheValue('fee', 'fee', this.data.inputs, this.#cache, disableOutputChecks);
215
305
  }
216
306
  finalizeAllInputs() {
217
- checkForInput(this.data.inputs, 0);
307
+ checkForInput(this.data.inputs, 0); // making sure we have at least one
218
308
  range(this.data.inputs.length).forEach((idx) => this.finalizeInput(idx));
219
309
  return this;
220
310
  }
221
311
  finalizeInput(inputIndex, finalScriptsFunc, canRunChecks) {
222
312
  const input = checkForInput(this.data.inputs, inputIndex);
223
313
  if (isTaprootInput(input)) {
224
- return this._finalizeTaprootInput(inputIndex, input, undefined, finalScriptsFunc);
314
+ return this.#finalizeTaprootInput(inputIndex, input, undefined, finalScriptsFunc);
225
315
  }
226
- return this._finalizeInput(inputIndex, input, finalScriptsFunc, canRunChecks ?? true);
316
+ return this.#finalizeInput(inputIndex, input, finalScriptsFunc, canRunChecks ?? true);
227
317
  }
228
318
  finalizeTaprootInput(inputIndex, tapLeafHashToFinalize, finalScriptsFunc = tapScriptFinalizer) {
229
319
  const input = checkForInput(this.data.inputs, inputIndex);
230
320
  if (isTaprootInput(input))
231
- return this._finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc);
321
+ return this.#finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc);
232
322
  throw new Error(`Cannot finalize input #${inputIndex}. Not Taproot.`);
233
323
  }
234
324
  getInputType(inputIndex) {
235
325
  const input = checkForInput(this.data.inputs, inputIndex);
236
- const script = getScriptFromUtxo(inputIndex, input, this.__CACHE);
326
+ const script = getScriptFromUtxo(inputIndex, input, this.#cache);
237
327
  const result = getMeaningfulScript(script, inputIndex, 'input', input.redeemScript || redeemFromFinalScriptSig(input.finalScriptSig), input.witnessScript || redeemFromFinalWitnessScript(input.finalScriptWitness));
238
328
  const type = result.type === 'raw' ? '' : result.type + '-';
239
329
  const mainType = classifyScript(result.meaningfulScript);
@@ -241,7 +331,7 @@ export class Psbt {
241
331
  }
242
332
  inputHasPubkey(inputIndex, pubkey) {
243
333
  const input = checkForInput(this.data.inputs, inputIndex);
244
- return pubkeyInInput(pubkey, input, inputIndex, this.__CACHE);
334
+ return pubkeyInInput(pubkey, input, inputIndex, this.#cache);
245
335
  }
246
336
  inputHasHDKey(inputIndex, root) {
247
337
  const input = checkForInput(this.data.inputs, inputIndex);
@@ -250,7 +340,7 @@ export class Psbt {
250
340
  }
251
341
  outputHasPubkey(outputIndex, pubkey) {
252
342
  const output = checkForOutput(this.data.outputs, outputIndex);
253
- return pubkeyInOutput(pubkey, output, outputIndex, this.__CACHE);
343
+ return pubkeyInOutput(pubkey, output, outputIndex, this.#cache);
254
344
  }
255
345
  outputHasHDKey(outputIndex, root) {
256
346
  const output = checkForOutput(this.data.outputs, outputIndex);
@@ -258,15 +348,15 @@ export class Psbt {
258
348
  return !!output.bip32Derivation && output.bip32Derivation.some(derivationIsMine);
259
349
  }
260
350
  validateSignaturesOfAllInputs(validator) {
261
- checkForInput(this.data.inputs, 0);
351
+ checkForInput(this.data.inputs, 0); // making sure we have at least one
262
352
  const results = range(this.data.inputs.length).map((idx) => this.validateSignaturesOfInput(idx, validator));
263
353
  return results.reduce((final, res) => res && final, true);
264
354
  }
265
355
  validateSignaturesOfInput(inputIndex, validator, pubkey) {
266
356
  const input = this.data.inputs[inputIndex];
267
357
  if (isTaprootInput(input))
268
- return this.validateSignaturesOfTaprootInput(inputIndex, validator, pubkey);
269
- return this._validateSignaturesOfInput(inputIndex, validator, pubkey);
358
+ return this.#validateSignaturesOfTaprootInput(inputIndex, validator, pubkey);
359
+ return this.#validateSignaturesOfInput(inputIndex, validator, pubkey);
270
360
  }
271
361
  signAllInputsHD(hdKeyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
272
362
  if (!hdKeyPair || !hdKeyPair.publicKey || !hdKeyPair.fingerprint) {
@@ -334,6 +424,9 @@ export class Psbt {
334
424
  signAllInputs(keyPair, sighashTypes) {
335
425
  if (!keyPair || !keyPair.publicKey)
336
426
  throw new Error('Need Signer to sign input');
427
+ // TODO: Add a pubkey/pubkeyhash cache to each input
428
+ // as input information is added, then eventually
429
+ // optimize this method.
337
430
  const results = [];
338
431
  for (const i of range(this.data.inputs.length)) {
339
432
  try {
@@ -353,6 +446,9 @@ export class Psbt {
353
446
  return new Promise((resolve, reject) => {
354
447
  if (!keyPair || !keyPair.publicKey)
355
448
  return reject(new Error('Need Signer to sign input'));
449
+ // TODO: Add a pubkey/pubkeyhash cache to each input
450
+ // as input information is added, then eventually
451
+ // optimize this method.
356
452
  const results = [];
357
453
  const promises = [];
358
454
  for (const [i] of this.data.inputs.entries()) {
@@ -376,9 +472,9 @@ export class Psbt {
376
472
  }
377
473
  const input = checkForInput(this.data.inputs, inputIndex);
378
474
  if (isTaprootInput(input)) {
379
- return this._signTaprootInput(inputIndex, input, keyPair, undefined, sighashTypes);
475
+ return this.#signTaprootInput(inputIndex, input, keyPair, undefined, sighashTypes);
380
476
  }
381
- return this._signInput(inputIndex, keyPair, sighashTypes);
477
+ return this.#signInput(inputIndex, keyPair, sighashTypes);
382
478
  }
383
479
  signTaprootInput(inputIndex, keyPair, tapLeafHashToSign, sighashTypes) {
384
480
  if (!keyPair || !keyPair.publicKey) {
@@ -386,7 +482,7 @@ export class Psbt {
386
482
  }
387
483
  const input = checkForInput(this.data.inputs, inputIndex);
388
484
  if (isTaprootInput(input)) {
389
- return this._signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, sighashTypes);
485
+ return this.#signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, sighashTypes);
390
486
  }
391
487
  throw new Error(`Input #${inputIndex} is not of type Taproot.`);
392
488
  }
@@ -396,8 +492,8 @@ export class Psbt {
396
492
  throw new Error('Need Signer to sign input');
397
493
  const input = checkForInput(this.data.inputs, inputIndex);
398
494
  if (isTaprootInput(input))
399
- return this._signTaprootInputAsync(inputIndex, input, keyPair, undefined, sighashTypes);
400
- return this._signInputAsync(inputIndex, keyPair, sighashTypes);
495
+ return this.#signTaprootInputAsync(inputIndex, input, keyPair, undefined, sighashTypes);
496
+ return this.#signInputAsync(inputIndex, keyPair, sighashTypes);
401
497
  });
402
498
  }
403
499
  signTaprootInputAsync(inputIndex, keyPair, tapLeafHash, sighashTypes) {
@@ -406,20 +502,20 @@ export class Psbt {
406
502
  throw new Error('Need Signer to sign input');
407
503
  const input = checkForInput(this.data.inputs, inputIndex);
408
504
  if (isTaprootInput(input))
409
- return this._signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes);
505
+ return this.#signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes);
410
506
  throw new Error(`Input #${inputIndex} is not of type Taproot.`);
411
507
  });
412
508
  }
413
509
  toBuffer() {
414
- checkCache(this.__CACHE);
415
- return this.data.toBuffer();
510
+ checkCache(this.#cache);
511
+ return new Uint8Array(this.data.toBuffer());
416
512
  }
417
513
  toHex() {
418
- checkCache(this.__CACHE);
514
+ checkCache(this.#cache);
419
515
  return this.data.toHex();
420
516
  }
421
517
  toBase64() {
422
- checkCache(this.__CACHE);
518
+ checkCache(this.#cache);
423
519
  return this.data.toBase64();
424
520
  }
425
521
  updateGlobal(updateData) {
@@ -430,9 +526,21 @@ export class Psbt {
430
526
  if (updateData.witnessScript)
431
527
  checkInvalidP2WSH(updateData.witnessScript);
432
528
  checkTaprootInputFields(this.data.inputs[inputIndex], updateData, 'updateInput');
433
- this.data.updateInput(inputIndex, updateData);
529
+ // Convert witnessUtxo for bip174 v3 compatibility (value: bigint, script: Uint8Array)
530
+ const normalizedUpdate = updateData.witnessUtxo
531
+ ? {
532
+ ...updateData,
533
+ witnessUtxo: {
534
+ script: updateData.witnessUtxo.script,
535
+ value: typeof updateData.witnessUtxo.value === 'bigint'
536
+ ? updateData.witnessUtxo.value
537
+ : BigInt(updateData.witnessUtxo.value),
538
+ },
539
+ }
540
+ : updateData;
541
+ this.data.updateInput(inputIndex, normalizedUpdate);
434
542
  if (updateData.nonWitnessUtxo) {
435
- addNonWitnessTxCache(this.__CACHE, this.data.inputs[inputIndex], inputIndex);
543
+ addNonWitnessTxCache(this.#cache, this.data.inputs[inputIndex], inputIndex);
436
544
  }
437
545
  return this;
438
546
  }
@@ -459,18 +567,18 @@ export class Psbt {
459
567
  return this;
460
568
  }
461
569
  checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes) {
462
- if (typeof keyPair.signSchnorr !== 'function')
570
+ if (!('signSchnorr' in keyPair) || typeof keyPair.signSchnorr !== 'function')
463
571
  throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
464
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
572
+ const pubkey = keyPair.publicKey instanceof Uint8Array
465
573
  ? keyPair.publicKey
466
- : Buffer.from(keyPair.publicKey);
467
- const hashesForSig = getTaprootHashesForSig(inputIndex, input, this.data.inputs, pubkey, this.__CACHE, tapLeafHashToSign, allowedSighashTypes);
574
+ : new Uint8Array(keyPair.publicKey);
575
+ const hashesForSig = getTaprootHashesForSig(inputIndex, input, this.data.inputs, pubkey, this.#cache, tapLeafHashToSign, allowedSighashTypes);
468
576
  if (!hashesForSig || !hashesForSig.length)
469
- throw new Error(`Can not sign for input #${inputIndex} with the key ${pubkey.toString('hex')}`);
577
+ throw new Error(`Can not sign for input #${inputIndex} with the key ${toHex(pubkey)}`);
470
578
  return hashesForSig;
471
579
  }
472
- _finalizeInput(inputIndex, input, finalScriptsFunc = getFinalScripts, canRunChecks = true) {
473
- const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(inputIndex, input, this.__CACHE);
580
+ #finalizeInput(inputIndex, input, finalScriptsFunc = getFinalScripts, canRunChecks = true) {
581
+ const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(inputIndex, input, this.#cache);
474
582
  if (!script)
475
583
  throw new Error(`No script found for input #${inputIndex}`);
476
584
  checkPartialSigSighashes(input);
@@ -484,9 +592,10 @@ export class Psbt {
484
592
  this.data.clearFinalizedInput(inputIndex);
485
593
  return this;
486
594
  }
487
- _finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc = tapScriptFinalizer) {
595
+ #finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc = tapScriptFinalizer) {
488
596
  if (!input.witnessUtxo)
489
597
  throw new Error(`Cannot finalize input #${inputIndex}. Missing witness utxo.`);
598
+ // Check key spend first. Increased privacy and reduced block space.
490
599
  if (input.tapKeySig) {
491
600
  const payment = payments.p2tr({
492
601
  output: input.witnessUtxo.script,
@@ -504,14 +613,14 @@ export class Psbt {
504
613
  this.data.clearFinalizedInput(inputIndex);
505
614
  return this;
506
615
  }
507
- _validateSignaturesOfInput(inputIndex, validator, pubkey) {
616
+ #validateSignaturesOfInput(inputIndex, validator, pubkey) {
508
617
  const input = this.data.inputs[inputIndex];
509
618
  const partialSig = (input || {}).partialSig;
510
619
  if (!input || !partialSig || partialSig.length < 1)
511
620
  throw new Error('No signatures to validate');
512
621
  if (typeof validator !== 'function')
513
622
  throw new Error('Need validator function to validate signatures');
514
- const mySigs = pubkey ? partialSig.filter((sig) => sig.pubkey.equals(pubkey)) : partialSig;
623
+ const mySigs = pubkey ? partialSig.filter((sig) => equals(sig.pubkey, pubkey)) : partialSig;
515
624
  if (mySigs.length < 1)
516
625
  throw new Error('No signatures for this pubkey');
517
626
  const results = [];
@@ -519,21 +628,23 @@ export class Psbt {
519
628
  let scriptCache;
520
629
  let sighashCache;
521
630
  for (const pSig of mySigs) {
522
- const sig = bscript.signature.decode(pSig.signature);
631
+ const pSigSignature = pSig.signature;
632
+ const pSigPubkey = pSig.pubkey;
633
+ const sig = bscript.signature.decode(pSigSignature);
523
634
  const { hash, script } = sighashCache !== sig.hashType || !hashCache || !scriptCache
524
635
  ? getHashForSig(inputIndex, Object.assign({}, input, {
525
636
  sighashType: sig.hashType,
526
- }), this.__CACHE, true)
637
+ }), this.#cache, true)
527
638
  : { hash: hashCache, script: scriptCache };
528
639
  sighashCache = sig.hashType;
529
640
  hashCache = hash;
530
641
  scriptCache = script;
531
- checkScriptForPubkey(pSig.pubkey, script, 'verify');
532
- results.push(validator(pSig.pubkey, hash, sig.signature));
642
+ checkScriptForPubkey(pSigPubkey, script, 'verify');
643
+ results.push(validator(pSigPubkey, hash, sig.signature));
533
644
  }
534
645
  return results.every((res) => res);
535
646
  }
536
- validateSignaturesOfTaprootInput(inputIndex, validator, pubkey) {
647
+ #validateSignaturesOfTaprootInput(inputIndex, validator, pubkey) {
537
648
  const input = this.data.inputs[inputIndex];
538
649
  const tapKeySig = (input || {}).tapKeySig;
539
650
  const tapScriptSig = (input || {}).tapScriptSig;
@@ -541,10 +652,10 @@ export class Psbt {
541
652
  throw new Error('No signatures to validate');
542
653
  if (typeof validator !== 'function')
543
654
  throw new Error('Need validator function to validate signatures');
544
- pubkey = pubkey && toXOnly(pubkey);
545
- const allHashses = pubkey
546
- ? getTaprootHashesForSig(inputIndex, input, this.data.inputs, pubkey, this.__CACHE)
547
- : getAllTaprootHashesForSig(inputIndex, input, this.data.inputs, this.__CACHE);
655
+ const xPubkey = pubkey ? toXOnly(pubkey) : undefined;
656
+ const allHashses = xPubkey
657
+ ? getTaprootHashesForSig(inputIndex, input, this.data.inputs, xPubkey, this.#cache)
658
+ : getAllTaprootHashesForSig(inputIndex, input, this.data.inputs, this.#cache);
548
659
  if (!allHashses.length)
549
660
  throw new Error('No signatures for this pubkey');
550
661
  const tapKeyHash = allHashses.find((h) => !h.leafHash);
@@ -557,9 +668,10 @@ export class Psbt {
557
668
  }
558
669
  if (tapScriptSig) {
559
670
  for (const tapSig of tapScriptSig) {
560
- const tapSigHash = allHashses.find((h) => tapSig.pubkey.equals(h.pubkey));
671
+ const tapSigPubkey = tapSig.pubkey;
672
+ const tapSigHash = allHashses.find((h) => equals(tapSigPubkey, h.pubkey));
561
673
  if (tapSigHash) {
562
- const isValidTapScriptSig = validator(tapSig.pubkey, tapSigHash.hash, trimTaprootSig(tapSig.signature));
674
+ const isValidTapScriptSig = validator(tapSigPubkey, tapSigHash.hash, trimTaprootSig(tapSig.signature));
563
675
  if (!isValidTapScriptSig)
564
676
  return false;
565
677
  validationResultCount++;
@@ -568,53 +680,58 @@ export class Psbt {
568
680
  }
569
681
  return validationResultCount > 0;
570
682
  }
571
- _signInput(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
572
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
683
+ #signInput(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
684
+ const pubkey = keyPair.publicKey instanceof Uint8Array
573
685
  ? keyPair.publicKey
574
- : Buffer.from(keyPair.publicKey);
575
- const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.__CACHE, sighashTypes);
686
+ : new Uint8Array(keyPair.publicKey);
687
+ const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.#cache, sighashTypes);
576
688
  const sig = keyPair.sign(hash);
577
689
  const partialSig = [
578
690
  {
579
691
  pubkey,
580
- signature: bscript.signature.encode(Buffer.isBuffer(sig) ? sig : Buffer.from(sig), sighashType),
692
+ signature: bscript.signature.encode(sig instanceof Uint8Array ? sig : new Uint8Array(sig), sighashType),
581
693
  },
582
694
  ];
583
695
  this.data.updateInput(inputIndex, { partialSig });
696
+ this.#cache.hasSignatures = true;
584
697
  return this;
585
698
  }
586
- _signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes = [Transaction.SIGHASH_DEFAULT]) {
587
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
699
+ #signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes = [Transaction.SIGHASH_DEFAULT]) {
700
+ const pubkey = (keyPair.publicKey instanceof Uint8Array
588
701
  ? keyPair.publicKey
589
- : Buffer.from(keyPair.publicKey);
702
+ : new Uint8Array(keyPair.publicKey));
703
+ if (!('signSchnorr' in keyPair) || typeof keyPair.signSchnorr !== 'function')
704
+ throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
705
+ // checkTaprootHashesForSig validates signSchnorr exists
590
706
  const hashesForSig = this.checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes);
591
707
  const signSchnorr = keyPair.signSchnorr.bind(keyPair);
592
- const toBuffer = (data) => Buffer.isBuffer(data) ? data : Buffer.from(data);
593
708
  const tapKeySig = hashesForSig
594
709
  .filter((h) => !h.leafHash)
595
- .map((h) => serializeTaprootSignature(toBuffer(signSchnorr(h.hash)), input.sighashType))[0];
710
+ .map((h) => serializeTaprootSignature(signSchnorr(h.hash), input.sighashType))[0];
596
711
  const tapScriptSig = hashesForSig
597
712
  .filter((h) => !!h.leafHash)
598
713
  .map((h) => ({
599
714
  pubkey: toXOnly(pubkey),
600
- signature: serializeTaprootSignature(toBuffer(signSchnorr(h.hash)), input.sighashType),
715
+ signature: serializeTaprootSignature(signSchnorr(h.hash), input.sighashType),
601
716
  leafHash: h.leafHash,
602
717
  }));
603
718
  if (tapKeySig) {
604
719
  this.data.updateInput(inputIndex, { tapKeySig });
720
+ this.#cache.hasSignatures = true;
605
721
  }
606
722
  if (tapScriptSig.length) {
607
723
  this.data.updateInput(inputIndex, { tapScriptSig });
724
+ this.#cache.hasSignatures = true;
608
725
  }
609
726
  return this;
610
727
  }
611
- _signInputAsync(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
612
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
728
+ #signInputAsync(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
729
+ const pubkey = keyPair.publicKey instanceof Uint8Array
613
730
  ? keyPair.publicKey
614
- : Buffer.from(keyPair.publicKey);
615
- const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.__CACHE, sighashTypes);
731
+ : new Uint8Array(keyPair.publicKey);
732
+ const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.#cache, sighashTypes);
616
733
  return Promise.resolve(keyPair.sign(hash)).then((signature) => {
617
- const sig = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
734
+ const sig = signature instanceof Uint8Array ? signature : new Uint8Array(signature);
618
735
  const partialSig = [
619
736
  {
620
737
  pubkey,
@@ -622,21 +739,24 @@ export class Psbt {
622
739
  },
623
740
  ];
624
741
  this.data.updateInput(inputIndex, { partialSig });
742
+ this.#cache.hasSignatures = true;
625
743
  });
626
744
  }
627
- async _signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes = [Transaction.SIGHASH_DEFAULT]) {
628
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
745
+ async #signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes = [Transaction.SIGHASH_DEFAULT]) {
746
+ const pubkey = (keyPair.publicKey instanceof Uint8Array
629
747
  ? keyPair.publicKey
630
- : Buffer.from(keyPair.publicKey);
748
+ : new Uint8Array(keyPair.publicKey));
749
+ if (!('signSchnorr' in keyPair) || typeof keyPair.signSchnorr !== 'function')
750
+ throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
751
+ // checkTaprootHashesForSig validates signSchnorr exists
631
752
  const hashesForSig = this.checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHash, sighashTypes);
632
753
  const signSchnorr = keyPair.signSchnorr.bind(keyPair);
633
- const toBuffer = (data) => Buffer.isBuffer(data) ? data : Buffer.from(data);
634
754
  const signaturePromises = [];
635
755
  const tapKeyHash = hashesForSig.filter((h) => !h.leafHash)[0];
636
756
  if (tapKeyHash) {
637
757
  const tapKeySigPromise = Promise.resolve(signSchnorr(tapKeyHash.hash)).then((sig) => {
638
758
  return {
639
- tapKeySig: serializeTaprootSignature(toBuffer(sig), input.sighashType),
759
+ tapKeySig: serializeTaprootSignature(sig, input.sighashType),
640
760
  };
641
761
  });
642
762
  signaturePromises.push(tapKeySigPromise);
@@ -648,7 +768,7 @@ export class Psbt {
648
768
  const tapScriptSig = [
649
769
  {
650
770
  pubkey: toXOnly(pubkey),
651
- signature: serializeTaprootSignature(toBuffer(signature), input.sighashType),
771
+ signature: serializeTaprootSignature(signature, input.sighashType),
652
772
  leafHash: tsh.leafHash,
653
773
  },
654
774
  ];
@@ -659,12 +779,23 @@ export class Psbt {
659
779
  const results = await Promise.all(signaturePromises);
660
780
  for (const v of results) {
661
781
  this.data.updateInput(inputIndex, v);
782
+ this.#cache.hasSignatures = true;
662
783
  }
663
784
  }
664
785
  }
786
+ /**
787
+ * This function is needed to pass to the bip174 base class's fromBuffer.
788
+ * It takes the "transaction buffer" portion of the psbt buffer and returns a
789
+ * Transaction (From the bip174 library) interface.
790
+ */
665
791
  const transactionFromBuffer = (buffer) => new PsbtTransaction(buffer);
792
+ /**
793
+ * This class implements the Transaction interface from bip174 library.
794
+ * It contains a bitcoinjs-lib Transaction object.
795
+ */
666
796
  class PsbtTransaction {
667
- constructor(buffer = Buffer.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
797
+ tx;
798
+ constructor(buffer = new Uint8Array([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
668
799
  this.tx = Transaction.fromBuffer(buffer);
669
800
  checkTxEmpty(this.tx);
670
801
  Object.defineProperty(this, 'tx', {
@@ -681,20 +812,18 @@ class PsbtTransaction {
681
812
  addInput(input) {
682
813
  if (input.hash === undefined ||
683
814
  input.index === undefined ||
684
- (!Buffer.isBuffer(input.hash) && typeof input.hash !== 'string') ||
815
+ (!(input.hash instanceof Uint8Array) && typeof input.hash !== 'string') ||
685
816
  typeof input.index !== 'number') {
686
817
  throw new Error('Error adding input.');
687
818
  }
688
- const hash = typeof input.hash === 'string'
689
- ? reverseBuffer(Buffer.from(input.hash, 'hex'))
690
- : input.hash;
819
+ const hash = (typeof input.hash === 'string' ? reverse(fromHex(input.hash)) : input.hash);
691
820
  this.tx.addInput(hash, input.index, input.sequence);
692
821
  }
693
822
  addOutput(output) {
694
823
  if (output.script === undefined ||
695
824
  output.value === undefined ||
696
- !Buffer.isBuffer(output.script) ||
697
- typeof output.value !== 'number') {
825
+ !(output.script instanceof Uint8Array) ||
826
+ typeof output.value !== 'bigint') {
698
827
  throw new Error('Error adding output.');
699
828
  }
700
829
  this.tx.addOutput(output.script, output.value);
@@ -713,6 +842,8 @@ function canFinalize(input, script, scriptType) {
713
842
  const p2ms = payments.p2ms({
714
843
  output: script,
715
844
  });
845
+ if (p2ms.m === undefined)
846
+ throw new Error('Cannot determine m for multisig');
716
847
  return hasSigs(p2ms.m, input.partialSig, p2ms.pubkeys);
717
848
  }
718
849
  case 'nonstandard':
@@ -721,11 +852,6 @@ function canFinalize(input, script, scriptType) {
721
852
  return false;
722
853
  }
723
854
  }
724
- function checkCache(cache) {
725
- if (cache.__UNSAFE_SIGN_NONSEGWIT) {
726
- throw new Error('Not BIP174 compliant, can not export');
727
- }
728
- }
729
855
  function hasSigs(neededSigs, partialSig, pubkeys) {
730
856
  if (!partialSig)
731
857
  return false;
@@ -734,7 +860,7 @@ function hasSigs(neededSigs, partialSig, pubkeys) {
734
860
  sigs = pubkeys
735
861
  .map((pkey) => {
736
862
  const pubkey = compressPubkey(pkey);
737
- return partialSig.find((pSig) => pSig.pubkey.equals(pubkey));
863
+ return partialSig.find((pSig) => equals(pSig.pubkey, pubkey));
738
864
  })
739
865
  .filter((v) => !!v);
740
866
  }
@@ -745,31 +871,25 @@ function hasSigs(neededSigs, partialSig, pubkeys) {
745
871
  throw new Error('Too many signatures');
746
872
  return sigs.length === neededSigs;
747
873
  }
748
- function isFinalized(input) {
749
- return !!input.finalScriptSig || !!input.finalScriptWitness;
750
- }
751
874
  function bip32DerivationIsMine(root) {
752
875
  return (d) => {
753
- const fingerprint = Buffer.isBuffer(root.fingerprint)
876
+ const fingerprint = root.fingerprint instanceof Uint8Array
754
877
  ? root.fingerprint
755
- : Buffer.from(root.fingerprint);
756
- if (!d.masterFingerprint.equals(fingerprint))
878
+ : new Uint8Array(root.fingerprint);
879
+ if (!equals(d.masterFingerprint, fingerprint))
757
880
  return false;
758
881
  const derivedPubkey = root.derivePath(d.path).publicKey;
759
- const pubkey = Buffer.isBuffer(derivedPubkey) ? derivedPubkey : Buffer.from(derivedPubkey);
760
- if (!pubkey.equals(d.pubkey))
882
+ const pubkey = derivedPubkey instanceof Uint8Array ? derivedPubkey : new Uint8Array(derivedPubkey);
883
+ if (!equals(pubkey, d.pubkey))
761
884
  return false;
762
885
  return true;
763
886
  };
764
887
  }
765
- function check32Bit(num) {
766
- if (typeof num !== 'number' || num !== Math.floor(num) || num > 0xffffffff || num < 0) {
767
- throw new Error('Invalid 32 bit integer');
768
- }
769
- }
770
888
  function checkFees(psbt, cache, opts) {
771
- const feeRate = cache.__FEE_RATE || psbt.getFeeRate();
772
- const vsize = cache.__EXTRACTED_TX.virtualSize();
889
+ const feeRate = cache.feeRate || psbt.getFeeRate();
890
+ if (!cache.extractedTx)
891
+ throw new Error('Transaction not extracted');
892
+ const vsize = cache.extractedTx.virtualSize();
773
893
  const satoshis = feeRate * vsize;
774
894
  if (feeRate >= opts.maximumFeeRate) {
775
895
  throw new Error(`Warning: You are paying around ${(satoshis / 1e8).toFixed(8)} in ` +
@@ -779,81 +899,24 @@ function checkFees(psbt, cache, opts) {
779
899
  `pass true to the first arg of extractTransaction.`);
780
900
  }
781
901
  }
782
- function checkInputsForPartialSig(inputs, action) {
783
- inputs.forEach((input) => {
784
- const throws = isTaprootInput(input)
785
- ? checkTaprootInputForSigs(input, action)
786
- : checkInputForSig(input, action);
787
- if (throws)
788
- throw new Error('Can not modify transaction, signatures exist.');
789
- });
790
- }
791
- function checkPartialSigSighashes(input) {
792
- if (!input.sighashType || !input.partialSig)
793
- return;
794
- const { partialSig, sighashType } = input;
795
- partialSig.forEach((pSig) => {
796
- const { hashType } = bscript.signature.decode(pSig.signature);
797
- if (sighashType !== hashType) {
798
- throw new Error('Signature sighash does not match input sighash type');
799
- }
800
- });
801
- }
802
- function checkScriptForPubkey(pubkey, script, action) {
803
- if (!pubkeyInScript(pubkey, script)) {
804
- throw new Error(`Can not ${action} for this input with the key ${pubkey.toString('hex')}`);
805
- }
806
- }
807
- function checkTxEmpty(tx) {
808
- const isEmpty = tx.ins.every((input) => input.script &&
809
- input.script.length === 0 &&
810
- input.witness &&
811
- input.witness.length === 0);
812
- if (!isEmpty) {
813
- throw new Error('Format Error: Transaction ScriptSigs are not empty');
814
- }
815
- }
816
- function checkTxForDupeIns(tx, cache) {
817
- tx.ins.forEach((input) => {
818
- checkTxInputCache(cache, input);
819
- });
820
- }
821
- function checkTxInputCache(cache, input) {
822
- const key = `${reverseBuffer(Buffer.from(input.hash)).toString('hex')}:${input.index}`;
823
- if (cache.__TX_IN_CACHE[key])
824
- throw new Error('Duplicate input detected.');
825
- cache.__TX_IN_CACHE[key] = 1;
826
- }
827
- function scriptCheckerFactory(payment, paymentScriptName) {
828
- return (inputIndex, scriptPubKey, redeemScript, ioType) => {
829
- const redeemScriptOutput = payment({
830
- redeem: { output: redeemScript },
831
- }).output;
832
- if (!scriptPubKey.equals(redeemScriptOutput)) {
833
- throw new Error(`${paymentScriptName} for ${ioType} #${inputIndex} doesn't match the scriptPubKey in the prevout`);
834
- }
835
- };
836
- }
837
- const checkRedeemScript = scriptCheckerFactory(payments.p2sh, 'Redeem script');
838
- const checkWitnessScript = scriptCheckerFactory(payments.p2wsh, 'Witness script');
839
902
  function getTxCacheValue(key, name, inputs, c, disableOutputChecks = false) {
840
903
  if (!inputs.every(isFinalized))
841
904
  throw new Error(`PSBT must be finalized to calculate ${name}`);
842
- if (key === '__FEE_RATE' && c.__FEE_RATE)
843
- return c.__FEE_RATE;
844
- if (key === '__FEE' && c.__FEE)
845
- return c.__FEE;
905
+ if (key === 'feeRate' && c.feeRate)
906
+ return c.feeRate;
907
+ if (key === 'fee' && c.fee)
908
+ return c.fee;
846
909
  let tx;
847
910
  let mustFinalize = true;
848
- if (c.__EXTRACTED_TX) {
849
- tx = c.__EXTRACTED_TX;
911
+ if (c.extractedTx) {
912
+ tx = c.extractedTx;
850
913
  mustFinalize = false;
851
914
  }
852
915
  else {
853
- tx = c.__TX.clone();
916
+ tx = c.tx.clone();
854
917
  }
855
918
  inputFinalizeGetAmts(inputs, tx, c, mustFinalize, disableOutputChecks);
856
- const value = key === '__FEE_RATE' ? c.__FEE_RATE : c.__FEE;
919
+ const value = key === 'feeRate' ? c.feeRate : c.fee;
857
920
  if (value === undefined)
858
921
  throw new Error(`Failed to calculate ${name}`);
859
922
  return value;
@@ -863,23 +926,27 @@ export function getFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP
863
926
  if (!canFinalize(input, script, scriptType) && canRunChecks) {
864
927
  throw new Error(`Can not finalize input #${inputIndex}`);
865
928
  }
929
+ if (!input.partialSig)
930
+ throw new Error('Input missing partial signatures');
866
931
  return prepareFinalScripts(script, scriptType, input.partialSig, isSegwit, isP2SH, isP2WSH, solution);
867
932
  }
868
933
  export function prepareFinalScripts(script, scriptType, partialSig, isSegwit, isP2SH, isP2WSH, solution) {
869
934
  let finalScriptSig;
870
935
  let finalScriptWitness;
936
+ // Wow, the payments API is very handy
871
937
  const payment = getPayment(script, scriptType, partialSig);
872
938
  const p2wsh = !isP2WSH ? null : payments.p2wsh({ redeem: payment });
873
939
  const p2sh = !isP2SH ? null : payments.p2sh({ redeem: p2wsh || payment });
874
940
  if (isSegwit) {
875
- if (p2wsh) {
941
+ if (p2wsh && p2wsh.witness) {
876
942
  finalScriptWitness = witnessStackToScriptWitness(p2wsh.witness);
877
943
  }
878
- else if (payment) {
944
+ else if (payment && payment.witness) {
879
945
  finalScriptWitness = witnessStackToScriptWitness(payment.witness);
880
946
  }
881
947
  else {
882
- finalScriptWitness = witnessStackToScriptWitness(solution ?? [Buffer.from([0x00])]);
948
+ // nonstandard segwit script
949
+ finalScriptWitness = witnessStackToScriptWitness(solution ?? [new Uint8Array([0x00])]);
883
950
  }
884
951
  if (p2sh) {
885
952
  finalScriptSig = p2sh?.input;
@@ -891,8 +958,7 @@ export function prepareFinalScripts(script, scriptType, partialSig, isSegwit, is
891
958
  }
892
959
  else {
893
960
  if (!payment) {
894
- finalScriptSig =
895
- Array.isArray(solution) && solution[0] ? solution[0] : Buffer.from([0x01]);
961
+ finalScriptSig = (Array.isArray(solution) && solution[0] ? solution[0] : new Uint8Array([0x01]));
896
962
  }
897
963
  else {
898
964
  finalScriptSig = payment.input;
@@ -914,7 +980,7 @@ function getHashAndSighashType(inputs, inputIndex, pubkey, cache, sighashTypes)
914
980
  };
915
981
  }
916
982
  function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
917
- const unsignedTx = cache.__TX;
983
+ const unsignedTx = cache.tx;
918
984
  const sighashType = input.sighashType || Transaction.SIGHASH_ALL;
919
985
  checkSighashTypeAllowed(sighashType, sighashTypes);
920
986
  let hash;
@@ -923,33 +989,42 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
923
989
  const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(cache, input, inputIndex);
924
990
  const prevoutHash = unsignedTx.ins[inputIndex].hash;
925
991
  const utxoHash = nonWitnessUtxoTx.getHash();
926
- if (!prevoutHash.equals(utxoHash)) {
992
+ // If a non-witness UTXO is provided, its hash must match the hash specified in the prevout
993
+ if (!equals(prevoutHash, utxoHash)) {
927
994
  throw new Error(`Non-witness UTXO hash for input #${inputIndex} doesn't match the hash specified in the prevout`);
928
995
  }
929
996
  const prevoutIndex = unsignedTx.ins[inputIndex].index;
930
997
  prevout = nonWitnessUtxoTx.outs[prevoutIndex];
931
998
  }
932
999
  else if (input.witnessUtxo) {
933
- prevout = input.witnessUtxo;
1000
+ prevout = {
1001
+ script: input.witnessUtxo.script,
1002
+ value: input.witnessUtxo.value,
1003
+ };
934
1004
  }
935
1005
  else {
936
1006
  throw new Error('Need a Utxo input item for signing');
937
1007
  }
938
1008
  const { meaningfulScript, type } = getMeaningfulScript(prevout.script, inputIndex, 'input', input.redeemScript, input.witnessScript);
1009
+ const script = meaningfulScript;
939
1010
  if (['p2sh-p2wsh', 'p2wsh'].indexOf(type) >= 0) {
940
- hash = unsignedTx.hashForWitnessV0(inputIndex, meaningfulScript, prevout.value, sighashType);
1011
+ hash = unsignedTx.hashForWitnessV0(inputIndex, script, prevout.value, sighashType);
941
1012
  }
942
1013
  else if (isP2WPKH(meaningfulScript)) {
943
- const signingScript = payments.p2pkh({
1014
+ // P2WPKH uses the P2PKH template for prevoutScript when signing
1015
+ const p2pkhPayment = payments.p2pkh({
944
1016
  hash: meaningfulScript.subarray(2),
945
- }).output;
946
- hash = unsignedTx.hashForWitnessV0(inputIndex, signingScript, prevout.value, sighashType);
1017
+ });
1018
+ if (!p2pkhPayment.output)
1019
+ throw new Error('Unable to create signing script');
1020
+ hash = unsignedTx.hashForWitnessV0(inputIndex, p2pkhPayment.output, prevout.value, sighashType);
947
1021
  }
948
1022
  else {
949
- if (input.nonWitnessUtxo === undefined && !cache.__UNSAFE_SIGN_NONSEGWIT)
1023
+ // non-segwit
1024
+ if (input.nonWitnessUtxo === undefined && !cache.unsafeSignNonSegwit)
950
1025
  throw new Error(`Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
951
- meaningfulScript.toString('hex'));
952
- if (!forValidate && cache.__UNSAFE_SIGN_NONSEGWIT)
1026
+ toHex(meaningfulScript));
1027
+ if (!forValidate && cache.unsafeSignNonSegwit)
953
1028
  console.warn('Warning: Signing non-segwit inputs without the full parent transaction ' +
954
1029
  'means there is a chance that a miner could feed you incorrect information ' +
955
1030
  "to trick you into paying large fees. This behavior is the same as Psbt's predecessor " +
@@ -957,10 +1032,10 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
957
1032
  'able to export this Psbt with toBuffer|toBase64|toHex since it is not ' +
958
1033
  'BIP174 compliant.\n*********************\nPROCEED WITH CAUTION!\n' +
959
1034
  '*********************');
960
- hash = unsignedTx.hashForSignature(inputIndex, meaningfulScript, sighashType);
1035
+ hash = unsignedTx.hashForSignature(inputIndex, script, sighashType);
961
1036
  }
962
1037
  return {
963
- script: meaningfulScript,
1038
+ script,
964
1039
  sighashType,
965
1040
  hash,
966
1041
  };
@@ -982,24 +1057,34 @@ function getAllTaprootHashesForSig(inputIndex, input, inputs, cache) {
982
1057
  }
983
1058
  function getPrevoutTaprootKey(inputIndex, input, cache) {
984
1059
  const { script } = getScriptAndAmountFromUtxo(inputIndex, input, cache);
985
- return isP2TR(script) ? Buffer.from(script.subarray(2, 34)) : null;
1060
+ return isP2TR(script) ? script.subarray(2, 34) : null;
986
1061
  }
987
1062
  function trimTaprootSig(signature) {
988
- return signature.length === 64 ? signature : Buffer.from(signature.subarray(0, 64));
1063
+ return signature.length === 64 ? signature : signature.subarray(0, 64);
989
1064
  }
990
1065
  function getTaprootHashesForSig(inputIndex, input, inputs, pubkey, cache, tapLeafHashToSign, allowedSighashTypes) {
991
- const unsignedTx = cache.__TX;
1066
+ const unsignedTx = cache.tx;
992
1067
  const sighashType = input.sighashType || Transaction.SIGHASH_DEFAULT;
993
1068
  checkSighashTypeAllowed(sighashType, allowedSighashTypes);
994
- const prevOuts = inputs.map((i, index) => getScriptAndAmountFromUtxo(index, i, cache));
995
- const signingScripts = prevOuts.map((o) => o.script);
996
- const values = prevOuts.map((o) => o.value);
1069
+ if (!cache.prevOuts) {
1070
+ const prevOuts = inputs.map((i, index) => getScriptAndAmountFromUtxo(index, i, cache));
1071
+ cache.prevOuts = prevOuts;
1072
+ cache.signingScripts = prevOuts.map((o) => o.script);
1073
+ cache.values = prevOuts.map((o) => o.value);
1074
+ }
1075
+ const signingScripts = cache.signingScripts;
1076
+ const values = cache.values;
1077
+ // Compute taproot hash cache once for all inputs (O(n) -> O(1) per input)
1078
+ if (!cache.taprootHashCache) {
1079
+ cache.taprootHashCache = unsignedTx.getTaprootHashCache(signingScripts, values);
1080
+ }
1081
+ const taprootCache = cache.taprootHashCache;
997
1082
  const hashes = [];
998
1083
  if (input.tapInternalKey && !tapLeafHashToSign) {
999
- const outputKey = getPrevoutTaprootKey(inputIndex, input, cache) || Buffer.from([]);
1000
- if (toXOnly(pubkey).equals(outputKey)) {
1001
- const tapKeyHash = unsignedTx.hashForWitnessV1(inputIndex, signingScripts, values, sighashType);
1002
- hashes.push({ pubkey, hash: tapKeyHash });
1084
+ const outputKey = getPrevoutTaprootKey(inputIndex, input, cache) || new Uint8Array(0);
1085
+ if (equals(toXOnly(pubkey), outputKey)) {
1086
+ const tapKeyHash = unsignedTx.hashForWitnessV1(inputIndex, signingScripts, values, sighashType, undefined, undefined, taprootCache);
1087
+ hashes.push({ pubkey: pubkey, hash: tapKeyHash });
1003
1088
  }
1004
1089
  }
1005
1090
  const tapLeafHashes = (input.tapLeafScript || [])
@@ -1011,11 +1096,11 @@ function getTaprootHashesForSig(inputIndex, input, inputs, pubkey, cache, tapLea
1011
1096
  });
1012
1097
  return Object.assign({ hash }, tapLeaf);
1013
1098
  })
1014
- .filter((tapLeaf) => !tapLeafHashToSign || tapLeafHashToSign.equals(tapLeaf.hash))
1099
+ .filter((tapLeaf) => !tapLeafHashToSign || equals(tapLeafHashToSign, tapLeaf.hash))
1015
1100
  .map((tapLeaf) => {
1016
- const tapScriptHash = unsignedTx.hashForWitnessV1(inputIndex, signingScripts, values, sighashType, tapLeaf.hash);
1101
+ const tapScriptHash = unsignedTx.hashForWitnessV1(inputIndex, signingScripts, values, sighashType, tapLeaf.hash, undefined, taprootCache);
1017
1102
  return {
1018
- pubkey,
1103
+ pubkey: pubkey,
1019
1104
  hash: tapScriptHash,
1020
1105
  leafHash: tapLeaf.hash,
1021
1106
  };
@@ -1030,41 +1115,38 @@ function checkSighashTypeAllowed(sighashType, sighashTypes) {
1030
1115
  }
1031
1116
  }
1032
1117
  function getPayment(script, scriptType, partialSig) {
1033
- let payment;
1118
+ const scriptBranded = script;
1034
1119
  switch (scriptType) {
1035
1120
  case 'multisig': {
1036
1121
  const sigs = getSortedSigs(script, partialSig);
1037
- payment = payments.p2ms({
1038
- output: script,
1122
+ return payments.p2ms({
1123
+ output: scriptBranded,
1039
1124
  signatures: sigs,
1040
1125
  });
1041
- break;
1042
1126
  }
1043
1127
  case 'pubkey':
1044
- payment = payments.p2pk({
1045
- output: script,
1128
+ return payments.p2pk({
1129
+ output: scriptBranded,
1046
1130
  signature: partialSig[0].signature,
1047
1131
  });
1048
- break;
1049
1132
  case 'pubkeyhash':
1050
- payment = payments.p2pkh({
1051
- output: script,
1133
+ return payments.p2pkh({
1134
+ output: scriptBranded,
1052
1135
  pubkey: partialSig[0].pubkey,
1053
1136
  signature: partialSig[0].signature,
1054
1137
  });
1055
- break;
1056
1138
  case 'witnesspubkeyhash':
1057
- payment = payments.p2wpkh({
1058
- output: script,
1139
+ return payments.p2wpkh({
1140
+ output: scriptBranded,
1059
1141
  pubkey: partialSig[0].pubkey,
1060
1142
  signature: partialSig[0].signature,
1061
1143
  });
1062
- break;
1144
+ default:
1145
+ throw new Error(`Unknown script type: ${scriptType}`);
1063
1146
  }
1064
- return payment;
1065
1147
  }
1066
1148
  function getScriptFromInput(inputIndex, input, cache) {
1067
- const unsignedTx = cache.__TX;
1149
+ const unsignedTx = cache.tx;
1068
1150
  const res = {
1069
1151
  script: null,
1070
1152
  isSegwit: false,
@@ -1089,7 +1171,7 @@ function getScriptFromInput(inputIndex, input, cache) {
1089
1171
  res.script = input.witnessUtxo.script;
1090
1172
  }
1091
1173
  }
1092
- if (input.witnessScript || isP2WPKH(res.script)) {
1174
+ if (input.witnessScript || (res.script && isP2WPKH(res.script))) {
1093
1175
  res.isSegwit = true;
1094
1176
  }
1095
1177
  else {
@@ -1110,7 +1192,7 @@ function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
1110
1192
  }
1111
1193
  const myDerivations = input.bip32Derivation
1112
1194
  .map((bipDv) => {
1113
- if (bipDv.masterFingerprint.equals(hdKeyPair.fingerprint)) {
1195
+ if (equals(bipDv.masterFingerprint, hdKeyPair.fingerprint)) {
1114
1196
  return bipDv;
1115
1197
  }
1116
1198
  else {
@@ -1123,7 +1205,7 @@ function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
1123
1205
  }
1124
1206
  return myDerivations.map((bipDv) => {
1125
1207
  const node = hdKeyPair.derivePath(bipDv.path);
1126
- if (!bipDv.pubkey.equals(node.publicKey)) {
1208
+ if (!equals(bipDv.pubkey, node.publicKey)) {
1127
1209
  throw new Error('pubkey did not match bip32Derivation');
1128
1210
  }
1129
1211
  return node;
@@ -1131,80 +1213,56 @@ function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
1131
1213
  }
1132
1214
  function getSortedSigs(script, partialSig) {
1133
1215
  const p2ms = payments.p2ms({ output: script });
1134
- return p2ms
1135
- .pubkeys.map((pk) => {
1136
- return (partialSig.filter((ps) => {
1137
- return ps.pubkey.equals(pk);
1138
- })[0] || {}).signature;
1139
- })
1140
- .filter((v) => !!v);
1141
- }
1142
- function scriptWitnessToWitnessStack(buffer) {
1143
- let offset = 0;
1144
- function readSlice(n) {
1145
- offset += n;
1146
- return buffer.subarray(offset - n, offset);
1147
- }
1148
- function readVarInt() {
1149
- const vi = varuintDecode(buffer, offset);
1150
- offset += varuintDecode.bytes;
1151
- return vi;
1152
- }
1153
- function readVarSlice() {
1154
- return readSlice(readVarInt());
1155
- }
1156
- function readVector() {
1157
- const count = readVarInt();
1158
- const vector = [];
1159
- for (let i = 0; i < count; i++)
1160
- vector.push(readVarSlice());
1161
- return vector;
1162
- }
1163
- return readVector();
1164
- }
1165
- function sighashTypeToString(sighashType) {
1166
- let text = sighashType & Transaction.SIGHASH_ANYONECANPAY ? 'SIGHASH_ANYONECANPAY | ' : '';
1167
- const sigMod = sighashType & 0x1f;
1168
- switch (sigMod) {
1169
- case Transaction.SIGHASH_ALL:
1170
- text += 'SIGHASH_ALL';
1171
- break;
1172
- case Transaction.SIGHASH_SINGLE:
1173
- text += 'SIGHASH_SINGLE';
1174
- break;
1175
- case Transaction.SIGHASH_NONE:
1176
- text += 'SIGHASH_NONE';
1177
- break;
1178
- }
1179
- return text;
1216
+ if (!p2ms.pubkeys)
1217
+ throw new Error('Cannot extract pubkeys from multisig script');
1218
+ // for each pubkey in order of p2ms script
1219
+ const result = [];
1220
+ for (const pk of p2ms.pubkeys) {
1221
+ // filter partialSig array by pubkey being equal
1222
+ const matched = partialSig.filter((ps) => {
1223
+ return equals(ps.pubkey, pk);
1224
+ })[0];
1225
+ if (matched) {
1226
+ result.push(new Uint8Array(matched.signature));
1227
+ }
1228
+ }
1229
+ return result;
1180
1230
  }
1181
1231
  function addNonWitnessTxCache(cache, input, inputIndex) {
1182
- cache.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo;
1183
- cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = Transaction.fromBuffer(input.nonWitnessUtxo);
1232
+ if (!input.nonWitnessUtxo)
1233
+ throw new Error('nonWitnessUtxo is required');
1234
+ // Prevent prototype pollution - ensure input is a valid object
1235
+ if (input === null || input === Object.prototype) {
1236
+ throw new Error('Invalid input object');
1237
+ }
1238
+ const nonWitnessUtxoBuf = input.nonWitnessUtxo;
1239
+ cache.nonWitnessUtxoBufCache[inputIndex] = nonWitnessUtxoBuf;
1240
+ cache.nonWitnessUtxoTxCache[inputIndex] = Transaction.fromBuffer(nonWitnessUtxoBuf);
1184
1241
  const self = cache;
1185
1242
  const selfIndex = inputIndex;
1186
1243
  delete input.nonWitnessUtxo;
1187
- Object.defineProperty(input, 'nonWitnessUtxo', {
1244
+ // Using Reflect.defineProperty to avoid prototype pollution concerns
1245
+ Reflect.defineProperty(input, 'nonWitnessUtxo', {
1188
1246
  enumerable: true,
1189
1247
  get() {
1190
- const buf = self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex];
1191
- const txCache = self.__NON_WITNESS_UTXO_TX_CACHE[selfIndex];
1248
+ const buf = self.nonWitnessUtxoBufCache[selfIndex];
1249
+ const txCache = self.nonWitnessUtxoTxCache[selfIndex];
1192
1250
  if (buf !== undefined) {
1193
1251
  return buf;
1194
1252
  }
1195
1253
  else {
1196
1254
  const newBuf = txCache.toBuffer();
1197
- self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = newBuf;
1255
+ self.nonWitnessUtxoBufCache[selfIndex] = newBuf;
1198
1256
  return newBuf;
1199
1257
  }
1200
1258
  },
1201
1259
  set(data) {
1202
- self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = data;
1260
+ self.nonWitnessUtxoBufCache[selfIndex] = data;
1203
1261
  },
1204
1262
  });
1205
1263
  }
1206
1264
  function inputFinalizeGetAmts(inputs, tx, cache, mustFinalize, disableOutputChecks) {
1207
- let inputAmount = 0;
1265
+ let inputAmount = 0n;
1208
1266
  inputs.forEach((input, idx) => {
1209
1267
  if (mustFinalize && input.finalScriptSig)
1210
1268
  tx.ins[idx].script = input.finalScriptSig;
@@ -1221,20 +1279,20 @@ function inputFinalizeGetAmts(inputs, tx, cache, mustFinalize, disableOutputChec
1221
1279
  inputAmount += out.value;
1222
1280
  }
1223
1281
  });
1224
- const outputAmount = tx.outs.reduce((total, o) => total + o.value, 0);
1282
+ const outputAmount = tx.outs.reduce((total, o) => total + o.value, 0n);
1225
1283
  const fee = inputAmount - outputAmount;
1226
1284
  if (!disableOutputChecks) {
1227
- if (fee < 0) {
1285
+ if (fee < 0n) {
1228
1286
  throw new Error(`Outputs are spending more than Inputs ${inputAmount} < ${outputAmount}`);
1229
1287
  }
1230
1288
  }
1231
1289
  const bytes = tx.virtualSize();
1232
- cache.__FEE = fee;
1233
- cache.__EXTRACTED_TX = tx;
1234
- cache.__FEE_RATE = Math.floor(fee / bytes);
1290
+ cache.fee = Number(fee);
1291
+ cache.extractedTx = tx;
1292
+ cache.feeRate = Math.floor(Number(fee) / bytes);
1235
1293
  }
1236
1294
  function nonWitnessUtxoTxFromCache(cache, input, inputIndex) {
1237
- const c = cache.__NON_WITNESS_UTXO_TX_CACHE;
1295
+ const c = cache.nonWitnessUtxoTxCache;
1238
1296
  if (!c[inputIndex]) {
1239
1297
  addNonWitnessTxCache(cache, input, inputIndex);
1240
1298
  }
@@ -1253,7 +1311,7 @@ function getScriptAndAmountFromUtxo(inputIndex, input, cache) {
1253
1311
  }
1254
1312
  else if (input.nonWitnessUtxo !== undefined) {
1255
1313
  const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(cache, input, inputIndex);
1256
- const o = nonWitnessUtxoTx.outs[cache.__TX.ins[inputIndex].index];
1314
+ const o = nonWitnessUtxoTx.outs[cache.tx.ins[inputIndex].index];
1257
1315
  return { script: o.script, value: o.value };
1258
1316
  }
1259
1317
  else {
@@ -1266,7 +1324,7 @@ function pubkeyInInput(pubkey, input, inputIndex, cache) {
1266
1324
  return pubkeyInScript(pubkey, meaningfulScript);
1267
1325
  }
1268
1326
  function pubkeyInOutput(pubkey, output, outputIndex, cache) {
1269
- const script = cache.__TX.outs[outputIndex].script;
1327
+ const script = cache.tx.outs[outputIndex].script;
1270
1328
  const { meaningfulScript } = getMeaningfulScript(script, outputIndex, 'output', output.redeemScript, output.witnessScript);
1271
1329
  return pubkeyInScript(pubkey, meaningfulScript);
1272
1330
  }
@@ -1277,7 +1335,7 @@ function redeemFromFinalScriptSig(finalScript) {
1277
1335
  if (!decomp)
1278
1336
  return;
1279
1337
  const lastItem = decomp[decomp.length - 1];
1280
- if (!Buffer.isBuffer(lastItem) || isPubkeyLike(lastItem) || isSigLike(lastItem))
1338
+ if (!(lastItem instanceof Uint8Array) || isPubkeyLike(lastItem) || isSigLike(lastItem))
1281
1339
  return;
1282
1340
  const sDecomp = bscript.decompile(lastItem);
1283
1341
  if (!sDecomp)
@@ -1296,69 +1354,4 @@ function redeemFromFinalWitnessScript(finalScript) {
1296
1354
  return;
1297
1355
  return lastItem;
1298
1356
  }
1299
- function compressPubkey(pubkey) {
1300
- if (pubkey.length === 65) {
1301
- const parity = pubkey[64] & 1;
1302
- const newKey = Buffer.from(pubkey.subarray(0, 33));
1303
- newKey[0] = 2 | parity;
1304
- return newKey;
1305
- }
1306
- return Buffer.from(pubkey);
1307
- }
1308
- function isPubkeyLike(buf) {
1309
- return buf.length === 33 && bscript.isCanonicalPubKey(buf);
1310
- }
1311
- function isSigLike(buf) {
1312
- return bscript.isCanonicalScriptSignature(buf);
1313
- }
1314
- function getMeaningfulScript(script, index, ioType, redeemScript, witnessScript) {
1315
- const isP2SH = isP2SHScript(script);
1316
- const isP2SHP2WSH = isP2SH && redeemScript && isP2WSHScript(redeemScript);
1317
- const isP2WSH = isP2WSHScript(script);
1318
- if (isP2SH && redeemScript === undefined)
1319
- throw new Error('scriptPubkey is P2SH but redeemScript missing');
1320
- if ((isP2WSH || isP2SHP2WSH) && witnessScript === undefined)
1321
- throw new Error('scriptPubkey or redeemScript is P2WSH but witnessScript missing');
1322
- let meaningfulScript;
1323
- if (isP2SHP2WSH) {
1324
- meaningfulScript = witnessScript;
1325
- checkRedeemScript(index, script, redeemScript, ioType);
1326
- checkWitnessScript(index, redeemScript, witnessScript, ioType);
1327
- checkInvalidP2WSH(meaningfulScript);
1328
- }
1329
- else if (isP2WSH) {
1330
- meaningfulScript = witnessScript;
1331
- checkWitnessScript(index, script, witnessScript, ioType);
1332
- checkInvalidP2WSH(meaningfulScript);
1333
- }
1334
- else if (isP2SH) {
1335
- meaningfulScript = redeemScript;
1336
- checkRedeemScript(index, script, redeemScript, ioType);
1337
- }
1338
- else {
1339
- meaningfulScript = script;
1340
- }
1341
- return {
1342
- meaningfulScript,
1343
- type: isP2SHP2WSH ? 'p2sh-p2wsh' : isP2SH ? 'p2sh' : isP2WSH ? 'p2wsh' : 'raw',
1344
- };
1345
- }
1346
- function checkInvalidP2WSH(script) {
1347
- if (isP2WPKH(script) || isP2SHScript(script)) {
1348
- throw new Error('P2WPKH or P2SH can not be contained within P2WSH');
1349
- }
1350
- }
1351
- function classifyScript(script) {
1352
- if (isP2WPKH(script))
1353
- return 'witnesspubkeyhash';
1354
- if (isP2PKH(script))
1355
- return 'pubkeyhash';
1356
- if (isP2MS(script))
1357
- return 'multisig';
1358
- if (isP2PK(script))
1359
- return 'pubkey';
1360
- return 'nonstandard';
1361
- }
1362
- function range(n) {
1363
- return [...Array(n).keys()];
1364
- }
1357
+ //# sourceMappingURL=psbt.js.map