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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. package/HOW_TO_WRITE_GOOD_CODE.md +2436 -0
  2. package/benchmark/psbt-2000-inputs.bench.ts +178 -0
  3. package/benchmark/signing.bench.ts +147 -0
  4. package/browser/address.d.ts +56 -9
  5. package/browser/address.d.ts.map +1 -0
  6. package/browser/bech32utils.d.ts +9 -1
  7. package/browser/bech32utils.d.ts.map +1 -0
  8. package/browser/bip66.d.ts +11 -6
  9. package/browser/bip66.d.ts.map +1 -0
  10. package/browser/block.d.ts +117 -11
  11. package/browser/block.d.ts.map +1 -0
  12. package/browser/branded.d.ts +20 -0
  13. package/browser/branded.d.ts.map +1 -0
  14. package/browser/crypto/crypto.d.ts +1 -0
  15. package/browser/crypto/crypto.d.ts.map +1 -0
  16. package/browser/crypto.d.ts +46 -7
  17. package/browser/crypto.d.ts.map +1 -0
  18. package/browser/ecc/context.d.ts +129 -0
  19. package/browser/ecc/context.d.ts.map +1 -0
  20. package/browser/ecc/index.d.ts +11 -0
  21. package/browser/ecc/index.d.ts.map +1 -0
  22. package/browser/ecc/types.d.ts +128 -0
  23. package/browser/ecc/types.d.ts.map +1 -0
  24. package/browser/ecpair.d.ts +99 -0
  25. package/browser/errors.d.ts +124 -0
  26. package/browser/errors.d.ts.map +1 -0
  27. package/browser/index.d.ts +32 -5
  28. package/browser/index.d.ts.map +1 -0
  29. package/browser/index.js +12482 -101
  30. package/browser/io/BinaryReader.d.ts +276 -0
  31. package/browser/io/BinaryReader.d.ts.map +1 -0
  32. package/browser/io/BinaryWriter.d.ts +391 -0
  33. package/browser/io/BinaryWriter.d.ts.map +1 -0
  34. package/browser/io/MemoryPool.d.ts +220 -0
  35. package/browser/io/MemoryPool.d.ts.map +1 -0
  36. package/browser/io/base64.d.ts +13 -0
  37. package/browser/io/base64.d.ts.map +1 -0
  38. package/browser/io/hex.d.ts +67 -0
  39. package/browser/io/hex.d.ts.map +1 -0
  40. package/browser/io/index.d.ts +17 -0
  41. package/browser/io/index.d.ts.map +1 -0
  42. package/browser/io/utils.d.ts +199 -0
  43. package/browser/io/utils.d.ts.map +1 -0
  44. package/browser/merkle.d.ts +10 -1
  45. package/browser/merkle.d.ts.map +1 -0
  46. package/browser/networks.d.ts +70 -9
  47. package/browser/networks.d.ts.map +1 -0
  48. package/browser/opcodes.d.ts +1 -0
  49. package/browser/opcodes.d.ts.map +1 -0
  50. package/browser/payments/bip341.d.ts +35 -9
  51. package/browser/payments/bip341.d.ts.map +1 -0
  52. package/browser/payments/embed.d.ts +112 -1
  53. package/browser/payments/embed.d.ts.map +1 -0
  54. package/browser/payments/index.d.ts +17 -10
  55. package/browser/payments/index.d.ts.map +1 -0
  56. package/browser/payments/p2ms.d.ts +150 -0
  57. package/browser/payments/p2ms.d.ts.map +1 -0
  58. package/browser/payments/p2op.d.ts +150 -24
  59. package/browser/payments/p2op.d.ts.map +1 -0
  60. package/browser/payments/p2pk.d.ts +154 -1
  61. package/browser/payments/p2pk.d.ts.map +1 -0
  62. package/browser/payments/p2pkh.d.ts +176 -1
  63. package/browser/payments/p2pkh.d.ts.map +1 -0
  64. package/browser/payments/p2sh.d.ts +150 -1
  65. package/browser/payments/p2sh.d.ts.map +1 -0
  66. package/browser/payments/p2tr.d.ts +185 -1
  67. package/browser/payments/p2tr.d.ts.map +1 -0
  68. package/browser/payments/p2wpkh.d.ts +161 -1
  69. package/browser/payments/p2wpkh.d.ts.map +1 -0
  70. package/browser/payments/p2wsh.d.ts +146 -1
  71. package/browser/payments/p2wsh.d.ts.map +1 -0
  72. package/browser/payments/types.d.ts +94 -64
  73. package/browser/payments/types.d.ts.map +1 -0
  74. package/browser/psbt/bip371.d.ts +34 -8
  75. package/browser/psbt/bip371.d.ts.map +1 -0
  76. package/browser/psbt/psbtutils.d.ts +56 -16
  77. package/browser/psbt/psbtutils.d.ts.map +1 -0
  78. package/browser/psbt/types.d.ts +245 -0
  79. package/browser/psbt/types.d.ts.map +1 -0
  80. package/browser/psbt/utils.d.ts +64 -0
  81. package/browser/psbt/utils.d.ts.map +1 -0
  82. package/browser/psbt/validation.d.ts +84 -0
  83. package/browser/psbt/validation.d.ts.map +1 -0
  84. package/browser/psbt.d.ts +82 -118
  85. package/browser/psbt.d.ts.map +1 -0
  86. package/browser/pubkey.d.ts +27 -6
  87. package/browser/pubkey.d.ts.map +1 -0
  88. package/browser/push_data.d.ts +24 -2
  89. package/browser/push_data.d.ts.map +1 -0
  90. package/browser/script.d.ts +33 -8
  91. package/browser/script.d.ts.map +1 -0
  92. package/browser/script_number.d.ts +17 -0
  93. package/browser/script_number.d.ts.map +1 -0
  94. package/browser/script_signature.d.ts +23 -5
  95. package/browser/script_signature.d.ts.map +1 -0
  96. package/browser/transaction.d.ts +160 -18
  97. package/browser/transaction.d.ts.map +1 -0
  98. package/browser/types.d.ts +36 -38
  99. package/browser/types.d.ts.map +1 -0
  100. package/browser/workers/WorkerSigningPool.d.ts +143 -0
  101. package/browser/workers/WorkerSigningPool.d.ts.map +1 -0
  102. package/browser/workers/WorkerSigningPool.node.d.ts +116 -0
  103. package/browser/workers/WorkerSigningPool.node.d.ts.map +1 -0
  104. package/browser/workers/ecc-bundle.d.ts +25 -0
  105. package/browser/workers/ecc-bundle.d.ts.map +1 -0
  106. package/browser/workers/index.d.ts +91 -0
  107. package/browser/workers/index.d.ts.map +1 -0
  108. package/browser/workers/psbt-parallel.d.ts +88 -0
  109. package/browser/workers/psbt-parallel.d.ts.map +1 -0
  110. package/browser/workers/signing-worker.d.ts +37 -0
  111. package/browser/workers/signing-worker.d.ts.map +1 -0
  112. package/browser/workers/types.d.ts +365 -0
  113. package/browser/workers/types.d.ts.map +1 -0
  114. package/build/address.d.ts +57 -10
  115. package/build/address.d.ts.map +1 -0
  116. package/build/address.js +80 -24
  117. package/build/address.js.map +1 -0
  118. package/build/bech32utils.d.ts +9 -1
  119. package/build/bech32utils.d.ts.map +1 -0
  120. package/build/bech32utils.js +10 -2
  121. package/build/bech32utils.js.map +1 -0
  122. package/build/bip66.d.ts +11 -6
  123. package/build/bip66.d.ts.map +1 -0
  124. package/build/bip66.js +32 -3
  125. package/build/bip66.js.map +1 -0
  126. package/build/block.d.ts +117 -11
  127. package/build/block.d.ts.map +1 -0
  128. package/build/block.js +204 -72
  129. package/build/block.js.map +1 -0
  130. package/build/branded.d.ts +20 -0
  131. package/build/branded.d.ts.map +1 -0
  132. package/build/branded.js +7 -0
  133. package/build/branded.js.map +1 -0
  134. package/build/crypto/crypto.d.ts +1 -0
  135. package/build/crypto/crypto.d.ts.map +1 -0
  136. package/build/crypto/crypto.js +1 -0
  137. package/build/crypto/crypto.js.map +1 -0
  138. package/build/crypto.d.ts +46 -7
  139. package/build/crypto.d.ts.map +1 -0
  140. package/build/crypto.js +65 -20
  141. package/build/crypto.js.map +1 -0
  142. package/build/ecc/context.d.ts +135 -0
  143. package/build/ecc/context.d.ts.map +1 -0
  144. package/build/ecc/context.js +232 -0
  145. package/build/ecc/context.js.map +1 -0
  146. package/build/ecc/index.d.ts +11 -0
  147. package/build/ecc/index.d.ts.map +1 -0
  148. package/build/ecc/index.js +11 -0
  149. package/build/ecc/index.js.map +1 -0
  150. package/build/ecc/types.d.ts +134 -0
  151. package/build/ecc/types.d.ts.map +1 -0
  152. package/build/ecc/types.js +8 -0
  153. package/build/ecc/types.js.map +1 -0
  154. package/build/errors.d.ts +124 -0
  155. package/build/errors.d.ts.map +1 -0
  156. package/build/errors.js +155 -0
  157. package/build/errors.js.map +1 -0
  158. package/build/index.d.ts +32 -5
  159. package/build/index.d.ts.map +1 -0
  160. package/build/index.js +26 -3
  161. package/build/index.js.map +1 -0
  162. package/build/io/BinaryReader.d.ts +276 -0
  163. package/build/io/BinaryReader.d.ts.map +1 -0
  164. package/build/io/BinaryReader.js +425 -0
  165. package/build/io/BinaryReader.js.map +1 -0
  166. package/build/io/BinaryWriter.d.ts +391 -0
  167. package/build/io/BinaryWriter.d.ts.map +1 -0
  168. package/build/io/BinaryWriter.js +611 -0
  169. package/build/io/BinaryWriter.js.map +1 -0
  170. package/build/io/MemoryPool.d.ts +220 -0
  171. package/build/io/MemoryPool.d.ts.map +1 -0
  172. package/build/io/MemoryPool.js +309 -0
  173. package/build/io/MemoryPool.js.map +1 -0
  174. package/build/io/base64.d.ts +13 -0
  175. package/build/io/base64.d.ts.map +1 -0
  176. package/build/io/base64.js +20 -0
  177. package/build/io/base64.js.map +1 -0
  178. package/build/io/hex.d.ts +67 -0
  179. package/build/io/hex.d.ts.map +1 -0
  180. package/build/io/hex.js +138 -0
  181. package/build/io/hex.js.map +1 -0
  182. package/build/io/index.d.ts +17 -0
  183. package/build/io/index.d.ts.map +1 -0
  184. package/build/io/index.js +23 -0
  185. package/build/io/index.js.map +1 -0
  186. package/build/io/utils.d.ts +199 -0
  187. package/build/io/utils.d.ts.map +1 -0
  188. package/build/io/utils.js +271 -0
  189. package/build/io/utils.js.map +1 -0
  190. package/build/merkle.d.ts +10 -1
  191. package/build/merkle.d.ts.map +1 -0
  192. package/build/merkle.js +12 -1
  193. package/build/merkle.js.map +1 -0
  194. package/build/networks.d.ts +70 -9
  195. package/build/networks.d.ts.map +1 -0
  196. package/build/networks.js +90 -4
  197. package/build/networks.js.map +1 -0
  198. package/build/opcodes.d.ts +1 -0
  199. package/build/opcodes.d.ts.map +1 -0
  200. package/build/opcodes.js +1 -0
  201. package/build/opcodes.js.map +1 -0
  202. package/build/payments/bip341.d.ts +36 -9
  203. package/build/payments/bip341.d.ts.map +1 -0
  204. package/build/payments/bip341.js +35 -15
  205. package/build/payments/bip341.js.map +1 -0
  206. package/build/payments/embed.d.ts +120 -1
  207. package/build/payments/embed.d.ts.map +1 -0
  208. package/build/payments/embed.js +215 -34
  209. package/build/payments/embed.js.map +1 -0
  210. package/build/payments/index.d.ts +17 -10
  211. package/build/payments/index.d.ts.map +1 -0
  212. package/build/payments/index.js +20 -10
  213. package/build/payments/index.js.map +1 -0
  214. package/build/payments/p2ms.d.ts +159 -1
  215. package/build/payments/p2ms.d.ts.map +1 -0
  216. package/build/payments/p2ms.js +427 -108
  217. package/build/payments/p2ms.js.map +1 -0
  218. package/build/payments/p2op.d.ts +158 -24
  219. package/build/payments/p2op.d.ts.map +1 -0
  220. package/build/payments/p2op.js +379 -93
  221. package/build/payments/p2op.js.map +1 -0
  222. package/build/payments/p2pk.d.ts +162 -1
  223. package/build/payments/p2pk.d.ts.map +1 -0
  224. package/build/payments/p2pk.js +327 -58
  225. package/build/payments/p2pk.js.map +1 -0
  226. package/build/payments/p2pkh.d.ts +185 -1
  227. package/build/payments/p2pkh.d.ts.map +1 -0
  228. package/build/payments/p2pkh.js +467 -114
  229. package/build/payments/p2pkh.js.map +1 -0
  230. package/build/payments/p2sh.d.ts +159 -1
  231. package/build/payments/p2sh.d.ts.map +1 -0
  232. package/build/payments/p2sh.js +500 -152
  233. package/build/payments/p2sh.js.map +1 -0
  234. package/build/payments/p2tr.d.ts +193 -1
  235. package/build/payments/p2tr.d.ts.map +1 -0
  236. package/build/payments/p2tr.js +592 -174
  237. package/build/payments/p2tr.js.map +1 -0
  238. package/build/payments/p2wpkh.d.ts +170 -1
  239. package/build/payments/p2wpkh.d.ts.map +1 -0
  240. package/build/payments/p2wpkh.js +429 -104
  241. package/build/payments/p2wpkh.js.map +1 -0
  242. package/build/payments/p2wsh.d.ts +155 -1
  243. package/build/payments/p2wsh.d.ts.map +1 -0
  244. package/build/payments/p2wsh.js +466 -144
  245. package/build/payments/p2wsh.js.map +1 -0
  246. package/build/payments/types.d.ts +98 -64
  247. package/build/payments/types.d.ts.map +1 -0
  248. package/build/payments/types.js +17 -13
  249. package/build/payments/types.js.map +1 -0
  250. package/build/psbt/bip371.d.ts +35 -9
  251. package/build/psbt/bip371.d.ts.map +1 -0
  252. package/build/psbt/bip371.js +113 -28
  253. package/build/psbt/bip371.js.map +1 -0
  254. package/build/psbt/psbtutils.d.ts +56 -16
  255. package/build/psbt/psbtutils.d.ts.map +1 -0
  256. package/build/psbt/psbtutils.js +71 -16
  257. package/build/psbt/psbtutils.js.map +1 -0
  258. package/build/psbt/types.d.ts +249 -0
  259. package/build/psbt/types.d.ts.map +1 -0
  260. package/build/psbt/types.js +6 -0
  261. package/build/psbt/types.js.map +1 -0
  262. package/build/psbt/utils.d.ts +68 -0
  263. package/build/psbt/utils.d.ts.map +1 -0
  264. package/build/psbt/utils.js +171 -0
  265. package/build/psbt/utils.js.map +1 -0
  266. package/build/psbt/validation.d.ts +88 -0
  267. package/build/psbt/validation.d.ts.map +1 -0
  268. package/build/psbt/validation.js +149 -0
  269. package/build/psbt/validation.js.map +1 -0
  270. package/build/psbt.d.ts +84 -120
  271. package/build/psbt.d.ts.map +1 -0
  272. package/build/psbt.js +411 -412
  273. package/build/psbt.js.map +1 -0
  274. package/build/pubkey.d.ts +27 -6
  275. package/build/pubkey.d.ts.map +1 -0
  276. package/build/pubkey.js +36 -12
  277. package/build/pubkey.js.map +1 -0
  278. package/build/push_data.d.ts +24 -2
  279. package/build/push_data.d.ts.map +1 -0
  280. package/build/push_data.js +44 -12
  281. package/build/push_data.js.map +1 -0
  282. package/build/script.d.ts +33 -8
  283. package/build/script.d.ts.map +1 -0
  284. package/build/script.js +100 -36
  285. package/build/script.js.map +1 -0
  286. package/build/script_number.d.ts +17 -0
  287. package/build/script_number.d.ts.map +1 -0
  288. package/build/script_number.js +19 -0
  289. package/build/script_number.js.map +1 -0
  290. package/build/script_signature.d.ts +23 -5
  291. package/build/script_signature.d.ts.map +1 -0
  292. package/build/script_signature.js +48 -15
  293. package/build/script_signature.js.map +1 -0
  294. package/build/transaction.d.ts +160 -18
  295. package/build/transaction.d.ts.map +1 -0
  296. package/build/transaction.js +443 -176
  297. package/build/transaction.js.map +1 -0
  298. package/build/tsconfig.build.tsbuildinfo +1 -0
  299. package/build/types.d.ts +36 -38
  300. package/build/types.d.ts.map +1 -0
  301. package/build/types.js +175 -57
  302. package/build/types.js.map +1 -0
  303. package/build/workers/WorkerSigningPool.d.ts +174 -0
  304. package/build/workers/WorkerSigningPool.d.ts.map +1 -0
  305. package/build/workers/WorkerSigningPool.js +553 -0
  306. package/build/workers/WorkerSigningPool.js.map +1 -0
  307. package/build/workers/WorkerSigningPool.node.d.ts +124 -0
  308. package/build/workers/WorkerSigningPool.node.d.ts.map +1 -0
  309. package/build/workers/WorkerSigningPool.node.js +753 -0
  310. package/build/workers/WorkerSigningPool.node.js.map +1 -0
  311. package/build/workers/ecc-bundle.d.ts +25 -0
  312. package/build/workers/ecc-bundle.d.ts.map +1 -0
  313. package/build/workers/ecc-bundle.js +25 -0
  314. package/build/workers/ecc-bundle.js.map +1 -0
  315. package/build/workers/index.d.ts +91 -0
  316. package/build/workers/index.d.ts.map +1 -0
  317. package/build/workers/index.js +114 -0
  318. package/build/workers/index.js.map +1 -0
  319. package/build/workers/psbt-parallel.d.ts +117 -0
  320. package/build/workers/psbt-parallel.d.ts.map +1 -0
  321. package/build/workers/psbt-parallel.js +233 -0
  322. package/build/workers/psbt-parallel.js.map +1 -0
  323. package/build/workers/signing-worker.d.ts +37 -0
  324. package/build/workers/signing-worker.d.ts.map +1 -0
  325. package/build/workers/signing-worker.js +350 -0
  326. package/build/workers/signing-worker.js.map +1 -0
  327. package/build/workers/types.d.ts +365 -0
  328. package/build/workers/types.d.ts.map +1 -0
  329. package/build/workers/types.js +60 -0
  330. package/build/workers/types.js.map +1 -0
  331. package/package.json +66 -8
  332. package/scripts/bundle-ecc.ts +111 -0
  333. package/src/address.ts +81 -44
  334. package/src/bech32utils.ts +3 -3
  335. package/src/bip66.ts +34 -24
  336. package/src/block.ts +196 -84
  337. package/src/branded.ts +18 -0
  338. package/src/crypto.ts +64 -26
  339. package/src/ecc/context.ts +277 -0
  340. package/src/ecc/index.ts +14 -0
  341. package/src/ecc/types.ts +154 -0
  342. package/src/ecpair.d.ts +99 -0
  343. package/src/errors.ts +163 -0
  344. package/src/index.ts +113 -9
  345. package/src/io/BinaryReader.ts +461 -0
  346. package/src/io/BinaryWriter.ts +696 -0
  347. package/src/io/MemoryPool.ts +343 -0
  348. package/src/io/base64.ts +20 -0
  349. package/src/io/hex.ts +155 -0
  350. package/src/io/index.ts +41 -0
  351. package/src/io/utils.ts +283 -0
  352. package/src/merkle.ts +14 -9
  353. package/src/networks.ts +9 -9
  354. package/src/payments/bip341.ts +34 -33
  355. package/src/payments/embed.ts +244 -41
  356. package/src/payments/index.ts +12 -10
  357. package/src/payments/p2ms.ts +490 -118
  358. package/src/payments/p2op.ts +431 -133
  359. package/src/payments/p2pk.ts +370 -72
  360. package/src/payments/p2pkh.ts +524 -130
  361. package/src/payments/p2sh.ts +572 -172
  362. package/src/payments/p2tr.ts +686 -194
  363. package/src/payments/p2wpkh.ts +484 -107
  364. package/src/payments/p2wsh.ts +526 -164
  365. package/src/payments/types.ts +80 -66
  366. package/src/psbt/bip371.ts +68 -51
  367. package/src/psbt/psbtutils.ts +39 -40
  368. package/src/psbt/types.ts +331 -0
  369. package/src/psbt/utils.ts +188 -0
  370. package/src/psbt/validation.ts +192 -0
  371. package/src/psbt.ts +566 -809
  372. package/src/pubkey.ts +22 -23
  373. package/src/push_data.ts +18 -16
  374. package/src/script.ts +82 -64
  375. package/src/script_number.ts +6 -6
  376. package/src/script_signature.ts +33 -36
  377. package/src/transaction.ts +458 -238
  378. package/src/types.ts +231 -100
  379. package/src/workers/WorkerSigningPool.node.ts +887 -0
  380. package/src/workers/WorkerSigningPool.ts +670 -0
  381. package/src/workers/ecc-bundle.ts +26 -0
  382. package/src/workers/index.ts +165 -0
  383. package/src/workers/psbt-parallel.ts +332 -0
  384. package/src/workers/signing-worker.ts +353 -0
  385. package/src/workers/types.ts +413 -0
  386. package/test/address.spec.ts +9 -6
  387. package/test/bitcoin.core.spec.ts +16 -17
  388. package/test/block.spec.ts +8 -7
  389. package/test/bufferutils.spec.ts +228 -214
  390. package/test/crypto.spec.ts +19 -11
  391. package/test/fixtures/p2pk.json +0 -8
  392. package/test/fixtures/p2pkh.json +1 -1
  393. package/test/fixtures/p2sh.json +1 -1
  394. package/test/fixtures/script.json +1 -1
  395. package/test/fixtures/transaction.json +2 -2
  396. package/test/integration/_regtest.ts +25 -0
  397. package/test/integration/addresses.spec.ts +4 -3
  398. package/test/integration/bip32.spec.ts +2 -1
  399. package/test/integration/blocks.spec.ts +1 -1
  400. package/test/integration/cltv.spec.ts +18 -16
  401. package/test/integration/csv.spec.ts +37 -64
  402. package/test/integration/payments.spec.ts +5 -3
  403. package/test/integration/taproot.spec.ts +76 -83
  404. package/test/integration/transactions.spec.ts +38 -35
  405. package/test/payments.spec.ts +35 -13
  406. package/test/payments.utils.ts +17 -16
  407. package/test/psbt.spec.ts +111 -100
  408. package/test/script.spec.ts +11 -10
  409. package/test/script_signature.spec.ts +9 -11
  410. package/test/taproot-cache.spec.ts +694 -0
  411. package/test/transaction.spec.ts +32 -40
  412. package/test/types.spec.ts +74 -29
  413. package/test/workers-pool.spec.ts +963 -0
  414. package/test/workers-signing.spec.ts +635 -0
  415. package/test/workers.spec.ts +1390 -0
  416. package/tsconfig.base.json +34 -18
  417. package/tsconfig.browser.json +15 -0
  418. package/tsconfig.build.json +5 -0
  419. package/tsconfig.json +5 -14
  420. package/vite.config.browser.ts +3 -42
  421. package/vitest.config.integration.ts +2 -0
  422. package/browser/bufferutils.d.ts +0 -34
  423. package/browser/chunks/crypto-BhCpKpek.js +0 -2033
  424. package/browser/chunks/payments-B1wlSccx.js +0 -1089
  425. package/browser/chunks/psbt-BCNk7JUx.js +0 -4055
  426. package/browser/chunks/script-DyPItFEl.js +0 -318
  427. package/browser/chunks/transaction-C_UbhMGn.js +0 -432
  428. package/browser/chunks/utils-DNZi-T5W.js +0 -761
  429. package/browser/ecc_lib.d.ts +0 -3
  430. package/browser/hooks/AdvancedSignatureManager.d.ts +0 -16
  431. package/browser/hooks/HookedSigner.d.ts +0 -4
  432. package/browser/hooks/SignatureManager.d.ts +0 -13
  433. package/browser/payments/lazy.d.ts +0 -2
  434. package/browser/typeforce.d.ts +0 -38
  435. package/build/bufferutils.d.ts +0 -34
  436. package/build/bufferutils.js +0 -141
  437. package/build/ecc_lib.d.ts +0 -3
  438. package/build/ecc_lib.js +0 -61
  439. package/build/hooks/AdvancedSignatureManager.d.ts +0 -16
  440. package/build/hooks/AdvancedSignatureManager.js +0 -52
  441. package/build/hooks/HookedSigner.d.ts +0 -4
  442. package/build/hooks/HookedSigner.js +0 -64
  443. package/build/hooks/SignatureManager.d.ts +0 -13
  444. package/build/hooks/SignatureManager.js +0 -45
  445. package/build/payments/lazy.d.ts +0 -2
  446. package/build/payments/lazy.js +0 -28
  447. package/build/tsconfig.tsbuildinfo +0 -1
  448. package/src/bufferutils.ts +0 -188
  449. package/src/ecc_lib.ts +0 -94
  450. package/src/hooks/AdvancedSignatureManager.ts +0 -104
  451. package/src/hooks/HookedSigner.ts +0 -108
  452. package/src/hooks/SignatureManager.ts +0 -84
  453. package/src/payments/lazy.ts +0 -28
  454. package/src/typeforce.d.ts +0 -38
  455. package/tsconfig.webpack.json +0 -18
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 { Psbt as PsbtBase, checkForInput, checkForOutput, } from 'bip174';
2
+ import { clone, reverse, equals, fromHex, toHex, fromBase64 } 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,80 @@ 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 ||
262
+ if (!outputData ||
174
263
  outputData.value === undefined ||
175
264
  (!hasAddress && !hasScript)) {
176
265
  throw new Error(`Invalid arguments for Psbt.addOutput. ` +
177
266
  `Requires single object with at least [script or address] and [value]`);
178
267
  }
