@btc-vision/transaction 1.8.0-beta.3 → 1.8.0-beta.5

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 (764) hide show
  1. package/browser/_version.d.ts +1 -0
  2. package/browser/_version.d.ts.map +1 -0
  3. package/browser/abi/ABICoder.d.ts +1 -1
  4. package/browser/abi/ABICoder.d.ts.map +1 -0
  5. package/browser/branded/Branded.d.ts +4 -0
  6. package/browser/branded/Branded.d.ts.map +1 -0
  7. package/browser/btc-vision-bitcoin.js +11999 -2647
  8. package/browser/buffer/BinaryReader.d.ts +120 -1
  9. package/browser/buffer/BinaryReader.d.ts.map +1 -0
  10. package/browser/buffer/BinaryWriter.d.ts +51 -1
  11. package/browser/buffer/BinaryWriter.d.ts.map +1 -0
  12. package/browser/bytecode/Compressor.d.ts +12 -0
  13. package/browser/bytecode/Compressor.d.ts.map +1 -0
  14. package/browser/chain/ChainData.d.ts +2 -2
  15. package/browser/chain/ChainData.d.ts.map +1 -0
  16. package/browser/consensus/Consensus.d.ts +11 -3
  17. package/browser/consensus/Consensus.d.ts.map +1 -0
  18. package/browser/consensus/ConsensusConfig.d.ts +1 -0
  19. package/browser/consensus/ConsensusConfig.d.ts.map +1 -0
  20. package/browser/consensus/IConsensusConfig.d.ts +1 -0
  21. package/browser/consensus/IConsensusConfig.d.ts.map +1 -0
  22. package/browser/consensus/metadata/RoswellConsensus.d.ts +1 -0
  23. package/browser/consensus/metadata/RoswellConsensus.d.ts.map +1 -0
  24. package/browser/crypto/crypto.d.ts +1 -0
  25. package/browser/crypto/crypto.d.ts.map +1 -0
  26. package/browser/deterministic/AddressMap.d.ts +6 -1
  27. package/browser/deterministic/AddressMap.d.ts.map +1 -0
  28. package/browser/deterministic/AddressSet.d.ts +3 -1
  29. package/browser/deterministic/AddressSet.d.ts.map +1 -0
  30. package/browser/deterministic/CustomMap.d.ts +3 -1
  31. package/browser/deterministic/CustomMap.d.ts.map +1 -0
  32. package/browser/deterministic/DeterministicMap.d.ts +3 -1
  33. package/browser/deterministic/DeterministicMap.d.ts.map +1 -0
  34. package/browser/deterministic/DeterministicSet.d.ts +3 -1
  35. package/browser/deterministic/DeterministicSet.d.ts.map +1 -0
  36. package/browser/deterministic/ExtendedAddressMap.d.ts +7 -1
  37. package/browser/deterministic/ExtendedAddressMap.d.ts.map +1 -0
  38. package/browser/deterministic/FastMap.d.ts +7 -1
  39. package/browser/deterministic/FastMap.d.ts.map +1 -0
  40. package/browser/ecc/backend.d.ts +13 -0
  41. package/browser/ecc/backend.d.ts.map +1 -0
  42. package/browser/epoch/ChallengeSolution.d.ts +33 -1
  43. package/browser/epoch/ChallengeSolution.d.ts.map +1 -0
  44. package/browser/epoch/interfaces/IChallengeSolution.d.ts +14 -13
  45. package/browser/epoch/interfaces/IChallengeSolution.d.ts.map +1 -0
  46. package/browser/epoch/validator/EpochValidator.d.ts +37 -7
  47. package/browser/epoch/validator/EpochValidator.d.ts.map +1 -0
  48. package/browser/event/NetEvent.d.ts +1 -0
  49. package/browser/event/NetEvent.d.ts.map +1 -0
  50. package/browser/generators/AddressGenerator.d.ts +4 -3
  51. package/browser/generators/AddressGenerator.d.ts.map +1 -0
  52. package/browser/generators/Features.d.ts +1 -0
  53. package/browser/generators/Features.d.ts.map +1 -0
  54. package/browser/generators/Generator.d.ts +46 -10
  55. package/browser/generators/Generator.d.ts.map +1 -0
  56. package/browser/generators/MLDSAData.d.ts +1 -0
  57. package/browser/generators/MLDSAData.d.ts.map +1 -0
  58. package/browser/generators/builders/CalldataGenerator.d.ts +25 -4
  59. package/browser/generators/builders/CalldataGenerator.d.ts.map +1 -0
  60. package/browser/generators/builders/CustomGenerator.d.ts +13 -3
  61. package/browser/generators/builders/CustomGenerator.d.ts.map +1 -0
  62. package/browser/generators/builders/DeploymentGenerator.d.ts +15 -4
  63. package/browser/generators/builders/DeploymentGenerator.d.ts.map +1 -0
  64. package/browser/generators/builders/HashCommitmentGenerator.d.ts +164 -12
  65. package/browser/generators/builders/HashCommitmentGenerator.d.ts.map +1 -0
  66. package/browser/generators/builders/LegacyCalldataGenerator.d.ts +26 -4
  67. package/browser/generators/builders/LegacyCalldataGenerator.d.ts.map +1 -0
  68. package/browser/generators/builders/MultiSignGenerator.d.ts +6 -1
  69. package/browser/generators/builders/MultiSignGenerator.d.ts.map +1 -0
  70. package/browser/generators/builders/P2WDAGenerator.d.ts +42 -4
  71. package/browser/generators/builders/P2WDAGenerator.d.ts.map +1 -0
  72. package/browser/index.d.ts +1 -0
  73. package/browser/index.d.ts.map +1 -0
  74. package/browser/index.js +3558 -3167
  75. package/browser/keypair/Address.d.ts +283 -13
  76. package/browser/keypair/Address.d.ts.map +1 -0
  77. package/browser/keypair/AddressVerificator.d.ts +7 -6
  78. package/browser/keypair/AddressVerificator.d.ts.map +1 -0
  79. package/browser/keypair/EcKeyPair.d.ts +183 -21
  80. package/browser/keypair/EcKeyPair.d.ts.map +1 -0
  81. package/browser/keypair/MessageSigner.d.ts +17 -16
  82. package/browser/keypair/MessageSigner.d.ts.map +1 -0
  83. package/browser/keypair/Secp256k1PointDeriver.d.ts +55 -0
  84. package/browser/keypair/Secp256k1PointDeriver.d.ts.map +1 -0
  85. package/browser/keypair/Wallet.d.ts +27 -13
  86. package/browser/keypair/Wallet.d.ts.map +1 -0
  87. package/browser/keypair/interfaces/IWallet.d.ts +19 -0
  88. package/browser/keypair/interfaces/IWallet.d.ts.map +1 -0
  89. package/browser/metadata/ContractBaseMetadata.d.ts +10 -2
  90. package/browser/metadata/ContractBaseMetadata.d.ts.map +1 -0
  91. package/browser/mnemonic/BIPStandard.d.ts +59 -0
  92. package/browser/mnemonic/BIPStandard.d.ts.map +1 -0
  93. package/browser/mnemonic/Mnemonic.d.ts +15 -3
  94. package/browser/mnemonic/Mnemonic.d.ts.map +1 -0
  95. package/browser/mnemonic/MnemonicStrength.d.ts +6 -0
  96. package/browser/mnemonic/MnemonicStrength.d.ts.map +1 -0
  97. package/browser/network/ChainId.d.ts +1 -0
  98. package/browser/network/ChainId.d.ts.map +1 -0
  99. package/browser/noble-curves.js +844 -2746
  100. package/browser/noble-hashes.js +1338 -2067
  101. package/browser/opnet.d.ts +22 -1
  102. package/browser/opnet.d.ts.map +1 -0
  103. package/browser/p2wda/P2WDADetector.d.ts +36 -9
  104. package/browser/p2wda/P2WDADetector.d.ts.map +1 -0
  105. package/browser/polyfill/disposable.d.ts +16 -0
  106. package/browser/polyfill/disposable.d.ts.map +1 -0
  107. package/browser/signer/AddressRotation.d.ts +36 -0
  108. package/browser/signer/AddressRotation.d.ts.map +1 -0
  109. package/browser/signer/IRotationSigner.d.ts +27 -3
  110. package/browser/signer/IRotationSigner.d.ts.map +1 -0
  111. package/browser/signer/ParallelSignerAdapter.d.ts +14 -0
  112. package/browser/signer/ParallelSignerAdapter.d.ts.map +1 -0
  113. package/browser/signer/SignerUtils.d.ts +11 -4
  114. package/browser/signer/SignerUtils.d.ts.map +1 -0
  115. package/browser/signer/TweakedSigner.d.ts +28 -4
  116. package/browser/signer/TweakedSigner.d.ts.map +1 -0
  117. package/browser/transaction/ContractAddress.d.ts +2 -2
  118. package/browser/transaction/ContractAddress.d.ts.map +1 -0
  119. package/browser/transaction/TransactionFactory.d.ts +140 -2
  120. package/browser/transaction/TransactionFactory.d.ts.map +1 -0
  121. package/browser/transaction/browser/BrowserSignerBase.d.ts +12 -6
  122. package/browser/transaction/browser/BrowserSignerBase.d.ts.map +1 -0
  123. package/browser/transaction/browser/WalletNetworks.d.ts +1 -0
  124. package/browser/transaction/browser/WalletNetworks.d.ts.map +1 -0
  125. package/browser/transaction/browser/Web3Provider.d.ts +27 -0
  126. package/browser/transaction/browser/Web3Provider.d.ts.map +1 -0
  127. package/browser/transaction/browser/extensions/UnisatSigner.d.ts +9 -7
  128. package/browser/transaction/browser/extensions/UnisatSigner.d.ts.map +1 -0
  129. package/browser/transaction/browser/extensions/XverseSigner.d.ts +9 -7
  130. package/browser/transaction/browser/extensions/XverseSigner.d.ts.map +1 -0
  131. package/browser/transaction/browser/types/OPWallet.d.ts +10 -0
  132. package/browser/transaction/browser/types/OPWallet.d.ts.map +1 -0
  133. package/browser/transaction/browser/types/Unisat.d.ts +1 -0
  134. package/browser/transaction/browser/types/Unisat.d.ts.map +1 -0
  135. package/browser/transaction/browser/types/Xverse.d.ts +1 -0
  136. package/browser/transaction/browser/types/Xverse.d.ts.map +1 -0
  137. package/browser/transaction/builders/CancelTransaction.d.ts +29 -4
  138. package/browser/transaction/builders/CancelTransaction.d.ts.map +1 -0
  139. package/browser/transaction/builders/ChallengeSolutionTransaction.d.ts +1 -0
  140. package/browser/transaction/builders/ChallengeSolutionTransaction.d.ts.map +1 -0
  141. package/browser/transaction/builders/ConsolidatedInteractionTransaction.d.ts +137 -10
  142. package/browser/transaction/builders/ConsolidatedInteractionTransaction.d.ts.map +1 -0
  143. package/browser/transaction/builders/CustomScriptTransaction.d.ts +106 -6
  144. package/browser/transaction/builders/CustomScriptTransaction.d.ts.map +1 -0
  145. package/browser/transaction/builders/DeploymentTransaction.d.ts +116 -5
  146. package/browser/transaction/builders/DeploymentTransaction.d.ts.map +1 -0
  147. package/browser/transaction/builders/FundingTransaction.d.ts +4 -3
  148. package/browser/transaction/builders/FundingTransaction.d.ts.map +1 -0
  149. package/browser/transaction/builders/InteractionTransaction.d.ts +12 -3
  150. package/browser/transaction/builders/InteractionTransaction.d.ts.map +1 -0
  151. package/browser/transaction/builders/InteractionTransactionP2WDA.d.ts +56 -5
  152. package/browser/transaction/builders/InteractionTransactionP2WDA.d.ts.map +1 -0
  153. package/browser/transaction/builders/MultiSignTransaction.d.ts +125 -16
  154. package/browser/transaction/builders/MultiSignTransaction.d.ts.map +1 -0
  155. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +103 -15
  156. package/browser/transaction/builders/SharedInteractionTransaction.d.ts.map +1 -0
  157. package/browser/transaction/builders/TransactionBuilder.d.ts +243 -14
  158. package/browser/transaction/builders/TransactionBuilder.d.ts.map +1 -0
  159. package/browser/transaction/enums/TransactionType.d.ts +1 -0
  160. package/browser/transaction/enums/TransactionType.d.ts.map +1 -0
  161. package/browser/transaction/interfaces/ICancelTransactionParameters.d.ts +2 -1
  162. package/browser/transaction/interfaces/ICancelTransactionParameters.d.ts.map +1 -0
  163. package/browser/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +46 -3
  164. package/browser/transaction/interfaces/IConsolidatedTransactionParameters.d.ts.map +1 -0
  165. package/browser/transaction/interfaces/ICustomTransactionParameters.d.ts +6 -4
  166. package/browser/transaction/interfaces/ICustomTransactionParameters.d.ts.map +1 -0
  167. package/browser/transaction/interfaces/ITransactionParameters.d.ts +22 -10
  168. package/browser/transaction/interfaces/ITransactionParameters.d.ts.map +1 -0
  169. package/browser/transaction/interfaces/ITransactionResponses.d.ts +1 -0
  170. package/browser/transaction/interfaces/ITransactionResponses.d.ts.map +1 -0
  171. package/browser/transaction/interfaces/ITweakedTransactionData.d.ts +17 -5
  172. package/browser/transaction/interfaces/ITweakedTransactionData.d.ts.map +1 -0
  173. package/browser/transaction/interfaces/IWeb3ProviderTypes.d.ts +26 -0
  174. package/browser/transaction/interfaces/IWeb3ProviderTypes.d.ts.map +1 -0
  175. package/browser/transaction/interfaces/Tap.d.ts +4 -3
  176. package/browser/transaction/interfaces/Tap.d.ts.map +1 -0
  177. package/browser/transaction/mineable/IP2WSHAddress.d.ts +2 -1
  178. package/browser/transaction/mineable/IP2WSHAddress.d.ts.map +1 -0
  179. package/browser/transaction/mineable/TimelockGenerator.d.ts +12 -3
  180. package/browser/transaction/mineable/TimelockGenerator.d.ts.map +1 -0
  181. package/browser/transaction/offline/OfflineTransactionManager.d.ts +190 -9
  182. package/browser/transaction/offline/OfflineTransactionManager.d.ts.map +1 -0
  183. package/browser/transaction/offline/TransactionReconstructor.d.ts +53 -3
  184. package/browser/transaction/offline/TransactionReconstructor.d.ts.map +1 -0
  185. package/browser/transaction/offline/TransactionSerializer.d.ts +53 -2
  186. package/browser/transaction/offline/TransactionSerializer.d.ts.map +1 -0
  187. package/browser/transaction/offline/TransactionStateCapture.d.ts +64 -5
  188. package/browser/transaction/offline/TransactionStateCapture.d.ts.map +1 -0
  189. package/browser/transaction/offline/interfaces/ISerializableState.d.ts +71 -0
  190. package/browser/transaction/offline/interfaces/ISerializableState.d.ts.map +1 -0
  191. package/browser/transaction/offline/interfaces/ITypeSpecificData.d.ts +76 -0
  192. package/browser/transaction/offline/interfaces/ITypeSpecificData.d.ts.map +1 -0
  193. package/browser/transaction/psbt/PSBTTypes.d.ts +1 -0
  194. package/browser/transaction/psbt/PSBTTypes.d.ts.map +1 -0
  195. package/browser/transaction/shared/P2TR_MS.d.ts +11 -2
  196. package/browser/transaction/shared/P2TR_MS.d.ts.map +1 -0
  197. package/browser/transaction/shared/TweakedTransaction.d.ts +274 -33
  198. package/browser/transaction/shared/TweakedTransaction.d.ts.map +1 -0
  199. package/browser/transaction/utils/WitnessUtils.d.ts +7 -1
  200. package/browser/transaction/utils/WitnessUtils.d.ts.map +1 -0
  201. package/browser/utils/BitcoinUtils.d.ts +19 -0
  202. package/browser/utils/BitcoinUtils.d.ts.map +1 -0
  203. package/browser/utils/BufferHelper.d.ts +1 -0
  204. package/browser/utils/BufferHelper.d.ts.map +1 -0
  205. package/browser/utils/StringToBuffer.d.ts +1 -0
  206. package/browser/utils/StringToBuffer.d.ts.map +1 -0
  207. package/browser/utils/lengths.d.ts +1 -0
  208. package/browser/utils/lengths.d.ts.map +1 -0
  209. package/browser/utils/types.d.ts +1 -0
  210. package/browser/utils/types.d.ts.map +1 -0
  211. package/browser/utxo/OPNetLimitedProvider.d.ts +37 -1
  212. package/browser/utxo/OPNetLimitedProvider.d.ts.map +1 -0
  213. package/browser/utxo/interfaces/BroadcastResponse.d.ts +1 -0
  214. package/browser/utxo/interfaces/BroadcastResponse.d.ts.map +1 -0
  215. package/browser/utxo/interfaces/IUTXO.d.ts +11 -5
  216. package/browser/utxo/interfaces/IUTXO.d.ts.map +1 -0
  217. package/browser/vendors.js +14351 -10031
  218. package/browser/verification/TapscriptVerificator.d.ts +10 -8
  219. package/browser/verification/TapscriptVerificator.d.ts.map +1 -0
  220. package/build/_version.d.ts +1 -0
  221. package/build/_version.d.ts.map +1 -0
  222. package/build/_version.js +1 -0
  223. package/build/_version.js.map +1 -0
  224. package/build/abi/ABICoder.d.ts +1 -1
  225. package/build/abi/ABICoder.d.ts.map +1 -0
  226. package/build/abi/ABICoder.js +9 -10
  227. package/build/abi/ABICoder.js.map +1 -0
  228. package/build/branded/Branded.d.ts +4 -0
  229. package/build/branded/Branded.d.ts.map +1 -0
  230. package/build/branded/Branded.js +2 -0
  231. package/build/branded/Branded.js.map +1 -0
  232. package/build/buffer/BinaryReader.d.ts +121 -2
  233. package/build/buffer/BinaryReader.d.ts.map +1 -0
  234. package/build/buffer/BinaryReader.js +129 -5
  235. package/build/buffer/BinaryReader.js.map +1 -0
  236. package/build/buffer/BinaryWriter.d.ts +52 -2
  237. package/build/buffer/BinaryWriter.d.ts.map +1 -0
  238. package/build/buffer/BinaryWriter.js +62 -2
  239. package/build/buffer/BinaryWriter.js.map +1 -0
  240. package/build/bytecode/Compressor.d.ts +12 -0
  241. package/build/bytecode/Compressor.d.ts.map +1 -0
  242. package/build/bytecode/Compressor.js +17 -5
  243. package/build/bytecode/Compressor.js.map +1 -0
  244. package/build/chain/ChainData.d.ts +2 -2
  245. package/build/chain/ChainData.d.ts.map +1 -0
  246. package/build/chain/ChainData.js +35 -17
  247. package/build/chain/ChainData.js.map +1 -0
  248. package/build/consensus/Consensus.d.ts +11 -3
  249. package/build/consensus/Consensus.d.ts.map +1 -0
  250. package/build/consensus/Consensus.js +8 -0
  251. package/build/consensus/Consensus.js.map +1 -0
  252. package/build/consensus/ConsensusConfig.d.ts +2 -1
  253. package/build/consensus/ConsensusConfig.d.ts.map +1 -0
  254. package/build/consensus/ConsensusConfig.js +1 -0
  255. package/build/consensus/ConsensusConfig.js.map +1 -0
  256. package/build/consensus/IConsensusConfig.d.ts +1 -0
  257. package/build/consensus/IConsensusConfig.d.ts.map +1 -0
  258. package/build/consensus/IConsensusConfig.js +2 -1
  259. package/build/consensus/IConsensusConfig.js.map +1 -0
  260. package/build/consensus/metadata/RoswellConsensus.d.ts +2 -1
  261. package/build/consensus/metadata/RoswellConsensus.d.ts.map +1 -0
  262. package/build/consensus/metadata/RoswellConsensus.js +2 -0
  263. package/build/consensus/metadata/RoswellConsensus.js.map +1 -0
  264. package/build/crypto/crypto.d.ts +1 -0
  265. package/build/crypto/crypto.d.ts.map +1 -0
  266. package/build/crypto/crypto.js +1 -0
  267. package/build/crypto/crypto.js.map +1 -0
  268. package/build/deterministic/AddressMap.d.ts +6 -1
  269. package/build/deterministic/AddressMap.d.ts.map +1 -0
  270. package/build/deterministic/AddressMap.js +8 -0
  271. package/build/deterministic/AddressMap.js.map +1 -0
  272. package/build/deterministic/AddressSet.d.ts +3 -1
  273. package/build/deterministic/AddressSet.d.ts.map +1 -0
  274. package/build/deterministic/AddressSet.js +7 -0
  275. package/build/deterministic/AddressSet.js.map +1 -0
  276. package/build/deterministic/CustomMap.d.ts +3 -1
  277. package/build/deterministic/CustomMap.d.ts.map +1 -0
  278. package/build/deterministic/CustomMap.js +65 -47
  279. package/build/deterministic/CustomMap.js.map +1 -0
  280. package/build/deterministic/DeterministicMap.d.ts +4 -2
  281. package/build/deterministic/DeterministicMap.d.ts.map +1 -0
  282. package/build/deterministic/DeterministicMap.js +24 -27
  283. package/build/deterministic/DeterministicMap.js.map +1 -0
  284. package/build/deterministic/DeterministicSet.d.ts +3 -1
  285. package/build/deterministic/DeterministicSet.d.ts.map +1 -0
  286. package/build/deterministic/DeterministicSet.js +6 -0
  287. package/build/deterministic/DeterministicSet.js.map +1 -0
  288. package/build/deterministic/ExtendedAddressMap.d.ts +7 -1
  289. package/build/deterministic/ExtendedAddressMap.d.ts.map +1 -0
  290. package/build/deterministic/ExtendedAddressMap.js +18 -2
  291. package/build/deterministic/ExtendedAddressMap.js.map +1 -0
  292. package/build/deterministic/FastMap.d.ts +7 -1
  293. package/build/deterministic/FastMap.d.ts.map +1 -0
  294. package/build/deterministic/FastMap.js +7 -2
  295. package/build/deterministic/FastMap.js.map +1 -0
  296. package/build/ecc/backend.d.ts +13 -0
  297. package/build/ecc/backend.d.ts.map +1 -0
  298. package/build/ecc/backend.js +15 -0
  299. package/build/ecc/backend.js.map +1 -0
  300. package/build/epoch/ChallengeSolution.d.ts +34 -2
  301. package/build/epoch/ChallengeSolution.d.ts.map +1 -0
  302. package/build/epoch/ChallengeSolution.js +52 -0
  303. package/build/epoch/ChallengeSolution.js.map +1 -0
  304. package/build/epoch/interfaces/IChallengeSolution.d.ts +14 -13
  305. package/build/epoch/interfaces/IChallengeSolution.d.ts.map +1 -0
  306. package/build/epoch/interfaces/IChallengeSolution.js +2 -1
  307. package/build/epoch/interfaces/IChallengeSolution.js.map +1 -0
  308. package/build/epoch/validator/EpochValidator.d.ts +38 -8
  309. package/build/epoch/validator/EpochValidator.d.ts.map +1 -0
  310. package/build/epoch/validator/EpochValidator.js +45 -19
  311. package/build/epoch/validator/EpochValidator.js.map +1 -0
  312. package/build/event/NetEvent.d.ts +1 -0
  313. package/build/event/NetEvent.d.ts.map +1 -0
  314. package/build/event/NetEvent.js +3 -0
  315. package/build/event/NetEvent.js.map +1 -0
  316. package/build/generators/AddressGenerator.d.ts +4 -3
  317. package/build/generators/AddressGenerator.d.ts.map +1 -0
  318. package/build/generators/AddressGenerator.js +9 -4
  319. package/build/generators/AddressGenerator.js.map +1 -0
  320. package/build/generators/Features.d.ts +4 -3
  321. package/build/generators/Features.d.ts.map +1 -0
  322. package/build/generators/Features.js +1 -0
  323. package/build/generators/Features.js.map +1 -0
  324. package/build/generators/Generator.d.ts +47 -11
  325. package/build/generators/Generator.d.ts.map +1 -0
  326. package/build/generators/Generator.js +48 -12
  327. package/build/generators/Generator.js.map +1 -0
  328. package/build/generators/MLDSAData.d.ts +1 -0
  329. package/build/generators/MLDSAData.d.ts.map +1 -0
  330. package/build/generators/MLDSAData.js +1 -0
  331. package/build/generators/MLDSAData.js.map +1 -0
  332. package/build/generators/builders/CalldataGenerator.d.ts +27 -6
  333. package/build/generators/builders/CalldataGenerator.d.ts.map +1 -0
  334. package/build/generators/builders/CalldataGenerator.js +33 -4
  335. package/build/generators/builders/CalldataGenerator.js.map +1 -0
  336. package/build/generators/builders/CustomGenerator.d.ts +13 -3
  337. package/build/generators/builders/CustomGenerator.d.ts.map +1 -0
  338. package/build/generators/builders/CustomGenerator.js +11 -0
  339. package/build/generators/builders/CustomGenerator.js.map +1 -0
  340. package/build/generators/builders/DeploymentGenerator.d.ts +17 -6
  341. package/build/generators/builders/DeploymentGenerator.d.ts.map +1 -0
  342. package/build/generators/builders/DeploymentGenerator.js +18 -2
  343. package/build/generators/builders/DeploymentGenerator.js.map +1 -0
  344. package/build/generators/builders/HashCommitmentGenerator.d.ts +166 -14
  345. package/build/generators/builders/HashCommitmentGenerator.d.ts.map +1 -0
  346. package/build/generators/builders/HashCommitmentGenerator.js +193 -27
  347. package/build/generators/builders/HashCommitmentGenerator.js.map +1 -0
  348. package/build/generators/builders/LegacyCalldataGenerator.d.ts +27 -5
  349. package/build/generators/builders/LegacyCalldataGenerator.d.ts.map +1 -0
  350. package/build/generators/builders/LegacyCalldataGenerator.js +35 -5
  351. package/build/generators/builders/LegacyCalldataGenerator.js.map +1 -0
  352. package/build/generators/builders/MultiSignGenerator.d.ts +6 -1
  353. package/build/generators/builders/MultiSignGenerator.d.ts.map +1 -0
  354. package/build/generators/builders/MultiSignGenerator.js +20 -10
  355. package/build/generators/builders/MultiSignGenerator.js.map +1 -0
  356. package/build/generators/builders/P2WDAGenerator.d.ts +44 -6
  357. package/build/generators/builders/P2WDAGenerator.d.ts.map +1 -0
  358. package/build/generators/builders/P2WDAGenerator.js +41 -2
  359. package/build/generators/builders/P2WDAGenerator.js.map +1 -0
  360. package/build/index.d.ts +1 -0
  361. package/build/index.d.ts.map +1 -0
  362. package/build/index.js +1 -0
  363. package/build/index.js.map +1 -0
  364. package/build/keypair/Address.d.ts +284 -14
  365. package/build/keypair/Address.d.ts.map +1 -0
  366. package/build/keypair/Address.js +446 -128
  367. package/build/keypair/Address.js.map +1 -0
  368. package/build/keypair/AddressVerificator.d.ts +7 -6
  369. package/build/keypair/AddressVerificator.d.ts.map +1 -0
  370. package/build/keypair/AddressVerificator.js +4 -5
  371. package/build/keypair/AddressVerificator.js.map +1 -0
  372. package/build/keypair/EcKeyPair.d.ts +185 -23
  373. package/build/keypair/EcKeyPair.d.ts.map +1 -0
  374. package/build/keypair/EcKeyPair.js +218 -50
  375. package/build/keypair/EcKeyPair.js.map +1 -0
  376. package/build/keypair/MessageSigner.d.ts +18 -17
  377. package/build/keypair/MessageSigner.d.ts.map +1 -0
  378. package/build/keypair/MessageSigner.js +34 -25
  379. package/build/keypair/MessageSigner.js.map +1 -0
  380. package/build/keypair/Secp256k1PointDeriver.d.ts +55 -0
  381. package/build/keypair/Secp256k1PointDeriver.d.ts.map +1 -0
  382. package/build/keypair/Secp256k1PointDeriver.js +66 -0
  383. package/build/keypair/Secp256k1PointDeriver.js.map +1 -0
  384. package/build/keypair/Wallet.d.ts +29 -15
  385. package/build/keypair/Wallet.d.ts.map +1 -0
  386. package/build/keypair/Wallet.js +46 -14
  387. package/build/keypair/Wallet.js.map +1 -0
  388. package/build/keypair/interfaces/IWallet.d.ts +19 -0
  389. package/build/keypair/interfaces/IWallet.d.ts.map +1 -0
  390. package/build/keypair/interfaces/IWallet.js +1 -0
  391. package/build/keypair/interfaces/IWallet.js.map +1 -0
  392. package/build/metadata/ContractBaseMetadata.d.ts +10 -2
  393. package/build/metadata/ContractBaseMetadata.d.ts.map +1 -0
  394. package/build/metadata/ContractBaseMetadata.js +10 -1
  395. package/build/metadata/ContractBaseMetadata.js.map +1 -0
  396. package/build/mnemonic/BIPStandard.d.ts +59 -0
  397. package/build/mnemonic/BIPStandard.d.ts.map +1 -0
  398. package/build/mnemonic/BIPStandard.js +59 -0
  399. package/build/mnemonic/BIPStandard.js.map +1 -0
  400. package/build/mnemonic/Mnemonic.d.ts +16 -4
  401. package/build/mnemonic/Mnemonic.d.ts.map +1 -0
  402. package/build/mnemonic/Mnemonic.js +35 -8
  403. package/build/mnemonic/Mnemonic.js.map +1 -0
  404. package/build/mnemonic/MnemonicStrength.d.ts +6 -0
  405. package/build/mnemonic/MnemonicStrength.d.ts.map +1 -0
  406. package/build/mnemonic/MnemonicStrength.js +6 -0
  407. package/build/mnemonic/MnemonicStrength.js.map +1 -0
  408. package/build/network/ChainId.d.ts +1 -0
  409. package/build/network/ChainId.d.ts.map +1 -0
  410. package/build/network/ChainId.js +1 -0
  411. package/build/network/ChainId.js.map +1 -0
  412. package/build/opnet.d.ts +26 -3
  413. package/build/opnet.d.ts.map +1 -0
  414. package/build/opnet.js +23 -0
  415. package/build/opnet.js.map +1 -0
  416. package/build/p2wda/P2WDADetector.d.ts +38 -11
  417. package/build/p2wda/P2WDADetector.d.ts.map +1 -0
  418. package/build/p2wda/P2WDADetector.js +43 -10
  419. package/build/p2wda/P2WDADetector.js.map +1 -0
  420. package/build/polyfill/disposable.d.ts +16 -0
  421. package/build/polyfill/disposable.d.ts.map +1 -0
  422. package/build/polyfill/disposable.js +23 -0
  423. package/build/polyfill/disposable.js.map +1 -0
  424. package/build/signer/AddressRotation.d.ts +37 -1
  425. package/build/signer/AddressRotation.d.ts.map +1 -0
  426. package/build/signer/AddressRotation.js +16 -0
  427. package/build/signer/AddressRotation.js.map +1 -0
  428. package/build/signer/IRotationSigner.d.ts +27 -3
  429. package/build/signer/IRotationSigner.d.ts.map +1 -0
  430. package/build/signer/IRotationSigner.js +2 -1
  431. package/build/signer/IRotationSigner.js.map +1 -0
  432. package/build/signer/ParallelSignerAdapter.d.ts +14 -0
  433. package/build/signer/ParallelSignerAdapter.d.ts.map +1 -0
  434. package/build/signer/ParallelSignerAdapter.js +51 -0
  435. package/build/signer/ParallelSignerAdapter.js.map +1 -0
  436. package/build/signer/SignerUtils.d.ts +11 -4
  437. package/build/signer/SignerUtils.d.ts.map +1 -0
  438. package/build/signer/SignerUtils.js +16 -0
  439. package/build/signer/SignerUtils.js.map +1 -0
  440. package/build/signer/TweakedSigner.d.ts +28 -4
  441. package/build/signer/TweakedSigner.d.ts.map +1 -0
  442. package/build/signer/TweakedSigner.js +23 -6
  443. package/build/signer/TweakedSigner.js.map +1 -0
  444. package/build/transaction/ContractAddress.d.ts +2 -2
  445. package/build/transaction/ContractAddress.d.ts.map +1 -0
  446. package/build/transaction/ContractAddress.js +4 -8
  447. package/build/transaction/ContractAddress.js.map +1 -0
  448. package/build/transaction/TransactionFactory.d.ts +147 -9
  449. package/build/transaction/TransactionFactory.d.ts.map +1 -0
  450. package/build/transaction/TransactionFactory.js +145 -26
  451. package/build/transaction/TransactionFactory.js.map +1 -0
  452. package/build/transaction/browser/BrowserSignerBase.d.ts +12 -6
  453. package/build/transaction/browser/BrowserSignerBase.d.ts.map +1 -0
  454. package/build/transaction/browser/BrowserSignerBase.js +7 -0
  455. package/build/transaction/browser/BrowserSignerBase.js.map +1 -0
  456. package/build/transaction/browser/WalletNetworks.d.ts +1 -0
  457. package/build/transaction/browser/WalletNetworks.d.ts.map +1 -0
  458. package/build/transaction/browser/WalletNetworks.js +1 -0
  459. package/build/transaction/browser/WalletNetworks.js.map +1 -0
  460. package/build/transaction/browser/Web3Provider.d.ts +30 -3
  461. package/build/transaction/browser/Web3Provider.d.ts.map +1 -0
  462. package/build/transaction/browser/Web3Provider.js +1 -0
  463. package/build/transaction/browser/Web3Provider.js.map +1 -0
  464. package/build/transaction/browser/extensions/UnisatSigner.d.ts +11 -9
  465. package/build/transaction/browser/extensions/UnisatSigner.d.ts.map +1 -0
  466. package/build/transaction/browser/extensions/UnisatSigner.js +27 -17
  467. package/build/transaction/browser/extensions/UnisatSigner.js.map +1 -0
  468. package/build/transaction/browser/extensions/XverseSigner.d.ts +10 -8
  469. package/build/transaction/browser/extensions/XverseSigner.d.ts.map +1 -0
  470. package/build/transaction/browser/extensions/XverseSigner.js +25 -15
  471. package/build/transaction/browser/extensions/XverseSigner.js.map +1 -0
  472. package/build/transaction/browser/types/OPWallet.d.ts +12 -2
  473. package/build/transaction/browser/types/OPWallet.d.ts.map +1 -0
  474. package/build/transaction/browser/types/OPWallet.js +4 -0
  475. package/build/transaction/browser/types/OPWallet.js.map +1 -0
  476. package/build/transaction/browser/types/Unisat.d.ts +2 -1
  477. package/build/transaction/browser/types/Unisat.d.ts.map +1 -0
  478. package/build/transaction/browser/types/Unisat.js +2 -0
  479. package/build/transaction/browser/types/Unisat.js.map +1 -0
  480. package/build/transaction/browser/types/Xverse.d.ts +1 -0
  481. package/build/transaction/browser/types/Xverse.d.ts.map +1 -0
  482. package/build/transaction/browser/types/Xverse.js +1 -0
  483. package/build/transaction/browser/types/Xverse.js.map +1 -0
  484. package/build/transaction/builders/CancelTransaction.d.ts +31 -6
  485. package/build/transaction/builders/CancelTransaction.d.ts.map +1 -0
  486. package/build/transaction/builders/CancelTransaction.js +116 -33
  487. package/build/transaction/builders/CancelTransaction.js.map +1 -0
  488. package/build/transaction/builders/ChallengeSolutionTransaction.d.ts +1 -0
  489. package/build/transaction/builders/ChallengeSolutionTransaction.d.ts.map +1 -0
  490. package/build/transaction/builders/ChallengeSolutionTransaction.js +88 -0
  491. package/build/transaction/builders/ChallengeSolutionTransaction.js.map +1 -0
  492. package/build/transaction/builders/ConsolidatedInteractionTransaction.d.ts +140 -13
  493. package/build/transaction/builders/ConsolidatedInteractionTransaction.d.ts.map +1 -0
  494. package/build/transaction/builders/ConsolidatedInteractionTransaction.js +197 -20
  495. package/build/transaction/builders/ConsolidatedInteractionTransaction.js.map +1 -0
  496. package/build/transaction/builders/CustomScriptTransaction.d.ts +108 -8
  497. package/build/transaction/builders/CustomScriptTransaction.d.ts.map +1 -0
  498. package/build/transaction/builders/CustomScriptTransaction.js +176 -39
  499. package/build/transaction/builders/CustomScriptTransaction.js.map +1 -0
  500. package/build/transaction/builders/DeploymentTransaction.d.ts +120 -9
  501. package/build/transaction/builders/DeploymentTransaction.d.ts.map +1 -0
  502. package/build/transaction/builders/DeploymentTransaction.js +194 -51
  503. package/build/transaction/builders/DeploymentTransaction.js.map +1 -0
  504. package/build/transaction/builders/FundingTransaction.d.ts +5 -4
  505. package/build/transaction/builders/FundingTransaction.d.ts.map +1 -0
  506. package/build/transaction/builders/FundingTransaction.js +15 -8
  507. package/build/transaction/builders/FundingTransaction.js.map +1 -0
  508. package/build/transaction/builders/InteractionTransaction.d.ts +14 -5
  509. package/build/transaction/builders/InteractionTransaction.d.ts.map +1 -0
  510. package/build/transaction/builders/InteractionTransaction.js +18 -5
  511. package/build/transaction/builders/InteractionTransaction.js.map +1 -0
  512. package/build/transaction/builders/InteractionTransactionP2WDA.d.ts +58 -7
  513. package/build/transaction/builders/InteractionTransactionP2WDA.d.ts.map +1 -0
  514. package/build/transaction/builders/InteractionTransactionP2WDA.js +95 -18
  515. package/build/transaction/builders/InteractionTransactionP2WDA.js.map +1 -0
  516. package/build/transaction/builders/MultiSignTransaction.d.ts +126 -17
  517. package/build/transaction/builders/MultiSignTransaction.d.ts.map +1 -0
  518. package/build/transaction/builders/MultiSignTransaction.js +201 -76
  519. package/build/transaction/builders/MultiSignTransaction.js.map +1 -0
  520. package/build/transaction/builders/SharedInteractionTransaction.d.ts +106 -18
  521. package/build/transaction/builders/SharedInteractionTransaction.d.ts.map +1 -0
  522. package/build/transaction/builders/SharedInteractionTransaction.js +158 -40
  523. package/build/transaction/builders/SharedInteractionTransaction.js.map +1 -0
  524. package/build/transaction/builders/TransactionBuilder.d.ts +249 -19
  525. package/build/transaction/builders/TransactionBuilder.d.ts.map +1 -0
  526. package/build/transaction/builders/TransactionBuilder.js +375 -60
  527. package/build/transaction/builders/TransactionBuilder.js.map +1 -0
  528. package/build/transaction/enums/TransactionType.d.ts +1 -0
  529. package/build/transaction/enums/TransactionType.d.ts.map +1 -0
  530. package/build/transaction/enums/TransactionType.js +1 -0
  531. package/build/transaction/enums/TransactionType.js.map +1 -0
  532. package/build/transaction/interfaces/ICancelTransactionParameters.d.ts +3 -2
  533. package/build/transaction/interfaces/ICancelTransactionParameters.d.ts.map +1 -0
  534. package/build/transaction/interfaces/ICancelTransactionParameters.js +1 -0
  535. package/build/transaction/interfaces/ICancelTransactionParameters.js.map +1 -0
  536. package/build/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +48 -5
  537. package/build/transaction/interfaces/IConsolidatedTransactionParameters.d.ts.map +1 -0
  538. package/build/transaction/interfaces/IConsolidatedTransactionParameters.js +1 -0
  539. package/build/transaction/interfaces/IConsolidatedTransactionParameters.js.map +1 -0
  540. package/build/transaction/interfaces/ICustomTransactionParameters.d.ts +7 -5
  541. package/build/transaction/interfaces/ICustomTransactionParameters.d.ts.map +1 -0
  542. package/build/transaction/interfaces/ICustomTransactionParameters.js +1 -0
  543. package/build/transaction/interfaces/ICustomTransactionParameters.js.map +1 -0
  544. package/build/transaction/interfaces/ITransactionParameters.d.ts +27 -15
  545. package/build/transaction/interfaces/ITransactionParameters.d.ts.map +1 -0
  546. package/build/transaction/interfaces/ITransactionParameters.js +1 -0
  547. package/build/transaction/interfaces/ITransactionParameters.js.map +1 -0
  548. package/build/transaction/interfaces/ITransactionResponses.d.ts +3 -2
  549. package/build/transaction/interfaces/ITransactionResponses.d.ts.map +1 -0
  550. package/build/transaction/interfaces/ITransactionResponses.js +1 -0
  551. package/build/transaction/interfaces/ITransactionResponses.js.map +1 -0
  552. package/build/transaction/interfaces/ITweakedTransactionData.d.ts +21 -8
  553. package/build/transaction/interfaces/ITweakedTransactionData.d.ts.map +1 -0
  554. package/build/transaction/interfaces/ITweakedTransactionData.js +1 -0
  555. package/build/transaction/interfaces/ITweakedTransactionData.js.map +1 -0
  556. package/build/transaction/interfaces/IWeb3ProviderTypes.d.ts +29 -3
  557. package/build/transaction/interfaces/IWeb3ProviderTypes.d.ts.map +1 -0
  558. package/build/transaction/interfaces/IWeb3ProviderTypes.js +2 -1
  559. package/build/transaction/interfaces/IWeb3ProviderTypes.js.map +1 -0
  560. package/build/transaction/interfaces/Tap.d.ts +4 -3
  561. package/build/transaction/interfaces/Tap.d.ts.map +1 -0
  562. package/build/transaction/interfaces/Tap.js +1 -0
  563. package/build/transaction/interfaces/Tap.js.map +1 -0
  564. package/build/transaction/mineable/IP2WSHAddress.d.ts +2 -1
  565. package/build/transaction/mineable/IP2WSHAddress.d.ts.map +1 -0
  566. package/build/transaction/mineable/IP2WSHAddress.js +1 -0
  567. package/build/transaction/mineable/IP2WSHAddress.js.map +1 -0
  568. package/build/transaction/mineable/TimelockGenerator.d.ts +13 -4
  569. package/build/transaction/mineable/TimelockGenerator.d.ts.map +1 -0
  570. package/build/transaction/mineable/TimelockGenerator.js +12 -3
  571. package/build/transaction/mineable/TimelockGenerator.js.map +1 -0
  572. package/build/transaction/offline/OfflineTransactionManager.d.ts +193 -12
  573. package/build/transaction/offline/OfflineTransactionManager.d.ts.map +1 -0
  574. package/build/transaction/offline/OfflineTransactionManager.js +192 -8
  575. package/build/transaction/offline/OfflineTransactionManager.js.map +1 -0
  576. package/build/transaction/offline/TransactionReconstructor.d.ts +56 -6
  577. package/build/transaction/offline/TransactionReconstructor.d.ts.map +1 -0
  578. package/build/transaction/offline/TransactionReconstructor.js +111 -75
  579. package/build/transaction/offline/TransactionReconstructor.js.map +1 -0
  580. package/build/transaction/offline/TransactionSerializer.d.ts +54 -3
  581. package/build/transaction/offline/TransactionSerializer.d.ts.map +1 -0
  582. package/build/transaction/offline/TransactionSerializer.js +206 -95
  583. package/build/transaction/offline/TransactionSerializer.js.map +1 -0
  584. package/build/transaction/offline/TransactionStateCapture.d.ts +66 -7
  585. package/build/transaction/offline/TransactionStateCapture.d.ts.map +1 -0
  586. package/build/transaction/offline/TransactionStateCapture.js +124 -60
  587. package/build/transaction/offline/TransactionStateCapture.js.map +1 -0
  588. package/build/transaction/offline/interfaces/ISerializableState.d.ts +72 -1
  589. package/build/transaction/offline/interfaces/ISerializableState.d.ts.map +1 -0
  590. package/build/transaction/offline/interfaces/ISerializableState.js +10 -1
  591. package/build/transaction/offline/interfaces/ISerializableState.js.map +1 -0
  592. package/build/transaction/offline/interfaces/ITypeSpecificData.d.ts +77 -1
  593. package/build/transaction/offline/interfaces/ITypeSpecificData.d.ts.map +1 -0
  594. package/build/transaction/offline/interfaces/ITypeSpecificData.js +19 -0
  595. package/build/transaction/offline/interfaces/ITypeSpecificData.js.map +1 -0
  596. package/build/transaction/psbt/PSBTTypes.d.ts +1 -0
  597. package/build/transaction/psbt/PSBTTypes.d.ts.map +1 -0
  598. package/build/transaction/psbt/PSBTTypes.js +1 -0
  599. package/build/transaction/psbt/PSBTTypes.js.map +1 -0
  600. package/build/transaction/shared/P2TR_MS.d.ts +11 -2
  601. package/build/transaction/shared/P2TR_MS.d.ts.map +1 -0
  602. package/build/transaction/shared/P2TR_MS.js +10 -0
  603. package/build/transaction/shared/P2TR_MS.js.map +1 -0
  604. package/build/transaction/shared/TweakedTransaction.d.ts +281 -38
  605. package/build/transaction/shared/TweakedTransaction.d.ts.map +1 -0
  606. package/build/transaction/shared/TweakedTransaction.js +576 -114
  607. package/build/transaction/shared/TweakedTransaction.js.map +1 -0
  608. package/build/transaction/utils/WitnessUtils.d.ts +7 -1
  609. package/build/transaction/utils/WitnessUtils.d.ts.map +1 -0
  610. package/build/transaction/utils/WitnessUtils.js +17 -3
  611. package/build/transaction/utils/WitnessUtils.js.map +1 -0
  612. package/build/tsconfig.build.tsbuildinfo +1 -1
  613. package/build/utils/BitcoinUtils.d.ts +19 -0
  614. package/build/utils/BitcoinUtils.d.ts.map +1 -0
  615. package/build/utils/BitcoinUtils.js +19 -0
  616. package/build/utils/BitcoinUtils.js.map +1 -0
  617. package/build/utils/BufferHelper.d.ts +2 -1
  618. package/build/utils/BufferHelper.d.ts.map +1 -0
  619. package/build/utils/BufferHelper.js +38 -32
  620. package/build/utils/BufferHelper.js.map +1 -0
  621. package/build/utils/StringToBuffer.d.ts +1 -0
  622. package/build/utils/StringToBuffer.d.ts.map +1 -0
  623. package/build/utils/StringToBuffer.js +1 -0
  624. package/build/utils/StringToBuffer.js.map +1 -0
  625. package/build/utils/lengths.d.ts +1 -0
  626. package/build/utils/lengths.d.ts.map +1 -0
  627. package/build/utils/lengths.js +1 -0
  628. package/build/utils/lengths.js.map +1 -0
  629. package/build/utils/types.d.ts +1 -0
  630. package/build/utils/types.d.ts.map +1 -0
  631. package/build/utils/types.js +2 -1
  632. package/build/utils/types.js.map +1 -0
  633. package/build/utxo/OPNetLimitedProvider.d.ts +39 -3
  634. package/build/utxo/OPNetLimitedProvider.d.ts.map +1 -0
  635. package/build/utxo/OPNetLimitedProvider.js +43 -5
  636. package/build/utxo/OPNetLimitedProvider.js.map +1 -0
  637. package/build/utxo/interfaces/BroadcastResponse.d.ts +1 -0
  638. package/build/utxo/interfaces/BroadcastResponse.d.ts.map +1 -0
  639. package/build/utxo/interfaces/BroadcastResponse.js +1 -0
  640. package/build/utxo/interfaces/BroadcastResponse.js.map +1 -0
  641. package/build/utxo/interfaces/IUTXO.d.ts +13 -7
  642. package/build/utxo/interfaces/IUTXO.d.ts.map +1 -0
  643. package/build/utxo/interfaces/IUTXO.js +1 -0
  644. package/build/utxo/interfaces/IUTXO.js.map +1 -0
  645. package/build/verification/TapscriptVerificator.d.ts +12 -10
  646. package/build/verification/TapscriptVerificator.d.ts.map +1 -0
  647. package/build/verification/TapscriptVerificator.js +28 -38
  648. package/build/verification/TapscriptVerificator.js.map +1 -0
  649. package/eslint.config.js +0 -1
  650. package/package.json +12 -35
  651. package/src/abi/ABICoder.ts +0 -13
  652. package/src/branded/Branded.ts +5 -0
  653. package/src/buffer/BinaryReader.ts +7 -7
  654. package/src/buffer/BinaryWriter.ts +29 -24
  655. package/src/bytecode/Compressor.ts +1 -1
  656. package/src/chain/ChainData.ts +34 -27
  657. package/src/consensus/ConsensusConfig.ts +1 -1
  658. package/src/consensus/IConsensusConfig.ts +0 -17
  659. package/src/consensus/metadata/RoswellConsensus.ts +1 -17
  660. package/src/deterministic/AddressMap.ts +5 -1
  661. package/src/deterministic/AddressSet.ts +5 -1
  662. package/src/deterministic/CustomMap.ts +6 -2
  663. package/src/deterministic/DeterministicMap.ts +8 -4
  664. package/src/deterministic/DeterministicSet.ts +6 -2
  665. package/src/deterministic/ExtendedAddressMap.ts +9 -4
  666. package/src/deterministic/FastMap.ts +9 -5
  667. package/src/ecc/backend.ts +17 -0
  668. package/src/epoch/ChallengeSolution.ts +3 -3
  669. package/src/epoch/interfaces/IChallengeSolution.ts +13 -13
  670. package/src/epoch/validator/EpochValidator.ts +24 -43
  671. package/src/generators/AddressGenerator.ts +4 -7
  672. package/src/generators/Features.ts +3 -3
  673. package/src/generators/Generator.ts +42 -26
  674. package/src/generators/builders/CalldataGenerator.ts +26 -24
  675. package/src/generators/builders/CustomGenerator.ts +4 -4
  676. package/src/generators/builders/DeploymentGenerator.ts +25 -23
  677. package/src/generators/builders/HashCommitmentGenerator.ts +31 -31
  678. package/src/generators/builders/LegacyCalldataGenerator.ts +26 -24
  679. package/src/generators/builders/MultiSignGenerator.ts +12 -12
  680. package/src/generators/builders/P2WDAGenerator.ts +10 -10
  681. package/src/keypair/Address.ts +114 -71
  682. package/src/keypair/AddressVerificator.ts +14 -148
  683. package/src/keypair/EcKeyPair.ts +104 -116
  684. package/src/keypair/MessageSigner.ts +70 -150
  685. package/src/keypair/Wallet.ts +56 -241
  686. package/src/metadata/ContractBaseMetadata.ts +2 -2
  687. package/src/mnemonic/Mnemonic.ts +31 -222
  688. package/src/opnet.ts +12 -6
  689. package/src/p2wda/P2WDADetector.ts +23 -72
  690. package/src/polyfill/disposable.ts +29 -0
  691. package/src/signer/AddressRotation.ts +1 -1
  692. package/src/signer/IRotationSigner.ts +3 -3
  693. package/src/signer/ParallelSignerAdapter.ts +59 -0
  694. package/src/signer/SignerUtils.ts +4 -4
  695. package/src/signer/TweakedSigner.ts +26 -14
  696. package/src/transaction/ContractAddress.ts +3 -7
  697. package/src/transaction/TransactionFactory.ts +28 -50
  698. package/src/transaction/browser/BrowserSignerBase.ts +12 -6
  699. package/src/transaction/browser/Web3Provider.ts +3 -3
  700. package/src/transaction/browser/extensions/UnisatSigner.ts +52 -48
  701. package/src/transaction/browser/extensions/XverseSigner.ts +55 -38
  702. package/src/transaction/browser/types/OPWallet.ts +2 -2
  703. package/src/transaction/browser/types/Unisat.ts +1 -1
  704. package/src/transaction/builders/CancelTransaction.ts +59 -24
  705. package/src/transaction/builders/ChallengeSolutionTransaction.ts +3 -3
  706. package/src/transaction/builders/ConsolidatedInteractionTransaction.ts +39 -34
  707. package/src/transaction/builders/CustomScriptTransaction.ts +79 -56
  708. package/src/transaction/builders/DeploymentTransaction.ts +82 -63
  709. package/src/transaction/builders/FundingTransaction.ts +11 -11
  710. package/src/transaction/builders/InteractionTransaction.ts +10 -10
  711. package/src/transaction/builders/InteractionTransactionP2WDA.ts +38 -40
  712. package/src/transaction/builders/MultiSignTransaction.ts +68 -61
  713. package/src/transaction/builders/SharedInteractionTransaction.ts +81 -57
  714. package/src/transaction/builders/TransactionBuilder.ts +99 -81
  715. package/src/transaction/interfaces/ICancelTransactionParameters.ts +2 -2
  716. package/src/transaction/interfaces/IConsolidatedTransactionParameters.ts +5 -5
  717. package/src/transaction/interfaces/ICustomTransactionParameters.ts +5 -5
  718. package/src/transaction/interfaces/ITransactionParameters.ts +15 -15
  719. package/src/transaction/interfaces/ITransactionResponses.ts +2 -2
  720. package/src/transaction/interfaces/ITweakedTransactionData.ts +17 -8
  721. package/src/transaction/interfaces/IWeb3ProviderTypes.ts +3 -3
  722. package/src/transaction/interfaces/Tap.ts +3 -3
  723. package/src/transaction/mineable/IP2WSHAddress.ts +1 -1
  724. package/src/transaction/mineable/TimelockGenerator.ts +19 -12
  725. package/src/transaction/offline/OfflineTransactionManager.ts +22 -23
  726. package/src/transaction/offline/TransactionReconstructor.ts +83 -91
  727. package/src/transaction/offline/TransactionSerializer.ts +151 -101
  728. package/src/transaction/offline/TransactionStateCapture.ts +83 -79
  729. package/src/transaction/offline/interfaces/ISerializableState.ts +1 -1
  730. package/src/transaction/offline/interfaces/ITypeSpecificData.ts +1 -1
  731. package/src/transaction/shared/P2TR_MS.ts +4 -4
  732. package/src/transaction/shared/TweakedTransaction.ts +326 -124
  733. package/src/transaction/utils/WitnessUtils.ts +18 -9
  734. package/src/utils/BufferHelper.ts +39 -37
  735. package/src/utxo/OPNetLimitedProvider.ts +9 -9
  736. package/src/utxo/interfaces/IUTXO.ts +7 -7
  737. package/src/verification/TapscriptVerificator.ts +73 -86
  738. package/test/address-rotation.test.ts +24 -24
  739. package/test/address.test.ts +12 -12
  740. package/test/addressmap.test.ts +30 -30
  741. package/test/binary-reader-writer.test.ts +8 -8
  742. package/test/browser/offline-transaction.test.ts +2206 -0
  743. package/test/browser/parallel-signing.test.ts +316 -0
  744. package/test/browser/setup.ts +11 -0
  745. package/test/browser/transaction-signing.test.ts +416 -0
  746. package/test/buffer-helper.test.ts +287 -0
  747. package/test/derivePath.test.ts +4 -3
  748. package/test/disposable.test.ts +279 -0
  749. package/test/fastmap-setall.test.ts +1 -1
  750. package/test/fastmap.test.ts +3 -3
  751. package/test/messagesigner-mldsa.test.ts +3 -3
  752. package/test/messagesigner-schnorr.test.ts +9 -9
  753. package/test/offline-transaction.test.ts +461 -288
  754. package/test/old/FastBigIntMap.ts +3 -3
  755. package/test/oldfastmap.test.ts +6 -6
  756. package/test/transaction-builders.test.ts +321 -0
  757. package/tsconfig.base.json +34 -18
  758. package/tsconfig.browser.json +15 -0
  759. package/tsconfig.json +3 -8
  760. package/vite.config.browser.ts +4 -5
  761. package/vitest.config.browser.ts +68 -0
  762. package/vitest.config.ts +1 -1
  763. package/browser/valibot.js +0 -4948
  764. package/tsconfig.webpack.json +0 -18
