@bsv/sdk 1.3.12 → 1.3.14

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 (607) hide show
  1. package/dist/cjs/package.json +15 -3
  2. package/dist/cjs/src/auth/Peer.js +83 -57
  3. package/dist/cjs/src/auth/Peer.js.map +1 -1
  4. package/dist/cjs/src/auth/SessionManager.js +14 -9
  5. package/dist/cjs/src/auth/SessionManager.js.map +1 -1
  6. package/dist/cjs/src/auth/certificates/Certificate.js +16 -10
  7. package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
  8. package/dist/cjs/src/auth/certificates/MasterCertificate.js +25 -23
  9. package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
  10. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +2 -2
  11. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  12. package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js +62 -46
  13. package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  14. package/dist/cjs/src/auth/clients/AuthFetch.js +1 -0
  15. package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
  16. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +70 -43
  17. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  18. package/dist/cjs/src/auth/utils/createNonce.js +2 -1
  19. package/dist/cjs/src/auth/utils/createNonce.js.map +1 -1
  20. package/dist/cjs/src/auth/utils/getVerifiableCertificates.js.map +1 -1
  21. package/dist/cjs/src/auth/utils/validateCertificates.js +5 -2
  22. package/dist/cjs/src/auth/utils/validateCertificates.js.map +1 -1
  23. package/dist/cjs/src/auth/utils/verifyNonce.js +2 -1
  24. package/dist/cjs/src/auth/utils/verifyNonce.js.map +1 -1
  25. package/dist/cjs/src/compat/BSM.js +7 -17
  26. package/dist/cjs/src/compat/BSM.js.map +1 -1
  27. package/dist/cjs/src/compat/ECIES.js +172 -133
  28. package/dist/cjs/src/compat/ECIES.js.map +1 -1
  29. package/dist/cjs/src/compat/HD.js +63 -73
  30. package/dist/cjs/src/compat/HD.js.map +1 -1
  31. package/dist/cjs/src/compat/Mnemonic.js +102 -106
  32. package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
  33. package/dist/cjs/src/compat/Utxo.js +2 -2
  34. package/dist/cjs/src/compat/Utxo.js.map +1 -1
  35. package/dist/cjs/src/compat/index.js +7 -17
  36. package/dist/cjs/src/compat/index.js.map +1 -1
  37. package/dist/cjs/src/messages/EncryptedMessage.js +3 -1
  38. package/dist/cjs/src/messages/EncryptedMessage.js.map +1 -1
  39. package/dist/cjs/src/messages/SignedMessage.js +1 -0
  40. package/dist/cjs/src/messages/SignedMessage.js.map +1 -1
  41. package/dist/cjs/src/messages/index.js +7 -17
  42. package/dist/cjs/src/messages/index.js.map +1 -1
  43. package/dist/cjs/src/overlay-tools/LookupResolver.js +54 -35
  44. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  45. package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js +32 -20
  46. package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
  47. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +40 -28
  48. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  49. package/dist/cjs/src/primitives/AESGCM.js +6 -5
  50. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  51. package/dist/cjs/src/primitives/BasePoint.js +1 -1
  52. package/dist/cjs/src/primitives/BasePoint.js.map +1 -1
  53. package/dist/cjs/src/primitives/BigNumber.js +50 -62
  54. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  55. package/dist/cjs/src/primitives/Curve.js +46 -22
  56. package/dist/cjs/src/primitives/Curve.js.map +1 -1
  57. package/dist/cjs/src/primitives/DRBG.js +2 -8
  58. package/dist/cjs/src/primitives/DRBG.js.map +1 -1
  59. package/dist/cjs/src/primitives/ECDSA.js +51 -35
  60. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  61. package/dist/cjs/src/primitives/Hash.js +191 -216
  62. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  63. package/dist/cjs/src/primitives/JacobianPoint.js +19 -5
  64. package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
  65. package/dist/cjs/src/primitives/K256.js.map +1 -1
  66. package/dist/cjs/src/primitives/Mersenne.js.map +1 -1
  67. package/dist/cjs/src/primitives/MontgomoryMethod.js.map +1 -1
  68. package/dist/cjs/src/primitives/Point.js +117 -88
  69. package/dist/cjs/src/primitives/Point.js.map +1 -1
  70. package/dist/cjs/src/primitives/Polynomial.js +4 -2
  71. package/dist/cjs/src/primitives/Polynomial.js.map +1 -1
  72. package/dist/cjs/src/primitives/PrivateKey.js +32 -33
  73. package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
  74. package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
  75. package/dist/cjs/src/primitives/Random.js +6 -5
  76. package/dist/cjs/src/primitives/Random.js.map +1 -1
  77. package/dist/cjs/src/primitives/ReductionContext.js +1 -1
  78. package/dist/cjs/src/primitives/ReductionContext.js.map +1 -1
  79. package/dist/cjs/src/primitives/Schnorr.js +21 -15
  80. package/dist/cjs/src/primitives/Schnorr.js.map +1 -1
  81. package/dist/cjs/src/primitives/Signature.js +8 -7
  82. package/dist/cjs/src/primitives/Signature.js.map +1 -1
  83. package/dist/cjs/src/primitives/SymmetricKey.js +13 -13
  84. package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
  85. package/dist/cjs/src/primitives/TransactionSignature.js +31 -29
  86. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  87. package/dist/cjs/src/primitives/index.js +7 -17
  88. package/dist/cjs/src/primitives/index.js.map +1 -1
  89. package/dist/cjs/src/primitives/utils.js +79 -68
  90. package/dist/cjs/src/primitives/utils.js.map +1 -1
  91. package/dist/cjs/src/script/OP.js +3 -3
  92. package/dist/cjs/src/script/OP.js.map +1 -1
  93. package/dist/cjs/src/script/Script.js +12 -10
  94. package/dist/cjs/src/script/Script.js.map +1 -1
  95. package/dist/cjs/src/script/Spend.js +47 -49
  96. package/dist/cjs/src/script/Spend.js.map +1 -1
  97. package/dist/cjs/src/script/templates/P2PKH.js +24 -12
  98. package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
  99. package/dist/cjs/src/script/templates/PushDrop.js +28 -23
  100. package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
  101. package/dist/cjs/src/script/templates/RPuzzle.js +10 -6
  102. package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
  103. package/dist/cjs/src/totp/totp.js +2 -1
  104. package/dist/cjs/src/totp/totp.js.map +1 -1
  105. package/dist/cjs/src/transaction/Beef.js +177 -154
  106. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  107. package/dist/cjs/src/transaction/BeefParty.js +24 -24
  108. package/dist/cjs/src/transaction/BeefParty.js.map +1 -1
  109. package/dist/cjs/src/transaction/BeefTx.js +26 -18
  110. package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
  111. package/dist/cjs/src/transaction/Broadcaster.js +3 -2
  112. package/dist/cjs/src/transaction/Broadcaster.js.map +1 -1
  113. package/dist/cjs/src/transaction/MerklePath.js +64 -37
  114. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  115. package/dist/cjs/src/transaction/Transaction.js +111 -137
  116. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  117. package/dist/cjs/src/transaction/broadcasters/ARC.js +25 -16
  118. package/dist/cjs/src/transaction/broadcasters/ARC.js.map +1 -1
  119. package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js +2 -1
  120. package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
  121. package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
  122. package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js +2 -1
  123. package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js.map +1 -1
  124. package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js +3 -3
  125. package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
  126. package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
  127. package/dist/cjs/src/transaction/http/DefaultHttpClient.js +5 -3
  128. package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
  129. package/dist/cjs/src/transaction/http/FetchHttpClient.js +5 -2
  130. package/dist/cjs/src/transaction/http/FetchHttpClient.js.map +1 -1
  131. package/dist/cjs/src/transaction/http/NodejsHttpClient.js +5 -3
  132. package/dist/cjs/src/transaction/http/NodejsHttpClient.js.map +1 -1
  133. package/dist/cjs/src/transaction/http/index.js.map +1 -1
  134. package/dist/cjs/src/transaction/index.js.map +1 -1
  135. package/dist/cjs/src/wallet/CachedKeyDeriver.js +91 -66
  136. package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
  137. package/dist/cjs/src/wallet/KeyDeriver.js +61 -52
  138. package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -1
  139. package/dist/cjs/src/wallet/ProtoWallet.js +79 -29
  140. package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
  141. package/dist/cjs/src/wallet/WalletClient.js +7 -2
  142. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  143. package/dist/cjs/src/wallet/WalletError.js +2 -2
  144. package/dist/cjs/src/wallet/WalletError.js.map +1 -1
  145. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js +4 -3
  146. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  147. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +2 -2
  148. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  149. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +1239 -1261
  150. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  151. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +102 -43
  152. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  153. package/dist/cjs/src/wallet/substrates/XDM.js +8 -3
  154. package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
  155. package/dist/cjs/src/wallet/substrates/window.CWI.js +28 -28
  156. package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -1
  157. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  158. package/dist/esm/mod.js +15 -15
  159. package/dist/esm/src/auth/Peer.js +75 -54
  160. package/dist/esm/src/auth/Peer.js.map +1 -1
  161. package/dist/esm/src/auth/SessionManager.js +14 -9
  162. package/dist/esm/src/auth/SessionManager.js.map +1 -1
  163. package/dist/esm/src/auth/certificates/Certificate.js +15 -11
  164. package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
  165. package/dist/esm/src/auth/certificates/MasterCertificate.js +25 -23
  166. package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
  167. package/dist/esm/src/auth/certificates/VerifiableCertificate.js +2 -2
  168. package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  169. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js +64 -47
  170. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  171. package/dist/esm/src/auth/clients/AuthFetch.js +1 -0
  172. package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
  173. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +69 -43
  174. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  175. package/dist/esm/src/auth/utils/createNonce.js.map +1 -1
  176. package/dist/esm/src/auth/utils/getVerifiableCertificates.js +1 -1
  177. package/dist/esm/src/auth/utils/getVerifiableCertificates.js.map +1 -1
  178. package/dist/esm/src/auth/utils/validateCertificates.js +6 -3
  179. package/dist/esm/src/auth/utils/validateCertificates.js.map +1 -1
  180. package/dist/esm/src/auth/utils/verifyNonce.js.map +1 -1
  181. package/dist/esm/src/compat/BSM.js.map +1 -1
  182. package/dist/esm/src/compat/ECIES.js +165 -116
  183. package/dist/esm/src/compat/ECIES.js.map +1 -1
  184. package/dist/esm/src/compat/HD.js +56 -56
  185. package/dist/esm/src/compat/HD.js.map +1 -1
  186. package/dist/esm/src/compat/Mnemonic.js +95 -89
  187. package/dist/esm/src/compat/Mnemonic.js.map +1 -1
  188. package/dist/esm/src/compat/Utxo.js +1 -1
  189. package/dist/esm/src/compat/Utxo.js.map +1 -1
  190. package/dist/esm/src/messages/EncryptedMessage.js +3 -1
  191. package/dist/esm/src/messages/EncryptedMessage.js.map +1 -1
  192. package/dist/esm/src/messages/SignedMessage.js +1 -0
  193. package/dist/esm/src/messages/SignedMessage.js.map +1 -1
  194. package/dist/esm/src/overlay-tools/LookupResolver.js +53 -35
  195. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  196. package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js +32 -20
  197. package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
  198. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +40 -28
  199. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  200. package/dist/esm/src/primitives/AESGCM.js +1 -0
  201. package/dist/esm/src/primitives/AESGCM.js.map +1 -1
  202. package/dist/esm/src/primitives/BasePoint.js +1 -1
  203. package/dist/esm/src/primitives/BasePoint.js.map +1 -1
  204. package/dist/esm/src/primitives/BigNumber.js +50 -62
  205. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  206. package/dist/esm/src/primitives/Curve.js +45 -22
  207. package/dist/esm/src/primitives/Curve.js.map +1 -1
  208. package/dist/esm/src/primitives/DRBG.js +2 -8
  209. package/dist/esm/src/primitives/DRBG.js.map +1 -1
  210. package/dist/esm/src/primitives/ECDSA.js +50 -35
  211. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  212. package/dist/esm/src/primitives/Hash.js +188 -213
  213. package/dist/esm/src/primitives/Hash.js.map +1 -1
  214. package/dist/esm/src/primitives/JacobianPoint.js +18 -5
  215. package/dist/esm/src/primitives/JacobianPoint.js.map +1 -1
  216. package/dist/esm/src/primitives/K256.js.map +1 -1
  217. package/dist/esm/src/primitives/Mersenne.js.map +1 -1
  218. package/dist/esm/src/primitives/MontgomoryMethod.js.map +1 -1
  219. package/dist/esm/src/primitives/Point.js +107 -88
  220. package/dist/esm/src/primitives/Point.js.map +1 -1
  221. package/dist/esm/src/primitives/Polynomial.js +4 -2
  222. package/dist/esm/src/primitives/Polynomial.js.map +1 -1
  223. package/dist/esm/src/primitives/PrivateKey.js +25 -16
  224. package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
  225. package/dist/esm/src/primitives/PublicKey.js.map +1 -1
  226. package/dist/esm/src/primitives/Random.js +7 -6
  227. package/dist/esm/src/primitives/Random.js.map +1 -1
  228. package/dist/esm/src/primitives/ReductionContext.js +1 -1
  229. package/dist/esm/src/primitives/ReductionContext.js.map +1 -1
  230. package/dist/esm/src/primitives/Schnorr.js +21 -15
  231. package/dist/esm/src/primitives/Schnorr.js.map +1 -1
  232. package/dist/esm/src/primitives/Signature.js +8 -7
  233. package/dist/esm/src/primitives/Signature.js.map +1 -1
  234. package/dist/esm/src/primitives/SymmetricKey.js +13 -13
  235. package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
  236. package/dist/esm/src/primitives/TransactionSignature.js +22 -12
  237. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  238. package/dist/esm/src/primitives/utils.js +76 -66
  239. package/dist/esm/src/primitives/utils.js.map +1 -1
  240. package/dist/esm/src/script/OP.js +3 -3
  241. package/dist/esm/src/script/OP.js.map +1 -1
  242. package/dist/esm/src/script/Script.js +12 -10
  243. package/dist/esm/src/script/Script.js.map +1 -1
  244. package/dist/esm/src/script/Spend.js +39 -32
  245. package/dist/esm/src/script/Spend.js.map +1 -1
  246. package/dist/esm/src/script/templates/P2PKH.js +26 -11
  247. package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
  248. package/dist/esm/src/script/templates/PushDrop.js +29 -22
  249. package/dist/esm/src/script/templates/PushDrop.js.map +1 -1
  250. package/dist/esm/src/script/templates/RPuzzle.js +11 -6
  251. package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
  252. package/dist/esm/src/totp/totp.js +2 -1
  253. package/dist/esm/src/totp/totp.js.map +1 -1
  254. package/dist/esm/src/transaction/Beef.js +176 -154
  255. package/dist/esm/src/transaction/Beef.js.map +1 -1
  256. package/dist/esm/src/transaction/BeefParty.js +24 -24
  257. package/dist/esm/src/transaction/BeefParty.js.map +1 -1
  258. package/dist/esm/src/transaction/BeefTx.js +26 -18
  259. package/dist/esm/src/transaction/BeefTx.js.map +1 -1
  260. package/dist/esm/src/transaction/Broadcaster.js.map +1 -1
  261. package/dist/esm/src/transaction/MerklePath.js +61 -36
  262. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  263. package/dist/esm/src/transaction/Transaction.js +105 -138
  264. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  265. package/dist/esm/src/transaction/broadcasters/ARC.js +25 -16
  266. package/dist/esm/src/transaction/broadcasters/ARC.js.map +1 -1
  267. package/dist/esm/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
  268. package/dist/esm/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
  269. package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js +3 -3
  270. package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
  271. package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
  272. package/dist/esm/src/transaction/http/DefaultHttpClient.js +3 -2
  273. package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
  274. package/dist/esm/src/transaction/http/FetchHttpClient.js +4 -2
  275. package/dist/esm/src/transaction/http/FetchHttpClient.js.map +1 -1
  276. package/dist/esm/src/transaction/http/NodejsHttpClient.js +5 -3
  277. package/dist/esm/src/transaction/http/NodejsHttpClient.js.map +1 -1
  278. package/dist/esm/src/transaction/http/index.js.map +1 -1
  279. package/dist/esm/src/transaction/index.js.map +1 -1
  280. package/dist/esm/src/wallet/CachedKeyDeriver.js +91 -66
  281. package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
  282. package/dist/esm/src/wallet/KeyDeriver.js +60 -52
  283. package/dist/esm/src/wallet/KeyDeriver.js.map +1 -1
  284. package/dist/esm/src/wallet/ProtoWallet.js +75 -29
  285. package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
  286. package/dist/esm/src/wallet/WalletClient.js +7 -2
  287. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  288. package/dist/esm/src/wallet/WalletError.js +2 -2
  289. package/dist/esm/src/wallet/WalletError.js.map +1 -1
  290. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js +4 -4
  291. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  292. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js +2 -2
  293. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  294. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1239 -1261
  295. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  296. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +95 -43
  297. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  298. package/dist/esm/src/wallet/substrates/XDM.js +8 -3
  299. package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
  300. package/dist/esm/src/wallet/substrates/window.CWI.js +28 -28
  301. package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -1
  302. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  303. package/dist/types/mod.d.ts +15 -15
  304. package/dist/types/src/auth/Peer.d.ts +10 -10
  305. package/dist/types/src/auth/Peer.d.ts.map +1 -1
  306. package/dist/types/src/auth/SessionManager.d.ts +4 -4
  307. package/dist/types/src/auth/SessionManager.d.ts.map +1 -1
  308. package/dist/types/src/auth/certificates/Certificate.d.ts +6 -6
  309. package/dist/types/src/auth/certificates/Certificate.d.ts.map +1 -1
  310. package/dist/types/src/auth/certificates/MasterCertificate.d.ts +5 -5
  311. package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
  312. package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts.map +1 -1
  313. package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts +23 -22
  314. package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts.map +1 -1
  315. package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
  316. package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts +1 -1
  317. package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts.map +1 -1
  318. package/dist/types/src/auth/utils/createNonce.d.ts.map +1 -1
  319. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts +3 -3
  320. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
  321. package/dist/types/src/auth/utils/validateCertificates.d.ts +2 -2
  322. package/dist/types/src/auth/utils/validateCertificates.d.ts.map +1 -1
  323. package/dist/types/src/auth/utils/verifyNonce.d.ts +1 -1
  324. package/dist/types/src/auth/utils/verifyNonce.d.ts.map +1 -1
  325. package/dist/types/src/compat/BSM.d.ts +1 -1
  326. package/dist/types/src/compat/BSM.d.ts.map +1 -1
  327. package/dist/types/src/compat/ECIES.d.ts +36 -36
  328. package/dist/types/src/compat/ECIES.d.ts.map +1 -1
  329. package/dist/types/src/compat/HD.d.ts +51 -51
  330. package/dist/types/src/compat/HD.d.ts.map +1 -1
  331. package/dist/types/src/compat/Mnemonic.d.ts +79 -79
  332. package/dist/types/src/compat/Mnemonic.d.ts.map +1 -1
  333. package/dist/types/src/compat/Utxo.d.ts.map +1 -1
  334. package/dist/types/src/messages/EncryptedMessage.d.ts.map +1 -1
  335. package/dist/types/src/messages/SignedMessage.d.ts.map +1 -1
  336. package/dist/types/src/overlay-tools/LookupResolver.d.ts +9 -9
  337. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
  338. package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts +17 -17
  339. package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts.map +1 -1
  340. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts +14 -14
  341. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -1
  342. package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
  343. package/dist/types/src/primitives/BasePoint.d.ts +8 -8
  344. package/dist/types/src/primitives/BasePoint.d.ts.map +1 -1
  345. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  346. package/dist/types/src/primitives/Curve.d.ts +14 -7
  347. package/dist/types/src/primitives/Curve.d.ts.map +1 -1
  348. package/dist/types/src/primitives/DRBG.d.ts.map +1 -1
  349. package/dist/types/src/primitives/ECDSA.d.ts +1 -1
  350. package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
  351. package/dist/types/src/primitives/Hash.d.ts +11 -11
  352. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  353. package/dist/types/src/primitives/JacobianPoint.d.ts.map +1 -1
  354. package/dist/types/src/primitives/Point.d.ts +14 -10
  355. package/dist/types/src/primitives/Point.d.ts.map +1 -1
  356. package/dist/types/src/primitives/Polynomial.d.ts.map +1 -1
  357. package/dist/types/src/primitives/PrivateKey.d.ts +2 -2
  358. package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
  359. package/dist/types/src/primitives/PublicKey.d.ts.map +1 -1
  360. package/dist/types/src/primitives/Random.d.ts.map +1 -1
  361. package/dist/types/src/primitives/Schnorr.d.ts +14 -14
  362. package/dist/types/src/primitives/Schnorr.d.ts.map +1 -1
  363. package/dist/types/src/primitives/Signature.d.ts +1 -1
  364. package/dist/types/src/primitives/Signature.d.ts.map +1 -1
  365. package/dist/types/src/primitives/SymmetricKey.d.ts +13 -13
  366. package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
  367. package/dist/types/src/primitives/TransactionSignature.d.ts +4 -4
  368. package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
  369. package/dist/types/src/primitives/utils.d.ts +3 -6
  370. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  371. package/dist/types/src/script/Script.d.ts +3 -3
  372. package/dist/types/src/script/Script.d.ts.map +1 -1
  373. package/dist/types/src/script/ScriptTemplate.d.ts +2 -2
  374. package/dist/types/src/script/ScriptTemplate.d.ts.map +1 -1
  375. package/dist/types/src/script/Spend.d.ts.map +1 -1
  376. package/dist/types/src/script/templates/P2PKH.d.ts.map +1 -1
  377. package/dist/types/src/script/templates/PushDrop.d.ts +1 -2
  378. package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -1
  379. package/dist/types/src/script/templates/RPuzzle.d.ts.map +1 -1
  380. package/dist/types/src/totp/totp.d.ts.map +1 -1
  381. package/dist/types/src/transaction/Beef.d.ts +96 -96
  382. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  383. package/dist/types/src/transaction/BeefParty.d.ts +22 -22
  384. package/dist/types/src/transaction/BeefParty.d.ts.map +1 -1
  385. package/dist/types/src/transaction/BeefTx.d.ts +5 -5
  386. package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
  387. package/dist/types/src/transaction/Broadcaster.d.ts.map +1 -1
  388. package/dist/types/src/transaction/ChainTracker.d.ts +2 -2
  389. package/dist/types/src/transaction/FeeModel.d.ts.map +1 -1
  390. package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
  391. package/dist/types/src/transaction/Transaction.d.ts +4 -12
  392. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  393. package/dist/types/src/transaction/TransactionOutput.d.ts.map +1 -1
  394. package/dist/types/src/transaction/broadcasters/ARC.d.ts +1 -1
  395. package/dist/types/src/transaction/broadcasters/ARC.d.ts.map +1 -1
  396. package/dist/types/src/transaction/broadcasters/DefaultBroadcaster.d.ts.map +1 -1
  397. package/dist/types/src/transaction/broadcasters/WhatsOnChainBroadcaster.d.ts.map +1 -1
  398. package/dist/types/src/transaction/chaintrackers/DefaultChainTracker.d.ts.map +1 -1
  399. package/dist/types/src/transaction/chaintrackers/WhatsOnChain.d.ts.map +1 -1
  400. package/dist/types/src/transaction/fee-models/SatoshisPerKilobyte.d.ts.map +1 -1
  401. package/dist/types/src/transaction/http/DefaultHttpClient.d.ts +1 -1
  402. package/dist/types/src/transaction/http/DefaultHttpClient.d.ts.map +1 -1
  403. package/dist/types/src/transaction/http/FetchHttpClient.d.ts +5 -5
  404. package/dist/types/src/transaction/http/FetchHttpClient.d.ts.map +1 -1
  405. package/dist/types/src/transaction/http/HttpClient.d.ts +4 -4
  406. package/dist/types/src/transaction/http/HttpClient.d.ts.map +1 -1
  407. package/dist/types/src/transaction/http/NodejsHttpClient.d.ts +3 -3
  408. package/dist/types/src/transaction/http/NodejsHttpClient.d.ts.map +1 -1
  409. package/dist/types/src/transaction/http/index.d.ts.map +1 -1
  410. package/dist/types/src/transaction/index.d.ts.map +1 -1
  411. package/dist/types/src/wallet/CachedKeyDeriver.d.ts +58 -58
  412. package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -1
  413. package/dist/types/src/wallet/KeyDeriver.d.ts +78 -78
  414. package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -1
  415. package/dist/types/src/wallet/ProtoWallet.d.ts +10 -10
  416. package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -1
  417. package/dist/types/src/wallet/Wallet.interfaces.d.ts +151 -152
  418. package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
  419. package/dist/types/src/wallet/WalletClient.d.ts +5 -5
  420. package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
  421. package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts +6 -6
  422. package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts.map +1 -1
  423. package/dist/types/src/wallet/substrates/HTTPWalletWire.d.ts.map +1 -1
  424. package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts.map +1 -1
  425. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -1
  426. package/dist/types/src/wallet/substrates/XDM.d.ts +1 -1
  427. package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -1
  428. package/dist/types/src/wallet/substrates/window.CWI.d.ts +6 -6
  429. package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -1
  430. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  431. package/dist/umd/bundle.js +1 -1
  432. package/docs/auth.md +92 -82
  433. package/docs/compat.md +24 -24
  434. package/docs/messages.md +7 -5
  435. package/docs/overlay-tools.md +21 -21
  436. package/docs/primitives.md +336 -315
  437. package/docs/script.md +35 -35
  438. package/docs/swagger/dist/swagger-initializer.js +7 -7
  439. package/docs/swagger/dist/swagger-ui-bundle.js +1 -1
  440. package/docs/swagger/dist/swagger-ui-es-bundle-core.js +2 -2
  441. package/docs/swagger/dist/swagger-ui-es-bundle.js +1 -1
  442. package/docs/swagger/dist/swagger-ui-standalone-preset.js +1 -1
  443. package/docs/swagger/dist/swagger-ui.js +2 -2
  444. package/docs/totp.md +5 -5
  445. package/docs/transaction.md +103 -105
  446. package/docs/wallet-substrates.md +17 -17
  447. package/docs/wallet.md +202 -204
  448. package/mod.ts +15 -15
  449. package/package.json +15 -3
  450. package/src/auth/Peer.ts +271 -121
  451. package/src/auth/SessionManager.ts +17 -10
  452. package/src/auth/__tests/Peer.test.ts +361 -179
  453. package/src/auth/__tests/SessionManager.test.ts +67 -19
  454. package/src/auth/__tests/build.test.ts +11 -0
  455. package/src/auth/certificates/Certificate.ts +27 -14
  456. package/src/auth/certificates/MasterCertificate.ts +106 -62
  457. package/src/auth/certificates/VerifiableCertificate.ts +30 -8
  458. package/src/auth/certificates/__tests/Certificate.test.ts +32 -17
  459. package/src/auth/certificates/__tests/CompletedProtoWallet.ts +171 -68
  460. package/src/auth/certificates/__tests/MasterCertificate.test.ts +63 -47
  461. package/src/auth/certificates/__tests/VerifiableCertificate.test.ts +42 -31
  462. package/src/auth/certificates/index.ts +1 -1
  463. package/src/auth/clients/AuthFetch.ts +1 -0
  464. package/src/auth/clients/index.ts +1 -1
  465. package/src/auth/transports/SimplifiedFetchTransport.ts +145 -72
  466. package/src/auth/transports/index.ts +1 -1
  467. package/src/auth/utils/__tests/cryptononce.test.ts +52 -23
  468. package/src/auth/utils/__tests/getVerifiableCertificates.test.ts +56 -30
  469. package/src/auth/utils/__tests/validateCertificates.test.ts +53 -31
  470. package/src/auth/utils/createNonce.ts +11 -3
  471. package/src/auth/utils/getVerifiableCertificates.ts +12 -7
  472. package/src/auth/utils/validateCertificates.ts +57 -39
  473. package/src/auth/utils/verifyNonce.ts +6 -2
  474. package/src/compat/BSM.ts +10 -2
  475. package/src/compat/ECIES.ts +265 -141
  476. package/src/compat/HD.ts +81 -63
  477. package/src/compat/Mnemonic.ts +104 -91
  478. package/src/compat/Utxo.ts +8 -5
  479. package/src/compat/__tests/BSM.test.ts +42 -16
  480. package/src/compat/__tests/ECIES.test.ts +117 -52
  481. package/src/compat/__tests/HD.test.ts +55 -42
  482. package/src/compat/__tests/Mnemonic.test.ts +11 -12
  483. package/src/compat/__tests/Mnemonic.vectors.ts +110 -55
  484. package/src/messages/EncryptedMessage.ts +6 -2
  485. package/src/messages/SignedMessage.ts +14 -8
  486. package/src/messages/__tests/EncryptedMessage.test.ts +23 -24
  487. package/src/messages/__tests/SignedMessage.test.ts +17 -11
  488. package/src/overlay-tools/LookupResolver.ts +108 -56
  489. package/src/overlay-tools/OverlayAdminTokenTemplate.ts +52 -23
  490. package/src/overlay-tools/SHIPBroadcaster.ts +135 -59
  491. package/src/overlay-tools/__tests/LookupResolver.test.ts +723 -323
  492. package/src/overlay-tools/__tests/OverlayAdminTokenTemplate.test.ts +50 -22
  493. package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +607 -290
  494. package/src/primitives/AESGCM.ts +2 -0
  495. package/src/primitives/BasePoint.ts +4 -4
  496. package/src/primitives/BigNumber.ts +99 -90
  497. package/src/primitives/Curve.ts +117 -46
  498. package/src/primitives/DRBG.ts +9 -11
  499. package/src/primitives/ECDSA.ts +109 -63
  500. package/src/primitives/Hash.ts +492 -321
  501. package/src/primitives/JacobianPoint.ts +67 -19
  502. package/src/primitives/Point.ts +254 -152
  503. package/src/primitives/Polynomial.ts +8 -3
  504. package/src/primitives/PrivateKey.ts +41 -17
  505. package/src/primitives/PublicKey.ts +13 -3
  506. package/src/primitives/Random.ts +14 -8
  507. package/src/primitives/ReductionContext.ts +1 -1
  508. package/src/primitives/Schnorr.ts +40 -18
  509. package/src/primitives/Signature.ts +26 -16
  510. package/src/primitives/SymmetricKey.ts +14 -14
  511. package/src/primitives/TransactionSignature.ts +41 -17
  512. package/src/primitives/__tests/AESGCM.test.ts +457 -151
  513. package/src/primitives/__tests/BRC42.private.vectors.ts +30 -15
  514. package/src/primitives/__tests/BRC42.public.vectors.ts +30 -15
  515. package/src/primitives/__tests/BigNumber.arithmatic.test.ts +344 -125
  516. package/src/primitives/__tests/BigNumber.binary.test.ts +148 -67
  517. package/src/primitives/__tests/BigNumber.constructor.test.ts +65 -25
  518. package/src/primitives/__tests/BigNumber.dhGroup.test.ts +15 -11
  519. package/src/primitives/__tests/BigNumber.fixtures.ts +16 -8
  520. package/src/primitives/__tests/BigNumber.serializers.test.ts +41 -15
  521. package/src/primitives/__tests/BigNumber.utils.test.ts +132 -42
  522. package/src/primitives/__tests/Curve.unit.test.ts +75 -53
  523. package/src/primitives/__tests/DRBG.test.ts +1 -1
  524. package/src/primitives/__tests/DRBG.vectors.ts +45 -75
  525. package/src/primitives/__tests/ECDH.test.ts +15 -8
  526. package/src/primitives/__tests/ECDSA.test.ts +12 -6
  527. package/src/primitives/__tests/HMAC.test.ts +24 -18
  528. package/src/primitives/__tests/Hash.test.ts +57 -46
  529. package/src/primitives/__tests/PBKDF2.vectors.ts +130 -117
  530. package/src/primitives/__tests/PrivateKey.split.test.ts +33 -11
  531. package/src/primitives/__tests/PrivateKey.test.ts +11 -10
  532. package/src/primitives/__tests/PublicKey.test.ts +64 -53
  533. package/src/primitives/__tests/Random.test.ts +1 -1
  534. package/src/primitives/__tests/Reader.test.ts +240 -219
  535. package/src/primitives/__tests/ReductionContext.test.ts +98 -61
  536. package/src/primitives/__tests/Schnorr.test.ts +249 -237
  537. package/src/primitives/__tests/SymmetricKey.test.ts +18 -15
  538. package/src/primitives/__tests/SymmetricKey.vectors.ts +16 -8
  539. package/src/primitives/__tests/Writer.test.ts +23 -13
  540. package/src/primitives/__tests/bug-31.test.ts +6 -10
  541. package/src/primitives/__tests/utils.test.ts +70 -19
  542. package/src/primitives/utils.ts +103 -79
  543. package/src/script/Script.ts +18 -12
  544. package/src/script/ScriptTemplate.ts +3 -5
  545. package/src/script/Spend.ts +306 -108
  546. package/src/script/__tests/Script.test.ts +73 -55
  547. package/src/script/__tests/Spend.test.ts +208 -83
  548. package/src/script/__tests/SpendComplex.test.ts +19 -13
  549. package/src/script/__tests/script.invalid.vectors.ts +428 -1796
  550. package/src/script/__tests/script.valid.vectors.ts +728 -2764
  551. package/src/script/templates/P2PKH.ts +34 -12
  552. package/src/script/templates/PushDrop.ts +65 -31
  553. package/src/script/templates/RPuzzle.ts +29 -8
  554. package/src/script/templates/__tests/PushDrop.test.ts +146 -41
  555. package/src/totp/__tests/totp.test.ts +45 -44
  556. package/src/totp/totp.ts +3 -2
  557. package/src/transaction/Beef.ts +269 -174
  558. package/src/transaction/BeefParty.ts +41 -31
  559. package/src/transaction/BeefTx.ts +36 -26
  560. package/src/transaction/Broadcaster.ts +10 -6
  561. package/src/transaction/ChainTracker.ts +2 -2
  562. package/src/transaction/FeeModel.ts +0 -1
  563. package/src/transaction/MerklePath.ts +124 -59
  564. package/src/transaction/Transaction.ts +188 -187
  565. package/src/transaction/TransactionOutput.ts +0 -1
  566. package/src/transaction/__tests/Beef.test.ts +390 -287
  567. package/src/transaction/__tests/MerklePath.test.ts +59 -26
  568. package/src/transaction/__tests/Transaction.benchmarks.test.ts +231 -201
  569. package/src/transaction/__tests/Transaction.test.ts +758 -482
  570. package/src/transaction/__tests/bigtx.vectors.ts +2 -1
  571. package/src/transaction/__tests/bump.invalid.vectors.ts +24 -6
  572. package/src/transaction/__tests/bump.valid.vectors.ts +6 -2
  573. package/src/transaction/__tests/tx.invalid.vectors.ts +881 -185
  574. package/src/transaction/__tests/tx.valid.vectors.ts +1210 -257
  575. package/src/transaction/broadcasters/ARC.ts +69 -38
  576. package/src/transaction/broadcasters/DefaultBroadcaster.ts +9 -3
  577. package/src/transaction/broadcasters/WhatsOnChainBroadcaster.ts +20 -7
  578. package/src/transaction/broadcasters/__tests/ARC.test.ts +127 -59
  579. package/src/transaction/broadcasters/__tests/WhatsOnChainBroadcaster.test.ts +27 -18
  580. package/src/transaction/chaintrackers/DefaultChainTracker.ts +1 -1
  581. package/src/transaction/chaintrackers/WhatsOnChain.ts +27 -11
  582. package/src/transaction/chaintrackers/__tests/WhatsOnChainChainTracker.test.ts +59 -23
  583. package/src/transaction/fee-models/SatoshisPerKilobyte.ts +9 -5
  584. package/src/transaction/http/DefaultHttpClient.ts +5 -4
  585. package/src/transaction/http/FetchHttpClient.ts +18 -9
  586. package/src/transaction/http/HttpClient.ts +27 -22
  587. package/src/transaction/http/NodejsHttpClient.ts +23 -9
  588. package/src/transaction/http/index.ts +5 -1
  589. package/src/transaction/index.ts +5 -1
  590. package/src/wallet/CachedKeyDeriver.ts +151 -82
  591. package/src/wallet/KeyDeriver.ts +186 -105
  592. package/src/wallet/ProtoWallet.ts +121 -52
  593. package/src/wallet/Wallet.interfaces.ts +167 -156
  594. package/src/wallet/WalletClient.ts +314 -59
  595. package/src/wallet/WalletError.ts +2 -2
  596. package/src/wallet/__tests/CachedKeyDeriver.test.ts +86 -27
  597. package/src/wallet/__tests/KeyDeriver.test.ts +136 -33
  598. package/src/wallet/__tests/ProtoWallet.test.ts +190 -102
  599. package/src/wallet/substrates/HTTPWalletJSON.ts +250 -67
  600. package/src/wallet/substrates/HTTPWalletWire.ts +7 -3
  601. package/src/wallet/substrates/WalletWireCalls.ts +2 -2
  602. package/src/wallet/substrates/WalletWireProcessor.ts +1412 -1277
  603. package/src/wallet/substrates/WalletWireTransceiver.ts +713 -138
  604. package/src/wallet/substrates/XDM.ts +425 -36
  605. package/src/wallet/substrates/__tests/WalletWire.integration.test.ts +488 -225
  606. package/src/wallet/substrates/__tests/XDM.test.ts +232 -234
  607. package/src/wallet/substrates/window.CWI.ts +520 -61
