@btc-vision/transaction 1.0.85 → 1.0.87

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 (281) hide show
  1. package/.gitattributes +2 -2
  2. package/browser/_version.d.ts +1 -1
  3. package/browser/index.js +1 -1
  4. package/browser/keypair/Wallet.d.ts +3 -0
  5. package/browser/transaction/builders/TapUnwarpTransaction.d.ts +40 -40
  6. package/browser/transaction/builders/UnwarpTransaction.d.ts +34 -34
  7. package/browser/utxo/UTXOManager.d.ts +7 -7
  8. package/build/Utils.d.ts +0 -0
  9. package/build/Utils.js +1 -0
  10. package/build/_version.d.ts +1 -1
  11. package/build/_version.js +1 -1
  12. package/build/consensus/metadata/RoswsellConsensus.d.ts +2 -0
  13. package/build/consensus/metadata/RoswsellConsensus.js +4 -0
  14. package/build/contracts/ContractMetadataManager.d.ts +0 -0
  15. package/build/contracts/ContractMetadataManager.js +1 -0
  16. package/build/generators/OPNetAddressGenerator.d.ts +0 -0
  17. package/build/generators/OPNetAddressGenerator.js +1 -0
  18. package/build/generators/builders/UnwrapGenerator.d.ts +8 -0
  19. package/build/generators/builders/UnwrapGenerator.js +79 -0
  20. package/build/keypair/Wallet.d.ts +3 -0
  21. package/build/keypair/Wallet.js +8 -0
  22. package/build/keypair/interfaces/GeneratedWallet.d.ts +5 -0
  23. package/build/keypair/interfaces/GeneratedWallet.js +1 -0
  24. package/build/metadata/CommonContracts.d.ts +6 -0
  25. package/build/metadata/CommonContracts.js +5 -0
  26. package/build/metadata/ContractMetadataManager.d.ts +1 -0
  27. package/build/metadata/ContractMetadataManager.js +9 -0
  28. package/build/metadata/contracts/ContractBase.d.ts +9 -0
  29. package/build/metadata/contracts/ContractBase.js +13 -0
  30. package/build/metadata/contracts/ContractBaseMetadata.d.ts +9 -0
  31. package/build/metadata/contracts/ContractBaseMetadata.js +13 -0
  32. package/build/metadata/contracts/ContractMetadataManager.d.ts +0 -0
  33. package/build/metadata/contracts/ContractMetadataManager.js +1 -0
  34. package/build/metadata/tokens.js +1 -1
  35. package/build/network/NetworkConverter.d.ts +0 -0
  36. package/build/network/NetworkConverter.js +14 -0
  37. package/build/scripts/Regtest.d.ts +2 -0
  38. package/build/scripts/Regtest.js +15 -0
  39. package/build/scripts/test.d.ts +1 -0
  40. package/build/scripts/test.js +74 -0
  41. package/build/signer/Regtest.d.ts +2 -0
  42. package/build/signer/Regtest.js +15 -0
  43. package/build/tests/Regtest.d.ts +3 -0
  44. package/build/tests/Regtest.js +29 -0
  45. package/build/tests/adaptPSBT.d.ts +1 -0
  46. package/build/tests/adaptPSBT.js +44 -0
  47. package/build/tests/btc/send.d.ts +1 -0
  48. package/build/tests/btc/send.js +35 -0
  49. package/build/tests/btc/transfer.d.ts +1 -0
  50. package/build/tests/btc/transfer.js +35 -0
  51. package/build/tests/createPairReg.d.ts +1 -0
  52. package/build/tests/createPairReg.js +73 -0
  53. package/build/tests/deploy/deployMoto.d.ts +4 -0
  54. package/build/tests/deploy/deployMoto.js +89 -0
  55. package/build/tests/deploy/deployPool.d.ts +1 -0
  56. package/build/tests/deploy/deployPool.js +5 -0
  57. package/build/tests/deploy/deployStep1.d.ts +1 -0
  58. package/build/tests/deploy/deployStep1.js +5 -0
  59. package/build/tests/deploy/deployStep2.d.ts +1 -0
  60. package/build/tests/deploy/deployStep2.js +5 -0
  61. package/build/tests/deploy/deployStep3.d.ts +1 -0
  62. package/build/tests/deploy/deployStep3.js +5 -0
  63. package/build/tests/deploy.d.ts +1 -0
  64. package/build/tests/deploy.js +41 -0
  65. package/build/tests/deployMotoRegStep1.d.ts +1 -0
  66. package/build/tests/deployMotoRegStep1.js +85 -0
  67. package/build/tests/deployReg.d.ts +1 -0
  68. package/build/tests/deployReg.js +85 -0
  69. package/build/tests/factory/createPairReg.d.ts +1 -0
  70. package/build/tests/factory/createPairReg.js +13 -0
  71. package/build/tests/gen.d.ts +1 -0
  72. package/build/tests/gen.js +19 -0
  73. package/build/tests/interaction.d.ts +5 -0
  74. package/build/tests/interaction.js +62 -0
  75. package/build/tests/massWrapReg.d.ts +1 -0
  76. package/build/tests/massWrapReg.js +105 -0
  77. package/build/tests/mineReg.d.ts +1 -0
  78. package/build/tests/mineReg.js +19 -0
  79. package/build/tests/moto/airdropToken.d.ts +1 -0
  80. package/build/tests/moto/airdropToken.js +21 -0
  81. package/build/tests/moto/airdropTokens.d.ts +1 -0
  82. package/build/tests/moto/airdropTokens.js +60 -0
  83. package/build/tests/moto/allowance.d.ts +1 -0
  84. package/build/tests/moto/allowance.js +6 -0
  85. package/build/tests/moto/approve.d.ts +1 -0
  86. package/build/tests/moto/approve.js +10 -0
  87. package/build/tests/moto/approveWBTC.d.ts +1 -0
  88. package/build/tests/moto/approveWBTC.js +12 -0
  89. package/build/tests/moto/balanceOf.d.ts +1 -0
  90. package/build/tests/moto/balanceOf.js +12 -0
  91. package/build/tests/moto/transfer.d.ts +1 -0
  92. package/build/tests/moto/transfer.js +16 -0
  93. package/build/tests/motoswap/airdropToken.d.ts +11 -0
  94. package/build/tests/motoswap/airdropToken.js +36 -0
  95. package/build/tests/motoswap/deployMoto.d.ts +4 -0
  96. package/build/tests/motoswap/deployMoto.js +89 -0
  97. package/build/tests/motoswap/deployMotoRegStep1.d.ts +1 -0
  98. package/build/tests/motoswap/deployMotoRegStep1.js +91 -0
  99. package/build/tests/motoswap/deployMotoRegStep2.d.ts +1 -0
  100. package/build/tests/motoswap/deployMotoRegStep2.js +91 -0
  101. package/build/tests/motoswap/deployPool.d.ts +1 -0
  102. package/build/tests/motoswap/deployPool.js +5 -0
  103. package/build/tests/motoswap/deployStep1.d.ts +1 -0
  104. package/build/tests/motoswap/deployStep1.js +5 -0
  105. package/build/tests/motoswap/deployStep2.d.ts +1 -0
  106. package/build/tests/motoswap/deployStep2.js +5 -0
  107. package/build/tests/motoswap/deployStep3.d.ts +1 -0
  108. package/build/tests/motoswap/deployStep3.js +5 -0
  109. package/build/tests/motoswap/interaction.d.ts +3 -0
  110. package/build/tests/motoswap/interaction.js +63 -0
  111. package/build/tests/motoswap/routerAddLiquidity.d.ts +11 -0
  112. package/build/tests/motoswap/routerAddLiquidity.js +35 -0
  113. package/build/tests/motoswap-router/addLiquidity.d.ts +11 -0
  114. package/build/tests/motoswap-router/addLiquidity.js +36 -0
  115. package/build/tests/motoswap-router/deployMoto.d.ts +4 -0
  116. package/build/tests/motoswap-router/deployMoto.js +89 -0
  117. package/build/tests/motoswap-router/deployPool.d.ts +1 -0
  118. package/build/tests/motoswap-router/deployPool.js +5 -0
  119. package/build/tests/motoswap-router/deployStep1.d.ts +1 -0
  120. package/build/tests/motoswap-router/deployStep1.js +5 -0
  121. package/build/tests/motoswap-router/deployStep2.d.ts +1 -0
  122. package/build/tests/motoswap-router/deployStep2.js +5 -0
  123. package/build/tests/motoswap-router/deployStep3.d.ts +1 -0
  124. package/build/tests/motoswap-router/deployStep3.js +5 -0
  125. package/build/tests/motoswap-router/getAmountsOut.d.ts +5 -0
  126. package/build/tests/motoswap-router/getAmountsOut.js +34 -0
  127. package/build/tests/motoswap-router/routerAddLiquidity.d.ts +11 -0
  128. package/build/tests/motoswap-router/routerAddLiquidity.js +35 -0
  129. package/build/tests/motoswap-router/swap.d.ts +8 -0
  130. package/build/tests/motoswap-router/swap.js +24 -0
  131. package/build/tests/multisign.d.ts +1 -0
  132. package/build/tests/multisign.js +47 -0
  133. package/build/tests/multisign2.d.ts +1 -0
  134. package/build/tests/multisign2.js +27 -0
  135. package/build/tests/pool/DecodePoolAddress.d.ts +6 -0
  136. package/build/tests/pool/DecodePoolAddress.js +12 -0
  137. package/build/tests/pool/decodeReserves.d.ts +5 -0
  138. package/build/tests/pool/decodeReserves.js +13 -0
  139. package/build/tests/pool/reserves.d.ts +1 -0
  140. package/build/tests/pool/reserves.js +18 -0
  141. package/build/tests/shared/Utils.d.ts +2 -0
  142. package/build/tests/shared/Utils.js +14 -0
  143. package/build/tests/shared/interaction.d.ts +7 -0
  144. package/build/tests/shared/interaction.js +85 -0
  145. package/build/tests/shared/tokens.d.ts +6 -0
  146. package/build/tests/shared/tokens.js +5 -0
  147. package/build/tests/stakeReg.d.ts +1 -0
  148. package/build/tests/stakeReg.js +73 -0
  149. package/build/tests/stakedReg.d.ts +1 -0
  150. package/build/tests/stakedReg.js +28 -0
  151. package/build/tests/test.d.ts +1 -0
  152. package/build/tests/test.js +51 -0
  153. package/build/tests/test2.d.ts +1 -0
  154. package/build/tests/test2.js +73 -0
  155. package/build/tests/testReg.d.ts +1 -0
  156. package/build/tests/testReg.js +91 -0
  157. package/build/tests/tokens.d.ts +6 -0
  158. package/build/tests/tokens.js +5 -0
  159. package/build/tests/totalRewardReg.d.ts +1 -0
  160. package/build/tests/totalRewardReg.js +28 -0
  161. package/build/tests/transfer.d.ts +1 -0
  162. package/build/tests/transfer.js +74 -0
  163. package/build/tests/transferReg.d.ts +1 -0
  164. package/build/tests/transferReg.js +74 -0
  165. package/build/tests/unStakeReg.d.ts +1 -0
  166. package/build/tests/unStakeReg.js +72 -0
  167. package/build/tests/unwrapReg.d.ts +1 -0
  168. package/build/tests/unwrapReg.js +61 -0
  169. package/build/tests/unwrapReg2.d.ts +1 -0
  170. package/build/tests/unwrapReg2.js +56 -0
  171. package/build/tests/unwrapRegSegwit.d.ts +1 -0
  172. package/build/tests/unwrapRegSegwit.js +83 -0
  173. package/build/tests/wbtc/approve.d.ts +1 -0
  174. package/build/tests/wbtc/approve.js +6 -0
  175. package/build/tests/wbtc/approveWBTC.d.ts +1 -0
  176. package/build/tests/wbtc/approveWBTC.js +12 -0
  177. package/build/tests/wbtc/massWrapReg.d.ts +1 -0
  178. package/build/tests/wbtc/massWrapReg.js +105 -0
  179. package/build/tests/wbtc/transfer.d.ts +1 -0
  180. package/build/tests/wbtc/transfer.js +16 -0
  181. package/build/tests/wbtc/transferReg.d.ts +1 -0
  182. package/build/tests/wbtc/transferReg.js +16 -0
  183. package/build/tests/wbtc/unStakeReg.d.ts +1 -0
  184. package/build/tests/wbtc/unStakeReg.js +72 -0
  185. package/build/tests/wbtc/unwrapReg.d.ts +1 -0
  186. package/build/tests/wbtc/unwrapReg.js +60 -0
  187. package/build/tests/wbtc/unwrapRegSegwit.d.ts +1 -0
  188. package/build/tests/wbtc/unwrapRegSegwit.js +83 -0
  189. package/build/tests/wbtc/withdrawalRequestReg.d.ts +1 -0
  190. package/build/tests/wbtc/withdrawalRequestReg.js +71 -0
  191. package/build/tests/wbtc/wrapReg.d.ts +1 -0
  192. package/build/tests/wbtc/wrapReg.js +65 -0
  193. package/build/tests/wbtc/wrapTest.d.ts +1 -0
  194. package/build/tests/wbtc/wrapTest.js +66 -0
  195. package/build/tests/withdrawalRequestReg.d.ts +1 -0
  196. package/build/tests/withdrawalRequestReg.js +71 -0
  197. package/build/tests/wrap.d.ts +1 -0
  198. package/build/tests/wrap.js +65 -0
  199. package/build/tests/wrapReg.d.ts +1 -0
  200. package/build/tests/wrapReg.js +68 -0
  201. package/build/tests/wrapTest.d.ts +1 -0
  202. package/build/tests/wrapTest.js +66 -0
  203. package/build/tests/wrapTestg.d.ts +1 -0
  204. package/build/tests/wrapTestg.js +66 -0
  205. package/build/tests/writers/allowance.d.ts +3 -0
  206. package/build/tests/writers/allowance.js +10 -0
  207. package/build/tests/writers/approve.d.ts +4 -0
  208. package/build/tests/writers/approve.js +11 -0
  209. package/build/transaction/TransactionBuilder.d.ts +60 -0
  210. package/build/transaction/TransactionBuilder.js +244 -0
  211. package/build/transaction/TransactionFactory.js +2 -0
  212. package/build/transaction/browser/BrowserSigner.d.ts +11 -0
  213. package/build/transaction/browser/BrowserSigner.js +10 -0
  214. package/build/transaction/browser/extensions/Unisat.d.ts +54 -0
  215. package/build/transaction/browser/extensions/Unisat.js +11 -0
  216. package/build/transaction/builders/GenericTransaction.d.ts +11 -0
  217. package/build/transaction/builders/GenericTransaction.js +23 -0
  218. package/build/transaction/builders/TapUnwarpTransaction.d.ts +37 -0
  219. package/build/transaction/builders/TapUnwarpTransaction.js +201 -0
  220. package/build/transaction/builders/UnwarpSegwitTransaction.d.ts +34 -0
  221. package/build/transaction/builders/UnwarpSegwitTransaction.js +184 -0
  222. package/build/transaction/builders/UnwarpTransaction.d.ts +35 -0
  223. package/build/transaction/builders/UnwarpTransaction.js +199 -0
  224. package/build/transaction/interfaces/ITransactions.d.ts +32 -0
  225. package/build/transaction/interfaces/ITransactions.js +1 -0
  226. package/build/utxo/IUTXO.d.ts +0 -0
  227. package/build/utxo/IUTXO.js +1 -0
  228. package/build/utxo/OPNetUtils.d.ts +7 -0
  229. package/build/utxo/OPNetUtils.js +47 -0
  230. package/build/utxo/UTXOManager.d.ts +7 -0
  231. package/build/utxo/UTXOManager.js +47 -0
  232. package/build/wbtc/BroadcastResponse.d.ts +0 -0
  233. package/build/wbtc/BroadcastResponse.js +1 -0
  234. package/gulpfile.js +152 -152
  235. package/package.json +109 -109
  236. package/src/_version.ts +1 -1
  237. package/src/consensus/Consensus.ts +36 -36
  238. package/src/consensus/ConsensusConfig.ts +39 -39
  239. package/src/crypto/crypto-browser.js +75 -75
  240. package/src/generators/AddressGenerator.ts +24 -24
  241. package/src/generators/Features.ts +5 -5
  242. package/src/generators/Generator.ts +75 -75
  243. package/src/generators/builders/CalldataGenerator.ts +148 -148
  244. package/src/generators/builders/DeploymentGenerator.ts +66 -66
  245. package/src/index.ts +4 -4
  246. package/src/keypair/AddressVerificator.ts +40 -40
  247. package/src/keypair/EcKeyPair.ts +282 -282
  248. package/src/keypair/Wallet.ts +120 -97
  249. package/src/keypair/interfaces/IWallet.ts +19 -19
  250. package/src/metadata/ContractBaseMetadata.ts +23 -23
  251. package/src/metadata/contracts/wBTC.ts +60 -60
  252. package/src/metadata/tokens.ts +1 -1
  253. package/src/network/NetworkInformation.ts +7 -7
  254. package/src/transaction/TransactionFactory.ts +2 -0
  255. package/src/transaction/browser/BrowserSignerBase.ts +37 -37
  256. package/src/transaction/browser/Web3Provider.ts +46 -46
  257. package/src/transaction/browser/extensions/UnisatSigner.ts +218 -218
  258. package/src/transaction/browser/types/Unisat.ts +97 -97
  259. package/src/transaction/builders/FundingTransaction.ts +40 -40
  260. package/src/transaction/builders/InteractionTransaction.ts +38 -38
  261. package/src/transaction/builders/SharedInteractionTransaction.ts +368 -368
  262. package/src/transaction/builders/TransactionBuilder.ts +665 -665
  263. package/src/transaction/builders/UnwrapSegwitTransaction.ts +365 -365
  264. package/src/transaction/builders/UnwrapTransaction.ts +507 -507
  265. package/src/transaction/builders/WrapTransaction.ts +346 -346
  266. package/src/transaction/interfaces/ITransactionParameters.ts +59 -59
  267. package/src/transaction/interfaces/Tap.ts +26 -26
  268. package/src/transaction/psbt/PSBTTypes.ts +3 -3
  269. package/src/transaction/shared/TweakedTransaction.ts +539 -539
  270. package/src/utxo/OPNetLimitedProvider.ts +244 -244
  271. package/src/utxo/interfaces/BroadcastResponse.ts +10 -10
  272. package/src/utxo/interfaces/IUTXO.ts +29 -29
  273. package/src/verification/TapscriptVerificator.ts +89 -89
  274. package/src/wbtc/Generate.ts +40 -40
  275. package/src/wbtc/UnwrapGeneration.ts +13 -13
  276. package/src/wbtc/WrappedGenerationParameters.ts +33 -33
  277. package/webpack.config.js +78 -78
  278. /package/build/generators/builders/{MultiSignGenerator.d.ts → MultisignGenerator.d.ts} +0 -0
  279. /package/build/generators/builders/{MultiSignGenerator.js → MultisignGenerator.js} +0 -0
  280. /package/build/generators/{Features.d.ts → features.d.ts} +0 -0
  281. /package/build/generators/{Features.js → features.js} +0 -0