@@ -0,0 +1,2206 @@
1
+ import { describe, expect, it, beforeAll } from 'vitest';
2
+ import { networks, payments, toHex, fromHex } from '@btc-vision/bitcoin';
3
+ import { type UniversalSigner } from '@btc-vision/ecpair';
4
+ import { doubleSha256 } from './setup.js';
5
+ import {
6
+ // Core offline signing exports
7
+ TransactionSerializer,
8
+ TransactionStateCapture,
9
+ TransactionReconstructor,
10
+ OfflineTransactionManager,
11
+ SERIALIZATION_FORMAT_VERSION,
12
+ isFundingSpecificData,
13
+ isDeploymentSpecificData,
14
+ isInteractionSpecificData,
15
+ isMultiSigSpecificData,
16
+ isCustomScriptSpecificData,
17
+ isCancelSpecificData,
18
+ // Transaction types
19
+ TransactionType,
20
+ FundingTransaction,
21
+ // Utilities
22
+ EcKeyPair,
23
+ createSignerMap,
24
+ createAddressRotation,
25
+ ChainId,
26
+ currentConsensus,
27
+ } from '../build/opnet.js';
28
+ import type {
29
+ ReconstructionOptions,
30
+ ISerializableTransactionState,
31
+ SerializedUTXO,
32
+ SerializedOutput,
33
+ SerializedBaseParams,
34
+ PrecomputedData,
35
+ FundingSpecificData,
36
+ DeploymentSpecificData,
37
+ InteractionSpecificData,
38
+ MultiSigSpecificData,
39
+ CustomScriptSpecificData,
40
+ CancelSpecificData,
41
+ UTXO,
42
+ } from '../build/opnet.js';
43
+
44
+ describe('Offline Transaction Signing', () => {
45
+ const network = networks.regtest;
46
+
47
+ // Test keypairs
48
+ let signer1: UniversalSigner;
49
+ let signer2: UniversalSigner;
50
+ let signer3: UniversalSigner;
51
+ let defaultSigner: UniversalSigner;
52
+
53
+ let address1: string;
54
+ let address2: string;
55
+ let address3: string;
56
+ let defaultAddress: string;
57
+
58
+ beforeAll(() => {
59
+ signer1 = EcKeyPair.generateRandomKeyPair(network);
60
+ signer2 = EcKeyPair.generateRandomKeyPair(network);
61
+ signer3 = EcKeyPair.generateRandomKeyPair(network);
62
+ defaultSigner = EcKeyPair.generateRandomKeyPair(network);
63
+
64
+ address1 = EcKeyPair.getTaprootAddress(signer1, network);
65
+ address2 = EcKeyPair.getTaprootAddress(signer2, network);
66
+ address3 = EcKeyPair.getTaprootAddress(signer3, network);
67
+ defaultAddress = EcKeyPair.getTaprootAddress(defaultSigner, network);
68
+ });
69
+
70
+ // Helper to create a taproot UTXO
71
+ const createTaprootUtxo = (
72
+ address: string,
73
+ value: bigint,
74
+ txId: string = '0'.repeat(64),
75
+ index: number = 0,
76
+ ): UTXO => {
77
+ const p2tr = payments.p2tr({ address, network });
78
+ return {
79
+ transactionId: txId,
80
+ outputIndex: index,
81
+ value,
82
+ scriptPubKey: {
83
+ hex: toHex(p2tr.output as Uint8Array),
84
+ address,
85
+ },
86
+ };
87
+ };
88
+
89
+ // Helper to create mock serialized state
90
+ const createMockSerializedState = (
91
+ type: TransactionType = TransactionType.FUNDING,
92
+ overrides: Partial<ISerializableTransactionState> = {},
93
+ ): ISerializableTransactionState => {
94
+ const baseState: ISerializableTransactionState = {
95
+ header: {
96
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
97
+ consensusVersion: currentConsensus,
98
+ transactionType: type,
99
+ chainId: ChainId.Bitcoin,
100
+ timestamp: Date.now(),
101
+ },
102
+ baseParams: {
103
+ from: address1,
104
+ to: address2,
105
+ feeRate: 10,
106
+ priorityFee: '1000',
107
+ gasSatFee: '500',
108
+ networkName: 'regtest',
109
+ txVersion: 2,
110
+ anchor: false,
111
+ },
112
+ utxos: [
113
+ {
114
+ transactionId: '0'.repeat(64),
115
+ outputIndex: 0,
116
+ value: '100000',
117
+ scriptPubKeyHex: toHex(payments.p2tr({ address: address1, network }).output as Uint8Array),
118
+ scriptPubKeyAddress: address1,
119
+ },
120
+ ],
121
+ optionalInputs: [],
122
+ optionalOutputs: [],
123
+ addressRotationEnabled: false,
124
+ signerMappings: [],
125
+ typeSpecificData: {
126
+ type: TransactionType.FUNDING,
127
+ amount: '50000',
128
+ splitInputsInto: 1,
129
+ } as FundingSpecificData,
130
+ precomputedData: {},
131
+ };
132
+
133
+ return { ...baseState, ...overrides };
134
+ };
135
+
136
+ describe('TransactionSerializer', () => {
137
+ describe('serialize/deserialize', () => {
138
+ it('should serialize and deserialize a basic funding transaction state', () => {
139
+ const state = createMockSerializedState(TransactionType.FUNDING);
140
+
141
+ const serialized = TransactionSerializer.serialize(state);
142
+ expect(serialized).toBeInstanceOf(Uint8Array);
143
+ expect(serialized.length).toBeGreaterThan(32); // At least checksum size
144
+
145
+ const deserialized = TransactionSerializer.deserialize(serialized);
146
+ expect(deserialized.header.transactionType).toBe(TransactionType.FUNDING);
147
+ expect(deserialized.baseParams.from).toBe(state.baseParams.from);
148
+ expect(deserialized.baseParams.feeRate).toBe(state.baseParams.feeRate);
149
+ });
150
+
151
+ it('should preserve all header fields', () => {
152
+ const state = createMockSerializedState(TransactionType.FUNDING, {
153
+ header: {
154
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
155
+ consensusVersion: currentConsensus,
156
+ transactionType: TransactionType.FUNDING,
157
+ chainId: ChainId.Bitcoin,
158
+ timestamp: 1234567890123,
159
+ },
160
+ });
161
+
162
+ const deserialized = TransactionSerializer.deserialize(
163
+ TransactionSerializer.serialize(state),
164
+ );
165
+
166
+ expect(deserialized.header.formatVersion).toBe(SERIALIZATION_FORMAT_VERSION);
167
+ expect(deserialized.header.consensusVersion).toBe(currentConsensus);
168
+ expect(deserialized.header.transactionType).toBe(TransactionType.FUNDING);
169
+ expect(deserialized.header.chainId).toBe(ChainId.Bitcoin);
170
+ expect(deserialized.header.timestamp).toBe(1234567890123);
171
+ });
172
+
173
+ it('should preserve all base params fields', () => {
174
+ const baseParams: SerializedBaseParams = {
175
+ from: address1,
176
+ to: address2,
177
+ feeRate: 15.5, // Test decimal fee rate
178
+ priorityFee: '2000',
179
+ gasSatFee: '1000',
180
+ networkName: 'testnet',
181
+ txVersion: 2,
182
+ note: toHex(new TextEncoder().encode('test note')),
183
+ anchor: true,
184
+ debugFees: true,
185
+ };
186
+ const state = createMockSerializedState(TransactionType.FUNDING, {
187
+ baseParams,
188
+ });
189
+
190
+ const deserialized = TransactionSerializer.deserialize(
191
+ TransactionSerializer.serialize(state),
192
+ );
193
+
194
+ expect(deserialized.baseParams.from).toBe(baseParams.from);
195
+ expect(deserialized.baseParams.to).toBe(baseParams.to);
196
+ expect(deserialized.baseParams.feeRate).toBeCloseTo(baseParams.feeRate, 3);
197
+ expect(deserialized.baseParams.priorityFee).toBe(baseParams.priorityFee);
198
+ expect(deserialized.baseParams.gasSatFee).toBe(baseParams.gasSatFee);
199
+ expect(deserialized.baseParams.networkName).toBe(baseParams.networkName);
200
+ expect(deserialized.baseParams.txVersion).toBe(baseParams.txVersion);
201
+ expect(deserialized.baseParams.note).toBe(baseParams.note);
202
+ expect(deserialized.baseParams.anchor).toBe(baseParams.anchor);
203
+ expect(deserialized.baseParams.debugFees).toBe(baseParams.debugFees);
204
+ });
205
+
206
+ it('should handle optional "to" field being undefined', () => {
207
+ const base = createMockSerializedState();
208
+ const { to: _to, ...baseParamsWithoutTo } = base.baseParams;
209
+ const state = createMockSerializedState(TransactionType.FUNDING, {
210
+ baseParams: baseParamsWithoutTo as SerializedBaseParams,
211
+ });
212
+
213
+ const deserialized = TransactionSerializer.deserialize(
214
+ TransactionSerializer.serialize(state),
215
+ );
216
+
217
+ expect(deserialized.baseParams.to).toBeUndefined();
218
+ });
219
+
220
+ it('should preserve UTXO data correctly', () => {
221
+ const utxo: SerializedUTXO = {
222
+ transactionId: 'a'.repeat(64),
223
+ outputIndex: 5,
224
+ value: '999999999',
225
+ scriptPubKeyHex: 'deadbeef',
226
+ scriptPubKeyAddress: address1,
227
+ redeemScript: 'cafe0001',
228
+ witnessScript: 'babe0002',
229
+ nonWitnessUtxo: 'feed0003',
230
+ };
231
+
232
+ const state = createMockSerializedState(TransactionType.FUNDING, {
233
+ utxos: [utxo],
234
+ });
235
+
236
+ const deserialized = TransactionSerializer.deserialize(
237
+ TransactionSerializer.serialize(state),
238
+ );
239
+
240
+ expect(deserialized.utxos).toHaveLength(1);
241
+ const utxo0 = deserialized.utxos[0] as SerializedUTXO;
242
+ expect(utxo0.transactionId).toBe(utxo.transactionId);
243
+ expect(utxo0.outputIndex).toBe(utxo.outputIndex);
244
+ expect(utxo0.value).toBe(utxo.value);
245
+ expect(utxo0.scriptPubKeyHex).toBe(utxo.scriptPubKeyHex);
246
+ expect(utxo0.scriptPubKeyAddress).toBe(utxo.scriptPubKeyAddress);
247
+ expect(utxo0.redeemScript).toBe(utxo.redeemScript);
248
+ expect(utxo0.witnessScript).toBe(utxo.witnessScript);
249
+ expect(utxo0.nonWitnessUtxo).toBe(utxo.nonWitnessUtxo);
250
+ });
251
+
252
+ it('should handle multiple UTXOs', () => {
253
+ const state = createMockSerializedState(TransactionType.FUNDING, {
254
+ utxos: [
255
+ {
256
+ transactionId: '1'.repeat(64),
257
+ outputIndex: 0,
258
+ value: '10000',
259
+ scriptPubKeyHex: 'aa',
260
+ scriptPubKeyAddress: address1,
261
+ },
262
+ {
263
+ transactionId: '2'.repeat(64),
264
+ outputIndex: 1,
265
+ value: '20000',
266
+ scriptPubKeyHex: 'bb',
267
+ scriptPubKeyAddress: address2,
268
+ },
269
+ {
270
+ transactionId: '3'.repeat(64),
271
+ outputIndex: 2,
272
+ value: '30000',
273
+ scriptPubKeyHex: 'cc',
274
+ scriptPubKeyAddress: address3,
275
+ },
276
+ ],
277
+ });
278
+
279
+ const deserialized = TransactionSerializer.deserialize(
280
+ TransactionSerializer.serialize(state),
281
+ );
282
+
283
+ expect(deserialized.utxos).toHaveLength(3);
284
+ expect((deserialized.utxos[0] as SerializedUTXO).transactionId).toBe('1'.repeat(64));
285
+ expect((deserialized.utxos[1] as SerializedUTXO).transactionId).toBe('2'.repeat(64));
286
+ expect((deserialized.utxos[2] as SerializedUTXO).transactionId).toBe('3'.repeat(64));
287
+ });
288
+
289
+ it('should preserve optional inputs', () => {
290
+ const state = createMockSerializedState(TransactionType.FUNDING, {
291
+ optionalInputs: [
292
+ {
293
+ transactionId: 'f'.repeat(64),
294
+ outputIndex: 99,
295
+ value: '12345',
296
+ scriptPubKeyHex: 'ff',
297
+ },
298
+ ],
299
+ });
300
+
301
+ const deserialized = TransactionSerializer.deserialize(
302
+ TransactionSerializer.serialize(state),
303
+ );
304
+
305
+ expect(deserialized.optionalInputs).toHaveLength(1);
306
+ expect((deserialized.optionalInputs[0] as SerializedUTXO).outputIndex).toBe(99);
307
+ });
308
+
309
+ it('should preserve optional outputs', () => {
310
+ const output: SerializedOutput = {
311
+ value: 5000,
312
+ address: address2,
313
+ tapInternalKey: 'abcd1234',
314
+ };
315
+
316
+ const state = createMockSerializedState(TransactionType.FUNDING, {
317
+ optionalOutputs: [output],
318
+ });
319
+
320
+ const deserialized = TransactionSerializer.deserialize(
321
+ TransactionSerializer.serialize(state),
322
+ );
323
+
324
+ expect(deserialized.optionalOutputs).toHaveLength(1);
325
+ const output0 = deserialized.optionalOutputs[0] as SerializedOutput;
326
+ expect(output0.value).toBe(output.value);
327
+ expect(output0.address).toBe(output.address);
328
+ expect(output0.tapInternalKey).toBe(output.tapInternalKey);
329
+ });
330
+
331
+ it('should preserve script-based outputs', () => {
332
+ const output: SerializedOutput = {
333
+ value: 6000,
334
+ script: 'deadbeefcafe',
335
+ };
336
+
337
+ const state = createMockSerializedState(TransactionType.FUNDING, {
338
+ optionalOutputs: [output],
339
+ });
340
+
341
+ const deserialized = TransactionSerializer.deserialize(
342
+ TransactionSerializer.serialize(state),
343
+ );
344
+
345
+ expect(deserialized.optionalOutputs).toHaveLength(1);
346
+ const scriptOutput0 = deserialized.optionalOutputs[0] as SerializedOutput;
347
+ expect(scriptOutput0.script).toBe(output.script);
348
+ expect(scriptOutput0.address).toBeUndefined();
349
+ });
350
+
351
+ it('should preserve signer mappings for address rotation', () => {
352
+ const state = createMockSerializedState(TransactionType.FUNDING, {
353
+ addressRotationEnabled: true,
354
+ signerMappings: [
355
+ { address: address1, inputIndices: [0, 2, 4] },
356
+ { address: address2, inputIndices: [1, 3] },
357
+ ],
358
+ });
359
+
360
+ const deserialized = TransactionSerializer.deserialize(
361
+ TransactionSerializer.serialize(state),
362
+ );
363
+
364
+ expect(deserialized.addressRotationEnabled).toBe(true);
365
+ expect(deserialized.signerMappings).toHaveLength(2);
366
+ const mapping0 = deserialized.signerMappings[0] as (typeof deserialized.signerMappings)[0];
367
+ const mapping1 = deserialized.signerMappings[1] as (typeof deserialized.signerMappings)[0];
368
+ expect(mapping0.address).toBe(address1);
369
+ expect(mapping0.inputIndices).toEqual([0, 2, 4]);
370
+ expect(mapping1.address).toBe(address2);
371
+ expect(mapping1.inputIndices).toEqual([1, 3]);
372
+ });
373
+
374
+ it('should preserve precomputed data', () => {
375
+ const precomputed: PrecomputedData = {
376
+ compiledTargetScript: 'abcdef123456',
377
+ randomBytes: '0123456789abcdef',
378
+ estimatedFees: '5000',
379
+ contractSeed: 'seedvalue',
380
+ contractAddress: address3,
381
+ };
382
+
383
+ const state = createMockSerializedState(TransactionType.FUNDING, {
384
+ precomputedData: precomputed,
385
+ });
386
+
387
+ const deserialized = TransactionSerializer.deserialize(
388
+ TransactionSerializer.serialize(state),
389
+ );
390
+
391
+ expect(deserialized.precomputedData.compiledTargetScript).toBe(precomputed.compiledTargetScript);
392
+ expect(deserialized.precomputedData.randomBytes).toBe(precomputed.randomBytes);
393
+ expect(deserialized.precomputedData.estimatedFees).toBe(precomputed.estimatedFees);
394
+ expect(deserialized.precomputedData.contractSeed).toBe(precomputed.contractSeed);
395
+ expect(deserialized.precomputedData.contractAddress).toBe(precomputed.contractAddress);
396
+ });
397
+ });
398
+
399
+ describe('type-specific data', () => {
400
+ it('should serialize/deserialize FundingSpecificData', () => {
401
+ const typeData: FundingSpecificData = {
402
+ type: TransactionType.FUNDING,
403
+ amount: '123456789',
404
+ splitInputsInto: 5,
405
+ };
406
+
407
+ const state = createMockSerializedState(TransactionType.FUNDING, {
408
+ typeSpecificData: typeData,
409
+ });
410
+
411
+ const deserialized = TransactionSerializer.deserialize(
412
+ TransactionSerializer.serialize(state),
413
+ );
414
+
415
+ expect(isFundingSpecificData(deserialized.typeSpecificData)).toBe(true);
416
+ const data = deserialized.typeSpecificData as FundingSpecificData;
417
+ expect(data.amount).toBe(typeData.amount);
418
+ expect(data.splitInputsInto).toBe(typeData.splitInputsInto);
419
+ });
420
+
421
+ it('should serialize/deserialize DeploymentSpecificData', () => {
422
+ const typeData: DeploymentSpecificData = {
423
+ type: TransactionType.DEPLOYMENT,
424
+ bytecode: 'deadbeef'.repeat(100),
425
+ calldata: 'cafebabe',
426
+ challenge: createMockChallenge(),
427
+ revealMLDSAPublicKey: true,
428
+ linkMLDSAPublicKeyToAddress: true,
429
+ hashedPublicKey: 'abcd'.repeat(16),
430
+ };
431
+
432
+ const state = createMockSerializedState(TransactionType.DEPLOYMENT, {
433
+ header: {
434
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
435
+ consensusVersion: currentConsensus,
436
+ transactionType: TransactionType.DEPLOYMENT,
437
+ chainId: ChainId.Bitcoin,
438
+ timestamp: Date.now(),
439
+ },
440
+ typeSpecificData: typeData,
441
+ });
442
+
443
+ const deserialized = TransactionSerializer.deserialize(
444
+ TransactionSerializer.serialize(state),
445
+ );
446
+
447
+ expect(isDeploymentSpecificData(deserialized.typeSpecificData)).toBe(true);
448
+ const data = deserialized.typeSpecificData as DeploymentSpecificData;
449
+ expect(data.bytecode).toBe(typeData.bytecode);
450
+ expect(data.calldata).toBe(typeData.calldata);
451
+ expect(data.revealMLDSAPublicKey).toBe(true);
452
+ expect(data.linkMLDSAPublicKeyToAddress).toBe(true);
453
+ expect(data.hashedPublicKey).toBe(typeData.hashedPublicKey);
454
+ });
455
+
456
+ it('should serialize/deserialize InteractionSpecificData', () => {
457
+ const typeData: InteractionSpecificData = {
458
+ type: TransactionType.INTERACTION,
459
+ calldata: 'cafebabe12345678',
460
+ contract: 'bcrt1qtest',
461
+ challenge: createMockChallenge(),
462
+ loadedStorage: {
463
+ 'key1': ['value1', 'value2'],
464
+ 'key2': ['value3'],
465
+ },
466
+ isCancellation: true,
467
+ disableAutoRefund: true,
468
+ revealMLDSAPublicKey: false,
469
+ };
470
+
471
+ const state = createMockSerializedState(TransactionType.INTERACTION, {
472
+ header: {
473
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
474
+ consensusVersion: currentConsensus,
475
+ transactionType: TransactionType.INTERACTION,
476
+ chainId: ChainId.Bitcoin,
477
+ timestamp: Date.now(),
478
+ },
479
+ typeSpecificData: typeData,
480
+ });
481
+
482
+ const deserialized = TransactionSerializer.deserialize(
483
+ TransactionSerializer.serialize(state),
484
+ );
485
+
486
+ expect(isInteractionSpecificData(deserialized.typeSpecificData)).toBe(true);
487
+ const data = deserialized.typeSpecificData as InteractionSpecificData;
488
+ expect(data.calldata).toBe(typeData.calldata);
489
+ expect(data.contract).toBe(typeData.contract);
490
+ expect(data.loadedStorage).toEqual(typeData.loadedStorage);
491
+ expect(data.isCancellation).toBe(true);
492
+ expect(data.disableAutoRefund).toBe(true);
493
+ });
494
+
495
+ it('should serialize/deserialize MultiSigSpecificData', () => {
496
+ const typeData: MultiSigSpecificData = {
497
+ type: TransactionType.MULTI_SIG,
498
+ pubkeys: ['aa'.repeat(33), 'bb'.repeat(33), 'cc'.repeat(33)],
499
+ minimumSignatures: 2,
500
+ receiver: address2,
501
+ requestedAmount: '500000',
502
+ refundVault: address3,
503
+ originalInputCount: 3,
504
+ existingPsbtBase64: 'cHNidP8BAH...',
505
+ };
506
+
507
+ const state = createMockSerializedState(TransactionType.MULTI_SIG, {
508
+ header: {
509
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
510
+ consensusVersion: currentConsensus,
511
+ transactionType: TransactionType.MULTI_SIG,
512
+ chainId: ChainId.Bitcoin,
513
+ timestamp: Date.now(),
514
+ },
515
+ typeSpecificData: typeData,
516
+ });
517
+
518
+ const deserialized = TransactionSerializer.deserialize(
519
+ TransactionSerializer.serialize(state),
520
+ );
521
+
522
+ expect(isMultiSigSpecificData(deserialized.typeSpecificData)).toBe(true);
523
+ const data = deserialized.typeSpecificData as MultiSigSpecificData;
524
+ expect(data.pubkeys).toEqual(typeData.pubkeys);
525
+ expect(data.minimumSignatures).toBe(2);
526
+ expect(data.receiver).toBe(typeData.receiver);
527
+ expect(data.requestedAmount).toBe(typeData.requestedAmount);
528
+ expect(data.refundVault).toBe(typeData.refundVault);
529
+ expect(data.originalInputCount).toBe(3);
530
+ expect(data.existingPsbtBase64).toBe(typeData.existingPsbtBase64);
531
+ });
532
+
533
+ it('should serialize/deserialize CustomScriptSpecificData', () => {
534
+ const typeData: CustomScriptSpecificData = {
535
+ type: TransactionType.CUSTOM_CODE,
536
+ scriptElements: [
537
+ { elementType: 'buffer', value: 'deadbeef' },
538
+ { elementType: 'opcode', value: 118 }, // OP_DUP
539
+ { elementType: 'opcode', value: 169 }, // OP_HASH160
540
+ ],
541
+ witnesses: ['abcdef0123456789', 'fedcba9876543210'],
542
+ annex: 'aabbccdd',
543
+ };
544
+
545
+ const state = createMockSerializedState(TransactionType.CUSTOM_CODE, {
546
+ header: {
547
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
548
+ consensusVersion: currentConsensus,
549
+ transactionType: TransactionType.CUSTOM_CODE,
550
+ chainId: ChainId.Bitcoin,
551
+ timestamp: Date.now(),
552
+ },
553
+ typeSpecificData: typeData,
554
+ });
555
+
556
+ const deserialized = TransactionSerializer.deserialize(
557
+ TransactionSerializer.serialize(state),
558
+ );
559
+
560
+ expect(isCustomScriptSpecificData(deserialized.typeSpecificData)).toBe(true);
561
+ const data = deserialized.typeSpecificData as CustomScriptSpecificData;
562
+ expect(data.scriptElements).toHaveLength(3);
563
+ expect(data.scriptElements[0]).toEqual({ elementType: 'buffer', value: 'deadbeef' });
564
+ expect(data.scriptElements[1]).toEqual({ elementType: 'opcode', value: 118 });
565
+ expect(data.witnesses).toEqual(typeData.witnesses);
566
+ expect(data.annex).toBe(typeData.annex);
567
+ });
568
+
569
+ it('should serialize/deserialize CancelSpecificData', () => {
570
+ const typeData: CancelSpecificData = {
571
+ type: TransactionType.CANCEL,
572
+ compiledTargetScript: 'deadbeefcafe1234',
573
+ };
574
+
575
+ const state = createMockSerializedState(TransactionType.CANCEL, {
576
+ header: {
577
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
578
+ consensusVersion: currentConsensus,
579
+ transactionType: TransactionType.CANCEL,
580
+ chainId: ChainId.Bitcoin,
581
+ timestamp: Date.now(),
582
+ },
583
+ typeSpecificData: typeData,
584
+ });
585
+
586
+ const deserialized = TransactionSerializer.deserialize(
587
+ TransactionSerializer.serialize(state),
588
+ );
589
+
590
+ expect(isCancelSpecificData(deserialized.typeSpecificData)).toBe(true);
591
+ const data = deserialized.typeSpecificData as CancelSpecificData;
592
+ expect(data.compiledTargetScript).toBe(typeData.compiledTargetScript);
593
+ });
594
+ });
595
+
596
+ describe('format conversion', () => {
597
+ it('should convert to/from base64', () => {
598
+ const state = createMockSerializedState();
599
+
600
+ const base64 = TransactionSerializer.toBase64(state);
601
+ expect(typeof base64).toBe('string');
602
+ expect(base64.length).toBeGreaterThan(0);
603
+
604
+ const restored = TransactionSerializer.fromBase64(base64);
605
+ expect(restored.header.transactionType).toBe(state.header.transactionType);
606
+ expect(restored.baseParams.from).toBe(state.baseParams.from);
607
+ });
608
+
609
+ it('should convert to/from hex', () => {
610
+ const state = createMockSerializedState();
611
+
612
+ const hex = TransactionSerializer.toHex(state);
613
+ expect(typeof hex).toBe('string');
614
+ expect(/^[0-9a-f]+$/i.test(hex)).toBe(true);
615
+
616
+ const restored = TransactionSerializer.fromHex(hex);
617
+ expect(restored.header.transactionType).toBe(state.header.transactionType);
618
+ });
619
+ });
620
+
621
+ describe('error handling', () => {
622
+ it('should throw on invalid magic byte', () => {
623
+ const state = createMockSerializedState();
624
+ const serialized = TransactionSerializer.serialize(state);
625
+
626
+ // Corrupt magic byte
627
+ serialized[0] = 0x00;
628
+
629
+ // Recalculate checksum to bypass checksum error
630
+ const payload = serialized.subarray(0, -32);
631
+ const newChecksum = doubleSha256(payload);
632
+ serialized.set(newChecksum, serialized.length - 32);
633
+
634
+ expect(() => TransactionSerializer.deserialize(serialized)).toThrow(/Invalid magic byte/);
635
+ });
636
+
637
+ it('should throw on invalid checksum', () => {
638
+ const state = createMockSerializedState();
639
+ const serialized = TransactionSerializer.serialize(state);
640
+
641
+ // Corrupt checksum
642
+ serialized[serialized.length - 1] = (serialized[serialized.length - 1] as number) ^ 0xff;
643
+
644
+ expect(() => TransactionSerializer.deserialize(serialized)).toThrow(/Invalid checksum/);
645
+ });
646
+
647
+ it('should throw on data too short', () => {
648
+ const shortData = new Uint8Array(16); // Less than 32 bytes
649
+
650
+ expect(() => TransactionSerializer.deserialize(shortData)).toThrow(/too short/);
651
+ });
652
+
653
+ it('should throw on unsupported format version', () => {
654
+ const state = createMockSerializedState();
655
+ const serialized = TransactionSerializer.serialize(state);
656
+
657
+ // Set format version to a high value
658
+ serialized[1] = 255;
659
+
660
+ // Recalculate checksum
661
+ const payload = serialized.subarray(0, -32);
662
+ const newChecksum = doubleSha256(payload);
663
+ serialized.set(newChecksum, serialized.length - 32);
664
+
665
+ expect(() => TransactionSerializer.deserialize(serialized)).toThrow(/Unsupported format version/);
666
+ });
667
+ });
668
+
669
+ describe('network serialization', () => {
670
+ it('should serialize mainnet correctly', () => {
671
+ const base = createMockSerializedState();
672
+ const state = createMockSerializedState(TransactionType.FUNDING, {
673
+ baseParams: { ...base.baseParams, networkName: 'mainnet' },
674
+ });
675
+
676
+ const deserialized = TransactionSerializer.deserialize(
677
+ TransactionSerializer.serialize(state),
678
+ );
679
+
680
+ expect(deserialized.baseParams.networkName).toBe('mainnet');
681
+ });
682
+
683
+ it('should serialize testnet correctly', () => {
684
+ const base = createMockSerializedState();
685
+ const state = createMockSerializedState(TransactionType.FUNDING, {
686
+ baseParams: { ...base.baseParams, networkName: 'testnet' },
687
+ });
688
+
689
+ const deserialized = TransactionSerializer.deserialize(
690
+ TransactionSerializer.serialize(state),
691
+ );
692
+
693
+ expect(deserialized.baseParams.networkName).toBe('testnet');
694
+ });
695
+
696
+ it('should serialize regtest correctly', () => {
697
+ const base = createMockSerializedState();
698
+ const state = createMockSerializedState(TransactionType.FUNDING, {
699
+ baseParams: { ...base.baseParams, networkName: 'regtest' },
700
+ });
701
+
702
+ const deserialized = TransactionSerializer.deserialize(
703
+ TransactionSerializer.serialize(state),
704
+ );
705
+
706
+ expect(deserialized.baseParams.networkName).toBe('regtest');
707
+ });
708
+ });
709
+ });
710
+
711
+ describe('TransactionStateCapture', () => {
712
+ describe('fromFunding', () => {
713
+ it('should capture state from funding transaction parameters', () => {
714
+ const params = {
715
+ signer: defaultSigner,
716
+ mldsaSigner: null,
717
+ network,
718
+ utxos: [createTaprootUtxo(address1, 100000n)],
719
+ from: address1,
720
+ to: address2,
721
+ feeRate: 10,
722
+ priorityFee: 1000n,
723
+ gasSatFee: 500n,
724
+ amount: 50000n,
725
+ splitInputsInto: 2,
726
+ };
727
+
728
+ const state = TransactionStateCapture.fromFunding(params);
729
+
730
+ expect(state.header.transactionType).toBe(TransactionType.FUNDING);
731
+ expect(state.baseParams.from).toBe(address1);
732
+ expect(state.baseParams.to).toBe(address2);
733
+ expect(state.baseParams.feeRate).toBe(10);
734
+ expect(state.utxos).toHaveLength(1);
735
+ expect(isFundingSpecificData(state.typeSpecificData)).toBe(true);
736
+ const data = state.typeSpecificData as FundingSpecificData;
737
+ expect(data.amount).toBe('50000');
738
+ expect(data.splitInputsInto).toBe(2);
739
+ });
740
+
741
+ it('should capture precomputed data', () => {
742
+ const params = {
743
+ signer: defaultSigner,
744
+ mldsaSigner: null,
745
+ network,
746
+ utxos: [createTaprootUtxo(address1, 100000n)],
747
+ from: address1,
748
+ to: address2,
749
+ feeRate: 10,
750
+ priorityFee: 1000n,
751
+ gasSatFee: 500n,
752
+ amount: 50000n,
753
+ };
754
+
755
+ const precomputed = {
756
+ estimatedFees: '2000',
757
+ };
758
+
759
+ const state = TransactionStateCapture.fromFunding(params, precomputed);
760
+
761
+ expect(state.precomputedData.estimatedFees).toBe('2000');
762
+ });
763
+
764
+ it('should handle address rotation configuration', () => {
765
+ const signerMap = createSignerMap([
766
+ [address1, signer1],
767
+ [address2, signer2],
768
+ ]);
769
+
770
+ const params = {
771
+ signer: defaultSigner,
772
+ mldsaSigner: null,
773
+ network,
774
+ utxos: [
775
+ createTaprootUtxo(address1, 50000n, '1'.repeat(64), 0),
776
+ createTaprootUtxo(address2, 50000n, '2'.repeat(64), 0),
777
+ ],
778
+ from: address1,
779
+ to: address3,
780
+ feeRate: 10,
781
+ priorityFee: 1000n,
782
+ gasSatFee: 500n,
783
+ amount: 80000n,
784
+ addressRotation: createAddressRotation(signerMap),
785
+ };
786
+
787
+ const state = TransactionStateCapture.fromFunding(params);
788
+
789
+ expect(state.addressRotationEnabled).toBe(true);
790
+ expect(state.signerMappings).toHaveLength(2);
791
+ });
792
+ });
793
+
794
+ describe('UTXO serialization', () => {
795
+ it('should serialize UTXO with all optional fields', () => {
796
+ const utxo: UTXO = {
797
+ transactionId: 'a'.repeat(64),
798
+ outputIndex: 5,
799
+ value: 999999n,
800
+ scriptPubKey: {
801
+ hex: 'deadbeef',
802
+ address: address1,
803
+ },
804
+ redeemScript: fromHex('cafe'),
805
+ witnessScript: fromHex('babe'),
806
+ nonWitnessUtxo: fromHex('feed'),
807
+ };
808
+
809
+ const params = {
810
+ signer: defaultSigner,
811
+ mldsaSigner: null,
812
+ network,
813
+ utxos: [utxo],
814
+ from: address1,
815
+ to: address2,
816
+ feeRate: 10,
817
+ priorityFee: 1000n,
818
+ gasSatFee: 500n,
819
+ amount: 50000n,
820
+ };
821
+
822
+ const state = TransactionStateCapture.fromFunding(params);
823
+
824
+ const stateUtxo0 = state.utxos[0] as SerializedUTXO;
825
+ expect(stateUtxo0.transactionId).toBe(utxo.transactionId);
826
+ expect(stateUtxo0.redeemScript).toBe('cafe');
827
+ expect(stateUtxo0.witnessScript).toBe('babe');
828
+ expect(stateUtxo0.nonWitnessUtxo).toBe('feed');
829
+ });
830
+
831
+ it('should handle UTXOs with string scripts', () => {
832
+ const utxo: UTXO = {
833
+ transactionId: 'b'.repeat(64),
834
+ outputIndex: 0,
835
+ value: 10000n,
836
+ scriptPubKey: {
837
+ hex: 'aabbcc',
838
+ address: address1,
839
+ },
840
+ redeemScript: 'ddeeff', // String instead of Buffer
841
+ };
842
+
843
+ const params = {
844
+ signer: defaultSigner,
845
+ mldsaSigner: null,
846
+ network,
847
+ utxos: [utxo],
848
+ from: address1,
849
+ to: address2,
850
+ feeRate: 10,
851
+ priorityFee: 1000n,
852
+ gasSatFee: 500n,
853
+ amount: 5000n,
854
+ };
855
+
856
+ const state = TransactionStateCapture.fromFunding(params);
857
+
858
+ expect((state.utxos[0] as SerializedUTXO).redeemScript).toBe('ddeeff');
859
+ });
860
+ });
861
+ });
862
+
863
+ describe('TransactionReconstructor', () => {
864
+ describe('reconstruct', () => {
865
+ it('should reconstruct a funding transaction', () => {
866
+ const state = createMockSerializedState(TransactionType.FUNDING);
867
+
868
+ const options: ReconstructionOptions = {
869
+ signer: defaultSigner,
870
+ };
871
+
872
+ const builder = TransactionReconstructor.reconstruct(state, options);
873
+
874
+ expect(builder).toBeInstanceOf(FundingTransaction);
875
+ expect(builder.type).toBe(TransactionType.FUNDING);
876
+ });
877
+
878
+ it('should apply fee rate override', () => {
879
+ const base = createMockSerializedState();
880
+ const state = createMockSerializedState(TransactionType.FUNDING, {
881
+ baseParams: { ...base.baseParams, feeRate: 10 },
882
+ });
883
+
884
+ const options: ReconstructionOptions = {
885
+ signer: defaultSigner,
886
+ newFeeRate: 50,
887
+ };
888
+
889
+ const builder = TransactionReconstructor.reconstruct(state, options);
890
+
891
+ // The builder should have the new fee rate
892
+ expect(builder).toBeDefined();
893
+ });
894
+
895
+ it('should apply priority fee override', () => {
896
+ const state = createMockSerializedState(TransactionType.FUNDING);
897
+
898
+ const options: ReconstructionOptions = {
899
+ signer: defaultSigner,
900
+ newPriorityFee: 5000n,
901
+ };
902
+
903
+ const builder = TransactionReconstructor.reconstruct(state, options);
904
+ expect(builder).toBeDefined();
905
+ });
906
+
907
+ it('should apply gas sat fee override', () => {
908
+ const state = createMockSerializedState(TransactionType.FUNDING);
909
+
910
+ const options: ReconstructionOptions = {
911
+ signer: defaultSigner,
912
+ newGasSatFee: 2000n,
913
+ };
914
+
915
+ const builder = TransactionReconstructor.reconstruct(state, options);
916
+ expect(builder).toBeDefined();
917
+ });
918
+
919
+ it('should throw when address rotation enabled but no signerMap provided', () => {
920
+ const state = createMockSerializedState(TransactionType.FUNDING, {
921
+ addressRotationEnabled: true,
922
+ });
923
+
924
+ const options: ReconstructionOptions = {
925
+ signer: defaultSigner,
926
+ // No signerMap provided
927
+ };
928
+
929
+ expect(() => TransactionReconstructor.reconstruct(state, options)).toThrow(
930
+ /signerMap/,
931
+ );
932
+ });
933
+
934
+ it('should reconstruct with address rotation when signerMap provided', () => {
935
+ const state = createMockSerializedState(TransactionType.FUNDING, {
936
+ addressRotationEnabled: true,
937
+ signerMappings: [{ address: address1, inputIndices: [0] }],
938
+ });
939
+
940
+ const signerMap = createSignerMap([[address1, signer1]]);
941
+
942
+ const options: ReconstructionOptions = {
943
+ signer: defaultSigner,
944
+ signerMap,
945
+ };
946
+
947
+ const builder = TransactionReconstructor.reconstruct(state, options);
948
+ expect(builder).toBeDefined();
949
+ });
950
+ });
951
+
952
+ describe('network conversion', () => {
953
+ it('should convert mainnet name to network', () => {
954
+ const base = createMockSerializedState();
955
+ const state = createMockSerializedState(TransactionType.FUNDING, {
956
+ baseParams: { ...base.baseParams, networkName: 'mainnet' },
957
+ });
958
+
959
+ const options: ReconstructionOptions = {
960
+ signer: defaultSigner,
961
+ };
962
+
963
+ const builder = TransactionReconstructor.reconstruct(state, options);
964
+ expect(builder).toBeDefined();
965
+ });
966
+
967
+ it('should convert testnet name to network', () => {
968
+ const base = createMockSerializedState();
969
+ const state = createMockSerializedState(TransactionType.FUNDING, {
970
+ baseParams: { ...base.baseParams, networkName: 'testnet' },
971
+ });
972
+
973
+ const options: ReconstructionOptions = {
974
+ signer: defaultSigner,
975
+ };
976
+
977
+ const builder = TransactionReconstructor.reconstruct(state, options);
978
+ expect(builder).toBeDefined();
979
+ });
980
+
981
+ it('should convert regtest name to network', () => {
982
+ const base = createMockSerializedState();
983
+ const state = createMockSerializedState(TransactionType.FUNDING, {
984
+ baseParams: { ...base.baseParams, networkName: 'regtest' },
985
+ });
986
+
987
+ const options: ReconstructionOptions = {
988
+ signer: defaultSigner,
989
+ };
990
+
991
+ const builder = TransactionReconstructor.reconstruct(state, options);
992
+ expect(builder).toBeDefined();
993
+ });
994
+ });
995
+ });
996
+
997
+ describe('OfflineTransactionManager', () => {
998
+ describe('exportFunding', () => {
999
+ it('should export funding transaction to base64', () => {
1000
+ const params = {
1001
+ signer: defaultSigner,
1002
+ mldsaSigner: null,
1003
+ network,
1004
+ utxos: [createTaprootUtxo(address1, 100000n)],
1005
+ from: address1,
1006
+ to: address2,
1007
+ feeRate: 10,
1008
+ priorityFee: 1000n,
1009
+ gasSatFee: 500n,
1010
+ amount: 50000n,
1011
+ };
1012
+
1013
+ const exported = OfflineTransactionManager.exportFunding(params);
1014
+
1015
+ expect(typeof exported).toBe('string');
1016
+ expect(exported.length).toBeGreaterThan(0);
1017
+
1018
+ // Should be valid base64
1019
+ expect(() => atob(exported)).not.toThrow();
1020
+ });
1021
+ });
1022
+
1023
+ describe('importForSigning', () => {
1024
+ it('should import serialized state and create builder', () => {
1025
+ const params = {
1026
+ signer: defaultSigner,
1027
+ mldsaSigner: null,
1028
+ network,
1029
+ utxos: [createTaprootUtxo(address1, 100000n)],
1030
+ from: address1,
1031
+ to: address2,
1032
+ feeRate: 10,
1033
+ priorityFee: 1000n,
1034
+ gasSatFee: 500n,
1035
+ amount: 50000n,
1036
+ };
1037
+
1038
+ const exported = OfflineTransactionManager.exportFunding(params);
1039
+
1040
+ const builder = OfflineTransactionManager.importForSigning(exported, {
1041
+ signer: signer1,
1042
+ });
1043
+
1044
+ expect(builder).toBeInstanceOf(FundingTransaction);
1045
+ });
1046
+ });
1047
+
1048
+ describe('inspect', () => {
1049
+ it('should return parsed state for inspection', () => {
1050
+ const params = {
1051
+ signer: defaultSigner,
1052
+ mldsaSigner: null,
1053
+ network,
1054
+ utxos: [createTaprootUtxo(address1, 100000n)],
1055
+ from: address1,
1056
+ to: address2,
1057
+ feeRate: 15,
1058
+ priorityFee: 1000n,
1059
+ gasSatFee: 500n,
1060
+ amount: 50000n,
1061
+ };
1062
+
1063
+ const exported = OfflineTransactionManager.exportFunding(params);
1064
+ const inspected = OfflineTransactionManager.inspect(exported);
1065
+
1066
+ expect(inspected.header.transactionType).toBe(TransactionType.FUNDING);
1067
+ expect(inspected.baseParams.from).toBe(address1);
1068
+ expect(inspected.baseParams.to).toBe(address2);
1069
+ expect(inspected.baseParams.feeRate).toBeCloseTo(15, 3);
1070
+ });
1071
+ });
1072
+
1073
+ describe('validate', () => {
1074
+ it('should return true for valid serialized state', () => {
1075
+ const params = {
1076
+ signer: defaultSigner,
1077
+ mldsaSigner: null,
1078
+ network,
1079
+ utxos: [createTaprootUtxo(address1, 100000n)],
1080
+ from: address1,
1081
+ to: address2,
1082
+ feeRate: 10,
1083
+ priorityFee: 1000n,
1084
+ gasSatFee: 500n,
1085
+ amount: 50000n,
1086
+ };
1087
+
1088
+ const exported = OfflineTransactionManager.exportFunding(params);
1089
+
1090
+ expect(OfflineTransactionManager.validate(exported)).toBe(true);
1091
+ });
1092
+
1093
+ it('should return false for invalid serialized state', () => {
1094
+ expect(OfflineTransactionManager.validate('invalid base64!')).toBe(false);
1095
+ expect(OfflineTransactionManager.validate('')).toBe(false);
1096
+ expect(OfflineTransactionManager.validate('YWJj')).toBe(false); // Valid base64 but invalid data
1097
+ });
1098
+ });
1099
+
1100
+ describe('getType', () => {
1101
+ it('should return transaction type from serialized state', () => {
1102
+ const params = {
1103
+ signer: defaultSigner,
1104
+ mldsaSigner: null,
1105
+ network,
1106
+ utxos: [createTaprootUtxo(address1, 100000n)],
1107
+ from: address1,
1108
+ to: address2,
1109
+ feeRate: 10,
1110
+ priorityFee: 1000n,
1111
+ gasSatFee: 500n,
1112
+ amount: 50000n,
1113
+ };
1114
+
1115
+ const exported = OfflineTransactionManager.exportFunding(params);
1116
+ const type = OfflineTransactionManager.getType(exported);
1117
+
1118
+ expect(type).toBe(TransactionType.FUNDING);
1119
+ });
1120
+ });
1121
+
1122
+ describe('toHex/fromHex', () => {
1123
+ it('should convert between base64 and hex formats', () => {
1124
+ const params = {
1125
+ signer: defaultSigner,
1126
+ mldsaSigner: null,
1127
+ network,
1128
+ utxos: [createTaprootUtxo(address1, 100000n)],
1129
+ from: address1,
1130
+ to: address2,
1131
+ feeRate: 10,
1132
+ priorityFee: 1000n,
1133
+ gasSatFee: 500n,
1134
+ amount: 50000n,
1135
+ };
1136
+
1137
+ const base64 = OfflineTransactionManager.exportFunding(params);
1138
+ const hex = OfflineTransactionManager.toHex(base64);
1139
+
1140
+ expect(/^[0-9a-f]+$/i.test(hex)).toBe(true);
1141
+
1142
+ const backToBase64 = OfflineTransactionManager.fromHex(hex);
1143
+
1144
+ // Both should deserialize to the same state
1145
+ const state1 = OfflineTransactionManager.inspect(base64);
1146
+ const state2 = OfflineTransactionManager.inspect(backToBase64);
1147
+
1148
+ expect(state1.baseParams.from).toBe(state2.baseParams.from);
1149
+ expect(state1.baseParams.to).toBe(state2.baseParams.to);
1150
+ });
1151
+ });
1152
+
1153
+ describe('full workflow', () => {
1154
+ it('should complete export -> import -> reconstruct workflow', () => {
1155
+ // Phase 1: Export
1156
+ const params = {
1157
+ signer: defaultSigner,
1158
+ mldsaSigner: null,
1159
+ network,
1160
+ utxos: [createTaprootUtxo(address1, 100000n)],
1161
+ from: address1,
1162
+ to: address2,
1163
+ feeRate: 10,
1164
+ priorityFee: 1000n,
1165
+ gasSatFee: 500n,
1166
+ amount: 50000n,
1167
+ };
1168
+
1169
+ const exported = OfflineTransactionManager.exportFunding(params);
1170
+
1171
+ // Validate
1172
+ expect(OfflineTransactionManager.validate(exported)).toBe(true);
1173
+
1174
+ // Inspect
1175
+ const inspected = OfflineTransactionManager.inspect(exported);
1176
+ expect(inspected.header.transactionType).toBe(TransactionType.FUNDING);
1177
+
1178
+ // Phase 2: Import with different signer
1179
+ const builder = OfflineTransactionManager.importForSigning(exported, {
1180
+ signer: signer1,
1181
+ });
1182
+
1183
+ expect(builder).toBeDefined();
1184
+ expect(builder.type).toBe(TransactionType.FUNDING);
1185
+ });
1186
+
1187
+ it('should support fee bumping workflow', () => {
1188
+ const params = {
1189
+ signer: defaultSigner,
1190
+ mldsaSigner: null,
1191
+ network,
1192
+ utxos: [createTaprootUtxo(address1, 100000n)],
1193
+ from: address1,
1194
+ to: address2,
1195
+ feeRate: 10,
1196
+ priorityFee: 1000n,
1197
+ gasSatFee: 500n,
1198
+ amount: 50000n,
1199
+ };
1200
+
1201
+ const exported = OfflineTransactionManager.exportFunding(params);
1202
+
1203
+ // Rebuild with higher fee
1204
+ const bumpedState = OfflineTransactionManager.rebuildWithNewFees(
1205
+ exported,
1206
+ 50, // New fee rate
1207
+ );
1208
+
1209
+ // Verify the new state has updated fee
1210
+ const inspected = OfflineTransactionManager.inspect(bumpedState);
1211
+ expect(inspected.baseParams.feeRate).toBeCloseTo(50, 3);
1212
+ });
1213
+ });
1214
+ });
1215
+
1216
+ describe('Type Guards', () => {
1217
+ it('isFundingSpecificData should correctly identify funding data', () => {
1218
+ const fundingData: FundingSpecificData = {
1219
+ type: TransactionType.FUNDING,
1220
+ amount: '1000',
1221
+ splitInputsInto: 1,
1222
+ };
1223
+
1224
+ expect(isFundingSpecificData(fundingData)).toBe(true);
1225
+
1226
+ const otherData: CancelSpecificData = {
1227
+ type: TransactionType.CANCEL,
1228
+ compiledTargetScript: 'ab0c',
1229
+ };
1230
+
1231
+ expect(isFundingSpecificData(otherData)).toBe(false);
1232
+ });
1233
+
1234
+ it('isDeploymentSpecificData should correctly identify deployment data', () => {
1235
+ const deploymentData: DeploymentSpecificData = {
1236
+ type: TransactionType.DEPLOYMENT,
1237
+ bytecode: 'ab0c',
1238
+ challenge: createMockChallenge(),
1239
+ };
1240
+
1241
+ expect(isDeploymentSpecificData(deploymentData)).toBe(true);
1242
+
1243
+ const nonDeploymentData: FundingSpecificData = {
1244
+ type: TransactionType.FUNDING,
1245
+ amount: '0',
1246
+ splitInputsInto: 1,
1247
+ };
1248
+ expect(isDeploymentSpecificData(nonDeploymentData)).toBe(false);
1249
+ });
1250
+
1251
+ it('isInteractionSpecificData should correctly identify interaction data', () => {
1252
+ const interactionData: InteractionSpecificData = {
1253
+ type: TransactionType.INTERACTION,
1254
+ calldata: 'ab0c',
1255
+ challenge: createMockChallenge(),
1256
+ };
1257
+
1258
+ expect(isInteractionSpecificData(interactionData)).toBe(true);
1259
+
1260
+ const nonInteractionData: FundingSpecificData = {
1261
+ type: TransactionType.FUNDING,
1262
+ amount: '0',
1263
+ splitInputsInto: 1,
1264
+ };
1265
+ expect(isInteractionSpecificData(nonInteractionData)).toBe(false);
1266
+ });
1267
+
1268
+ it('isMultiSigSpecificData should correctly identify multisig data', () => {
1269
+ const multiSigData: MultiSigSpecificData = {
1270
+ type: TransactionType.MULTI_SIG,
1271
+ pubkeys: [],
1272
+ minimumSignatures: 2,
1273
+ receiver: 'addr',
1274
+ requestedAmount: '1000',
1275
+ refundVault: 'vault',
1276
+ originalInputCount: 1,
1277
+ };
1278
+
1279
+ expect(isMultiSigSpecificData(multiSigData)).toBe(true);
1280
+
1281
+ const nonMultiSigData: FundingSpecificData = {
1282
+ type: TransactionType.FUNDING,
1283
+ amount: '0',
1284
+ splitInputsInto: 1,
1285
+ };
1286
+ expect(isMultiSigSpecificData(nonMultiSigData)).toBe(false);
1287
+ });
1288
+
1289
+ it('isCustomScriptSpecificData should correctly identify custom script data', () => {
1290
+ const customData: CustomScriptSpecificData = {
1291
+ type: TransactionType.CUSTOM_CODE,
1292
+ scriptElements: [],
1293
+ witnesses: [],
1294
+ };
1295
+
1296
+ expect(isCustomScriptSpecificData(customData)).toBe(true);
1297
+
1298
+ const nonCustomData: FundingSpecificData = {
1299
+ type: TransactionType.FUNDING,
1300
+ amount: '0',
1301
+ splitInputsInto: 1,
1302
+ };
1303
+ expect(isCustomScriptSpecificData(nonCustomData)).toBe(false);
1304
+ });
1305
+
1306
+ it('isCancelSpecificData should correctly identify cancel data', () => {
1307
+ const cancelData: CancelSpecificData = {
1308
+ type: TransactionType.CANCEL,
1309
+ compiledTargetScript: 'ab0c',
1310
+ };
1311
+
1312
+ expect(isCancelSpecificData(cancelData)).toBe(true);
1313
+
1314
+ const nonCancelData: FundingSpecificData = {
1315
+ type: TransactionType.FUNDING,
1316
+ amount: '0',
1317
+ splitInputsInto: 1,
1318
+ };
1319
+ expect(isCancelSpecificData(nonCancelData)).toBe(false);
1320
+ });
1321
+ });
1322
+
1323
+ describe('Edge Cases', () => {
1324
+ it('should handle empty UTXOs array', () => {
1325
+ const state = createMockSerializedState(TransactionType.FUNDING, {
1326
+ utxos: [],
1327
+ });
1328
+
1329
+ const serialized = TransactionSerializer.serialize(state);
1330
+ const deserialized = TransactionSerializer.deserialize(serialized);
1331
+
1332
+ expect(deserialized.utxos).toHaveLength(0);
1333
+ });
1334
+
1335
+ it('should handle very large values', () => {
1336
+ const state = createMockSerializedState(TransactionType.FUNDING, {
1337
+ utxos: [
1338
+ {
1339
+ transactionId: '0'.repeat(64),
1340
+ outputIndex: 0,
1341
+ value: '9999999999999999', // Large value
1342
+ scriptPubKeyHex: 'aa',
1343
+ },
1344
+ ],
1345
+ });
1346
+
1347
+ const deserialized = TransactionSerializer.deserialize(
1348
+ TransactionSerializer.serialize(state),
1349
+ );
1350
+
1351
+ expect((deserialized.utxos[0] as SerializedUTXO).value).toBe('9999999999999999');
1352
+ });
1353
+
1354
+ it('should handle empty strings', () => {
1355
+ const base = createMockSerializedState();
1356
+ const state = createMockSerializedState(TransactionType.FUNDING, {
1357
+ baseParams: { ...base.baseParams, from: '', to: '' },
1358
+ });
1359
+
1360
+ const deserialized = TransactionSerializer.deserialize(
1361
+ TransactionSerializer.serialize(state),
1362
+ );
1363
+
1364
+ expect(deserialized.baseParams.from).toBe('');
1365
+ });
1366
+
1367
+ it('should handle special characters in note', () => {
1368
+ const base = createMockSerializedState();
1369
+ const specialNote = toHex(new TextEncoder().encode('Hello\x00World\n\t\r'));
1370
+ const state = createMockSerializedState(TransactionType.FUNDING, {
1371
+ baseParams: { ...base.baseParams, note: specialNote },
1372
+ });
1373
+
1374
+ const deserialized = TransactionSerializer.deserialize(
1375
+ TransactionSerializer.serialize(state),
1376
+ );
1377
+
1378
+ expect(deserialized.baseParams.note).toBe(specialNote);
1379
+ });
1380
+
1381
+ it('should handle zero fee rate', () => {
1382
+ const base = createMockSerializedState();
1383
+ const state = createMockSerializedState(TransactionType.FUNDING, {
1384
+ baseParams: { ...base.baseParams, feeRate: 0 },
1385
+ });
1386
+
1387
+ const deserialized = TransactionSerializer.deserialize(
1388
+ TransactionSerializer.serialize(state),
1389
+ );
1390
+
1391
+ expect(deserialized.baseParams.feeRate).toBe(0);
1392
+ });
1393
+
1394
+ it('should handle maximum input indices in signer mappings', () => {
1395
+ const state = createMockSerializedState(TransactionType.FUNDING, {
1396
+ addressRotationEnabled: true,
1397
+ signerMappings: [
1398
+ { address: address1, inputIndices: Array.from({ length: 100 }, (_, i) => i) },
1399
+ ],
1400
+ });
1401
+
1402
+ const deserialized = TransactionSerializer.deserialize(
1403
+ TransactionSerializer.serialize(state),
1404
+ );
1405
+
1406
+ expect((deserialized.signerMappings[0] as (typeof deserialized.signerMappings)[0]).inputIndices).toHaveLength(100);
1407
+ });
1408
+
1409
+ it('should handle loaded storage with many keys', () => {
1410
+ const loadedStorage: { [key: string]: string[] } = {};
1411
+ for (let i = 0; i < 50; i++) {
1412
+ loadedStorage[`key${i}`] = [`value${i}a`, `value${i}b`];
1413
+ }
1414
+
1415
+ const state = createMockSerializedState(TransactionType.INTERACTION, {
1416
+ header: {
1417
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
1418
+ consensusVersion: currentConsensus,
1419
+ transactionType: TransactionType.INTERACTION,
1420
+ chainId: ChainId.Bitcoin,
1421
+ timestamp: Date.now(),
1422
+ },
1423
+ typeSpecificData: {
1424
+ type: TransactionType.INTERACTION,
1425
+ calldata: 'ab0c',
1426
+ challenge: createMockChallenge(),
1427
+ loadedStorage,
1428
+ } as InteractionSpecificData,
1429
+ });
1430
+
1431
+ const deserialized = TransactionSerializer.deserialize(
1432
+ TransactionSerializer.serialize(state),
1433
+ );
1434
+
1435
+ const data = deserialized.typeSpecificData as InteractionSpecificData;
1436
+ expect(Object.keys(data.loadedStorage || {}).length).toBe(50);
1437
+ });
1438
+ });
1439
+
1440
+ describe('Round-trip Tests', () => {
1441
+ it('should preserve all data through serialize/deserialize cycle', () => {
1442
+ const originalState: ISerializableTransactionState = {
1443
+ header: {
1444
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
1445
+ consensusVersion: currentConsensus,
1446
+ transactionType: TransactionType.FUNDING,
1447
+ chainId: ChainId.Bitcoin,
1448
+ timestamp: 1700000000000,
1449
+ },
1450
+ baseParams: {
1451
+ from: address1,
1452
+ to: address2,
1453
+ feeRate: 12.5,
1454
+ priorityFee: '1500',
1455
+ gasSatFee: '750',
1456
+ networkName: 'regtest',
1457
+ txVersion: 2,
1458
+ note: 'deadbeef',
1459
+ anchor: true,
1460
+ debugFees: true,
1461
+ },
1462
+ utxos: [
1463
+ {
1464
+ transactionId: 'a'.repeat(64),
1465
+ outputIndex: 3,
1466
+ value: '123456',
1467
+ scriptPubKeyHex: 'aa',
1468
+ scriptPubKeyAddress: address1,
1469
+ redeemScript: 'bb',
1470
+ witnessScript: 'cc',
1471
+ nonWitnessUtxo: 'dd',
1472
+ },
1473
+ ],
1474
+ optionalInputs: [
1475
+ {
1476
+ transactionId: 'b'.repeat(64),
1477
+ outputIndex: 1,
1478
+ value: '789',
1479
+ scriptPubKeyHex: 'ee',
1480
+ },
1481
+ ],
1482
+ optionalOutputs: [
1483
+ {
1484
+ value: 5000,
1485
+ address: address3,
1486
+ tapInternalKey: 'ff'.repeat(16),
1487
+ },
1488
+ ],
1489
+ addressRotationEnabled: true,
1490
+ signerMappings: [
1491
+ { address: address1, inputIndices: [0, 1] },
1492
+ { address: address2, inputIndices: [2] },
1493
+ ],
1494
+ typeSpecificData: {
1495
+ type: TransactionType.FUNDING,
1496
+ amount: '99999',
1497
+ splitInputsInto: 3,
1498
+ },
1499
+ precomputedData: {
1500
+ compiledTargetScript: '1234',
1501
+ randomBytes: '5678',
1502
+ estimatedFees: '1000',
1503
+ contractSeed: 'seed',
1504
+ contractAddress: address3,
1505
+ },
1506
+ };
1507
+
1508
+ const serialized = TransactionSerializer.serialize(originalState);
1509
+ const deserialized = TransactionSerializer.deserialize(serialized);
1510
+
1511
+ // Verify header
1512
+ expect(deserialized.header.formatVersion).toBe(originalState.header.formatVersion);
1513
+ expect(deserialized.header.consensusVersion).toBe(originalState.header.consensusVersion);
1514
+ expect(deserialized.header.transactionType).toBe(originalState.header.transactionType);
1515
+ expect(deserialized.header.chainId).toBe(originalState.header.chainId);
1516
+ expect(deserialized.header.timestamp).toBe(originalState.header.timestamp);
1517
+
1518
+ // Verify base params
1519
+ expect(deserialized.baseParams.from).toBe(originalState.baseParams.from);
1520
+ expect(deserialized.baseParams.to).toBe(originalState.baseParams.to);
1521
+ expect(deserialized.baseParams.feeRate).toBeCloseTo(originalState.baseParams.feeRate, 3);
1522
+ expect(deserialized.baseParams.priorityFee).toBe(originalState.baseParams.priorityFee);
1523
+ expect(deserialized.baseParams.gasSatFee).toBe(originalState.baseParams.gasSatFee);
1524
+ expect(deserialized.baseParams.networkName).toBe(originalState.baseParams.networkName);
1525
+ expect(deserialized.baseParams.txVersion).toBe(originalState.baseParams.txVersion);
1526
+ expect(deserialized.baseParams.note).toBe(originalState.baseParams.note);
1527
+ expect(deserialized.baseParams.anchor).toBe(originalState.baseParams.anchor);
1528
+ expect(deserialized.baseParams.debugFees).toBe(originalState.baseParams.debugFees);
1529
+
1530
+ // Verify UTXOs
1531
+ expect(deserialized.utxos).toEqual(originalState.utxos);
1532
+
1533
+ // Verify optional inputs/outputs
1534
+ expect(deserialized.optionalInputs).toEqual(originalState.optionalInputs);
1535
+ expect(deserialized.optionalOutputs).toEqual(originalState.optionalOutputs);
1536
+
1537
+ // Verify address rotation
1538
+ expect(deserialized.addressRotationEnabled).toBe(originalState.addressRotationEnabled);
1539
+ expect(deserialized.signerMappings).toEqual(originalState.signerMappings);
1540
+
1541
+ // Verify type-specific data
1542
+ expect(deserialized.typeSpecificData).toEqual(originalState.typeSpecificData);
1543
+
1544
+ // Verify precomputed data
1545
+ expect(deserialized.precomputedData).toEqual(originalState.precomputedData);
1546
+ });
1547
+
1548
+ it('should preserve data through export/import/reconstruct cycle', () => {
1549
+ const params = {
1550
+ signer: defaultSigner,
1551
+ mldsaSigner: null,
1552
+ network,
1553
+ utxos: [
1554
+ createTaprootUtxo(address1, 50000n, '1'.repeat(64), 0),
1555
+ createTaprootUtxo(address2, 30000n, '2'.repeat(64), 1),
1556
+ ],
1557
+ from: address1,
1558
+ to: address3,
1559
+ feeRate: 20,
1560
+ priorityFee: 2000n,
1561
+ gasSatFee: 1000n,
1562
+ amount: 60000n,
1563
+ splitInputsInto: 2,
1564
+ };
1565
+
1566
+ // Export
1567
+ const exported = OfflineTransactionManager.exportFunding(params);
1568
+
1569
+ // Inspect
1570
+ const inspected = OfflineTransactionManager.inspect(exported);
1571
+ expect(inspected.baseParams.feeRate).toBeCloseTo(20, 3);
1572
+ expect(inspected.utxos).toHaveLength(2);
1573
+
1574
+ // Import with new signer
1575
+ const builder = OfflineTransactionManager.importForSigning(exported, {
1576
+ signer: signer1,
1577
+ });
1578
+
1579
+ expect(builder).toBeDefined();
1580
+ expect(builder.type).toBe(TransactionType.FUNDING);
1581
+ });
1582
+ });
1583
+
1584
+ describe('Actual Transaction Signing', () => {
1585
+ it('should sign a funding transaction through full offline workflow', async () => {
1586
+ // Phase 1: Online - Create and export transaction
1587
+ const params = {
1588
+ signer: defaultSigner,
1589
+ mldsaSigner: null,
1590
+ network,
1591
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, 'a'.repeat(64), 0)],
1592
+ from: defaultAddress,
1593
+ to: address2,
1594
+ feeRate: 10,
1595
+ priorityFee: 1000n,
1596
+ gasSatFee: 500n,
1597
+ amount: 50000n,
1598
+ };
1599
+
1600
+ const exportedState = OfflineTransactionManager.exportFunding(params);
1601
+
1602
+ // Verify export is valid
1603
+ expect(OfflineTransactionManager.validate(exportedState)).toBe(true);
1604
+
1605
+ // Phase 2: Offline - Import, sign, export
1606
+ const signedTxHex = await OfflineTransactionManager.importSignAndExport(
1607
+ exportedState,
1608
+ { signer: defaultSigner },
1609
+ );
1610
+
1611
+ // Verify we got a valid hex transaction
1612
+ expect(signedTxHex).toBeDefined();
1613
+ expect(typeof signedTxHex).toBe('string');
1614
+ expect(signedTxHex.length).toBeGreaterThan(0);
1615
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1616
+ });
1617
+
1618
+ it('should sign using two-step import then sign process', async () => {
1619
+ const params = {
1620
+ signer: signer1,
1621
+ mldsaSigner: null,
1622
+ network,
1623
+ utxos: [createTaprootUtxo(address1, 80000n, 'b'.repeat(64), 0)],
1624
+ from: address1,
1625
+ to: address2,
1626
+ feeRate: 15,
1627
+ priorityFee: 500n,
1628
+ gasSatFee: 300n,
1629
+ amount: 40000n,
1630
+ };
1631
+
1632
+ const exportedState = OfflineTransactionManager.exportFunding(params);
1633
+
1634
+ // Step 1: Import for signing
1635
+ const builder = OfflineTransactionManager.importForSigning(exportedState, {
1636
+ signer: signer1,
1637
+ });
1638
+
1639
+ expect(builder).toBeDefined();
1640
+ expect(builder.type).toBe(TransactionType.FUNDING);
1641
+
1642
+ // Step 2: Sign and export
1643
+ const signedTxHex = await OfflineTransactionManager.signAndExport(builder);
1644
+
1645
+ expect(signedTxHex).toBeDefined();
1646
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1647
+ });
1648
+
1649
+ it('should sign with fee bumping', async () => {
1650
+ const params = {
1651
+ signer: signer2,
1652
+ mldsaSigner: null,
1653
+ network,
1654
+ utxos: [createTaprootUtxo(address2, 120000n, 'c'.repeat(64), 0)],
1655
+ from: address2,
1656
+ to: address3,
1657
+ feeRate: 5,
1658
+ priorityFee: 200n,
1659
+ gasSatFee: 100n,
1660
+ amount: 60000n,
1661
+ };
1662
+
1663
+ const originalState = OfflineTransactionManager.exportFunding(params);
1664
+
1665
+ // Verify original fee rate
1666
+ const originalInspected = OfflineTransactionManager.inspect(originalState);
1667
+ expect(originalInspected.baseParams.feeRate).toBeCloseTo(5, 3);
1668
+
1669
+ // Bump fee to 25 sat/vB
1670
+ const bumpedState = OfflineTransactionManager.rebuildWithNewFees(
1671
+ originalState,
1672
+ 25,
1673
+ );
1674
+
1675
+ // Verify bumped fee rate
1676
+ const bumpedInspected = OfflineTransactionManager.inspect(bumpedState);
1677
+ expect(bumpedInspected.baseParams.feeRate).toBeCloseTo(25, 3);
1678
+
1679
+ // Sign the bumped transaction
1680
+ const signedTxHex = await OfflineTransactionManager.importSignAndExport(
1681
+ bumpedState,
1682
+ { signer: signer2 },
1683
+ );
1684
+
1685
+ expect(signedTxHex).toBeDefined();
1686
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1687
+ });
1688
+
1689
+ it('should sign with rebuildSignAndExport convenience method', async () => {
1690
+ const params = {
1691
+ signer: signer3,
1692
+ mldsaSigner: null,
1693
+ network,
1694
+ utxos: [createTaprootUtxo(address3, 90000n, 'd'.repeat(64), 0)],
1695
+ from: address3,
1696
+ to: address1,
1697
+ feeRate: 8,
1698
+ priorityFee: 300n,
1699
+ gasSatFee: 150n,
1700
+ amount: 45000n,
1701
+ };
1702
+
1703
+ const originalState = OfflineTransactionManager.exportFunding(params);
1704
+
1705
+ // Bump and sign in one call
1706
+ const signedTxHex = await OfflineTransactionManager.rebuildSignAndExport(
1707
+ originalState,
1708
+ 40, // New fee rate
1709
+ { signer: signer3 },
1710
+ );
1711
+
1712
+ expect(signedTxHex).toBeDefined();
1713
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1714
+ });
1715
+
1716
+ it('should sign with multiple UTXOs', async () => {
1717
+ const params = {
1718
+ signer: defaultSigner,
1719
+ mldsaSigner: null,
1720
+ network,
1721
+ utxos: [
1722
+ createTaprootUtxo(defaultAddress, 30000n, 'e'.repeat(64), 0),
1723
+ createTaprootUtxo(defaultAddress, 40000n, 'f'.repeat(64), 1),
1724
+ createTaprootUtxo(defaultAddress, 50000n, '1'.repeat(64), 2),
1725
+ ],
1726
+ from: defaultAddress,
1727
+ to: address2,
1728
+ feeRate: 12,
1729
+ priorityFee: 600n,
1730
+ gasSatFee: 400n,
1731
+ amount: 100000n,
1732
+ };
1733
+
1734
+ const exportedState = OfflineTransactionManager.exportFunding(params);
1735
+
1736
+ // Verify all UTXOs are captured
1737
+ const inspected = OfflineTransactionManager.inspect(exportedState);
1738
+ expect(inspected.utxos).toHaveLength(3);
1739
+
1740
+ // Sign
1741
+ const signedTxHex = await OfflineTransactionManager.importSignAndExport(
1742
+ exportedState,
1743
+ { signer: defaultSigner },
1744
+ );
1745
+
1746
+ expect(signedTxHex).toBeDefined();
1747
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1748
+ });
1749
+
1750
+ it('should sign with address rotation using multiple signers', async () => {
1751
+ // For address rotation, UTXOs must use addresses that match the signers
1752
+ // Use all UTXOs from defaultAddress with defaultSigner for simplicity
1753
+ const signerMap = createSignerMap([
1754
+ [defaultAddress, defaultSigner],
1755
+ ]);
1756
+
1757
+ const params = {
1758
+ signer: defaultSigner,
1759
+ mldsaSigner: null,
1760
+ network,
1761
+ utxos: [
1762
+ createTaprootUtxo(defaultAddress, 50000n, '2'.repeat(64), 0),
1763
+ createTaprootUtxo(defaultAddress, 60000n, '3'.repeat(64), 1),
1764
+ ],
1765
+ from: defaultAddress,
1766
+ to: address3,
1767
+ feeRate: 10,
1768
+ priorityFee: 500n,
1769
+ gasSatFee: 250n,
1770
+ amount: 80000n,
1771
+ addressRotation: createAddressRotation(signerMap),
1772
+ };
1773
+
1774
+ const exportedState = OfflineTransactionManager.exportFunding(params);
1775
+
1776
+ // Verify address rotation is captured
1777
+ const inspected = OfflineTransactionManager.inspect(exportedState);
1778
+ expect(inspected.addressRotationEnabled).toBe(true);
1779
+ expect(inspected.signerMappings.length).toBeGreaterThan(0);
1780
+
1781
+ // Sign with address rotation
1782
+ const signedTxHex = await OfflineTransactionManager.importSignAndExport(
1783
+ exportedState,
1784
+ {
1785
+ signer: defaultSigner,
1786
+ signerMap,
1787
+ },
1788
+ );
1789
+
1790
+ expect(signedTxHex).toBeDefined();
1791
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1792
+ });
1793
+
1794
+ it('should produce different signatures with different signers', async () => {
1795
+ // Export state that can be signed by either signer
1796
+ const params = {
1797
+ signer: signer1,
1798
+ mldsaSigner: null,
1799
+ network,
1800
+ utxos: [createTaprootUtxo(address1, 100000n, '4'.repeat(64), 0)],
1801
+ from: address1,
1802
+ to: address2,
1803
+ feeRate: 10,
1804
+ priorityFee: 1000n,
1805
+ gasSatFee: 500n,
1806
+ amount: 50000n,
1807
+ };
1808
+
1809
+ const exportedState = OfflineTransactionManager.exportFunding(params);
1810
+
1811
+ // Sign with signer1
1812
+ const signedTx1 = await OfflineTransactionManager.importSignAndExport(
1813
+ exportedState,
1814
+ { signer: signer1 },
1815
+ );
1816
+
1817
+ // Sign again with signer1 (should produce same structure, potentially different due to nonce)
1818
+ const signedTx1Again = await OfflineTransactionManager.importSignAndExport(
1819
+ exportedState,
1820
+ { signer: signer1 },
1821
+ );
1822
+
1823
+ // Both signatures should be valid hex
1824
+ expect(/^[0-9a-f]+$/i.test(signedTx1)).toBe(true);
1825
+ expect(/^[0-9a-f]+$/i.test(signedTx1Again)).toBe(true);
1826
+
1827
+ // Transaction structure should be similar in length
1828
+ // (exact match not guaranteed due to Schnorr signature randomness)
1829
+ expect(Math.abs(signedTx1.length - signedTx1Again.length)).toBeLessThan(10);
1830
+ });
1831
+
1832
+ it('should handle split funding transaction', async () => {
1833
+ const params = {
1834
+ signer: defaultSigner,
1835
+ mldsaSigner: null,
1836
+ network,
1837
+ utxos: [createTaprootUtxo(defaultAddress, 200000n, '5'.repeat(64), 0)],
1838
+ from: defaultAddress,
1839
+ to: address2,
1840
+ feeRate: 10,
1841
+ priorityFee: 1000n,
1842
+ gasSatFee: 500n,
1843
+ amount: 150000n,
1844
+ splitInputsInto: 3, // Split into 3 outputs
1845
+ };
1846
+
1847
+ const exportedState = OfflineTransactionManager.exportFunding(params);
1848
+
1849
+ // Verify split is captured
1850
+ const inspected = OfflineTransactionManager.inspect(exportedState);
1851
+ expect(isFundingSpecificData(inspected.typeSpecificData)).toBe(true);
1852
+ const fundingData = inspected.typeSpecificData as FundingSpecificData;
1853
+ expect(fundingData.splitInputsInto).toBe(3);
1854
+
1855
+ // Sign
1856
+ const signedTxHex = await OfflineTransactionManager.importSignAndExport(
1857
+ exportedState,
1858
+ { signer: defaultSigner },
1859
+ );
1860
+
1861
+ expect(signedTxHex).toBeDefined();
1862
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1863
+ });
1864
+
1865
+ it('should sign after format conversion (base64 -> hex -> base64)', async () => {
1866
+ const params = {
1867
+ signer: signer1,
1868
+ mldsaSigner: null,
1869
+ network,
1870
+ utxos: [createTaprootUtxo(address1, 75000n, '6'.repeat(64), 0)],
1871
+ from: address1,
1872
+ to: address3,
1873
+ feeRate: 20,
1874
+ priorityFee: 800n,
1875
+ gasSatFee: 400n,
1876
+ amount: 35000n,
1877
+ };
1878
+
1879
+ // Export as base64
1880
+ const base64State = OfflineTransactionManager.exportFunding(params);
1881
+
1882
+ // Convert to hex
1883
+ const hexState = OfflineTransactionManager.toHex(base64State);
1884
+ expect(/^[0-9a-f]+$/i.test(hexState)).toBe(true);
1885
+
1886
+ // Convert back to base64
1887
+ const backToBase64 = OfflineTransactionManager.fromHex(hexState);
1888
+
1889
+ // Both should validate
1890
+ expect(OfflineTransactionManager.validate(base64State)).toBe(true);
1891
+ expect(OfflineTransactionManager.validate(backToBase64)).toBe(true);
1892
+
1893
+ // Sign from the converted state
1894
+ const signedTxHex = await OfflineTransactionManager.importSignAndExport(
1895
+ backToBase64,
1896
+ { signer: signer1 },
1897
+ );
1898
+
1899
+ expect(signedTxHex).toBeDefined();
1900
+ expect(/^[0-9a-f]+$/i.test(signedTxHex)).toBe(true);
1901
+ });
1902
+ });
1903
+
1904
+ describe('MultiSig Offline Signing', () => {
1905
+ it('should export and validate multisig state', () => {
1906
+ const pubkeys: Uint8Array[] = [
1907
+ new Uint8Array(signer1.publicKey),
1908
+ new Uint8Array(signer2.publicKey),
1909
+ new Uint8Array(signer3.publicKey),
1910
+ ];
1911
+
1912
+ const params = {
1913
+ signer: defaultSigner,
1914
+ network,
1915
+ mldsaSigner: null,
1916
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, 'a'.repeat(64), 0)],
1917
+ feeRate: 10,
1918
+ priorityFee: 0n,
1919
+ gasSatFee: 0n,
1920
+ pubkeys,
1921
+ minimumSignatures: 2,
1922
+ receiver: address1,
1923
+ requestedAmount: 50000n,
1924
+ refundVault: address2,
1925
+ };
1926
+
1927
+ const state = OfflineTransactionManager.exportMultiSig(params);
1928
+
1929
+ expect(OfflineTransactionManager.validate(state)).toBe(true);
1930
+ expect(OfflineTransactionManager.getType(state)).toBe(TransactionType.MULTI_SIG);
1931
+
1932
+ const inspected = OfflineTransactionManager.inspect(state);
1933
+ expect(inspected.typeSpecificData.type).toBe(TransactionType.MULTI_SIG);
1934
+ });
1935
+
1936
+ it('should serialize and deserialize multisig specific data', () => {
1937
+ const pubkeys: Uint8Array[] = [
1938
+ new Uint8Array(signer1.publicKey),
1939
+ new Uint8Array(signer2.publicKey),
1940
+ ];
1941
+
1942
+ const params = {
1943
+ signer: defaultSigner,
1944
+ network,
1945
+ mldsaSigner: null,
1946
+ utxos: [createTaprootUtxo(defaultAddress, 80000n, 'b'.repeat(64), 0)],
1947
+ feeRate: 15,
1948
+ priorityFee: 0n,
1949
+ gasSatFee: 0n,
1950
+ pubkeys,
1951
+ minimumSignatures: 2,
1952
+ receiver: address1,
1953
+ requestedAmount: 40000n,
1954
+ refundVault: address2,
1955
+ };
1956
+
1957
+ const state = OfflineTransactionManager.exportMultiSig(params);
1958
+ const inspected = OfflineTransactionManager.inspect(state);
1959
+
1960
+ expect(isMultiSigSpecificData(inspected.typeSpecificData)).toBe(true);
1961
+
1962
+ if (isMultiSigSpecificData(inspected.typeSpecificData)) {
1963
+ expect(inspected.typeSpecificData.pubkeys).toHaveLength(2);
1964
+ expect(inspected.typeSpecificData.minimumSignatures).toBe(2);
1965
+ expect(inspected.typeSpecificData.receiver).toBe(address1);
1966
+ expect(inspected.typeSpecificData.requestedAmount).toBe('40000');
1967
+ expect(inspected.typeSpecificData.refundVault).toBe(address2);
1968
+ }
1969
+ });
1970
+
1971
+ it('should report no signatures initially', () => {
1972
+ const pubkeys: Uint8Array[] = [
1973
+ new Uint8Array(signer1.publicKey),
1974
+ new Uint8Array(signer2.publicKey),
1975
+ ];
1976
+
1977
+ const params = {
1978
+ signer: defaultSigner,
1979
+ network,
1980
+ mldsaSigner: null,
1981
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, 'c'.repeat(64), 0)],
1982
+ feeRate: 10,
1983
+ priorityFee: 0n,
1984
+ gasSatFee: 0n,
1985
+ pubkeys,
1986
+ minimumSignatures: 2,
1987
+ receiver: address1,
1988
+ requestedAmount: 50000n,
1989
+ refundVault: address2,
1990
+ };
1991
+
1992
+ const state = OfflineTransactionManager.exportMultiSig(params);
1993
+ const status = OfflineTransactionManager.multiSigGetSignatureStatus(state);
1994
+
1995
+ expect(status.required).toBe(2);
1996
+ expect(status.collected).toBe(0);
1997
+ expect(status.isComplete).toBe(false);
1998
+ expect(status.signers).toHaveLength(0);
1999
+ });
2000
+
2001
+ it('should return null for PSBT before signing', () => {
2002
+ const pubkeys: Uint8Array[] = [
2003
+ new Uint8Array(signer1.publicKey),
2004
+ new Uint8Array(signer2.publicKey),
2005
+ ];
2006
+
2007
+ const params = {
2008
+ signer: defaultSigner,
2009
+ network,
2010
+ mldsaSigner: null,
2011
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, 'd'.repeat(64), 0)],
2012
+ feeRate: 10,
2013
+ priorityFee: 0n,
2014
+ gasSatFee: 0n,
2015
+ pubkeys,
2016
+ minimumSignatures: 2,
2017
+ receiver: address1,
2018
+ requestedAmount: 50000n,
2019
+ refundVault: address2,
2020
+ };
2021
+
2022
+ const state = OfflineTransactionManager.exportMultiSig(params);
2023
+ const psbt = OfflineTransactionManager.multiSigGetPsbt(state);
2024
+
2025
+ expect(psbt).toBeNull();
2026
+ });
2027
+
2028
+ it('should report signer has not signed before signing', () => {
2029
+ const pubkeys: Uint8Array[] = [
2030
+ new Uint8Array(signer1.publicKey),
2031
+ new Uint8Array(signer2.publicKey),
2032
+ ];
2033
+
2034
+ const params = {
2035
+ signer: defaultSigner,
2036
+ network,
2037
+ mldsaSigner: null,
2038
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, 'e'.repeat(64), 0)],
2039
+ feeRate: 10,
2040
+ priorityFee: 0n,
2041
+ gasSatFee: 0n,
2042
+ pubkeys,
2043
+ minimumSignatures: 2,
2044
+ receiver: address1,
2045
+ requestedAmount: 50000n,
2046
+ refundVault: address2,
2047
+ };
2048
+
2049
+ const state = OfflineTransactionManager.exportMultiSig(params);
2050
+
2051
+ expect(OfflineTransactionManager.multiSigHasSigned(state, new Uint8Array(signer1.publicKey))).toBe(false);
2052
+ expect(OfflineTransactionManager.multiSigHasSigned(state, new Uint8Array(signer2.publicKey))).toBe(false);
2053
+ });
2054
+
2055
+ it('should throw error for non-multisig state in multisig methods', () => {
2056
+ const fundingParams = {
2057
+ signer: defaultSigner,
2058
+ mldsaSigner: null,
2059
+ network,
2060
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, 'f'.repeat(64), 0)],
2061
+ from: defaultAddress,
2062
+ to: address1,
2063
+ feeRate: 10,
2064
+ priorityFee: 1000n,
2065
+ gasSatFee: 500n,
2066
+ amount: 50000n,
2067
+ };
2068
+
2069
+ const fundingState = OfflineTransactionManager.exportFunding(fundingParams);
2070
+
2071
+ expect(() => OfflineTransactionManager.multiSigGetSignatureStatus(fundingState))
2072
+ .toThrow('State is not a multisig transaction');
2073
+
2074
+ expect(() => OfflineTransactionManager.multiSigHasSigned(fundingState, new Uint8Array(signer1.publicKey)))
2075
+ .toThrow('State is not a multisig transaction');
2076
+
2077
+ expect(() => OfflineTransactionManager.multiSigGetPsbt(fundingState))
2078
+ .toThrow('State is not a multisig transaction');
2079
+
2080
+ expect(() => OfflineTransactionManager.multiSigFinalize(fundingState))
2081
+ .toThrow('State is not a multisig transaction');
2082
+ });
2083
+
2084
+ it('should throw error when finalizing without signatures', () => {
2085
+ const pubkeys: Uint8Array[] = [
2086
+ new Uint8Array(signer1.publicKey),
2087
+ new Uint8Array(signer2.publicKey),
2088
+ ];
2089
+
2090
+ const params = {
2091
+ signer: defaultSigner,
2092
+ network,
2093
+ mldsaSigner: null,
2094
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, '1'.repeat(64), 0)],
2095
+ feeRate: 10,
2096
+ priorityFee: 0n,
2097
+ gasSatFee: 0n,
2098
+ pubkeys,
2099
+ minimumSignatures: 2,
2100
+ receiver: address1,
2101
+ requestedAmount: 50000n,
2102
+ refundVault: address2,
2103
+ };
2104
+
2105
+ const state = OfflineTransactionManager.exportMultiSig(params);
2106
+
2107
+ expect(() => OfflineTransactionManager.multiSigFinalize(state))
2108
+ .toThrow('No PSBT found in state');
2109
+ });
2110
+
2111
+ it('should update PSBT in state', () => {
2112
+ const pubkeys: Uint8Array[] = [
2113
+ new Uint8Array(signer1.publicKey),
2114
+ new Uint8Array(signer2.publicKey),
2115
+ ];
2116
+
2117
+ const params = {
2118
+ signer: defaultSigner,
2119
+ network,
2120
+ mldsaSigner: null,
2121
+ utxos: [createTaprootUtxo(defaultAddress, 100000n, '2'.repeat(64), 0)],
2122
+ feeRate: 10,
2123
+ priorityFee: 0n,
2124
+ gasSatFee: 0n,
2125
+ pubkeys,
2126
+ minimumSignatures: 2,
2127
+ receiver: address1,
2128
+ requestedAmount: 50000n,
2129
+ refundVault: address2,
2130
+ };
2131
+
2132
+ const state = OfflineTransactionManager.exportMultiSig(params);
2133
+
2134
+ // Update with a mock PSBT
2135
+ const mockPsbtBase64 = 'cHNidP8BAH0CAAAAAb=='; // Minimal valid base64
2136
+ const updatedState = OfflineTransactionManager.multiSigUpdatePsbt(state, mockPsbtBase64);
2137
+
2138
+ const inspected = OfflineTransactionManager.inspect(updatedState);
2139
+ if (isMultiSigSpecificData(inspected.typeSpecificData)) {
2140
+ expect(inspected.typeSpecificData.existingPsbtBase64).toBe(mockPsbtBase64);
2141
+ }
2142
+ });
2143
+
2144
+ it('should preserve multisig data through serialization round-trip', () => {
2145
+ const pubkeys: Uint8Array[] = [
2146
+ new Uint8Array(signer1.publicKey),
2147
+ new Uint8Array(signer2.publicKey),
2148
+ new Uint8Array(signer3.publicKey),
2149
+ ];
2150
+
2151
+ const params = {
2152
+ signer: defaultSigner,
2153
+ network,
2154
+ mldsaSigner: null,
2155
+ utxos: [
2156
+ createTaprootUtxo(defaultAddress, 50000n, '3'.repeat(64), 0),
2157
+ createTaprootUtxo(defaultAddress, 60000n, '4'.repeat(64), 1),
2158
+ ],
2159
+ feeRate: 20,
2160
+ priorityFee: 0n,
2161
+ gasSatFee: 0n,
2162
+ pubkeys,
2163
+ minimumSignatures: 2,
2164
+ receiver: address1,
2165
+ requestedAmount: 80000n,
2166
+ refundVault: address2,
2167
+ };
2168
+
2169
+ // Export
2170
+ const state = OfflineTransactionManager.exportMultiSig(params);
2171
+
2172
+ // Convert to hex and back
2173
+ const hexState = OfflineTransactionManager.toHex(state);
2174
+ const backToBase64 = OfflineTransactionManager.fromHex(hexState);
2175
+
2176
+ // Verify data preserved
2177
+ const original = OfflineTransactionManager.inspect(state);
2178
+ const restored = OfflineTransactionManager.inspect(backToBase64);
2179
+
2180
+ expect(restored.typeSpecificData).toEqual(original.typeSpecificData);
2181
+ expect(restored.utxos).toHaveLength(2);
2182
+ });
2183
+ });
2184
+ });
2185
+
2186
+ // Helper function to create mock challenge data
2187
+ function createMockChallenge() {
2188
+ return {
2189
+ epochNumber: '100',
2190
+ mldsaPublicKey: '0x' + 'aa'.repeat(32),
2191
+ legacyPublicKey: '0x' + 'bb'.repeat(33),
2192
+ solution: '0x' + 'cc'.repeat(32),
2193
+ salt: '0x' + 'dd'.repeat(32),
2194
+ graffiti: '0x' + 'ee'.repeat(16),
2195
+ difficulty: 20,
2196
+ verification: {
2197
+ epochHash: '0x' + '11'.repeat(32),
2198
+ epochRoot: '0x' + '22'.repeat(32),
2199
+ targetHash: '0x' + '33'.repeat(32),
2200
+ targetChecksum: '0x' + '44'.repeat(32),
2201
+ startBlock: '1000',
2202
+ endBlock: '2000',
2203
+ proofs: ['0x' + '55'.repeat(32), '0x' + '66'.repeat(32)],
2204
+ },
2205
+ };
2206
+ }