@@ -1,43 +1,37 @@
1
- import BigNumber from '../../../dist/cjs/src/primitives/BigNumber'
2
- import TransactionSignature from '../../../dist/cjs/src/primitives/TransactionSignature'
3
- import { toHex, toArray, Writer } from '../../../dist/cjs/src/primitives/utils'
4
- import Script from '../../../dist/cjs/src/script/Script'
5
- import UnlockingScript from '../../../dist/cjs/src/script/UnlockingScript'
6
- import LockingScript from '../../../dist/cjs/src/script/LockingScript'
7
- import Transaction from '../../../dist/cjs/src/transaction/Transaction'
8
- import { hash256, hash160 } from '../../../dist/cjs/src/primitives/Hash'
9
- import PrivateKey from '../../../dist/cjs/src/primitives/PrivateKey'
10
- import Curve from '../../../dist/cjs/src/primitives/Curve'
11
- import P2PKH from '../../../dist/cjs/src/script/templates/P2PKH'
12
- import fromUtxo from '../../../dist/cjs/src/compat/Utxo'
13
- import MerklePath from '../../../dist/cjs/src/transaction/MerklePath'
14
- import { BEEF_V1 } from '../../../dist/cjs/src/transaction/Beef'
1
+
2
+ import BigNumber from '../../primitives/BigNumber'
3
+ import TransactionSignature from '../../primitives/TransactionSignature'
4
+ import { toHex, toArray, Writer } from '../../primitives/utils'
5
+ import Script from '../../script/Script'
6
+ import UnlockingScript from '../../script/UnlockingScript'
7
+ import LockingScript from '../../script/LockingScript'
8
+ import Transaction from '../../transaction/Transaction'
9
+ import { hash256, hash160 } from '../../primitives/Hash'
10
+ import PrivateKey from '../../primitives/PrivateKey'
11
+ import Curve from '../../primitives/Curve'
12
+ import P2PKH from '../../script/templates/P2PKH'
13
+ import fromUtxo from '../../compat/Utxo'
14
+ import MerklePath from '../../transaction/MerklePath'
15
+ import { BEEF_V1 } from '../../transaction/Beef'
15
16
 