@@ -1,365 +1,365 @@
1
- import { Taptree } from 'bitcoinjs-lib/src/types.js';
2
- import { TransactionType } from '../enums/TransactionType.js';
3
- import { IUnwrapParameters } from '../interfaces/ITransactionParameters.js';
4
- import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
5
- import { TransactionBuilder } from './TransactionBuilder.js';
6
- import { ABICoder, BinaryWriter, Selector } from '@btc-vision/bsi-binary';
7
- import { wBTC } from '../../metadata/contracts/wBTC.js';
8
- import { payments, Psbt, Signer } from 'bitcoinjs-lib';
9
- import { EcKeyPair } from '../../keypair/EcKeyPair.js';
10
- import { IWBTCUTXODocument, PsbtTransaction, VaultUTXOs } from '../processor/PsbtTransaction.js';
11
- import { PsbtInputExtended, PsbtOutputExtended } from '../interfaces/Tap.js';
12
- import { currentConsensusConfig } from '../../consensus/ConsensusConfig.js';
13
-
14
- const abiCoder: ABICoder = new ABICoder();
15
-
16
- /**
17
- * Unwrap transaction
18
- * @class UnwrapSegwitTransaction
19
- */
20
- export class UnwrapSegwitTransaction extends SharedInteractionTransaction<TransactionType.WBTC_UNWRAP> {
21
- private static readonly UNWRAP_SELECTOR: Selector = Number(
22
- '0x' + abiCoder.encodeSelector('burn'),
23
- );
24
-
25
- public type: TransactionType.WBTC_UNWRAP = TransactionType.WBTC_UNWRAP;
26
-
27
- /**
28
- * The amount to wrap
29
- * @private
30
- */
31
- public readonly amount: bigint;
32
-
33
- /**
34
- * The compiled target script
35
- * @protected
36
- */
37
- protected readonly compiledTargetScript: Buffer;
38
-
39
- /**
40
- * The script tree
41
- * @protected
42
- */
43
- protected readonly scriptTree: Taptree;
44
-
45
- /**
46
- * The sighash types for the transaction
47
- * @protected
48
- */
49
- protected sighashTypes: number[] = []; //Transaction.SIGHASH_ALL, Transaction.SIGHASH_ANYONECANPAY
50
-
51
- /**
52
- * Contract secret for the interaction
53
- * @protected
54
- */
55
- protected readonly contractSecret: Buffer;
56
-
57
- /**
58
- * The vault UTXOs
59
- * @protected
60
- */
61
- protected readonly vaultUTXOs: VaultUTXOs[];
62
-
63
- /**
64
- * The wBTC contract
65
- * @private
66
- */
67
- private readonly wbtc: wBTC;
68
-
69
- private readonly calculatedSignHash: number = PsbtTransaction.calculateSignHash(
70
- this.sighashTypes,
71
- );
72
-
73
- public constructor(parameters: IUnwrapParameters) {
74
- if (parameters.amount < TransactionBuilder.MINIMUM_DUST) {
75
- throw new Error('Amount is below dust limit');
76
- }
77
-
78
- parameters.disableAutoRefund = true; // we have to disable auto refund for this transaction, so it does not create an unwanted output.
79
- parameters.calldata = UnwrapSegwitTransaction.generateBurnCalldata(parameters.amount);
80
-
81
- super(parameters);
82
-
83
- this.wbtc = new wBTC(parameters.network, parameters.chainId);
84
- this.to = this.wbtc.getAddress();
85
-
86
- this.vaultUTXOs = parameters.unwrapUTXOs;
87
-
88
- this.amount = parameters.amount;
89
- this.contractSecret = this.generateSecret();
90
-
91
- this.compiledTargetScript = this.calldataGenerator.compile(
92
- this.calldata,
93
- this.contractSecret,
94
- );
95
-
96
- this.scriptTree = this.getScriptTree();
97
- this.internalInit();
98
- }
99
-
100
- /**
101
- * Generate a valid wBTC calldata
102
- * @param {bigint} amount - The amount to wrap
103
- * @private
104
- * @returns {Buffer} - The calldata
105
- */
106
- public static generateBurnCalldata(amount: bigint): Buffer {
107
- if (!amount) throw new Error('Amount is required');
108
-
109
- const bufWriter: BinaryWriter = new BinaryWriter();
110
- bufWriter.writeSelector(UnwrapSegwitTransaction.UNWRAP_SELECTOR);
111
- bufWriter.writeU256(amount);
112
-
113
- return Buffer.from(bufWriter.getBuffer());
114
- }
115
-
116
- /**
117
- * @description Signs the transaction
118
- * @public
119
- * @returns {Promise<Psbt>} - The signed transaction in hex format
120
- * @throws {Error} - If something went wrong
121
- */
122
- public async signPSBT(): Promise<Psbt> {
123
- if (this.to && !EcKeyPair.verifyContractAddress(this.to, this.network)) {
124
- throw new Error(
125
- 'Invalid contract address. The contract address must be a taproot address.',
126
- );
127
- }
128
-
129
- if (!this.vaultUTXOs.length) {
130
- throw new Error('No vault UTXOs provided');
131
- }
132
-
133
- if (this.signed) throw new Error('Transaction is already signed');
134
- this.signed = true;
135
-
136
- await this.buildTransaction();
137
-
138
- this.ignoreSignatureError();
139
- await this.mergeVaults(this.vaultUTXOs);
140
-
141
- const builtTx = await this.internalBuildTransaction(this.transaction);
142
- if (builtTx) {
143
- return this.transaction;
144
- }
145
-
146
- throw new Error('Could not sign transaction');
147
- }
148
-
149
- /**
150
- * @description Merge vault UTXOs into the transaction
151
- * @param {VaultUTXOs[]} input The vault UTXOs
152
- * @public
153
- */
154
- public async mergeVaults(input: VaultUTXOs[]): Promise<void> {
155
- const firstVault = input[0];
156
- if (!firstVault) {
157
- throw new Error('No vaults provided');
158
- }
159
-
160
- const total = this.getVaultTotalOutputAmount(input);
161
- if (total < this.amount) {
162
- throw new Error(
163
- `Total vault amount (${total} sat) is less than the amount to unwrap (${this.amount} sat)`,
164
- );
165
- }
166
-
167
- const outputLeftAmount = this.calculateOutputLeftAmountFromVaults(input);
168
- if (
169
- outputLeftAmount < currentConsensusConfig.VAULT_MINIMUM_AMOUNT &&
170
- outputLeftAmount !== currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT
171
- ) {
172
- throw new Error(
173
- `Output left amount is below minimum consolidation (${currentConsensusConfig.VAULT_MINIMUM_AMOUNT} sat) amount ${outputLeftAmount} for vault ${firstVault.vault}`,
174
- );
175
- }
176
-
177
- this.addOutput({
178
- address: firstVault.vault,
179
- value: Number(outputLeftAmount),
180
- });
181
-
182
- this.addOutput({
183
- address: this.from,
184
- value: Number(this.amount),
185
- });
186
-
187
- for (const vault of input) {
188
- await this.addVaultInputs(vault);
189
- }
190
- }
191
-
192
- /**
193
- * Builds the transaction.
194
- * @param {Psbt} transaction - The transaction to build
195
- * @protected
196
- * @returns {Promise<boolean>}
197
- * @throws {Error} - If something went wrong while building the transaction
198
- */
199
- protected async internalBuildTransaction(transaction: Psbt): Promise<boolean> {
200
- if (transaction.data.inputs.length === 0) {
201
- const inputs: PsbtInputExtended[] = this.getInputs();
202
- const outputs: PsbtOutputExtended[] = this.getOutputs();
203
-
204
- transaction.setMaximumFeeRate(this._maximumFeeRate);
205
- transaction.addInputs(inputs);
206
-
207
- for (let i = 0; i < this.updateInputs.length; i++) {
208
- transaction.updateInput(i, this.updateInputs[i]);
209
- }
210
-
211
- transaction.addOutputs(outputs);
212
- }
213
-
214
- try {
215
- await this.signInputs(transaction);
216
-
217
- if (this.finalized) {
218
- this.transactionFee = BigInt(transaction.getFee());
219
- }
220
-
221
- return true;
222
- } catch (e) {
223
- const err: Error = e as Error;
224
-
225
- this.error(
226
- `[internalBuildTransaction] Something went wrong while getting building the transaction: ${err.stack}`,
227
- );
228
- }
229
-
230
- return false;
231
- }
232
-
233
- /**
234
- * Generate a multi-signature redeem script
235
- * @param {string[]} publicKeys The public keys
236
- * @param {number} minimum The minimum number of signatures
237
- * @protected
238
- * @returns {{output: Buffer; redeem: Buffer}} The output and redeem script
239
- */
240
- protected generateMultiSignRedeemScript(
241
- publicKeys: string[],
242
- minimum: number,
243
- ): { witnessUtxo: Buffer; redeemScript: Buffer; witnessScript: Buffer } {
244
- const p2ms = payments.p2ms({
245
- m: minimum,
246
- pubkeys: publicKeys.map((key) => Buffer.from(key, 'base64')),
247
- network: this.network,
248
- });
249
-
250
- const p2wsh = payments.p2wsh({
251
- redeem: p2ms,
252
- network: this.network,
253
- });
254
-
255
- const witnessUtxo = p2wsh.output;
256
- const redeemScript = p2wsh.redeem?.output;
257
- const witnessScript = p2ms.output;
258
-
259
- if (!witnessUtxo || !redeemScript || !witnessScript) {
260
- throw new Error('Failed to generate redeem script');
261
- }
262
-
263
- return {
264
- witnessUtxo,
265
- redeemScript,
266
- witnessScript,
267
- };
268
- }
269
-
270
- /**
271
- * @description Add a vault UTXO to the transaction
272
- * @private
273
- */
274
- private addVaultUTXO(
275
- utxo: IWBTCUTXODocument,
276
- witness: {
277
- witnessUtxo: Buffer;
278
- redeemScript: Buffer;
279
- witnessScript: Buffer;
280
- },
281
- ): void {
282
- const input: PsbtInputExtended = {
283
- hash: utxo.hash,
284
- index: utxo.outputIndex,
285
- witnessUtxo: {
286
- script: Buffer.from(utxo.output, 'base64'),
287
- value: Number(utxo.value),
288
- },
289
- witnessScript: witness.witnessScript,
290
- sequence: this.sequence,
291
- };
292
-
293
- if (this.calculatedSignHash) {
294
- input.sighashType = this.calculatedSignHash;
295
- }
296
-
297
- this.addInput(input);
298
- }
299
-
300
- /**
301
- * @description Add vault inputs to the transaction
302
- * @param {VaultUTXOs} vault The vault UTXOs
303
- * @param {Signer} [firstSigner] The first signer
304
- * @private
305
- */
306
- private async addVaultInputs(
307
- vault: VaultUTXOs,
308
- firstSigner: Signer = this.signer,
309
- ): Promise<void> {
310
- const p2wshOutput = this.generateMultiSignRedeemScript(vault.publicKeys, vault.minimum);
311
- for (const utxo of vault.utxos) {
312
- const inputIndex = this.transaction.inputCount;
313
- this.addVaultUTXO(utxo, p2wshOutput);
314
-
315
- if (firstSigner) {
316
- this.log(
317
- `Signing input ${inputIndex} with ${firstSigner.publicKey.toString('hex')}`,
318
- );
319
-
320
- // we don't care if we fail to sign the input
321
- try {
322
- await this.signInput(
323
- this.transaction,
324
- this.transaction.data.inputs[inputIndex],
325
- inputIndex,
326
- this.signer,
327
- );
328
-
329
- this.log(
330
- `Signed input ${inputIndex} with ${firstSigner.publicKey.toString('hex')}`,
331
- );
332
- } catch (e) {
333
- if (!this.ignoreSignatureErrors) {
334
- this.warn(
335
- `Failed to sign input ${inputIndex} with ${firstSigner.publicKey.toString('hex')} ${(e as Error).message}`,
336
- );
337
- }
338
- }
339
- }
340
- }
341
- }
342
-
343
- /**
344
- * @description Calculate the amount left to refund to the first vault.
345
- * @param {VaultUTXOs[]} vaults The vaults
346
- * @private
347
- * @returns {bigint} The amount left
348
- */
349
- private calculateOutputLeftAmountFromVaults(vaults: VaultUTXOs[]): bigint {
350
- const total = this.getVaultTotalOutputAmount(vaults);
351
-
352
- return total - this.amount;
353
- }
354
-
355
- private getVaultTotalOutputAmount(vaults: VaultUTXOs[]): bigint {
356
- let total = BigInt(0);
357
- for (const vault of vaults) {
358
- for (const utxo of vault.utxos) {
359
- total += BigInt(utxo.value);
360
- }
361
- }
362
-
363
- return total;
364
- }
365
- }
1
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
2
+ import { TransactionType } from '../enums/TransactionType.js';
3
+ import { IUnwrapParameters } from '../interfaces/ITransactionParameters.js';
4
+ import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
5
+ import { TransactionBuilder } from './TransactionBuilder.js';
6
+ import { ABICoder, BinaryWriter, Selector } from '@btc-vision/bsi-binary';
7
+ import { wBTC } from '../../metadata/contracts/wBTC.js';
8
+ import { payments, Psbt, Signer } from 'bitcoinjs-lib';
9
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
10
+ import { IWBTCUTXODocument, PsbtTransaction, VaultUTXOs } from '../processor/PsbtTransaction.js';
11
+ import { PsbtInputExtended, PsbtOutputExtended } from '../interfaces/Tap.js';
12
+ import { currentConsensusConfig } from '../../consensus/ConsensusConfig.js';
13
+
14
+ const abiCoder: ABICoder = new ABICoder();
15
+
16
+ /**
17
+ * Unwrap transaction
18
+ * @class UnwrapSegwitTransaction
19
+ */
20
+ export class UnwrapSegwitTransaction extends SharedInteractionTransaction<TransactionType.WBTC_UNWRAP> {
21
+ private static readonly UNWRAP_SELECTOR: Selector = Number(
22
+ '0x' + abiCoder.encodeSelector('burn'),
23
+ );
24
+
25
+ public type: TransactionType.WBTC_UNWRAP = TransactionType.WBTC_UNWRAP;
26
+
27
+ /**
28
+ * The amount to wrap
29
+ * @private
30
+ */
31
+ public readonly amount: bigint;
32
+
33
+ /**
34
+ * The compiled target script
35
+ * @protected
36
+ */
37
+ protected readonly compiledTargetScript: Buffer;
38
+
39
+ /**
40
+ * The script tree
41
+ * @protected
42
+ */
43
+ protected readonly scriptTree: Taptree;
44
+
45
+ /**
46
+ * The sighash types for the transaction
47
+ * @protected
48
+ */
49
+ protected sighashTypes: number[] = []; //Transaction.SIGHASH_ALL, Transaction.SIGHASH_ANYONECANPAY
50
+
51
+ /**
52
+ * Contract secret for the interaction
53
+ * @protected
54
+ */
55
+ protected readonly contractSecret: Buffer;
56
+
57
+ /**
58
+ * The vault UTXOs
59
+ * @protected
60
+ */
61
+ protected readonly vaultUTXOs: VaultUTXOs[];
62
+
63
+ /**
64
+ * The wBTC contract
65
+ * @private
66
+ */
67
+ private readonly wbtc: wBTC;
68
+
69
+ private readonly calculatedSignHash: number = PsbtTransaction.calculateSignHash(
70
+ this.sighashTypes,
71
+ );
72
+
73
+ public constructor(parameters: IUnwrapParameters) {
74
+ if (parameters.amount < TransactionBuilder.MINIMUM_DUST) {
75
+ throw new Error('Amount is below dust limit');
76
+ }
77
+
78
+ parameters.disableAutoRefund = true; // we have to disable auto refund for this transaction, so it does not create an unwanted output.
79
+ parameters.calldata = UnwrapSegwitTransaction.generateBurnCalldata(parameters.amount);
80
+
81
+ super(parameters);
82
+
83
+ this.wbtc = new wBTC(parameters.network, parameters.chainId);
84
+ this.to = this.wbtc.getAddress();
85
+
86
+ this.vaultUTXOs = parameters.unwrapUTXOs;
87
+
88
+ this.amount = parameters.amount;
89
+ this.contractSecret = this.generateSecret();
90
+
91
+ this.compiledTargetScript = this.calldataGenerator.compile(
92
+ this.calldata,
93
+ this.contractSecret,
94
+ );
95
+
96
+ this.scriptTree = this.getScriptTree();
97
+ this.internalInit();
98
+ }
99
+
100
+ /**
101
+ * Generate a valid wBTC calldata
102
+ * @param {bigint} amount - The amount to wrap
103
+ * @private
104
+ * @returns {Buffer} - The calldata
105
+ */
106
+ public static generateBurnCalldata(amount: bigint): Buffer {
107
+ if (!amount) throw new Error('Amount is required');
108
+
109
+ const bufWriter: BinaryWriter = new BinaryWriter();
110
+ bufWriter.writeSelector(UnwrapSegwitTransaction.UNWRAP_SELECTOR);
111
+ bufWriter.writeU256(amount);
112
+
113
+ return Buffer.from(bufWriter.getBuffer());
114
+ }
115
+
116
+ /**
117
+ * @description Signs the transaction
118
+ * @public
119
+ * @returns {Promise<Psbt>} - The signed transaction in hex format
120
+ * @throws {Error} - If something went wrong
121
+ */
122
+ public async signPSBT(): Promise<Psbt> {
123
+ if (this.to && !EcKeyPair.verifyContractAddress(this.to, this.network)) {
124
+ throw new Error(
125
+ 'Invalid contract address. The contract address must be a taproot address.',
126
+ );
127
+ }
128
+
129
+ if (!this.vaultUTXOs.length) {
130
+ throw new Error('No vault UTXOs provided');
131
+ }
132
+
133
+ if (this.signed) throw new Error('Transaction is already signed');
134
+ this.signed = true;
135
+
136
+ await this.buildTransaction();
137
+
138
+ this.ignoreSignatureError();
139
+ await this.mergeVaults(this.vaultUTXOs);
140
+
141
+ const builtTx = await this.internalBuildTransaction(this.transaction);
142
+ if (builtTx) {
143
+ return this.transaction;
144
+ }
145
+
146
+ throw new Error('Could not sign transaction');
147
+ }
148
+
149
+ /**
150
+ * @description Merge vault UTXOs into the transaction
151
+ * @param {VaultUTXOs[]} input The vault UTXOs
152
+ * @public
153
+ */
154
+ public async mergeVaults(input: VaultUTXOs[]): Promise<void> {
155
+ const firstVault = input[0];
156
+ if (!firstVault) {
157
+ throw new Error('No vaults provided');
158
+ }
159
+
160
+ const total = this.getVaultTotalOutputAmount(input);
161
+ if (total < this.amount) {
162
+ throw new Error(
163
+ `Total vault amount (${total} sat) is less than the amount to unwrap (${this.amount} sat)`,
164
+ );
165
+ }
166
+
167
+ const outputLeftAmount = this.calculateOutputLeftAmountFromVaults(input);
168
+ if (
169
+ outputLeftAmount < currentConsensusConfig.VAULT_MINIMUM_AMOUNT &&
170
+ outputLeftAmount !== currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT
171
+ ) {
172
+ throw new Error(
173
+ `Output left amount is below minimum consolidation (${currentConsensusConfig.VAULT_MINIMUM_AMOUNT} sat) amount ${outputLeftAmount} for vault ${firstVault.vault}`,
174
+ );
175
+ }
176
+
177
+ this.addOutput({
178
+ address: firstVault.vault,
179
+ value: Number(outputLeftAmount),
180
+ });
181
+
182
+ this.addOutput({
183
+ address: this.from,
184
+ value: Number(this.amount),
185
+ });
186
+
187
+ for (const vault of input) {
188
+ await this.addVaultInputs(vault);
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Builds the transaction.
194
+ * @param {Psbt} transaction - The transaction to build
195
+ * @protected
196
+ * @returns {Promise<boolean>}
197
+ * @throws {Error} - If something went wrong while building the transaction
198
+ */
199
+ protected async internalBuildTransaction(transaction: Psbt): Promise<boolean> {
200
+ if (transaction.data.inputs.length === 0) {
201
+ const inputs: PsbtInputExtended[] = this.getInputs();
202
+ const outputs: PsbtOutputExtended[] = this.getOutputs();
203
+
204
+ transaction.setMaximumFeeRate(this._maximumFeeRate);
205
+ transaction.addInputs(inputs);
206
+
207
+ for (let i = 0; i < this.updateInputs.length; i++) {
208
+ transaction.updateInput(i, this.updateInputs[i]);
209
+ }
210
+
211
+ transaction.addOutputs(outputs);
212
+ }
213
+
214
+ try {
215
+ await this.signInputs(transaction);
216
+
217
+ if (this.finalized) {
218
+ this.transactionFee = BigInt(transaction.getFee());
219
+ }
220
+
221
+ return true;
222
+ } catch (e) {
223
+ const err: Error = e as Error;
224
+
225
+ this.error(
226
+ `[internalBuildTransaction] Something went wrong while getting building the transaction: ${err.stack}`,
227
+ );
228
+ }
229
+
230
+ return false;
231
+ }
232
+
233
+ /**
234
+ * Generate a multi-signature redeem script
235
+ * @param {string[]} publicKeys The public keys
236
+ * @param {number} minimum The minimum number of signatures
237
+ * @protected
238
+ * @returns {{output: Buffer; redeem: Buffer}} The output and redeem script
239
+ */
240
+ protected generateMultiSignRedeemScript(
241
+ publicKeys: string[],
242
+ minimum: number,
243
+ ): { witnessUtxo: Buffer; redeemScript: Buffer; witnessScript: Buffer } {
244
+ const p2ms = payments.p2ms({
245
+ m: minimum,
246
+ pubkeys: publicKeys.map((key) => Buffer.from(key, 'base64')),
247
+ network: this.network,
248
+ });
249
+
250
+ const p2wsh = payments.p2wsh({
251
+ redeem: p2ms,
252
+ network: this.network,
253
+ });
254
+
255
+ const witnessUtxo = p2wsh.output;
256
+ const redeemScript = p2wsh.redeem?.output;
257
+ const witnessScript = p2ms.output;
258
+
259
+ if (!witnessUtxo || !redeemScript || !witnessScript) {
260
+ throw new Error('Failed to generate redeem script');
261
+ }
262
+
263
+ return {
264
+ witnessUtxo,
265
+ redeemScript,
266
+ witnessScript,
267
+ };
268
+ }
269
+
270
+ /**
271
+ * @description Add a vault UTXO to the transaction
272
+ * @private
273
+ */
274
+ private addVaultUTXO(
275
+ utxo: IWBTCUTXODocument,
276
+ witness: {
277
+ witnessUtxo: Buffer;
278
+ redeemScript: Buffer;
279
+ witnessScript: Buffer;
280
+ },
281
+ ): void {
282
+ const input: PsbtInputExtended = {
283
+ hash: utxo.hash,
284
+ index: utxo.outputIndex,
285
+ witnessUtxo: {
286
+ script: Buffer.from(utxo.output, 'base64'),
287
+ value: Number(utxo.value),
288
+ },
289
+ witnessScript: witness.witnessScript,
290
+ sequence: this.sequence,
291
+ };
292
+
293
+ if (this.calculatedSignHash) {
294
+ input.sighashType = this.calculatedSignHash;
295
+ }
296
+
297
+ this.addInput(input);
298
+ }
299
+
300
+ /**
301
+ * @description Add vault inputs to the transaction
302
+ * @param {VaultUTXOs} vault The vault UTXOs
303
+ * @param {Signer} [firstSigner] The first signer
304
+ * @private
305
+ */
306
+ private async addVaultInputs(
307
+ vault: VaultUTXOs,
308
+ firstSigner: Signer = this.signer,
309
+ ): Promise<void> {
310
+ const p2wshOutput = this.generateMultiSignRedeemScript(vault.publicKeys, vault.minimum);
311
+ for (const utxo of vault.utxos) {
312
+ const inputIndex = this.transaction.inputCount;
313
+ this.addVaultUTXO(utxo, p2wshOutput);
314
+
315
+ if (firstSigner) {
316
+ this.log(
317
+ `Signing input ${inputIndex} with ${firstSigner.publicKey.toString('hex')}`,
318
+ );
319
+
320
+ // we don't care if we fail to sign the input
321
+ try {
322
+ await this.signInput(
323
+ this.transaction,
324
+ this.transaction.data.inputs[inputIndex],
325
+ inputIndex,
326
+ this.signer,
327
+ );
328
+
329
+ this.log(
330
+ `Signed input ${inputIndex} with ${firstSigner.publicKey.toString('hex')}`,
331
+ );
332
+ } catch (e) {
333
+ if (!this.ignoreSignatureErrors) {
334
+ this.warn(
335
+ `Failed to sign input ${inputIndex} with ${firstSigner.publicKey.toString('hex')} ${(e as Error).message}`,
336
+ );
337
+ }
338
+ }
339
+ }
340
+ }
341
+ }
342
+
343
+ /**
344
+ * @description Calculate the amount left to refund to the first vault.
345
+ * @param {VaultUTXOs[]} vaults The vaults
346
+ * @private
347
+ * @returns {bigint} The amount left
348
+ */
349
+ private calculateOutputLeftAmountFromVaults(vaults: VaultUTXOs[]): bigint {
350
+ const total = this.getVaultTotalOutputAmount(vaults);
351
+
352
+ return total - this.amount;
353
+ }
354
+
355
+ private getVaultTotalOutputAmount(vaults: VaultUTXOs[]): bigint {
356
+ let total = BigInt(0);
357
+ for (const vault of vaults) {
358
+ for (const utxo of vault.utxos) {
359
+ total += BigInt(utxo.value);
360
+ }
361
+ }
362
+
363
+ return total;
364
+ }
365
+ }