179
- checkInputsForPartialSig(this.data.inputs, 'addOutput');
268
+ if (checkPartialSigs) {
269
+ checkInputsForPartialSig(this.data.inputs, 'addOutput', this.#cache.hasSignatures);
270
+ }
180
271
  if (hasAddress) {
181
272
  const { address } = outputData;
182
- const { network } = this.opts;
273
+ const { network } = this.#opts;
183
274
  const script = toOutputScript(address, network);
184
275
  outputData = Object.assign({}, outputData, { script });
185
276
  }
186
277
  checkTaprootOutputFields(outputData, outputData, 'addOutput');
187
- const c = this.__CACHE;
278
+ const c = this.#cache;
188
279
  this.data.addOutput(outputData);
189
- c.__FEE = undefined;
190
- c.__FEE_RATE = undefined;
191
- c.__EXTRACTED_TX = undefined;
280
+ c.fee = undefined;
281
+ c.feeRate = undefined;
282
+ c.extractedTx = undefined;
283
+ c.taprootHashCache = undefined;
192
284
  return this;
193
285
  }
194
286
  extractTransaction(disableFeeCheck, disableOutputChecks) {
@@ -197,51 +289,53 @@ export class Psbt {
197
289
  }
198
290
  if (!this.data.inputs.every(isFinalized))
199
291
  throw new Error('Not finalized');
200
- const c = this.__CACHE;
292
+ const c = this.#cache;
201
293
  if (!disableFeeCheck) {
202
- checkFees(this, c, this.opts);
294
+ checkFees(this, c, this.#opts);
203
295
  }
204
- if (c.__EXTRACTED_TX)
205
- return c.__EXTRACTED_TX;
206
- const tx = c.__TX.clone();
296
+ if (c.extractedTx)
297
+ return c.extractedTx;
298
+ const tx = c.tx.clone();
207
299
  inputFinalizeGetAmts(this.data.inputs, tx, c, true, disableOutputChecks);
208
300
  return tx;
209
301
  }
210
302
  getFeeRate(disableOutputChecks = false) {
211
- return getTxCacheValue('__FEE_RATE', 'fee rate', this.data.inputs, this.__CACHE, disableOutputChecks);
303
+ return getTxCacheValue('feeRate', 'fee rate', this.data.inputs, this.#cache, disableOutputChecks);
212
304
  }
213
305
  getFee(disableOutputChecks = false) {
214
- return getTxCacheValue('__FEE', 'fee', this.data.inputs, this.__CACHE, disableOutputChecks);
306
+ return getTxCacheValue('fee', 'fee', this.data.inputs, this.#cache, disableOutputChecks);
215
307
  }
216
308
  finalizeAllInputs() {
217
- checkForInput(this.data.inputs, 0);
309
+ checkForInput(this.data.inputs, 0); // making sure we have at least one
218
310
  range(this.data.inputs.length).forEach((idx) => this.finalizeInput(idx));
219
311
  return this;
220
312
  }
221
313
  finalizeInput(inputIndex, finalScriptsFunc, canRunChecks) {
222
314
  const input = checkForInput(this.data.inputs, inputIndex);
223
315
  if (isTaprootInput(input)) {
224
- return this._finalizeTaprootInput(inputIndex, input, undefined, finalScriptsFunc);
316
+ return this.#finalizeTaprootInput(inputIndex, input, undefined, finalScriptsFunc);
225
317
  }
226
- return this._finalizeInput(inputIndex, input, finalScriptsFunc, canRunChecks ?? true);
318
+ return this.#finalizeInput(inputIndex, input, finalScriptsFunc, canRunChecks ?? true);
227
319
  }
228
320
  finalizeTaprootInput(inputIndex, tapLeafHashToFinalize, finalScriptsFunc = tapScriptFinalizer) {
229
321
  const input = checkForInput(this.data.inputs, inputIndex);
230
322
  if (isTaprootInput(input))
231
- return this._finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc);
323
+ return this.#finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc);
232
324
  throw new Error(`Cannot finalize input #${inputIndex}. Not Taproot.`);
233
325
  }
234
326
  getInputType(inputIndex) {
235
327
  const input = checkForInput(this.data.inputs, inputIndex);
236
- const script = getScriptFromUtxo(inputIndex, input, this.__CACHE);
237
- const result = getMeaningfulScript(script, inputIndex, 'input', input.redeemScript || redeemFromFinalScriptSig(input.finalScriptSig), input.witnessScript || redeemFromFinalWitnessScript(input.finalScriptWitness));
328
+ const script = getScriptFromUtxo(inputIndex, input, this.#cache);
329
+ const result = getMeaningfulScript(script, inputIndex, 'input', input.redeemScript ||
330
+ redeemFromFinalScriptSig(input.finalScriptSig), input.witnessScript ||
331
+ redeemFromFinalWitnessScript(input.finalScriptWitness));
238
332
  const type = result.type === 'raw' ? '' : result.type + '-';
239
333
  const mainType = classifyScript(result.meaningfulScript);
240
334
  return (type + mainType);
241
335
  }
242
336
  inputHasPubkey(inputIndex, pubkey) {
243
337
  const input = checkForInput(this.data.inputs, inputIndex);
244
- return pubkeyInInput(pubkey, input, inputIndex, this.__CACHE);
338
+ return pubkeyInInput(pubkey, input, inputIndex, this.#cache);
245
339
  }
246
340
  inputHasHDKey(inputIndex, root) {
247
341
  const input = checkForInput(this.data.inputs, inputIndex);
@@ -250,7 +344,7 @@ export class Psbt {
250
344
  }
251
345
  outputHasPubkey(outputIndex, pubkey) {
252
346
  const output = checkForOutput(this.data.outputs, outputIndex);
253
- return pubkeyInOutput(pubkey, output, outputIndex, this.__CACHE);
347
+ return pubkeyInOutput(pubkey, output, outputIndex, this.#cache);
254
348
  }
255
349
  outputHasHDKey(outputIndex, root) {
256
350
  const output = checkForOutput(this.data.outputs, outputIndex);
@@ -258,15 +352,15 @@ export class Psbt {
258
352
  return !!output.bip32Derivation && output.bip32Derivation.some(derivationIsMine);
259
353
  }
260
354
  validateSignaturesOfAllInputs(validator) {
261
- checkForInput(this.data.inputs, 0);
355
+ checkForInput(this.data.inputs, 0); // making sure we have at least one
262
356
  const results = range(this.data.inputs.length).map((idx) => this.validateSignaturesOfInput(idx, validator));
263
357
  return results.reduce((final, res) => res && final, true);
264
358
  }
265
359
  validateSignaturesOfInput(inputIndex, validator, pubkey) {
266
360
  const input = this.data.inputs[inputIndex];
267
361
  if (isTaprootInput(input))
268
- return this.validateSignaturesOfTaprootInput(inputIndex, validator, pubkey);
269
- return this._validateSignaturesOfInput(inputIndex, validator, pubkey);
362
+ return this.#validateSignaturesOfTaprootInput(inputIndex, validator, pubkey);
363
+ return this.#validateSignaturesOfInput(inputIndex, validator, pubkey);
270
364
  }
271
365
  signAllInputsHD(hdKeyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
272
366
  if (!hdKeyPair || !hdKeyPair.publicKey || !hdKeyPair.fingerprint) {
@@ -334,6 +428,9 @@ export class Psbt {
334
428
  signAllInputs(keyPair, sighashTypes) {
335
429
  if (!keyPair || !keyPair.publicKey)
336
430
  throw new Error('Need Signer to sign input');
431
+ // TODO: Add a pubkey/pubkeyhash cache to each input
432
+ // as input information is added, then eventually
433
+ // optimize this method.
337
434
  const results = [];
338
435
  for (const i of range(this.data.inputs.length)) {
339
436
  try {
@@ -353,6 +450,9 @@ export class Psbt {
353
450
  return new Promise((resolve, reject) => {
354
451
  if (!keyPair || !keyPair.publicKey)
355
452
  return reject(new Error('Need Signer to sign input'));
453
+ // TODO: Add a pubkey/pubkeyhash cache to each input
454
+ // as input information is added, then eventually
455
+ // optimize this method.
356
456
  const results = [];
357
457
  const promises = [];
358
458
  for (const [i] of this.data.inputs.entries()) {
@@ -376,9 +476,9 @@ export class Psbt {
376
476
  }
377
477
  const input = checkForInput(this.data.inputs, inputIndex);
378
478
  if (isTaprootInput(input)) {
379
- return this._signTaprootInput(inputIndex, input, keyPair, undefined, sighashTypes);
479
+ return this.#signTaprootInput(inputIndex, input, keyPair, undefined, sighashTypes);
380
480
  }
381
- return this._signInput(inputIndex, keyPair, sighashTypes);
481
+ return this.#signInput(inputIndex, keyPair, sighashTypes);
382
482
  }
383
483
  signTaprootInput(inputIndex, keyPair, tapLeafHashToSign, sighashTypes) {
384
484
  if (!keyPair || !keyPair.publicKey) {
@@ -386,7 +486,7 @@ export class Psbt {
386
486
  }
387
487
  const input = checkForInput(this.data.inputs, inputIndex);
388
488
  if (isTaprootInput(input)) {
389
- return this._signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, sighashTypes);
489
+ return this.#signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, sighashTypes);
390
490
  }
391
491
  throw new Error(`Input #${inputIndex} is not of type Taproot.`);
392
492
  }
@@ -396,8 +496,8 @@ export class Psbt {
396
496
  throw new Error('Need Signer to sign input');
397
497
  const input = checkForInput(this.data.inputs, inputIndex);
398
498
  if (isTaprootInput(input))
399
- return this._signTaprootInputAsync(inputIndex, input, keyPair, undefined, sighashTypes);
400
- return this._signInputAsync(inputIndex, keyPair, sighashTypes);
499
+ return this.#signTaprootInputAsync(inputIndex, input, keyPair, undefined, sighashTypes);
500
+ return this.#signInputAsync(inputIndex, keyPair, sighashTypes);
401
501
  });
402
502
  }
403
503
  signTaprootInputAsync(inputIndex, keyPair, tapLeafHash, sighashTypes) {
@@ -406,20 +506,20 @@ export class Psbt {
406
506
  throw new Error('Need Signer to sign input');
407
507
  const input = checkForInput(this.data.inputs, inputIndex);
408
508
  if (isTaprootInput(input))
409
- return this._signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes);
509
+ return this.#signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes);
410
510
  throw new Error(`Input #${inputIndex} is not of type Taproot.`);
411
511
  });
412
512
  }
413
513
  toBuffer() {
414
- checkCache(this.__CACHE);
415
- return this.data.toBuffer();
514
+ checkCache(this.#cache);
515
+ return new Uint8Array(this.data.toBuffer());
416
516
  }
417
517
  toHex() {
418
- checkCache(this.__CACHE);
518
+ checkCache(this.#cache);
419
519
  return this.data.toHex();
420
520
  }
421
521
  toBase64() {
422
- checkCache(this.__CACHE);
522
+ checkCache(this.#cache);
423
523
  return this.data.toBase64();
424
524
  }
425
525
  updateGlobal(updateData) {
@@ -430,9 +530,21 @@ export class Psbt {
430
530
  if (updateData.witnessScript)
431
531
  checkInvalidP2WSH(updateData.witnessScript);
432
532
  checkTaprootInputFields(this.data.inputs[inputIndex], updateData, 'updateInput');
433
- this.data.updateInput(inputIndex, updateData);
533
+ // Convert witnessUtxo for bip174 v3 compatibility (value: bigint, script: Uint8Array)
534
+ const normalizedUpdate = updateData.witnessUtxo
535
+ ? {
536
+ ...updateData,
537
+ witnessUtxo: {
538
+ script: updateData.witnessUtxo.script,
539
+ value: typeof updateData.witnessUtxo.value === 'bigint'
540
+ ? updateData.witnessUtxo.value
541
+ : BigInt(updateData.witnessUtxo.value),
542
+ },
543
+ }
544
+ : updateData;
545
+ this.data.updateInput(inputIndex, normalizedUpdate);
434
546
  if (updateData.nonWitnessUtxo) {
435
- addNonWitnessTxCache(this.__CACHE, this.data.inputs[inputIndex], inputIndex);
547
+ addNonWitnessTxCache(this.#cache, this.data.inputs[inputIndex], inputIndex);
436
548
  }
437
549
  return this;
438
550
  }
@@ -459,18 +571,18 @@ export class Psbt {
459
571
  return this;
460
572
  }
461
573
  checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes) {
462
- if (typeof keyPair.signSchnorr !== 'function')
574
+ if (!('signSchnorr' in keyPair) || typeof keyPair.signSchnorr !== 'function')
463
575
  throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
464
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
576
+ const pubkey = keyPair.publicKey instanceof Uint8Array
465
577
  ? keyPair.publicKey
466
- : Buffer.from(keyPair.publicKey);
467
- const hashesForSig = getTaprootHashesForSig(inputIndex, input, this.data.inputs, pubkey, this.__CACHE, tapLeafHashToSign, allowedSighashTypes);
578
+ : new Uint8Array(keyPair.publicKey);
579
+ const hashesForSig = getTaprootHashesForSig(inputIndex, input, this.data.inputs, pubkey, this.#cache, tapLeafHashToSign, allowedSighashTypes);
468
580
  if (!hashesForSig || !hashesForSig.length)
469
- throw new Error(`Can not sign for input #${inputIndex} with the key ${pubkey.toString('hex')}`);
581
+ throw new Error(`Can not sign for input #${inputIndex} with the key ${toHex(pubkey)}`);
470
582
  return hashesForSig;
471
583
  }
472
- _finalizeInput(inputIndex, input, finalScriptsFunc = getFinalScripts, canRunChecks = true) {
473
- const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(inputIndex, input, this.__CACHE);
584
+ #finalizeInput(inputIndex, input, finalScriptsFunc = getFinalScripts, canRunChecks = true) {
585
+ const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(inputIndex, input, this.#cache);
474
586
  if (!script)
475
587
  throw new Error(`No script found for input #${inputIndex}`);
476
588
  checkPartialSigSighashes(input);
@@ -484,9 +596,10 @@ export class Psbt {
484
596
  this.data.clearFinalizedInput(inputIndex);
485
597
  return this;
486
598
  }
487
- _finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc = tapScriptFinalizer) {
599
+ #finalizeTaprootInput(inputIndex, input, tapLeafHashToFinalize, finalScriptsFunc = tapScriptFinalizer) {
488
600
  if (!input.witnessUtxo)
489
601
  throw new Error(`Cannot finalize input #${inputIndex}. Missing witness utxo.`);
602
+ // Check key spend first. Increased privacy and reduced block space.
490
603
  if (input.tapKeySig) {
491
604
  const payment = payments.p2tr({
492
605
  output: input.witnessUtxo.script,
@@ -504,14 +617,16 @@ export class Psbt {
504
617
  this.data.clearFinalizedInput(inputIndex);
505
618
  return this;
506
619
  }
507
- _validateSignaturesOfInput(inputIndex, validator, pubkey) {
620
+ #validateSignaturesOfInput(inputIndex, validator, pubkey) {
508
621
  const input = this.data.inputs[inputIndex];
509
622
  const partialSig = (input || {}).partialSig;
510
623
  if (!input || !partialSig || partialSig.length < 1)
511
624
  throw new Error('No signatures to validate');
512
625
  if (typeof validator !== 'function')
513
626
  throw new Error('Need validator function to validate signatures');
514
- const mySigs = pubkey ? partialSig.filter((sig) => sig.pubkey.equals(pubkey)) : partialSig;
627
+ const mySigs = pubkey
628
+ ? partialSig.filter((sig) => equals(sig.pubkey, pubkey))
629
+ : partialSig;
515
630
  if (mySigs.length < 1)
516
631
  throw new Error('No signatures for this pubkey');
517
632
  const results = [];
@@ -519,21 +634,23 @@ export class Psbt {
519
634
  let scriptCache;
520
635
  let sighashCache;
521
636
  for (const pSig of mySigs) {
522
- const sig = bscript.signature.decode(pSig.signature);
637
+ const pSigSignature = pSig.signature;
638
+ const pSigPubkey = pSig.pubkey;
639
+ const sig = bscript.signature.decode(pSigSignature);
523
640
  const { hash, script } = sighashCache !== sig.hashType || !hashCache || !scriptCache
524
641
  ? getHashForSig(inputIndex, Object.assign({}, input, {
525
642
  sighashType: sig.hashType,
526
- }), this.__CACHE, true)
643
+ }), this.#cache, true)
527
644
  : { hash: hashCache, script: scriptCache };
528
645
  sighashCache = sig.hashType;
529
646
  hashCache = hash;
530
647
  scriptCache = script;
531
- checkScriptForPubkey(pSig.pubkey, script, 'verify');
532
- results.push(validator(pSig.pubkey, hash, sig.signature));
648
+ checkScriptForPubkey(pSigPubkey, script, 'verify');
649
+ results.push(validator(pSigPubkey, hash, sig.signature));
533
650
  }
534
651
  return results.every((res) => res);
535
652
  }
536
- validateSignaturesOfTaprootInput(inputIndex, validator, pubkey) {
653
+ #validateSignaturesOfTaprootInput(inputIndex, validator, pubkey) {
537
654
  const input = this.data.inputs[inputIndex];
538
655
  const tapKeySig = (input || {}).tapKeySig;
539
656
  const tapScriptSig = (input || {}).tapScriptSig;
@@ -541,10 +658,10 @@ export class Psbt {
541
658
  throw new Error('No signatures to validate');
542
659
  if (typeof validator !== 'function')
543
660
  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);
661
+ const xPubkey = pubkey ? toXOnly(pubkey) : undefined;
662
+ const allHashses = xPubkey
663
+ ? getTaprootHashesForSig(inputIndex, input, this.data.inputs, xPubkey, this.#cache)
664
+ : getAllTaprootHashesForSig(inputIndex, input, this.data.inputs, this.#cache);
548
665
  if (!allHashses.length)
549
666
  throw new Error('No signatures for this pubkey');
550
667
  const tapKeyHash = allHashses.find((h) => !h.leafHash);
@@ -557,9 +674,10 @@ export class Psbt {
557
674
  }
558
675
  if (tapScriptSig) {
559
676
  for (const tapSig of tapScriptSig) {
560
- const tapSigHash = allHashses.find((h) => tapSig.pubkey.equals(h.pubkey));
677
+ const tapSigPubkey = tapSig.pubkey;
678
+ const tapSigHash = allHashses.find((h) => equals(tapSigPubkey, h.pubkey));
561
679
  if (tapSigHash) {
562
- const isValidTapScriptSig = validator(tapSig.pubkey, tapSigHash.hash, trimTaprootSig(tapSig.signature));
680
+ const isValidTapScriptSig = validator(tapSigPubkey, tapSigHash.hash, trimTaprootSig(tapSig.signature));
563
681
  if (!isValidTapScriptSig)
564
682
  return false;
565
683
  validationResultCount++;
@@ -568,53 +686,58 @@ export class Psbt {
568
686
  }
569
687
  return validationResultCount > 0;
570
688
  }
571
- _signInput(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
572
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
689
+ #signInput(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
690
+ const pubkey = keyPair.publicKey instanceof Uint8Array
573
691
  ? keyPair.publicKey
574
- : Buffer.from(keyPair.publicKey);
575
- const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.__CACHE, sighashTypes);
692
+ : new Uint8Array(keyPair.publicKey);
693
+ const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.#cache, sighashTypes);
576
694
  const sig = keyPair.sign(hash);
577
695
  const partialSig = [
578
696
  {
579
697
  pubkey,
580
- signature: bscript.signature.encode(Buffer.isBuffer(sig) ? sig : Buffer.from(sig), sighashType),
698
+ signature: bscript.signature.encode(sig instanceof Uint8Array ? sig : new Uint8Array(sig), sighashType),
581
699
  },
582
700
  ];
583
701
  this.data.updateInput(inputIndex, { partialSig });
702
+ this.#cache.hasSignatures = true;
584
703
  return this;
585
704
  }
586
- _signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes = [Transaction.SIGHASH_DEFAULT]) {
587
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
705
+ #signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes = [Transaction.SIGHASH_DEFAULT]) {
706
+ const pubkey = (keyPair.publicKey instanceof Uint8Array
588
707
  ? keyPair.publicKey
589
- : Buffer.from(keyPair.publicKey);
708
+ : new Uint8Array(keyPair.publicKey));
709
+ if (!('signSchnorr' in keyPair) || typeof keyPair.signSchnorr !== 'function')
710
+ throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
711
+ // checkTaprootHashesForSig validates signSchnorr exists
590
712
  const hashesForSig = this.checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes);
591
713
  const signSchnorr = keyPair.signSchnorr.bind(keyPair);
592
- const toBuffer = (data) => Buffer.isBuffer(data) ? data : Buffer.from(data);
593
714
  const tapKeySig = hashesForSig
594
715
  .filter((h) => !h.leafHash)
595
- .map((h) => serializeTaprootSignature(toBuffer(signSchnorr(h.hash)), input.sighashType))[0];
716
+ .map((h) => serializeTaprootSignature(signSchnorr(h.hash), input.sighashType))[0];
596
717
  const tapScriptSig = hashesForSig
597
718
  .filter((h) => !!h.leafHash)
598
719
  .map((h) => ({
599
720
  pubkey: toXOnly(pubkey),
600
- signature: serializeTaprootSignature(toBuffer(signSchnorr(h.hash)), input.sighashType),
721
+ signature: serializeTaprootSignature(signSchnorr(h.hash), input.sighashType),
601
722
  leafHash: h.leafHash,
602
723
  }));
603
724
  if (tapKeySig) {
604
725
  this.data.updateInput(inputIndex, { tapKeySig });
726
+ this.#cache.hasSignatures = true;
605
727
  }
606
728
  if (tapScriptSig.length) {
607
729
  this.data.updateInput(inputIndex, { tapScriptSig });
730
+ this.#cache.hasSignatures = true;
608
731
  }
609
732
  return this;
610
733
  }
611
- _signInputAsync(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
612
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
734
+ #signInputAsync(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
735
+ const pubkey = keyPair.publicKey instanceof Uint8Array
613
736
  ? keyPair.publicKey
614
- : Buffer.from(keyPair.publicKey);
615
- const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.__CACHE, sighashTypes);
737
+ : new Uint8Array(keyPair.publicKey);
738
+ const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.#cache, sighashTypes);
616
739
  return Promise.resolve(keyPair.sign(hash)).then((signature) => {
617
- const sig = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
740
+ const sig = signature instanceof Uint8Array ? signature : new Uint8Array(signature);
618
741
  const partialSig = [
619
742
  {
620
743
  pubkey,
@@ -622,21 +745,24 @@ export class Psbt {
622
745
  },
623
746
  ];
624
747
  this.data.updateInput(inputIndex, { partialSig });
748
+ this.#cache.hasSignatures = true;
625
749
  });
626
750
  }
627
- async _signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes = [Transaction.SIGHASH_DEFAULT]) {
628
- const pubkey = Buffer.isBuffer(keyPair.publicKey)
751
+ async #signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes = [Transaction.SIGHASH_DEFAULT]) {
752
+ const pubkey = (keyPair.publicKey instanceof Uint8Array
629
753
  ? keyPair.publicKey
630
- : Buffer.from(keyPair.publicKey);
754
+ : new Uint8Array(keyPair.publicKey));
755
+ if (!('signSchnorr' in keyPair) || typeof keyPair.signSchnorr !== 'function')
756
+ throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
757
+ // checkTaprootHashesForSig validates signSchnorr exists
631
758
  const hashesForSig = this.checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHash, sighashTypes);
632
759
  const signSchnorr = keyPair.signSchnorr.bind(keyPair);
633
- const toBuffer = (data) => Buffer.isBuffer(data) ? data : Buffer.from(data);
634
760
  const signaturePromises = [];
635
761
  const tapKeyHash = hashesForSig.filter((h) => !h.leafHash)[0];
636
762
  if (tapKeyHash) {
637
763
  const tapKeySigPromise = Promise.resolve(signSchnorr(tapKeyHash.hash)).then((sig) => {
638
764
  return {
639
- tapKeySig: serializeTaprootSignature(toBuffer(sig), input.sighashType),
765
+ tapKeySig: serializeTaprootSignature(sig, input.sighashType),
640
766
  };
641
767
  });
642
768
  signaturePromises.push(tapKeySigPromise);
@@ -648,7 +774,7 @@ export class Psbt {
648
774
  const tapScriptSig = [
649
775
  {
650
776
  pubkey: toXOnly(pubkey),
651
- signature: serializeTaprootSignature(toBuffer(signature), input.sighashType),
777
+ signature: serializeTaprootSignature(signature, input.sighashType),
652
778
  leafHash: tsh.leafHash,
653
779
  },
654
780
  ];
@@ -659,12 +785,23 @@ export class Psbt {
659
785
  const results = await Promise.all(signaturePromises);
660
786
  for (const v of results) {
661
787
  this.data.updateInput(inputIndex, v);
788
+ this.#cache.hasSignatures = true;
662
789
  }
663
790
  }
664
791
  }
792
+ /**
793
+ * This function is needed to pass to the bip174 base class's fromBuffer.
794
+ * It takes the "transaction buffer" portion of the psbt buffer and returns a
795
+ * Transaction (From the bip174 library) interface.
796
+ */
665
797
  const transactionFromBuffer = (buffer) => new PsbtTransaction(buffer);
798
+ /**
799
+ * This class implements the Transaction interface from bip174 library.
800
+ * It contains a bitcoinjs-lib Transaction object.
801
+ */
666
802
  class PsbtTransaction {
667
- constructor(buffer = Buffer.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
803
+ tx;
804
+ constructor(buffer = new Uint8Array([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
668
805
  this.tx = Transaction.fromBuffer(buffer);
669
806
  checkTxEmpty(this.tx);
670
807
  Object.defineProperty(this, 'tx', {
@@ -681,20 +818,18 @@ class PsbtTransaction {
681
818
  addInput(input) {
682
819
  if (input.hash === undefined ||
683
820
  input.index === undefined ||
684
- (!Buffer.isBuffer(input.hash) && typeof input.hash !== 'string') ||
821
+ (!(input.hash instanceof Uint8Array) && typeof input.hash !== 'string') ||
685
822
  typeof input.index !== 'number') {
686
823
  throw new Error('Error adding input.');
687
824
  }
688
- const hash = typeof input.hash === 'string'
689
- ? reverseBuffer(Buffer.from(input.hash, 'hex'))
690
- : input.hash;
825
+ const hash = (typeof input.hash === 'string' ? reverse(fromHex(input.hash)) : input.hash);
691
826
  this.tx.addInput(hash, input.index, input.sequence);
692
827
  }
693
828
  addOutput(output) {
694
829
  if (output.script === undefined ||
695
830
  output.value === undefined ||
696
- !Buffer.isBuffer(output.script) ||
697
- typeof output.value !== 'number') {
831
+ !(output.script instanceof Uint8Array) ||
832
+ typeof output.value !== 'bigint') {
698
833
  throw new Error('Error adding output.');
699
834
  }
700
835
  this.tx.addOutput(output.script, output.value);
@@ -713,6 +848,8 @@ function canFinalize(input, script, scriptType) {
713
848
  const p2ms = payments.p2ms({
714
849
  output: script,
715
850
  });
851
+ if (p2ms.m === undefined)
852
+ throw new Error('Cannot determine m for multisig');
716
853
  return hasSigs(p2ms.m, input.partialSig, p2ms.pubkeys);
717
854
  }
718
855
  case 'nonstandard':
@@ -721,11 +858,6 @@ function canFinalize(input, script, scriptType) {
721
858
  return false;
722
859
  }
723
860
  }
724
- function checkCache(cache) {
725
- if (cache.__UNSAFE_SIGN_NONSEGWIT) {
726
- throw new Error('Not BIP174 compliant, can not export');
727
- }
728
- }
729
861
  function hasSigs(neededSigs, partialSig, pubkeys) {
730
862
  if (!partialSig)
731
863
  return false;
@@ -734,7 +866,7 @@ function hasSigs(neededSigs, partialSig, pubkeys) {
734
866
  sigs = pubkeys
735
867
  .map((pkey) => {
736
868
  const pubkey = compressPubkey(pkey);
737
- return partialSig.find((pSig) => pSig.pubkey.equals(pubkey));
869
+ return partialSig.find((pSig) => equals(pSig.pubkey, pubkey));
738
870
  })
739
871
  .filter((v) => !!v);
740
872
  }
@@ -745,31 +877,25 @@ function hasSigs(neededSigs, partialSig, pubkeys) {
745
877
  throw new Error('Too many signatures');
746
878
  return sigs.length === neededSigs;
747
879
  }
748
- function isFinalized(input) {
749
- return !!input.finalScriptSig || !!input.finalScriptWitness;
750
- }
751
880
  function bip32DerivationIsMine(root) {
752
881
  return (d) => {
753
- const fingerprint = Buffer.isBuffer(root.fingerprint)
882
+ const fingerprint = root.fingerprint instanceof Uint8Array
754
883
  ? root.fingerprint
755
- : Buffer.from(root.fingerprint);
756
- if (!d.masterFingerprint.equals(fingerprint))
884
+ : new Uint8Array(root.fingerprint);
885
+ if (!equals(d.masterFingerprint, fingerprint))
757
886
  return false;
758
887
  const derivedPubkey = root.derivePath(d.path).publicKey;
759
- const pubkey = Buffer.isBuffer(derivedPubkey) ? derivedPubkey : Buffer.from(derivedPubkey);
760
- if (!pubkey.equals(d.pubkey))
888
+ const pubkey = derivedPubkey instanceof Uint8Array ? derivedPubkey : new Uint8Array(derivedPubkey);
889
+ if (!equals(pubkey, d.pubkey))
761
890
  return false;
762
891
  return true;
763
892
  };
764
893
  }
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
894
  function checkFees(psbt, cache, opts) {
771
- const feeRate = cache.__FEE_RATE || psbt.getFeeRate();
772
- const vsize = cache.__EXTRACTED_TX.virtualSize();
895
+ const feeRate = cache.feeRate || psbt.getFeeRate();
896
+ if (!cache.extractedTx)
897
+ throw new Error('Transaction not extracted');
898
+ const vsize = cache.extractedTx.virtualSize();
773
899
  const satoshis = feeRate * vsize;
774
900
  if (feeRate >= opts.maximumFeeRate) {
775
901
  throw new Error(`Warning: You are paying around ${(satoshis / 1e8).toFixed(8)} in ` +
@@ -779,81 +905,24 @@ function checkFees(psbt, cache, opts) {
779
905
  `pass true to the first arg of extractTransaction.`);
780
906
  }
781
907
  }
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
908
  function getTxCacheValue(key, name, inputs, c, disableOutputChecks = false) {
840
909
  if (!inputs.every(isFinalized))
841
910
  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;
911
+ if (key === 'feeRate' && c.feeRate)
912
+ return c.feeRate;
913
+ if (key === 'fee' && c.fee)
914
+ return c.fee;
846
915
  let tx;
847
916
  let mustFinalize = true;
848
- if (c.__EXTRACTED_TX) {
849
- tx = c.__EXTRACTED_TX;
917
+ if (c.extractedTx) {
918
+ tx = c.extractedTx;
850
919
  mustFinalize = false;
851
920
  }
852
921
  else {
853
- tx = c.__TX.clone();
922
+ tx = c.tx.clone();
854
923
  }
855
924
  inputFinalizeGetAmts(inputs, tx, c, mustFinalize, disableOutputChecks);
856
- const value = key === '__FEE_RATE' ? c.__FEE_RATE : c.__FEE;
925
+ const value = key === 'feeRate' ? c.feeRate : c.fee;
857
926
  if (value === undefined)
858
927
  throw new Error(`Failed to calculate ${name}`);
859
928
  return value;
@@ -863,23 +932,27 @@ export function getFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP
863
932
  if (!canFinalize(input, script, scriptType) && canRunChecks) {
864
933
  throw new Error(`Can not finalize input #${inputIndex}`);
865
934
  }
935
+ if (!input.partialSig)
936
+ throw new Error('Input missing partial signatures');
866
937
  return prepareFinalScripts(script, scriptType, input.partialSig, isSegwit, isP2SH, isP2WSH, solution);
867
938
  }
868
939
  export function prepareFinalScripts(script, scriptType, partialSig, isSegwit, isP2SH, isP2WSH, solution) {
869
940
  let finalScriptSig;
870
941
  let finalScriptWitness;
942
+ // Wow, the payments API is very handy
871
943
  const payment = getPayment(script, scriptType, partialSig);
872
944
  const p2wsh = !isP2WSH ? null : payments.p2wsh({ redeem: payment });
873
945
  const p2sh = !isP2SH ? null : payments.p2sh({ redeem: p2wsh || payment });
874
946
  if (isSegwit) {
875
- if (p2wsh) {
947
+ if (p2wsh && p2wsh.witness) {
876
948
  finalScriptWitness = witnessStackToScriptWitness(p2wsh.witness);
877
949
  }
878
- else if (payment) {
950
+ else if (payment && payment.witness) {
879
951
  finalScriptWitness = witnessStackToScriptWitness(payment.witness);
880
952
  }
881
953
  else {
882
- finalScriptWitness = witnessStackToScriptWitness(solution ?? [Buffer.from([0x00])]);
954
+ // nonstandard segwit script
955
+ finalScriptWitness = witnessStackToScriptWitness(solution ?? [new Uint8Array([0x00])]);
883
956
  }
884
957
  if (p2sh) {
885
958
  finalScriptSig = p2sh?.input;
@@ -891,8 +964,7 @@ export function prepareFinalScripts(script, scriptType, partialSig, isSegwit, is
891
964
  }
892
965
  else {
893
966
  if (!payment) {
894
- finalScriptSig =
895
- Array.isArray(solution) && solution[0] ? solution[0] : Buffer.from([0x01]);
967
+ finalScriptSig = (Array.isArray(solution) && solution[0] ? solution[0] : new Uint8Array([0x01]));
896
968
  }
897
969
  else {
898
970
  finalScriptSig = payment.input;
@@ -914,7 +986,7 @@ function getHashAndSighashType(inputs, inputIndex, pubkey, cache, sighashTypes)
914
986
  };
915
987
  }
916
988
  function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
917
- const unsignedTx = cache.__TX;
989
+ const unsignedTx = cache.tx;
918
990
  const sighashType = input.sighashType || Transaction.SIGHASH_ALL;
919
991
  checkSighashTypeAllowed(sighashType, sighashTypes);
920
992
  let hash;
@@ -923,33 +995,42 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
923
995
  const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(cache, input, inputIndex);
924
996
  const prevoutHash = unsignedTx.ins[inputIndex].hash;
925
997
  const utxoHash = nonWitnessUtxoTx.getHash();
926
- if (!prevoutHash.equals(utxoHash)) {
998
+ // If a non-witness UTXO is provided, its hash must match the hash specified in the prevout
999
+ if (!equals(prevoutHash, utxoHash)) {
927
1000
  throw new Error(`Non-witness UTXO hash for input #${inputIndex} doesn't match the hash specified in the prevout`);
928
1001
  }
929
1002
  const prevoutIndex = unsignedTx.ins[inputIndex].index;
930
1003
  prevout = nonWitnessUtxoTx.outs[prevoutIndex];
931
1004
  }
932
1005
  else if (input.witnessUtxo) {
933
- prevout = input.witnessUtxo;
1006
+ prevout = {
1007
+ script: input.witnessUtxo.script,
1008
+ value: input.witnessUtxo.value,
1009
+ };
934
1010
  }
935
1011
  else {
936
1012
  throw new Error('Need a Utxo input item for signing');
937
1013
  }
938
1014
  const { meaningfulScript, type } = getMeaningfulScript(prevout.script, inputIndex, 'input', input.redeemScript, input.witnessScript);
1015
+ const script = meaningfulScript;
939
1016
  if (['p2sh-p2wsh', 'p2wsh'].indexOf(type) >= 0) {
940
- hash = unsignedTx.hashForWitnessV0(inputIndex, meaningfulScript, prevout.value, sighashType);
1017
+ hash = unsignedTx.hashForWitnessV0(inputIndex, script, prevout.value, sighashType);
941
1018
  }
942
1019
  else if (isP2WPKH(meaningfulScript)) {
943
- const signingScript = payments.p2pkh({
1020
+ // P2WPKH uses the P2PKH template for prevoutScript when signing
1021
+ const p2pkhPayment = payments.p2pkh({
944
1022
  hash: meaningfulScript.subarray(2),
945
- }).output;
946
- hash = unsignedTx.hashForWitnessV0(inputIndex, signingScript, prevout.value, sighashType);
1023
+ });
1024
+ if (!p2pkhPayment.output)
1025
+ throw new Error('Unable to create signing script');
1026
+ hash = unsignedTx.hashForWitnessV0(inputIndex, p2pkhPayment.output, prevout.value, sighashType);
947
1027
  }
948
1028
  else {
949
- if (input.nonWitnessUtxo === undefined && !cache.__UNSAFE_SIGN_NONSEGWIT)
1029
+ // non-segwit
1030
+ if (input.nonWitnessUtxo === undefined && !cache.unsafeSignNonSegwit)
950
1031
  throw new Error(`Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
951
- meaningfulScript.toString('hex'));
952
- if (!forValidate && cache.__UNSAFE_SIGN_NONSEGWIT)
1032
+ toHex(meaningfulScript));
1033
+ if (!forValidate && cache.unsafeSignNonSegwit)
953
1034
  console.warn('Warning: Signing non-segwit inputs without the full parent transaction ' +
954
1035
  'means there is a chance that a miner could feed you incorrect information ' +
955
1036
  "to trick you into paying large fees. This behavior is the same as Psbt's predecessor " +
@@ -957,10 +1038,10 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
957
1038
  'able to export this Psbt with toBuffer|toBase64|toHex since it is not ' +
958
1039
  'BIP174 compliant.\n*********************\nPROCEED WITH CAUTION!\n' +
959
1040
  '*********************');
960
- hash = unsignedTx.hashForSignature(inputIndex, meaningfulScript, sighashType);
1041
+ hash = unsignedTx.hashForSignature(inputIndex, script, sighashType);
961
1042
  }
962
1043
  return {
963
- script: meaningfulScript,
1044
+ script,
964
1045
  sighashType,
965
1046
  hash,
966
1047
  };
@@ -982,24 +1063,34 @@ function getAllTaprootHashesForSig(inputIndex, input, inputs, cache) {
982
1063
  }
983
1064
  function getPrevoutTaprootKey(inputIndex, input, cache) {
984
1065
  const { script } = getScriptAndAmountFromUtxo(inputIndex, input, cache);
985
- return isP2TR(script) ? Buffer.from(script.subarray(2, 34)) : null;
1066
+ return isP2TR(script) ? script.subarray(2, 34) : null;
986
1067
  }
987
1068
  function trimTaprootSig(signature) {
988
- return signature.length === 64 ? signature : Buffer.from(signature.subarray(0, 64));
1069
+ return signature.length === 64 ? signature : signature.subarray(0, 64);
989
1070
  }
990
1071
  function getTaprootHashesForSig(inputIndex, input, inputs, pubkey, cache, tapLeafHashToSign, allowedSighashTypes) {
991
- const unsignedTx = cache.__TX;
1072
+ const unsignedTx = cache.tx;
992
1073
  const sighashType = input.sighashType || Transaction.SIGHASH_DEFAULT;
993
1074
  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);
1075
+ if (!cache.prevOuts) {
1076
+ const prevOuts = inputs.map((i, index) => getScriptAndAmountFromUtxo(index, i, cache));
1077
+ cache.prevOuts = prevOuts;
1078
+ cache.signingScripts = prevOuts.map((o) => o.script);
1079
+ cache.values = prevOuts.map((o) => o.value);
1080
+ }
1081
+ const signingScripts = cache.signingScripts;
1082
+ const values = cache.values;
1083
+ // Compute taproot hash cache once for all inputs (O(n) -> O(1) per input)
1084
+ if (!cache.taprootHashCache) {
1085
+ cache.taprootHashCache = unsignedTx.getTaprootHashCache(signingScripts, values);
1086
+ }
1087
+ const taprootCache = cache.taprootHashCache;
997
1088
  const hashes = [];
998
1089
  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 });
1090
+ const outputKey = getPrevoutTaprootKey(inputIndex, input, cache) || new Uint8Array(0);
1091
+ if (equals(toXOnly(pubkey), outputKey)) {
1092
+ const tapKeyHash = unsignedTx.hashForWitnessV1(inputIndex, signingScripts, values, sighashType, undefined, undefined, taprootCache);
1093
+ hashes.push({ pubkey: pubkey, hash: tapKeyHash });
1003
1094
  }
1004
1095
  }
1005
1096
  const tapLeafHashes = (input.tapLeafScript || [])
@@ -1011,11 +1102,11 @@ function getTaprootHashesForSig(inputIndex, input, inputs, pubkey, cache, tapLea
1011
1102
  });
1012
1103
  return Object.assign({ hash }, tapLeaf);
1013
1104
  })
1014
- .filter((tapLeaf) => !tapLeafHashToSign || tapLeafHashToSign.equals(tapLeaf.hash))
1105
+ .filter((tapLeaf) => !tapLeafHashToSign || equals(tapLeafHashToSign, tapLeaf.hash))
1015
1106
  .map((tapLeaf) => {
1016
- const tapScriptHash = unsignedTx.hashForWitnessV1(inputIndex, signingScripts, values, sighashType, tapLeaf.hash);
1107
+ const tapScriptHash = unsignedTx.hashForWitnessV1(inputIndex, signingScripts, values, sighashType, tapLeaf.hash, undefined, taprootCache);
1017
1108
  return {
1018
- pubkey,
1109
+ pubkey: pubkey,
1019
1110
  hash: tapScriptHash,
1020
1111
  leafHash: tapLeaf.hash,
1021
1112
  };
@@ -1030,41 +1121,38 @@ function checkSighashTypeAllowed(sighashType, sighashTypes) {
1030
1121
  }
1031
1122
  }
1032
1123
  function getPayment(script, scriptType, partialSig) {
1033
- let payment;
1124
+ const scriptBranded = script;
1034
1125
  switch (scriptType) {
1035
1126
  case 'multisig': {
1036
1127
  const sigs = getSortedSigs(script, partialSig);
1037
- payment = payments.p2ms({
1038
- output: script,
1128
+ return payments.p2ms({
1129
+ output: scriptBranded,
1039
1130
  signatures: sigs,
1040
1131
  });
1041
- break;
1042
1132
  }
1043
1133
  case 'pubkey':
1044
- payment = payments.p2pk({
1045
- output: script,
1134
+ return payments.p2pk({
1135
+ output: scriptBranded,
1046
1136
  signature: partialSig[0].signature,
1047
1137
  });
1048
- break;
1049
1138
  case 'pubkeyhash':
1050
- payment = payments.p2pkh({
1051
- output: script,
1139
+ return payments.p2pkh({
1140
+ output: scriptBranded,
1052
1141
  pubkey: partialSig[0].pubkey,
1053
1142
  signature: partialSig[0].signature,
1054
1143
  });
1055
- break;
1056
1144
  case 'witnesspubkeyhash':
1057
- payment = payments.p2wpkh({
1058
- output: script,
1145
+ return payments.p2wpkh({
1146
+ output: scriptBranded,
1059
1147
  pubkey: partialSig[0].pubkey,
1060
1148
  signature: partialSig[0].signature,
1061
1149
  });
1062
- break;
1150
+ default:
1151
+ throw new Error(`Unknown script type: ${scriptType}`);
1063
1152
  }
1064
- return payment;
1065
1153
  }
1066
1154
  function getScriptFromInput(inputIndex, input, cache) {
1067
- const unsignedTx = cache.__TX;
1155
+ const unsignedTx = cache.tx;
1068
1156
  const res = {
1069
1157
  script: null,
1070
1158
  isSegwit: false,
@@ -1089,7 +1177,7 @@ function getScriptFromInput(inputIndex, input, cache) {
1089
1177
  res.script = input.witnessUtxo.script;
1090
1178
  }
1091
1179
  }
1092
- if (input.witnessScript || isP2WPKH(res.script)) {
1180
+ if (input.witnessScript || (res.script && isP2WPKH(res.script))) {
1093
1181
  res.isSegwit = true;
1094
1182
  }
1095
1183
  else {
@@ -1110,7 +1198,7 @@ function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
1110
1198
  }
1111
1199
  const myDerivations = input.bip32Derivation
1112
1200
  .map((bipDv) => {
1113
- if (bipDv.masterFingerprint.equals(hdKeyPair.fingerprint)) {
1201
+ if (equals(bipDv.masterFingerprint, hdKeyPair.fingerprint)) {
1114
1202
  return bipDv;
1115
1203
  }
1116
1204
  else {
@@ -1123,7 +1211,7 @@ function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
1123
1211
  }
1124
1212
  return myDerivations.map((bipDv) => {
1125
1213
  const node = hdKeyPair.derivePath(bipDv.path);
1126
- if (!bipDv.pubkey.equals(node.publicKey)) {
1214
+ if (!equals(bipDv.pubkey, node.publicKey)) {
1127
1215
  throw new Error('pubkey did not match bip32Derivation');
1128
1216
  }
1129
1217
  return node;
@@ -1131,80 +1219,56 @@ function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
1131
1219
  }
1132
1220
  function getSortedSigs(script, partialSig) {
1133
1221
  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;
1222
+ if (!p2ms.pubkeys)
1223
+ throw new Error('Cannot extract pubkeys from multisig script');
1224
+ // for each pubkey in order of p2ms script
1225
+ const result = [];
1226
+ for (const pk of p2ms.pubkeys) {
1227
+ // filter partialSig array by pubkey being equal
1228
+ const matched = partialSig.filter((ps) => {
1229
+ return equals(ps.pubkey, pk);
1230
+ })[0];
1231
+ if (matched) {
1232
+ result.push(new Uint8Array(matched.signature));
1233
+ }
1234
+ }
1235
+ return result;
1180
1236
  }
1181
1237
  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);
1238
+ if (!input.nonWitnessUtxo)
1239
+ throw new Error('nonWitnessUtxo is required');
1240
+ // Prevent prototype pollution - ensure input is a valid object
1241
+ if (input === null || input === Object.prototype) {
1242
+ throw new Error('Invalid input object');
1243
+ }
1244
+ const nonWitnessUtxoBuf = input.nonWitnessUtxo;
1245
+ cache.nonWitnessUtxoBufCache[inputIndex] = nonWitnessUtxoBuf;
1246
+ cache.nonWitnessUtxoTxCache[inputIndex] = Transaction.fromBuffer(nonWitnessUtxoBuf);
1184
1247
  const self = cache;
1185
1248
  const selfIndex = inputIndex;
1186
1249
  delete input.nonWitnessUtxo;
1187
- Object.defineProperty(input, 'nonWitnessUtxo', {
1250
+ // Using Reflect.defineProperty to avoid prototype pollution concerns
1251
+ Reflect.defineProperty(input, 'nonWitnessUtxo', {
1188
1252
  enumerable: true,
1189
1253
  get() {
1190
- const buf = self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex];
1191
- const txCache = self.__NON_WITNESS_UTXO_TX_CACHE[selfIndex];
1254
+ const buf = self.nonWitnessUtxoBufCache[selfIndex];
1255
+ const txCache = self.nonWitnessUtxoTxCache[selfIndex];
1192
1256
  if (buf !== undefined) {
1193
1257
  return buf;
1194
1258
  }
1195
1259
  else {
1196
1260
  const newBuf = txCache.toBuffer();
1197
- self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = newBuf;
1261
+ self.nonWitnessUtxoBufCache[selfIndex] = newBuf;
1198
1262
  return newBuf;
1199
1263
  }
1200
1264
  },
1201
1265
  set(data) {
1202
- self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = data;
1266
+ self.nonWitnessUtxoBufCache[selfIndex] = data;
1203
1267
  },
1204
1268
  });
1205
1269
  }
1206
1270
  function inputFinalizeGetAmts(inputs, tx, cache, mustFinalize, disableOutputChecks) {
1207
- let inputAmount = 0;
1271
+ let inputAmount = 0n;
1208
1272
  inputs.forEach((input, idx) => {
1209
1273
  if (mustFinalize && input.finalScriptSig)
1210
1274
  tx.ins[idx].script = input.finalScriptSig;
@@ -1221,20 +1285,20 @@ function inputFinalizeGetAmts(inputs, tx, cache, mustFinalize, disableOutputChec
1221
1285
  inputAmount += out.value;
1222
1286
  }
1223
1287
  });
1224
- const outputAmount = tx.outs.reduce((total, o) => total + o.value, 0);
1288
+ const outputAmount = tx.outs.reduce((total, o) => total + o.value, 0n);
1225
1289
  const fee = inputAmount - outputAmount;
1226
1290
  if (!disableOutputChecks) {
1227
- if (fee < 0) {
1291
+ if (fee < 0n) {
1228
1292
  throw new Error(`Outputs are spending more than Inputs ${inputAmount} < ${outputAmount}`);
1229
1293
  }
1230
1294
  }
1231
1295
  const bytes = tx.virtualSize();
1232
- cache.__FEE = fee;
1233
- cache.__EXTRACTED_TX = tx;
1234
- cache.__FEE_RATE = Math.floor(fee / bytes);
1296
+ cache.fee = Number(fee);
1297
+ cache.extractedTx = tx;
1298
+ cache.feeRate = Math.floor(Number(fee) / bytes);
1235
1299
  }
1236
1300
  function nonWitnessUtxoTxFromCache(cache, input, inputIndex) {
1237
- const c = cache.__NON_WITNESS_UTXO_TX_CACHE;
1301
+ const c = cache.nonWitnessUtxoTxCache;
1238
1302
  if (!c[inputIndex]) {
1239
1303
  addNonWitnessTxCache(cache, input, inputIndex);
1240
1304
  }
@@ -1253,7 +1317,7 @@ function getScriptAndAmountFromUtxo(inputIndex, input, cache) {
1253
1317
  }
1254
1318
  else if (input.nonWitnessUtxo !== undefined) {
1255
1319
  const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(cache, input, inputIndex);
1256
- const o = nonWitnessUtxoTx.outs[cache.__TX.ins[inputIndex].index];
1320
+ const o = nonWitnessUtxoTx.outs[cache.tx.ins[inputIndex].index];
1257
1321
  return { script: o.script, value: o.value };
1258
1322
  }
1259
1323
  else {
@@ -1266,7 +1330,7 @@ function pubkeyInInput(pubkey, input, inputIndex, cache) {
1266
1330
  return pubkeyInScript(pubkey, meaningfulScript);
1267
1331
  }
1268
1332
  function pubkeyInOutput(pubkey, output, outputIndex, cache) {
1269
- const script = cache.__TX.outs[outputIndex].script;
1333
+ const script = cache.tx.outs[outputIndex].script;
1270
1334
  const { meaningfulScript } = getMeaningfulScript(script, outputIndex, 'output', output.redeemScript, output.witnessScript);
1271
1335
  return pubkeyInScript(pubkey, meaningfulScript);
1272
1336
  }
@@ -1277,7 +1341,7 @@ function redeemFromFinalScriptSig(finalScript) {
1277
1341
  if (!decomp)
1278
1342
  return;
1279
1343
  const lastItem = decomp[decomp.length - 1];
1280
- if (!Buffer.isBuffer(lastItem) || isPubkeyLike(lastItem) || isSigLike(lastItem))
1344
+ if (!(lastItem instanceof Uint8Array) || isPubkeyLike(lastItem) || isSigLike(lastItem))
1281
1345
  return;
1282
1346
  const sDecomp = bscript.decompile(lastItem);
1283
1347
  if (!sDecomp)
@@ -1296,69 +1360,4 @@ function redeemFromFinalWitnessScript(finalScript) {
1296
1360
  return;
1297
1361
  return lastItem;
1298
1362
  }
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
- }
1363
+ //# sourceMappingURL=psbt.js.map