16
17
  import sighashVectors from '../../primitives/__tests/sighash.vectors'
17
18
  import invalidTransactions from './tx.invalid.vectors'
18
19
  import validTransactions from './tx.valid.vectors'
19
20
  import bigTX from './bigtx.vectors'
21
+ import { BroadcastResponse } from '../../transaction/Broadcaster'
20
22
 
21
- const BRC62Hex = '0100beef01fe636d0c0007021400fe507c0c7aa754cef1f7889d5fd395cf1f785dd7de98eed895dbedfe4e5bc70d1502ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e010b00bc4ff395efd11719b277694cface5aa50d085a0bb81f613f70313acd28cf4557010400574b2d9142b8d28b61d88e3b2c3f44d858411356b49a28a4643b6d1a6a092a5201030051a05fc84d531b5d250c23f4f886f6812f9fe3f402d61607f977b4ecd2701c19010000fd781529d58fc2523cf396a7f25440b409857e7e221766c57214b1d38c7b481f01010062f542f45ea3660f86c013ced80534cb5fd4c19d66c56e7e8c5d4bf2d40acc5e010100b121e91836fd7cd5102b654e9f72f3cf6fdbfd0b161c53a9c54b12c841126331020100000001cd4e4cac3c7b56920d1e7655e7e260d31f29d9a388d04910f1bbd72304a79029010000006b483045022100e75279a205a547c445719420aa3138bf14743e3f42618e5f86a19bde14bb95f7022064777d34776b05d816daf1699493fcdf2ef5a5ab1ad710d9c97bfb5b8f7cef3641210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000001000100000001ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000000'
22
- const MerkleRootFromBEEF = 'bb6f640cc4ee56bf38eb5a1969ac0c16caa2d3d202b22bf3735d10eec0ca6e00'
23
+ const BRC62Hex =
24
+ '0100beef01fe636d0c0007021400fe507c0c7aa754cef1f7889d5fd395cf1f785dd7de98eed895dbedfe4e5bc70d1502ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e010b00bc4ff395efd11719b277694cface5aa50d085a0bb81f613f70313acd28cf4557010400574b2d9142b8d28b61d88e3b2c3f44d858411356b49a28a4643b6d1a6a092a5201030051a05fc84d531b5d250c23f4f886f6812f9fe3f402d61607f977b4ecd2701c19010000fd781529d58fc2523cf396a7f25440b409857e7e221766c57214b1d38c7b481f01010062f542f45ea3660f86c013ced80534cb5fd4c19d66c56e7e8c5d4bf2d40acc5e010100b121e91836fd7cd5102b654e9f72f3cf6fdbfd0b161c53a9c54b12c841126331020100000001cd4e4cac3c7b56920d1e7655e7e260d31f29d9a388d04910f1bbd72304a79029010000006b483045022100e75279a205a547c445719420aa3138bf14743e3f42618e5f86a19bde14bb95f7022064777d34776b05d816daf1699493fcdf2ef5a5ab1ad710d9c97bfb5b8f7cef3641210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000001000100000001ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac0000000000'
25
+ const MerkleRootFromBEEF =
26
+ 'bb6f640cc4ee56bf38eb5a1969ac0c16caa2d3d202b22bf3735d10eec0ca6e00'
23
27
 
24
28
  describe('Transaction', () => {
25
- const txIn = {
26
- sourceTXID: '0000000000000000000000000000000000000000000000000000000000000000',
27
- sourceOutputIndex: 0,
28
- unlockingScript: UnlockingScript.fromHex('ae'),
29
- sequence: 0
30
- }
31
- const txOut = {
32
- satoshis: BigNumber.fromHex('0500000000000000', 'be'),
33
- lockingScript: LockingScript.fromHex('ae')
34
- }
35
- const tx = new Transaction(0, [txIn], [txOut], 0)
36
29
  const txhex =
37
30
  '000000000100000000000000000000000000000000000000000000000000000000000000000000000001ae0000000001050000000000000001ae00000000'
38
31
  const txbuf = toArray(txhex, 'hex')
39
32
 
40
- const tx2idhex = '8c9aa966d35bfeaf031409e0001b90ccdafd8d859799eb945a3c515b8260bcf2'
33
+ const tx2idhex =
34
+ '8c9aa966d35bfeaf031409e0001b90ccdafd8d859799eb945a3c515b8260bcf2'
41
35
  const tx2hex =
42
36
  '01000000029e8d016a7b0dc49a325922d05da1f916d1e4d4f0cb840c9727f3d22ce8d1363f000000008c493046022100e9318720bee5425378b4763b0427158b1051eec8b08442ce3fbfbf7b30202a44022100d4172239ebd701dae2fbaaccd9f038e7ca166707333427e3fb2a2865b19a7f27014104510c67f46d2cbb29476d1f0b794be4cb549ea59ab9cc1e731969a7bf5be95f7ad5e7f904e5ccf50a9dc1714df00fbeb794aa27aaff33260c1032d931a75c56f2ffffffffa3195e7a1ab665473ff717814f6881485dc8759bebe97e31c301ffe7933a656f020000008b48304502201c282f35f3e02a1f32d2089265ad4b561f07ea3c288169dedcf2f785e6065efa022100e8db18aadacb382eed13ee04708f00ba0a9c40e3b21cf91da8859d0f7d99e0c50141042b409e1ebbb43875be5edde9c452c82c01e3903d38fa4fd89f3887a52cb8aea9dc8aec7e2c9d5b3609c03eb16259a2537135a1bf0f9c5fbbcbdbaf83ba402442ffffffff02206b1000000000001976a91420bb5c3bfaef0231dc05190e7f1c8e22e098991e88acf0ca0100000000001976a9149e3e2d23973a04ec1b02be97c30ab9f2f27c3b2c88ac00000000'
43
37
  const tx2buf = toArray(tx2hex, 'hex')
@@ -90,7 +84,7 @@ describe('Transaction', () => {
90
84
  describe('#parseScriptOffsets', () => {
91
85
  it('should match sliced scripts to parsed scripts', async () => {
92
86
  const tx = Transaction.fromBinary(tx2buf)
93
- expect(tx.id("hex")).toBe(tx2idhex)
87
+ expect(tx.id('hex')).toBe(tx2idhex)
94
88
  const r = Transaction.parseScriptOffsets(tx2buf)
95
89
  expect(r.inputs.length).toBe(2)
96
90
  expect(r.outputs.length).toBe(2)
@@ -122,7 +116,11 @@ describe('Transaction', () => {
122
116
  describe('#hash', () => {
123
117
  it('should correctly calculate the hash of this known transaction', () => {
124
118
  const tx = Transaction.fromBinary(tx2buf)
125
- expect(toHex(tx.hash().reverse())).toEqual(tx2idhex)
119
+ const hash = tx.hash()
120
+ const reversedHash = Array.isArray(hash)
121
+ ? hash.reverse()
122
+ : toArray(hash, 'hex').reverse()
123
+ expect(toHex(reversedHash)).toEqual(tx2idhex)
126
124
  })
127
125
  })
128
126
 
@@ -136,7 +134,8 @@ describe('Transaction', () => {
136
134
  describe('#addInput', () => {
137
135
  it('should add an input', () => {
138
136
  const txIn = {
139
- sourceTXID: '0000000000000000000000000000000000000000000000000000000000000000',
137
+ sourceTXID:
138
+ '0000000000000000000000000000000000000000000000000000000000000000',
140
139
  sourceOutputIndex: 0,
141
140
  unlockingScript: new UnlockingScript(),
142
141
  sequence: 0xffffffff
@@ -165,35 +164,52 @@ describe('Transaction', () => {
165
164
  it('Signs unlocking script templates, hydrating the scripts', async () => {
166
165
  const privateKey = new PrivateKey(1)
167
166
  const publicKey = new Curve().g.mul(privateKey)
168
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
167
+ const publicKeyHash = hash160(publicKey.encode(true))
169
168
  const p2pkh = new P2PKH()
170
- const sourceTx = new Transaction(1, [], [{
171
- lockingScript: p2pkh.lock(publicKeyHash),
172
- satoshis: 4000
173
- }], 0)
174
- const spendTx = new Transaction(1, [{
175
- sourceTransaction: sourceTx,
176
- sourceOutputIndex: 0,
177
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
178
- sequence: 0xffffffff
179
- }], [{
180
- satoshis: 1000,
181
- lockingScript: p2pkh.lock(publicKeyHash)
182
- }, {
183
- lockingScript: p2pkh.lock(publicKeyHash),
184
- change: true
185
- }], 0)
169
+ const sourceTx = new Transaction(
170
+ 1,
171
+ [],
172
+ [
173
+ {
174
+ lockingScript: p2pkh.lock(publicKeyHash),
175
+ satoshis: 4000
176
+ }
177
+ ],
178
+ 0
179
+ )
180
+ const spendTx = new Transaction(
181
+ 1,
182
+ [
183
+ {
184
+ sourceTransaction: sourceTx,
185
+ sourceOutputIndex: 0,
186
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
187
+ sequence: 0xffffffff
188
+ }
189
+ ],
190
+ [
191
+ {
192
+ satoshis: 1000,
193
+ lockingScript: p2pkh.lock(publicKeyHash)
194
+ },
195
+ {
196
+ lockingScript: p2pkh.lock(publicKeyHash),
197
+ change: true
198
+ }
199
+ ],
200
+ 0
201
+ )
186
202
  expect(spendTx.inputs[0].unlockingScript).not.toBeDefined()
187
203
  await spendTx.fee()
188
204
  await spendTx.sign()
189
205
  expect(spendTx.inputs[0].unlockingScript).toBeDefined()
190
206
  // P2PKH unlocking scripts have two chunks (the signature and public key)
191
- expect(spendTx.inputs[0].unlockingScript.chunks.length).toBe(2)
207
+ expect(spendTx.inputs[0].unlockingScript?.chunks.length).toBe(2)
192
208
  })
193
209
  it('Signs a large number of unlocking script templates in a timely manner', async () => {
194
210
  const privateKey = new PrivateKey(134)
195
211
  const publicKey = new Curve().g.mul(privateKey)
196
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
212
+ const publicKeyHash = hash160(publicKey.encode(true))
197
213
  const p2pkh = new P2PKH()
198
214
  const spendCount = 30
199
215
  const output = {
@@ -223,41 +239,69 @@ describe('Transaction', () => {
223
239
  sequence: 0xffffffff
224
240
  }
225
241
  }
226
- const spendTx = new Transaction(1, manyInputs, [{
227
- satoshis: 1000,
228
- lockingScript: p2pkh.lock(publicKeyHash)
229
- }, {
230
- lockingScript: p2pkh.lock(publicKeyHash),
231
- change: true
232
- }], 0)
242
+ const spendTx = new Transaction(
243
+ 1,
244
+ manyInputs,
245
+ [
246
+ {
247
+ satoshis: 1000,
248
+ lockingScript: p2pkh.lock(publicKeyHash)
249
+ },
250
+ {
251
+ lockingScript: p2pkh.lock(publicKeyHash),
252
+ change: true
253
+ }
254
+ ],
255
+ 0
256
+ )
233
257
  expect(spendTx.inputs[0].unlockingScript).not.toBeDefined()
234
258
  await spendTx.fee()
235
259
  await spendTx.sign()
236
260
  expect(spendTx.inputs[0].unlockingScript).toBeDefined()
237
261
  // P2PKH unlocking scripts have two chunks (the signature and public key)
238
- expect(spendTx.inputs[0].unlockingScript.chunks.length).toBe(2)
262
+ expect(spendTx.inputs[0].unlockingScript?.chunks.length).toBe(2)
239
263
  })
240
264
  it('Throws an Error if signing before the fee is computed', async () => {
241
265
  const privateKey = new PrivateKey(1)
242
266
  const publicKey = new Curve().g.mul(privateKey)
243
- const publicKeyHash = hash160(publicKey.encode(true), 'hex') as unknown as number[]
267
+ const publicKeyHash = hash160(
268
+ publicKey.encode(true),
269
+ 'hex'
270
+ ) as unknown as number[]
244
271
  const p2pkh = new P2PKH()
245
- const sourceTx = new Transaction(1, [], [{
246
- lockingScript: p2pkh.lock(publicKeyHash),
247
- satoshis: 4000
248
- }], 0)
249
- const spendTx = new Transaction(1, [{
250
- sourceTransaction: sourceTx,
251
- sourceOutputIndex: 0,
252
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
253
- sequence: 0xffffffff
254
- }], [{
255
- satoshis: 1000,
256
- lockingScript: p2pkh.lock(publicKeyHash)
257
- }, {
258
- lockingScript: p2pkh.lock(publicKeyHash),
259
- change: true
260
- }], 0)
272
+ const sourceTx = new Transaction(
273
+ 1,
274
+ [],
275
+ [
276
+ {
277
+ lockingScript: p2pkh.lock(publicKeyHash),
278
+ satoshis: 4000
279
+ }
280
+ ],
281
+ 0
282
+ )
283
+ const spendTx = new Transaction(
284
+ 1,
285
+ [
286
+ {
287
+ sourceTransaction: sourceTx,
288
+ sourceOutputIndex: 0,
289
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
290
+ sequence: 0xffffffff
291
+ }
292
+ ],
293
+ [
294
+ {
295
+ satoshis: 1000,
296
+ lockingScript: p2pkh.lock(publicKeyHash)
297
+ },
298
+ {
299
+ lockingScript: p2pkh.lock(publicKeyHash),
300
+ change: true
301
+ }
302
+ ],
303
+ 0
304
+ )
261
305
  await expect(spendTx.sign()).rejects.toThrow()
262
306
  })
263
307
  })
@@ -266,24 +310,41 @@ describe('Transaction', () => {
266
310
  it('Computes fees with the default fee model', async () => {
267
311
  const privateKey = new PrivateKey(1)
268
312
  const publicKey = new Curve().g.mul(privateKey)
269
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
313
+ const publicKeyHash = hash160(publicKey.encode(true))
270
314
  const p2pkh = new P2PKH()
271
- const sourceTx = new Transaction(1, [], [{
272
- lockingScript: p2pkh.lock(publicKeyHash),
273
- satoshis: 4000
274
- }], 0)
275
- const spendTx = new Transaction(1, [{
276
- sourceTransaction: sourceTx,
277
- sourceOutputIndex: 0,
278
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
279
- sequence: 0xffffffff
280
- }], [{
281
- satoshis: 1000,
282
- lockingScript: p2pkh.lock(publicKeyHash)
283
- }, {
284
- lockingScript: p2pkh.lock(publicKeyHash),
285
- change: true
286
- }], 0)
315
+ const sourceTx = new Transaction(
316
+ 1,
317
+ [],
318
+ [
319
+ {
320
+ lockingScript: p2pkh.lock(publicKeyHash),
321
+ satoshis: 4000
322
+ }
323
+ ],
324
+ 0
325
+ )
326
+ const spendTx = new Transaction(
327
+ 1,
328
+ [
329
+ {
330
+ sourceTransaction: sourceTx,
331
+ sourceOutputIndex: 0,
332
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
333
+ sequence: 0xffffffff
334
+ }
335
+ ],
336
+ [
337
+ {
338
+ satoshis: 1000,
339
+ lockingScript: p2pkh.lock(publicKeyHash)
340
+ },
341
+ {
342
+ lockingScript: p2pkh.lock(publicKeyHash),
343
+ change: true
344
+ }
345
+ ],
346
+ 0
347
+ )
287
348
  expect(spendTx.outputs[1].satoshis).not.toBeDefined()
288
349
  await spendTx.fee()
289
350
  // Transaction size is 225 bytes for one-input two-output P2PKH.
@@ -294,24 +355,41 @@ describe('Transaction', () => {
294
355
  it('Computes fees with a custom fee model', async () => {
295
356
  const privateKey = new PrivateKey(1)
296
357
  const publicKey = new Curve().g.mul(privateKey)
297
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
358
+ const publicKeyHash = hash160(publicKey.encode(true))
298
359
  const p2pkh = new P2PKH()
299
- const sourceTx = new Transaction(1, [], [{
300
- lockingScript: p2pkh.lock(publicKeyHash),
301
- satoshis: 4000
302
- }], 0)
303
- const spendTx = new Transaction(1, [{
304
- sourceTransaction: sourceTx,
305
- sourceOutputIndex: 0,
306
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
307
- sequence: 0xffffffff
308
- }], [{
309
- satoshis: 1000,
310
- lockingScript: p2pkh.lock(publicKeyHash)
311
- }, {
312
- lockingScript: p2pkh.lock(publicKeyHash),
313
- change: true
314
- }], 0)
360
+ const sourceTx = new Transaction(
361
+ 1,
362
+ [],
363
+ [
364
+ {
365
+ lockingScript: p2pkh.lock(publicKeyHash),
366
+ satoshis: 4000
367
+ }
368
+ ],
369
+ 0
370
+ )
371
+ const spendTx = new Transaction(
372
+ 1,
373
+ [
374
+ {
375
+ sourceTransaction: sourceTx,
376
+ sourceOutputIndex: 0,
377
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
378
+ sequence: 0xffffffff
379
+ }
380
+ ],
381
+ [
382
+ {
383
+ satoshis: 1000,
384
+ lockingScript: p2pkh.lock(publicKeyHash)
385
+ },
386
+ {
387
+ lockingScript: p2pkh.lock(publicKeyHash),
388
+ change: true
389
+ }
390
+ ],
391
+ 0
392
+ )
315
393
  expect(spendTx.outputs[1].satoshis).not.toBeDefined()
316
394
  await spendTx.fee({
317
395
  // Our custom fee model will always charge 1033 sats for a tx.
@@ -323,24 +401,41 @@ describe('Transaction', () => {
323
401
  it('Computes fee using FixedFee model', async () => {
324
402
  const privateKey = new PrivateKey(1)
325
403
  const publicKey = new Curve().g.mul(privateKey)
326
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
404
+ const publicKeyHash = hash160(publicKey.encode(true))
327
405
  const p2pkh = new P2PKH()
328
- const sourceTx = new Transaction(1, [], [{
329
- lockingScript: p2pkh.lock(publicKeyHash),
330
- satoshis: 4000
331
- }], 0)
332
- const spendTx = new Transaction(1, [{
333
- sourceTransaction: sourceTx,
334
- sourceOutputIndex: 0,
335
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
336
- sequence: 0xffffffff
337
- }], [{
338
- satoshis: 1000,
339
- lockingScript: p2pkh.lock(publicKeyHash)
340
- }, {
341
- lockingScript: p2pkh.lock(publicKeyHash),
342
- change: true
343
- }], 0)
406
+ const sourceTx = new Transaction(
407
+ 1,
408
+ [],
409
+ [
410
+ {
411
+ lockingScript: p2pkh.lock(publicKeyHash),
412
+ satoshis: 4000
413
+ }
414
+ ],
415
+ 0
416
+ )
417
+ const spendTx = new Transaction(
418
+ 1,
419
+ [
420
+ {
421
+ sourceTransaction: sourceTx,
422
+ sourceOutputIndex: 0,
423
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
424
+ sequence: 0xffffffff
425
+ }
426
+ ],
427
+ [
428
+ {
429
+ satoshis: 1000,
430
+ lockingScript: p2pkh.lock(publicKeyHash)
431
+ },
432
+ {
433
+ lockingScript: p2pkh.lock(publicKeyHash),
434
+ change: true
435
+ }
436
+ ],
437
+ 0
438
+ )
344
439
  expect(spendTx.outputs[1].satoshis).not.toBeDefined()
345
440
  await spendTx.fee(1033)
346
441
  // 4000 sats in - 1000 sats out - 1033 sats fee = expected 1967 sats change
@@ -349,33 +444,53 @@ describe('Transaction', () => {
349
444
  it('Distributes change equally among multiple change outputs', async () => {
350
445
  const privateKey = new PrivateKey(1)
351
446
  const publicKey = new Curve().g.mul(privateKey)
352
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
447
+ const publicKeyHash = hash160(publicKey.encode(true))
353
448
  const p2pkh = new P2PKH()
354
- const sourceTx = new Transaction(1, [], [{
355
- lockingScript: p2pkh.lock(publicKeyHash),
356
- satoshis: 4000
357
- }], 0)
358
- const spendTx = new Transaction(1, [{
359
- sourceTransaction: sourceTx,
360
- sourceOutputIndex: 0,
361
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
362
- sequence: 0xffffffff
363
- }], [{
364
- satoshis: 1000,
365
- lockingScript: p2pkh.lock(publicKeyHash)
366
- }, {
367
- lockingScript: p2pkh.lock(publicKeyHash),
368
- change: true
369
- }, {
370
- lockingScript: p2pkh.lock(publicKeyHash),
371
- change: true
372
- }, {
373
- lockingScript: p2pkh.lock(publicKeyHash),
374
- change: true
375
- }, {
376
- lockingScript: p2pkh.lock(publicKeyHash),
377
- change: true
378
- }], 0)
449
+ const sourceTx = new Transaction(
450
+ 1,
451
+ [],
452
+ [
453
+ {
454
+ lockingScript: p2pkh.lock(publicKeyHash),
455
+ satoshis: 4000
456
+ }
457
+ ],
458
+ 0
459
+ )
460
+ const spendTx = new Transaction(
461
+ 1,
462
+ [
463
+ {
464
+ sourceTransaction: sourceTx,
465
+ sourceOutputIndex: 0,
466
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
467
+ sequence: 0xffffffff
468
+ }
469
+ ],
470
+ [
471
+ {
472
+ satoshis: 1000,
473
+ lockingScript: p2pkh.lock(publicKeyHash)
474
+ },
475
+ {
476
+ lockingScript: p2pkh.lock(publicKeyHash),
477
+ change: true
478
+ },
479
+ {
480
+ lockingScript: p2pkh.lock(publicKeyHash),
481
+ change: true
482
+ },
483
+ {
484
+ lockingScript: p2pkh.lock(publicKeyHash),
485
+ change: true
486
+ },
487
+ {
488
+ lockingScript: p2pkh.lock(publicKeyHash),
489
+ change: true
490
+ }
491
+ ],
492
+ 0
493
+ )
379
494
  expect(spendTx.outputs[1].satoshis).not.toBeDefined()
380
495
  expect(spendTx.outputs[2].satoshis).not.toBeDefined()
381
496
  expect(spendTx.outputs[3].satoshis).not.toBeDefined()
@@ -395,133 +510,205 @@ describe('Transaction', () => {
395
510
  it('Distributes change randomly among multiple change outputs', async () => {
396
511
  const privateKey = new PrivateKey(1)
397
512
  const publicKey = new Curve().g.mul(privateKey)
398
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
513
+ const publicKeyHash = hash160(publicKey.encode(true))
399
514
  const p2pkh = new P2PKH()
400
- const sourceTx = new Transaction(1, [], [{
401
- lockingScript: p2pkh.lock(publicKeyHash),
402
- satoshis: 900
403
- }], 0)
404
- const spendTx = new Transaction(1, [{
405
- sourceTransaction: sourceTx,
406
- sourceOutputIndex: 0,
407
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
408
- sequence: 0xffffffff
409
- }], [{
410
- satoshis: 1,
411
- lockingScript: p2pkh.lock(publicKeyHash)
412
- }, {
413
- lockingScript: p2pkh.lock(publicKeyHash),
414
- change: true
415
- }, {
416
- lockingScript: p2pkh.lock(publicKeyHash),
417
- change: true
418
- }, {
419
- lockingScript: p2pkh.lock(publicKeyHash),
420
- change: true
421
- }, {
422
- lockingScript: p2pkh.lock(publicKeyHash),
423
- change: true
424
- }, {
425
- lockingScript: p2pkh.lock(publicKeyHash),
426
- change: true
427
- }, {
428
- lockingScript: p2pkh.lock(publicKeyHash),
429
- change: true
430
- }], 0)
515
+ const sourceTx = new Transaction(
516
+ 1,
517
+ [],
518
+ [
519
+ {
520
+ lockingScript: p2pkh.lock(publicKeyHash),
521
+ satoshis: 900
522
+ }
523
+ ],
524
+ 0
525
+ )
526
+ const spendTx = new Transaction(
527
+ 1,
528
+ [
529
+ {
530
+ sourceTransaction: sourceTx,
531
+ sourceOutputIndex: 0,
532
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
533
+ sequence: 0xffffffff
534
+ }
535
+ ],
536
+ [
537
+ {
538
+ satoshis: 1,
539
+ lockingScript: p2pkh.lock(publicKeyHash)
540
+ },
541
+ {
542
+ lockingScript: p2pkh.lock(publicKeyHash),
543
+ change: true
544
+ },
545
+ {
546
+ lockingScript: p2pkh.lock(publicKeyHash),
547
+ change: true
548
+ },
549
+ {
550
+ lockingScript: p2pkh.lock(publicKeyHash),
551
+ change: true
552
+ },
553
+ {
554
+ lockingScript: p2pkh.lock(publicKeyHash),
555
+ change: true
556
+ },
557
+ {
558
+ lockingScript: p2pkh.lock(publicKeyHash),
559
+ change: true
560
+ },
561
+ {
562
+ lockingScript: p2pkh.lock(publicKeyHash),
563
+ change: true
564
+ }
565
+ ],
566
+ 0
567
+ )
431
568
  expect(spendTx.outputs[1].satoshis).not.toBeDefined()
432
569
  expect(spendTx.outputs[2].satoshis).not.toBeDefined()
433
570
  expect(spendTx.outputs[3].satoshis).not.toBeDefined()
434
571
  expect(spendTx.outputs[4].satoshis).not.toBeDefined()
435
572
  expect(spendTx.outputs[5].satoshis).not.toBeDefined()
436
573
  expect(spendTx.outputs[6].satoshis).not.toBeDefined()
437
- await spendTx.fee({
438
- computeFee: async () => 3
439
- }, 'random')
574
+ await spendTx.fee(
575
+ {
576
+ computeFee: async () => 3
577
+ },
578
+ 'random'
579
+ )
440
580
  expect(spendTx.outputs[0].satoshis).toEqual(1)
441
- expect(spendTx.outputs.reduce((a, b) => a + b.satoshis, 0)).toEqual(897)
581
+ expect(spendTx.outputs.reduce((a, b) => a + (b.satoshis ?? 0), 0)).toEqual(897)
442
582
  })
443
583
  it('Distributes change randomly among multiple change outputs, with one set output', async () => {
444
584
  const privateKey = new PrivateKey(1)
445
585
  const publicKey = new Curve().g.mul(privateKey)
446
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
586
+ const publicKeyHash = hash160(publicKey.encode(true))
447
587
  const p2pkh = new P2PKH()
448
- const sourceTx = new Transaction(1, [], [{
449
- lockingScript: p2pkh.lock(publicKeyHash),
450
- satoshis: 9
451
- }], 0)
452
- const spendTx = new Transaction(1, [{
453
- sourceTransaction: sourceTx,
454
- sourceOutputIndex: 0,
455
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
456
- sequence: 0xffffffff
457
- }], [{
458
- satoshis: 1,
459
- lockingScript: p2pkh.lock(publicKeyHash)
460
- }, {
461
- lockingScript: p2pkh.lock(publicKeyHash),
462
- change: true
463
- }, {
464
- lockingScript: p2pkh.lock(publicKeyHash),
465
- change: true
466
- }, {
467
- lockingScript: p2pkh.lock(publicKeyHash),
468
- change: true
469
- }, {
470
- lockingScript: p2pkh.lock(publicKeyHash),
471
- change: true
472
- }, {
473
- lockingScript: p2pkh.lock(publicKeyHash),
474
- change: true
475
- }, {
476
- lockingScript: p2pkh.lock(publicKeyHash),
477
- change: true
478
- }], 0)
588
+ const sourceTx = new Transaction(
589
+ 1,
590
+ [],
591
+ [
592
+ {
593
+ lockingScript: p2pkh.lock(publicKeyHash),
594
+ satoshis: 9
595
+ }
596
+ ],
597
+ 0
598
+ )
599
+ const spendTx = new Transaction(
600
+ 1,
601
+ [
602
+ {
603
+ sourceTransaction: sourceTx,
604
+ sourceOutputIndex: 0,
605
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
606
+ sequence: 0xffffffff
607
+ }
608
+ ],
609
+ [
610
+ {
611
+ satoshis: 1,
612
+ lockingScript: p2pkh.lock(publicKeyHash)
613
+ },
614
+ {
615
+ lockingScript: p2pkh.lock(publicKeyHash),
616
+ change: true
617
+ },
618
+ {
619
+ lockingScript: p2pkh.lock(publicKeyHash),
620
+ change: true
621
+ },
622
+ {
623
+ lockingScript: p2pkh.lock(publicKeyHash),
624
+ change: true
625
+ },
626
+ {
627
+ lockingScript: p2pkh.lock(publicKeyHash),
628
+ change: true
629
+ },
630
+ {
631
+ lockingScript: p2pkh.lock(publicKeyHash),
632
+ change: true
633
+ },
634
+ {
635
+ lockingScript: p2pkh.lock(publicKeyHash),
636
+ change: true
637
+ }
638
+ ],
639
+ 0
640
+ )
479
641
  expect(spendTx.outputs[1].satoshis).not.toBeDefined()
480
642
  expect(spendTx.outputs[2].satoshis).not.toBeDefined()
481
643
  expect(spendTx.outputs[3].satoshis).not.toBeDefined()
482
644
  expect(spendTx.outputs[4].satoshis).not.toBeDefined()
483
645
  expect(spendTx.outputs[5].satoshis).not.toBeDefined()
484
646
  expect(spendTx.outputs[6].satoshis).not.toBeDefined()
485
- await spendTx.fee({
486
- computeFee: async () => 1
487
- }, 'random')
488
- expect(spendTx.outputs.reduce((a, b) => a + b.satoshis, 0)).toEqual(8)
647
+ await spendTx.fee(
648
+ {
649
+ computeFee: async () => 1
650
+ },
651
+ 'random'
652
+ )
653
+ expect(spendTx.outputs.reduce((a, b) => a + (b.satoshis ?? 0), 0)).toEqual(8)
489
654
  })
490
655
  it('Distributes change randomly among multiple change outputs, thinnly spread', async () => {
491
656
  const privateKey = new PrivateKey(1)
492
657
  const publicKey = new Curve().g.mul(privateKey)
493
- const publicKeyHash = hash160(publicKey.encode(true)) as number[]
658
+ const publicKeyHash = hash160(publicKey.encode(true))
494
659
  const p2pkh = new P2PKH()
495
- const sourceTx = new Transaction(1, [], [{
496
- lockingScript: p2pkh.lock(publicKeyHash),
497
- satoshis: 46
498
- }], 0)
499
- const spendTx = new Transaction(1, [{
500
- sourceTransaction: sourceTx,
501
- sourceOutputIndex: 0,
502
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
503
- sequence: 0xffffffff
504
- }], Array(21).fill(null).map(() => ({
505
- lockingScript: p2pkh.lock(publicKeyHash),
506
- change: true
507
- })), 0)
508
- await spendTx.fee({
509
- computeFee: async () => 1
510
- }, 'random')
511
- expect(spendTx.outputs.reduce((a, b) => a + b.satoshis, 0)).toEqual(45)
660
+ const sourceTx = new Transaction(
661
+ 1,
662
+ [],
663
+ [
664
+ {
665
+ lockingScript: p2pkh.lock(publicKeyHash),
666
+ satoshis: 46
667
+ }
668
+ ],
669
+ 0
670
+ )
671
+ const spendTx = new Transaction(
672
+ 1,
673
+ [
674
+ {
675
+ sourceTransaction: sourceTx,
676
+ sourceOutputIndex: 0,
677
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
678
+ sequence: 0xffffffff
679
+ }
680
+ ],
681
+ Array(21)
682
+ .fill(null)
683
+ .map(() => ({
684
+ lockingScript: p2pkh.lock(publicKeyHash),
685
+ change: true
686
+ })),
687
+ 0
688
+ )
689
+ await spendTx.fee(
690
+ {
691
+ computeFee: async () => 1
692
+ },
693
+ 'random'
694
+ )
695
+ expect(spendTx.outputs.reduce((a, b) => a + (b.satoshis ?? 0), 0)).toEqual(45)
512
696
  })
513
697
  it('Calculates fee for utxo based transaction', async () => {
514
- const utxos = [ // WoC format utxos
698
+ const utxos = [
699
+ // WoC format utxos
515
700
  {
516
701
  height: 1600000,
517
702
  tx_pos: 0,
518
- tx_hash: '672dd6a93fa5d7ba6794e0bdf8b479440b95a55ec10ad3d9e03585ecb5628d8d',
703
+ tx_hash:
704
+ '672dd6a93fa5d7ba6794e0bdf8b479440b95a55ec10ad3d9e03585ecb5628d8d',
519
705
  value: 10000
520
706
  },
521
707
  {
522
708
  height: 1600000,
523
709
  tx_pos: 0,
524
- tx_hash: 'f33505acf37a7726cc37d391bc6f889b8684ac2a2d581c4be2a4b1c8b46609bc',
710
+ tx_hash:
711
+ 'f33505acf37a7726cc37d391bc6f889b8684ac2a2d581c4be2a4b1c8b46609bc',
525
712
  value: 10000
526
713
  }
527
714
  ]
@@ -564,9 +751,9 @@ describe('Transaction', () => {
564
751
  txStatus: 'success',
565
752
  extraInfo: 'received'
566
753
  })
567
- });
754
+ })
568
755
 
569
- (global as any).window = { fetch: mockedFetch } as any
756
+ ; (global as any).window = { fetch: mockedFetch } as any
570
757
 
571
758
  const tx = new Transaction()
572
759
  const rv = await tx.broadcast()
@@ -582,48 +769,70 @@ describe('Transaction', () => {
582
769
  })
583
770
 
584
771
  it('Broadcasts with the provided Broadcaster instance', async () => {
585
- const mockBroadcast = jest.fn(() => 'MOCK_RV')
772
+ const mockBroadcast = jest.fn(async (): Promise<BroadcastResponse> => {
773
+ return {
774
+ status: 'success', // Explicitly matches the literal type "success"
775
+ txid: 'mock_txid',
776
+ message: 'Transaction successfully broadcasted.'
777
+ }
778
+ })
779
+
586
780
  const tx = new Transaction()
587
781
  const rv = await tx.broadcast({
588
782
  broadcast: mockBroadcast
589
783
  })
784
+
785
+ // Ensure the mock function was called with the correct argument
590
786
  expect(mockBroadcast).toHaveBeenCalledWith(tx)
591
- expect(rv).toEqual('MOCK_RV')
592
- })
593
- })
594
787
 
595
- describe('BEEF', () => {
596
- it('Serialization and deserialization', async () => {
597
- const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
598
- expect(tx.inputs[0].sourceTransaction.merklePath.blockHeight).toEqual(814435)
599
- const beef = toHex(tx.toBEEF())
600
- expect(beef).toEqual(BRC62Hex)
788
+ // Verify the return value matches the mocked response
789
+ expect(rv).toEqual({
790
+ status: 'success',
791
+ txid: 'mock_txid',
792
+ message: 'Transaction successfully broadcasted.'
793
+ })
601
794
  })
602
- it('Does not double-encode transactions', () => {
603
- // Source: https://github.com/bitcoin-sv/ts-sdk/issues/77
604
- const incorrect = '0100beef01fe76eb0c000e02c402deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111c500f4076b7f48031fc467f87d5e99d9c3c0b59e4dca5e3049f58b735c59b413a8b6016300bad9c2d948e8a2ca647fdb50f2fd36641c4adf937b41134405a3e7f734b8beb201300053604a579558b5f7030e618d5c726a19229e0ff677f6edf109f41c5cfdafc93e0119005f8465c2a8d1558afbfa80c2395f3f8866a2fa5015e54fab778b0149da58376c010d00cd452b4e74f57d199cdb81b8a0e4a62dcdaf89504d6c63a5a65d5b866912b8c0010700d2ae7e2ce76da560509172066f1a1cf81faf81d73f9c0f6fd5af0904973dcfb10102006e5e077bcaa35c0240d61c1f3bba8d789223711ec035ef88b0911fc569d2b95a010000c961038959b9d404297a180c066816562dd2a34986c0960121a87ba91a51262f010100a50e381b4e8812479ea561e5bab7dcaa80078652b1b39ee5410966c515a3442b010100383ce8891ca7bf1ddefa5e0d8a1ba9ab01cb4e18046e9d7d0d438b5aaecc38b2010100c694be322b4e74acca8a5ef7703afedb708281321fd674f1221eebc743b0e01c0101000f3cc61f2b3d762cfecdd977ba768a5cbb0a4b402ad4f0d1bd3a98a582794c35010100094ad56eeea3b47edb2b298775f2efabe48172612cb3419962632251d8cdb78e010100de84bf9dd8873f37decbda1b5188e24ead978b147a63c809691702d19c47e8cb050200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac00000000000200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac000000000001000000022e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b000000006b483045022100d9a2d1efea4896b36b2eb5af42cf52009982c7c31b446213fe37f26835d9d72202203e4dee0ceb068a4936e79b0bf69f72203906a00a4256cb1a7b30a40764616e8441210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff2e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b010000006b483045022100b57a09145c57b7b5efb4b546f1b0bfb7adbc5e64d35d9d6989345d4c60c483940220280998a210a49a6efaacda6fb73670001bb7269d069be80eb14ea2227a73e82241210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff0174660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac0000000000'
605
- const correct = '0100beef01fe76eb0c000e02c402deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111c500f4076b7f48031fc467f87d5e99d9c3c0b59e4dca5e3049f58b735c59b413a8b6016300bad9c2d948e8a2ca647fdb50f2fd36641c4adf937b41134405a3e7f734b8beb201300053604a579558b5f7030e618d5c726a19229e0ff677f6edf109f41c5cfdafc93e0119005f8465c2a8d1558afbfa80c2395f3f8866a2fa5015e54fab778b0149da58376c010d00cd452b4e74f57d199cdb81b8a0e4a62dcdaf89504d6c63a5a65d5b866912b8c0010700d2ae7e2ce76da560509172066f1a1cf81faf81d73f9c0f6fd5af0904973dcfb10102006e5e077bcaa35c0240d61c1f3bba8d789223711ec035ef88b0911fc569d2b95a010000c961038959b9d404297a180c066816562dd2a34986c0960121a87ba91a51262f010100a50e381b4e8812479ea561e5bab7dcaa80078652b1b39ee5410966c515a3442b010100383ce8891ca7bf1ddefa5e0d8a1ba9ab01cb4e18046e9d7d0d438b5aaecc38b2010100c694be322b4e74acca8a5ef7703afedb708281321fd674f1221eebc743b0e01c0101000f3cc61f2b3d762cfecdd977ba768a5cbb0a4b402ad4f0d1bd3a98a582794c35010100094ad56eeea3b47edb2b298775f2efabe48172612cb3419962632251d8cdb78e010100de84bf9dd8873f37decbda1b5188e24ead978b147a63c809691702d19c47e8cb030200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac000000000001000000022e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b000000006b483045022100d9a2d1efea4896b36b2eb5af42cf52009982c7c31b446213fe37f26835d9d72202203e4dee0ceb068a4936e79b0bf69f72203906a00a4256cb1a7b30a40764616e8441210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff2e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b010000006b483045022100b57a09145c57b7b5efb4b546f1b0bfb7adbc5e64d35d9d6989345d4c60c483940220280998a210a49a6efaacda6fb73670001bb7269d069be80eb14ea2227a73e82241210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff0174660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac0000000000'
606
- const tx1 = Transaction.fromHexBEEF(incorrect)
607
- expect(tx1.toHexBEEF()).toEqual(correct)
795
+
796
+ describe('BEEF', () => {
797
+ it('Serialization and deserialization', async () => {
798
+ const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
799
+ expect(tx.inputs[0].sourceTransaction?.merklePath?.blockHeight).toEqual(
800
+ 814435
801
+ )
802
+ const beef = toHex(tx.toBEEF())
803
+ expect(beef).toEqual(BRC62Hex)
804
+ })
805
+ it('Does not double-encode transactions', () => {
806
+ // Source: https://github.com/bitcoin-sv/ts-sdk/issues/77
807
+ const incorrect =
808
+ '0100beef01fe76eb0c000e02c402deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111c500f4076b7f48031fc467f87d5e99d9c3c0b59e4dca5e3049f58b735c59b413a8b6016300bad9c2d948e8a2ca647fdb50f2fd36641c4adf937b41134405a3e7f734b8beb201300053604a579558b5f7030e618d5c726a19229e0ff677f6edf109f41c5cfdafc93e0119005f8465c2a8d1558afbfa80c2395f3f8866a2fa5015e54fab778b0149da58376c010d00cd452b4e74f57d199cdb81b8a0e4a62dcdaf89504d6c63a5a65d5b866912b8c0010700d2ae7e2ce76da560509172066f1a1cf81faf81d73f9c0f6fd5af0904973dcfb10102006e5e077bcaa35c0240d61c1f3bba8d789223711ec035ef88b0911fc569d2b95a010000c961038959b9d404297a180c066816562dd2a34986c0960121a87ba91a51262f010100a50e381b4e8812479ea561e5bab7dcaa80078652b1b39ee5410966c515a3442b010100383ce8891ca7bf1ddefa5e0d8a1ba9ab01cb4e18046e9d7d0d438b5aaecc38b2010100c694be322b4e74acca8a5ef7703afedb708281321fd674f1221eebc743b0e01c0101000f3cc61f2b3d762cfecdd977ba768a5cbb0a4b402ad4f0d1bd3a98a582794c35010100094ad56eeea3b47edb2b298775f2efabe48172612cb3419962632251d8cdb78e010100de84bf9dd8873f37decbda1b5188e24ead978b147a63c809691702d19c47e8cb050200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac00000000000200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac000000000001000000022e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b000000006b483045022100d9a2d1efea4896b36b2eb5af42cf52009982c7c31b446213fe37f26835d9d72202203e4dee0ceb068a4936e79b0bf69f72203906a00a4256cb1a7b30a40764616e8441210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff2e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b010000006b483045022100b57a09145c57b7b5efb4b546f1b0bfb7adbc5e64d35d9d6989345d4c60c483940220280998a210a49a6efaacda6fb73670001bb7269d069be80eb14ea2227a73e82241210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff0174660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac0000000000'
809
+ const correct =
810
+ '0100beef01fe76eb0c000e02c402deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111c500f4076b7f48031fc467f87d5e99d9c3c0b59e4dca5e3049f58b735c59b413a8b6016300bad9c2d948e8a2ca647fdb50f2fd36641c4adf937b41134405a3e7f734b8beb201300053604a579558b5f7030e618d5c726a19229e0ff677f6edf109f41c5cfdafc93e0119005f8465c2a8d1558afbfa80c2395f3f8866a2fa5015e54fab778b0149da58376c010d00cd452b4e74f57d199cdb81b8a0e4a62dcdaf89504d6c63a5a65d5b866912b8c0010700d2ae7e2ce76da560509172066f1a1cf81faf81d73f9c0f6fd5af0904973dcfb10102006e5e077bcaa35c0240d61c1f3bba8d789223711ec035ef88b0911fc569d2b95a010000c961038959b9d404297a180c066816562dd2a34986c0960121a87ba91a51262f010100a50e381b4e8812479ea561e5bab7dcaa80078652b1b39ee5410966c515a3442b010100383ce8891ca7bf1ddefa5e0d8a1ba9ab01cb4e18046e9d7d0d438b5aaecc38b2010100c694be322b4e74acca8a5ef7703afedb708281321fd674f1221eebc743b0e01c0101000f3cc61f2b3d762cfecdd977ba768a5cbb0a4b402ad4f0d1bd3a98a582794c35010100094ad56eeea3b47edb2b298775f2efabe48172612cb3419962632251d8cdb78e010100de84bf9dd8873f37decbda1b5188e24ead978b147a63c809691702d19c47e8cb030200000001b67f1b6a6c3e70742a39b82ba45d51c983f598963ebf237101cc372da1144b83020000006b483045022100d14c3eb0c1438747c124f099bc664bf945cd27cbd96915027057e508bbc9e03302203c73f79d4e00f8018783e1008ce0fbb8e8c58bff6bd8042ab7e3966a66c8788c41210356762156ee9347c3e2ceca17d13713028d5446f453e9cbcb0ea170b4ca7fab52ffffffff037c660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac75330100000000001976a914eb645f9ea7e4e232e54b9651474c100026698c3088acf2458005000000001976a914802737e30c85b6fe86e26fb28e03140058aca65e88ac0000000001000100000001deff5437203e0b5cb22646cbada24a60349bf45c8b280ffb755868f2955c3111000000006a473044022076da9f61380c208f43652587c219b4452a7b803a0407c2c7c0f3bc27612c4e88022021a9eb02da5529873a5986933f9c35965aa78537b9e2aef9382de33cfb1ab4bb41210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff023c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac3c330000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac000000000001000000022e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b000000006b483045022100d9a2d1efea4896b36b2eb5af42cf52009982c7c31b446213fe37f26835d9d72202203e4dee0ceb068a4936e79b0bf69f72203906a00a4256cb1a7b30a40764616e8441210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff2e7f69f3e1e17e22cfb8818577b3c83a4fbbbc1bab55c70ffcdd994ae30ea48b010000006b483045022100b57a09145c57b7b5efb4b546f1b0bfb7adbc5e64d35d9d6989345d4c60c483940220280998a210a49a6efaacda6fb73670001bb7269d069be80eb14ea2227a73e82241210314793e1758db3caa7d2bce97b347ae3ced2f8a402b797ed986be63473d4644a0ffffffff0174660000000000001976a91417c85798ff61f7ec8af257f672d973b6ec6d88fd88ac0000000000'
811
+ const tx1 = Transaction.fromHexBEEF(incorrect)
812
+ expect(tx1.toHexBEEF()).toEqual(correct)
813
+ })
608
814
  })
609
- })
610
815
 
611
- describe('EF', () => {
612
- it('Serialization and deserialization', async () => {
613
- const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
614
- const ef = toHex(tx.toEF())
615
- expect(ef).toEqual('010000000000000000ef01ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff3e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac00000000')
816
+ describe('EF', () => {
817
+ it('Serialization and deserialization', async () => {
818
+ const tx = Transaction.fromBEEF(toArray(BRC62Hex, 'hex'))
819
+ const ef = toHex(tx.toEF())
820
+ expect(ef).toEqual(
821
+ '010000000000000000ef01ac4e164f5bc16746bb0868404292ac8318bbac3800e4aad13a014da427adce3e000000006a47304402203a61a2e931612b4bda08d541cfb980885173b8dcf64a3471238ae7abcd368d6402204cbf24f04b9aa2256d8901f0ed97866603d2be8324c2bfb7a37bf8fc90edd5b441210263e2dee22b1ddc5e11f6fab8bcd2378bdd19580d640501ea956ec0e786f93e76ffffffff3e660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac013c660000000000001976a9146bfd5c7fbe21529d45803dbcf0c87dd3c71efbc288ac00000000'
822
+ )
823
+ })
616
824
  })
617
- })
618
825
 
619
- describe('Verification', () => {
620
- it('Verifies the transaction from the BEEF spec', async () => {
621
- const tx = Transaction.fromHexBEEF(BRC62Hex)
622
- const alwaysYesChainTracker = {
623
- isValidRootForHeight: async () => true
624
- }
625
- const verified = await tx.verify(alwaysYesChainTracker)
626
- expect(verified).toBe(true)
826
+ describe('Verification', () => {
827
+ it('Verifies the transaction from the BEEF spec', async () => {
828
+ const tx = Transaction.fromHexBEEF(BRC62Hex)
829
+ const alwaysYesChainTracker = {
830
+ currentHeight: async () => 1631619, // Mocked current height
831
+ isValidRootForHeight: async () => true // Always returns true
832
+ }
833
+ const verified = await tx.verify(alwaysYesChainTracker)
834
+ expect(verified).toBe(true)
835
+ })
627
836
  })
628
837
 
629
838
  it('Verifies the transaction from the BEEF spec with a default chain tracker', async () => {
@@ -641,9 +850,8 @@ describe('Transaction', () => {
641
850
  json: async () => ({
642
851
  merkleroot: MerkleRootFromBEEF
643
852
  })
644
- });
645
- (global as any).window = { fetch: mockFetch }
646
-
853
+ })
854
+ ; (global as any).window = { fetch: mockFetch }
647
855
 
648
856
  const tx = Transaction.fromHexBEEF(BRC62Hex)
649
857
 
@@ -654,105 +862,295 @@ describe('Transaction', () => {
654
862
  })
655
863
 
656
864
  it('Verifies the transaction from the BEEF spec with a scripts only', async () => {
657
- const BEEF = "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"
658
- const tx = Transaction.fromBEEF(toArray(BEEF, "base64"))
865
+ const BEEF =
866
+ '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'
867
+ const tx = Transaction.fromBEEF(toArray(BEEF, 'base64'))
659
868
 
660
869
  // Verifies transaction with scripts only
661
- const verified = await tx.verify("scripts only")
870
+ const verified = await tx.verify('scripts only')
662
871
  expect(verified).toBe(true)
663
872
  })
664
873
 
665
874
  it('Verifies tx scripts only when our input has no MerklePath.', async () => {
666
- const sourceTransaction = Transaction.fromHex('01000000013834506e4af751dc3a0d73e9bdd067709ade5248860967fb3eb72854be6011dc020000006b4830450221008abf2ce1afbcc3c4895265b0966ac69e2275fb35a738f9873b5416cd3bb68cc102202c906f9771d2d6868f81a34d6a3af4cd7de070969286db7097c5e0f3a009b638412102f6a81c442dcd903c7808a75abde9217268bb70417ad538c18fb597b4c553c354ffffffff0301000000000000007c21039bf52152665699e24c1018bf5b48e575de316f844962a79db32b93b7e328bf71ac1062656e63686d61726b546f6b656e5f36463044022034ca3cc49163e4d5bc24f41c5ea4631efd4ae7c243f904c90e1db6e6a55e8f0e02206bb031baca2fc6d64da5ad722ce2e07137718e5e58092e5ecf54e52fcdd664ab6dc8000000000000001976a91470763a553d615a8144fa0889a0e1f93d1d8da8b088acaf430000000000001976a9145aa12f9be0121eee54e7331d8f995fe4dded72f588ac00000000')
667
- const tx = Transaction.fromHex('01000000015c22e8d34a95a761a0685b8b5a99a0845e9f03d87d5716a7351d08939db5cd92020000006a47304402205101f2bdc40098cbde1a270071a5bfdd5a6fbefc8a38a8b4a1adaca0a6ff55e702200ec5c0a57cb65dfc6aa22e6856bb4c62b8987a7b9fa32cb601c94b579ba67d83412103c8be6b217fc55939851e28239fbbf731f997e026ad344aa9d4b739181fe96743ffffffff0301000000000000007c21039bf52152665699e24c1018bf5b48e575de316f844962a79db32b93b7e328bf71ac1062656e63686d61726b546f6b656e5f374630440220026808e9453f75ca1fc3c7bb0f7be1efaca5cea6b1eda96ab7db56c519b6793202207d1fa5e7d54254d2142256947f93a061781280a6ed2464052470633a7c888d1f6dc8000000000000001976a91428bb6f207ac8f4b7f6c1c5914e143a6165586b2488ace5420000000000001976a914197cbde77abbcb985ca60a85c2988b2ac32c541a88ac00000000')
668
- sourceTransaction.merklePath = { assumeValid: true } // can be any object.
875
+ const sourceTransaction = Transaction.fromHex(
876
+ '01000000013834506e4af751dc3a0d73e9bdd067709ade5248860967fb3eb72854be6011dc020000006b4830450221008abf2ce1afbcc3c4895265b0966ac69e2275fb35a738f9873b5416cd3bb68cc102202c906f9771d2d6868f81a34d6a3af4cd7de070969286db7097c5e0f3a009b638412102f6a81c442dcd903c7808a75abde9217268bb70417ad538c18fb597b4c553c354ffffffff0301000000000000007c21039bf52152665699e24c1018bf5b48e575de316f844962a79db32b93b7e328bf71ac1062656e63686d61726b546f6b656e5f36463044022034ca3cc49163e4d5bc24f41c5ea4631efd4ae7c243f904c90e1db6e6a55e8f0e02206bb031baca2fc6d64da5ad722ce2e07137718e5e58092e5ecf54e52fcdd664ab6dc8000000000000001976a91470763a553d615a8144fa0889a0e1f93d1d8da8b088acaf430000000000001976a9145aa12f9be0121eee54e7331d8f995fe4dded72f588ac00000000'
877
+ )
878
+ const tx = Transaction.fromHex(
879
+ '01000000015c22e8d34a95a761a0685b8b5a99a0845e9f03d87d5716a7351d08939db5cd92020000006a47304402205101f2bdc40098cbde1a270071a5bfdd5a6fbefc8a38a8b4a1adaca0a6ff55e702200ec5c0a57cb65dfc6aa22e6856bb4c62b8987a7b9fa32cb601c94b579ba67d83412103c8be6b217fc55939851e28239fbbf731f997e026ad344aa9d4b739181fe96743ffffffff0301000000000000007c21039bf52152665699e24c1018bf5b48e575de316f844962a79db32b93b7e328bf71ac1062656e63686d61726b546f6b656e5f374630440220026808e9453f75ca1fc3c7bb0f7be1efaca5cea6b1eda96ab7db56c519b6793202207d1fa5e7d54254d2142256947f93a061781280a6ed2464052470633a7c888d1f6dc8000000000000001976a91428bb6f207ac8f4b7f6c1c5914e143a6165586b2488ace5420000000000001976a914197cbde77abbcb985ca60a85c2988b2ac32c541a88ac00000000'
880
+ )
881
+
882
+ // Create a mock MerklePath
883
+ const mockMerklePath = new MerklePath(0, [
884
+ [{ offset: 0, hash: 'dummyHash' }]
885
+ ])
886
+ sourceTransaction.merklePath = mockMerklePath
887
+
669
888
  tx.inputs[0].sourceTransaction = sourceTransaction
670
889
  const verified = await tx.verify('scripts only', undefined)
671
890
  expect(verified).toBe(true)
672
891
  })
673
- })
674
892
 
675
- describe('vectors: a 1mb transaction', () => {
676
- it('should find the correct id of this (valid, on the blockchain) 1 mb transaction', () => {
677
- const txidhex = bigTX.txidhex
678
- const txhex = bigTX.txhex
679
- const tx = Transaction.fromHex(txhex)
680
- const txid = tx.id('hex')
681
- expect(txid).toEqual(txidhex)
893
+ describe('vectors: a 1mb transaction', () => {
894
+ it('should find the correct id of this (valid, on the blockchain) 1 mb transaction', () => {
895
+ const txidhex = bigTX.txidhex
896
+ const txhex = bigTX.txhex
897
+ const tx = Transaction.fromHex(txhex)
898
+ const txid = tx.id('hex')
899
+ expect(txid).toEqual(txidhex)
900
+ })
682
901
  })
683
- })
684
902
 
685
- describe('vectors: sighash and serialization', () => {
686
- sighashVectors.forEach((vector, i) => {
687
- if (i === 0) {
688
- return
689
- }
690
- it(`should pass bitcoin-abc sighash test vector ${i}`, () => {
691
- const txbuf = toArray(vector[0], 'hex')
692
- const scriptbuf = toArray(vector[1], 'hex')
693
- const subScript = Script.fromBinary(scriptbuf)
694
- const nIn = (vector[2]) as number
695
- const nHashType = (vector[3]) as number
696
- const sighashBuf = toArray(vector[4], 'hex')
697
- const tx = Transaction.fromBinary(txbuf)
698
-
699
- // make sure transacion to/from buffer is isomorphic
700
- expect(toHex(tx.toBinary())).toEqual(toHex(txbuf))
701
-
702
- // sighash ought to be correct
703
- const valueBn = new BigNumber(0)
704
- const otherInputs = [...tx.inputs]
705
- const [input] = otherInputs.splice(nIn, 1)
706
- const preimage = TransactionSignature.format({
707
- sourceTXID: input.sourceTXID,
708
- sourceOutputIndex: input.sourceOutputIndex,
709
- sourceSatoshis: valueBn,
710
- transactionVersion: tx.version,
711
- otherInputs,
712
- outputs: tx.outputs,
713
- inputIndex: nIn,
714
- subscript: subScript,
715
- inputSequence: input.sequence,
716
- lockTime: tx.lockTime,
717
- scope: nHashType
903
+ describe('vectors: sighash and serialization', () => {
904
+ sighashVectors.forEach((vector, i) => {
905
+ if (i === 0) {
906
+ return
907
+ }
908
+ it(`should pass bitcoin-abc sighash test vector ${i}`, () => {
909
+ const txbuf = toArray(vector[0], 'hex')
910
+ const scriptbuf = toArray(vector[1], 'hex')
911
+ const subScript = Script.fromBinary(scriptbuf)
912
+ const nIn = vector[2] as number
913
+ const nHashType = vector[3] as number
914
+ const sighashBuf = toArray(vector[4], 'hex')
915
+ const tx = Transaction.fromBinary(txbuf)
916
+
917
+ // make sure transacion to/from buffer is isomorphic
918
+ expect(toHex(tx.toBinary())).toEqual(toHex(txbuf))
919
+
920
+ // sighash ought to be correct
921
+ const valueBn = new BigNumber(0).toNumber()
922
+ const otherInputs = [...tx.inputs]
923
+ const [input] = otherInputs.splice(nIn, 1)
924
+ const preimage = TransactionSignature.format({
925
+ sourceTXID: input.sourceTXID ?? '',
926
+ sourceOutputIndex: input.sourceOutputIndex,
927
+ sourceSatoshis: valueBn,
928
+ transactionVersion: tx.version,
929
+ otherInputs,
930
+ outputs: tx.outputs,
931
+ inputIndex: nIn,
932
+ subscript: subScript,
933
+ inputSequence: input.sequence ?? 0xffffffff,
934
+ lockTime: tx.lockTime,
935
+ scope: nHashType
936
+ })
937
+ const hash = hash256(preimage)
938
+ hash.reverse()
939
+ expect(toHex(hash)).toEqual(toHex(sighashBuf))
718
940
  })
719
- const hash = hash256(preimage) as number[]
720
- hash.reverse()
721
- expect(toHex(hash)).toEqual(toHex(sighashBuf))
722
941
  })
723
- })
724
942
 
725
- validTransactions.forEach((vector, i) => {
726
- if (vector.length === 1) {
727
- return
728
- }
729
- it(`should correctly serialized/deserialize tx_valid test vector ${i}`, () => {
730
- const expectedHex = vector[1]
731
- const expectedBin = toArray(vector[1], 'hex')
732
- const actualTX = Transaction.fromBinary(expectedBin)
733
- const actualBin = actualTX.toBinary()
734
- const actualHex = toHex(actualBin)
735
- expect(actualHex).toEqual(expectedHex)
943
+ validTransactions.forEach((vector, i) => {
944
+ if (vector.length === 1) {
945
+ return
946
+ }
947
+ it(`should correctly serialized/deserialize tx_valid test vector ${i}`, () => {
948
+ const expectedHex = vector[1]
949
+ const expectedBin = toArray(vector[1], 'hex')
950
+ const actualTX = Transaction.fromBinary(expectedBin)
951
+ const actualBin = actualTX.toBinary()
952
+ const actualHex = toHex(actualBin)
953
+ expect(actualHex).toEqual(expectedHex)
954
+ })
955
+ })
956
+
957
+ invalidTransactions.forEach((vector, i) => {
958
+ if (vector.length === 1) {
959
+ return
960
+ }
961
+
962
+ // 151, 142 and 25 have invalid Satoshi amounts that exceed 53 bits in length, causing exceptions that make serialization and deserialization impossible.
963
+ if (i === 151 || i === 142 || i === 25) {
964
+ return
965
+ }
966
+
967
+ it(`should correctly serialized/deserialize tx_invalid test vector ${i}`, () => {
968
+ const expectedHex = vector[1]
969
+ const expectedBin = toArray(vector[1], 'hex')
970
+ const actualTX = Transaction.fromBinary(expectedBin)
971
+ const actualBin = actualTX.toBinary()
972
+ const actualHex = toHex(actualBin)
973
+ expect(actualHex).toEqual(expectedHex)
974
+ })
736
975
  })
737
976
  })
738
977
 
739
- invalidTransactions.forEach((vector, i) => {
740
- if (vector.length === 1) {
741
- return
742
- }
978
+ describe('Atomic BEEF', () => {
979
+ it('should serialize a transaction to Atomic BEEF format correctly', async () => {
980
+ const privateKey = new PrivateKey(1)
981
+ const publicKey = new Curve().g.mul(privateKey)
982
+ const publicKeyHash = hash160(publicKey.encode(true))
983
+ const p2pkh = new P2PKH()
984
+
985
+ // Create a simple transaction
986
+ const sourceTx = new Transaction(
987
+ 1,
988
+ [],
989
+ [
990
+ {
991
+ lockingScript: p2pkh.lock(publicKeyHash),
992
+ satoshis: 10000
993
+ }
994
+ ],
995
+ 0
996
+ )
997
+
998
+ const spendTx = new Transaction(
999
+ 1,
1000
+ [
1001
+ {
1002
+ sourceTransaction: sourceTx,
1003
+ sourceOutputIndex: 0,
1004
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
1005
+ sequence: 0xffffffff
1006
+ }
1007
+ ],
1008
+ [
1009
+ {
1010
+ satoshis: 9000,
1011
+ lockingScript: p2pkh.lock(publicKeyHash)
1012
+ }
1013
+ ],
1014
+ 0
1015
+ )
1016
+
1017
+ // Sign the transaction
1018
+ await spendTx.fee()
1019
+ await spendTx.sign()
1020
+
1021
+ // Assign a MerklePath to the source transaction to simulate mined transaction
1022
+ const sourceTxID = sourceTx.id('hex')
1023
+ const merklePath = new MerklePath(1000, [
1024
+ [
1025
+ { offset: 0, hash: sourceTxID, txid: true },
1026
+ { offset: 1, duplicate: true }
1027
+ ]
1028
+ ])
1029
+ sourceTx.merklePath = merklePath
1030
+
1031
+ // Serialize to Atomic BEEF
1032
+ const atomicBEEF = spendTx.toAtomicBEEF()
1033
+ expect(atomicBEEF).toBeDefined()
1034
+ // Verify that the Atomic BEEF starts with the correct prefix and TXID
1035
+ const expectedPrefix = [0x01, 0x01, 0x01, 0x01]
1036
+ expect(atomicBEEF.slice(0, 4)).toEqual(expectedPrefix)
1037
+ const txid = spendTx.id()
1038
+ expect(atomicBEEF.slice(4, 36)).toEqual(txid)
1039
+
1040
+ // Deserialize from Atomic BEEF
1041
+ const deserializedTx = Transaction.fromAtomicBEEF(atomicBEEF)
1042
+ expect(deserializedTx.toHex()).toEqual(spendTx.toHex())
1043
+ })
743
1044
 
744
- // 151, 142 and 25 have invalid Satoshi amounts that exceed 53 bits in length, causing exceptions that make serialization and deserialization impossible.
745
- if (i === 151 || i === 142 || i === 25) {
746
- return
747
- }
1045
+ it('should throw an error when deserializing Atomic BEEF if subject transaction is missing', () => {
1046
+ // Create Atomic BEEF data with missing subject transaction
1047
+ const writer = new Writer()
1048
+ // Write Atomic BEEF prefix
1049
+ writer.writeUInt32LE(0x01010101)
1050
+ // Write subject TXID
1051
+ const fakeTXID = toArray('00'.repeat(32), 'hex')
1052
+ writer.write(fakeTXID)
1053
+ // Write empty BEEF data
1054
+ writer.writeUInt32LE(BEEF_V1) // BEEF version
1055
+ writer.writeVarIntNum(0) // No BUMPs
1056
+ writer.writeVarIntNum(0) // No transactions
1057
+
1058
+ const atomicBEEFData = writer.toArray()
1059
+
1060
+ expect(() => {
1061
+ Transaction.fromAtomicBEEF(atomicBEEFData)
1062
+ }).toThrow('beef must include at least one transaction.')
1063
+ })
1064
+
1065
+ it('should allow selecting a specific TXID from BEEF data', async () => {
1066
+ // Create two transactions, one depending on the other
1067
+ const privateKey = new PrivateKey(1)
1068
+ const publicKey = new Curve().g.mul(privateKey)
1069
+ const publicKeyHash = hash160(publicKey.encode(true)) as number[]
1070
+ const p2pkh = new P2PKH()
1071
+
1072
+ const sourceTx = new Transaction(
1073
+ 1,
1074
+ [],
1075
+ [
1076
+ {
1077
+ lockingScript: p2pkh.lock(publicKeyHash),
1078
+ satoshis: 10000
1079
+ }
1080
+ ],
1081
+ 0
1082
+ )
1083
+
1084
+ const spendTx = new Transaction(
1085
+ 1,
1086
+ [
1087
+ {
1088
+ sourceTransaction: sourceTx,
1089
+ sourceOutputIndex: 0,
1090
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
1091
+ sequence: 0xffffffff
1092
+ }
1093
+ ],
1094
+ [
1095
+ {
1096
+ satoshis: 9000,
1097
+ lockingScript: p2pkh.lock(publicKeyHash)
1098
+ }
1099
+ ],
1100
+ 0
1101
+ )
1102
+
1103
+ // Sign transactions
1104
+ await spendTx.fee()
1105
+ await spendTx.sign()
1106
+
1107
+ // Assign merkle path to source transaction
1108
+ const sourceTxID = sourceTx.id('hex')
1109
+ sourceTx.merklePath = new MerklePath(1000, [
1110
+ [
1111
+ { offset: 0, hash: sourceTxID, txid: true },
1112
+ { offset: 1, duplicate: true }
1113
+ ]
1114
+ ])
1115
+
1116
+ // Serialize to BEEF
1117
+ const beefData = spendTx.toBEEF()
1118
+ // Get TXIDs
1119
+ const spendTxID = spendTx.id('hex')
1120
+
1121
+ // Deserialize the source transaction from BEEF data
1122
+ const deserializedSourceTx = Transaction.fromBEEF(beefData, sourceTxID)
1123
+ expect(deserializedSourceTx.id('hex')).toEqual(sourceTxID)
1124
+
1125
+ // Deserialize the spend transaction from BEEF data
1126
+ const deserializedSpendTx = Transaction.fromBEEF(beefData, spendTxID)
1127
+ expect(deserializedSpendTx.id('hex')).toEqual(spendTxID)
1128
+
1129
+ // Attempt to deserialize a non-existent transaction
1130
+ expect(() => {
1131
+ Transaction.fromBEEF(beefData, '00'.repeat(32))
1132
+ }).toThrowError(
1133
+ 'Transaction with TXID 0000000000000000000000000000000000000000000000000000000000000000 not found in BEEF data.'
1134
+ )
1135
+ })
1136
+ })
748
1137
 
749
- it(`should correctly serialized/deserialize tx_invalid test vector ${i}`, () => {
750
- const expectedHex = vector[1]
751
- const expectedBin = toArray(vector[1], 'hex')
752
- const actualTX = Transaction.fromBinary(expectedBin)
753
- const actualBin = actualTX.toBinary()
754
- const actualHex = toHex(actualBin)
755
- expect(actualHex).toEqual(expectedHex)
1138
+ describe('addP2PKHOutput', () => {
1139
+ it('should create an output on the current transaction using an address hash or string', async () => {
1140
+ const privateKey = PrivateKey.fromRandom()
1141
+ const lockingScript = new P2PKH().lock(privateKey.toAddress())
1142
+ const tx = new Transaction()
1143
+ tx.addInput({
1144
+ sourceTXID: '00'.repeat(32),
1145
+ sourceOutputIndex: 0,
1146
+ unlockingScriptTemplate: new P2PKH().unlock(privateKey)
1147
+ })
1148
+ tx.addP2PKHOutput(privateKey.toAddress(), 10000)
1149
+ expect(tx.outputs.length).toEqual(1)
1150
+ expect(tx.outputs[0].satoshis).toEqual(10000)
1151
+ expect(
1152
+ tx.outputs[0].lockingScript.toHex() === lockingScript.toHex()
1153
+ ).toBeTruthy()
756
1154
  })
757
1155
  })
758
1156
  })
@@ -825,98 +1223,7 @@ describe('Transaction', () => {
825
1223
 
826
1224
  expect(() => {
827
1225
  Transaction.fromAtomicBEEF(atomicBEEFData)
828
- }).toThrowError('Subject transaction with TXID 0000000000000000000000000000000000000000000000000000000000000000 not found in Atomic BEEF data.')
829
- })
830
-
831
- it('should throw an error when deserializing Atomic BEEF if there are unrelated transactions', async () => {
832
- // Create two unrelated transactions
833
- const privateKey1 = new PrivateKey(1)
834
- const publicKey1 = new Curve().g.mul(privateKey1)
835
- const publicKeyHash1 = hash160(publicKey1.encode(true)) as number[]
836
- const p2pkh = new P2PKH()
837
-
838
- const sourceTx1 = new Transaction(1, [], [{
839
- lockingScript: p2pkh.lock(publicKeyHash1),
840
- satoshis: 10000
841
- }], 0)
842
-
843
- const spendTx1 = new Transaction(1, [{
844
- sourceTransaction: sourceTx1,
845
- sourceOutputIndex: 0,
846
- unlockingScriptTemplate: p2pkh.unlock(privateKey1),
847
- sequence: 0xffffffff
848
- }], [{
849
- satoshis: 9000,
850
- lockingScript: p2pkh.lock(publicKeyHash1)
851
- }], 0)
852
-
853
- // Another unrelated transaction
854
- const privateKey2 = new PrivateKey(2)
855
- const publicKey2 = new Curve().g.mul(privateKey2)
856
- const publicKeyHash2 = hash160(publicKey2.encode(true)) as number[]
857
-
858
- const sourceTx2 = new Transaction(1, [], [{
859
- lockingScript: p2pkh.lock(publicKeyHash2),
860
- satoshis: 10000
861
- }], 0)
862
-
863
- // Assign merkle paths to source transactions to simulate mined transactions
864
- const sourceTx1ID = sourceTx1.id('hex')
865
- const sourceTx2ID = sourceTx2.id('hex')
866
- sourceTx1.merklePath = new MerklePath(1000, [
867
- [
868
- { offset: 0, hash: sourceTx1ID, txid: true },
869
- { offset: 1, duplicate: true }
870
- ]
871
- ])
872
- sourceTx2.merklePath = new MerklePath(1001, [
873
- [
874
- { offset: 0, hash: sourceTx2ID, txid: true },
875
- { offset: 1, duplicate: true }
876
- ]
877
- ])
878
-
879
- // Sign the transaction
880
- await spendTx1.fee()
881
- await spendTx1.sign()
882
-
883
- // Construct the Atomic BEEF data manually, including the unrelated transaction
884
- const writer = new Writer()
885
- // Write Atomic BEEF prefix
886
- writer.writeUInt32LE(0x01010101)
887
- // Write subject TXID (spendTx1)
888
- const spendTx1ID = spendTx1.id()
889
- writer.write(spendTx1ID)
890
-
891
- // Build BEEF data
892
- const beefWriter = new Writer()
893
- beefWriter.writeUInt32LE(BEEF_V1) // BEEF version
894
- // BUMPs
895
- beefWriter.writeVarIntNum(2)
896
- beefWriter.write(sourceTx1.merklePath.toBinary())
897
- beefWriter.write(sourceTx2.merklePath.toBinary())
898
- // Transactions
899
- beefWriter.writeVarIntNum(3)
900
- // Transaction 1 (sourceTx1)
901
- beefWriter.write(sourceTx1.toBinary())
902
- beefWriter.writeUInt8(1) // hasBump
903
- beefWriter.writeVarIntNum(0) // BUMP index
904
- // Transaction 2 (sourceTx2) - unrelated
905
- beefWriter.write(sourceTx2.toBinary())
906
- beefWriter.writeUInt8(1) // hasBump
907
- beefWriter.writeVarIntNum(1) // BUMP index
908
- // Transaction 3 (spendTx1)
909
- beefWriter.write(spendTx1.toBinary())
910
- beefWriter.writeUInt8(0) // no BUMP
911
-
912
- // Combine Atomic BEEF data
913
- writer.write(beefWriter.toArray())
914
- const atomicBEEFData = writer.toArray()
915
-
916
- // Attempt to deserialize
917
- expect(() => {
918
- Transaction.fromAtomicBEEF(atomicBEEFData)
919
- }).toThrowError(/Unrelated transaction with TXID .+ found in Atomic BEEF data./)
1226
+ }).toThrowError('beef must include at least one transaction.')
920
1227
  })
921
1228
 
922
1229
  it('should allow selecting a specific TXID from BEEF data', async () => {
@@ -984,37 +1291,6 @@ describe('Transaction', () => {
984
1291
  sourceOutputIndex: 0,
985
1292
  unlockingScriptTemplate: new P2PKH().unlock(privateKey),
986
1293
  })
987
- tx.addP2PKHOutput(privateKey.toAddress(), 10000)
988
- expect(tx.outputs.length).toEqual(1)
989
- expect(tx.outputs[0].satoshis).toEqual(10000)
990
- expect(tx.outputs[0].lockingScript.toHex() === lockingScript.toHex()).toBeTruthy()
991
- })
992
- it('should error is the address is non base58', async () => {
993
- const tx = new Transaction()
994
- expect(() => tx.addP2PKHOutput('A small chicken', 10000)).toThrow("Invalid base58 character ")
995
- })
996
- it('should error if the address is incorrectly copied', async () => {
997
- const tx = new Transaction()
998
- expect(() => tx.addP2PKHOutput('14afWk1jLH9Uwi2mC9C5ehrsvcFxTLYDp', 10000)).toThrow("Invalid checksum")
999
- })
1000
- it('should error if the address is a hash of wrong length', async () => {
1001
- const tx = new Transaction()
1002
- const address = [1,2,3,4,5]
1003
- expect(() => tx.addP2PKHOutput(address, 10000)).toThrow("P2PKH hash length must be 20 bytes")
1004
- })
1005
- it('should set the output to a change output if the satoshi value is not given', async () => {
1006
- const tx = new Transaction()
1007
- tx.addP2PKHOutput('18E63MgXH43KBb288ETM8u91J2cqdGNEmg')
1008
- expect(tx.outputs[0].change).toBeTruthy()
1009
- expect(tx.outputs[0].satoshis).toBeUndefined()
1010
- })
1011
- it('throw error when satoshi value is negative', async () => {
1012
- const tx = new Transaction()
1013
- expect(() => tx.addP2PKHOutput('18E63MgXH43KBb288ETM8u91J2cqdGNEmg', -1000)).toThrow('satoshis must be a positive integer or zero')
1014
- })
1015
- it('throw error when output does not set satoshi value', async () => {
1016
- const tx = new Transaction()
1017
- expect(() => tx.addOutput({ lockingScript: Script.fromASM('OP_TRUE') })).toThrow('either satoshis must be defined or change must be set to true')
1018
1294
  })
1019
1295
  })
1020
1296
  })