@btc-vision/transaction 1.0.54 → 1.0.55

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 (276) 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/transaction/builders/TapUnwarpTransaction.d.ts +40 -40
  5. package/browser/transaction/builders/UnwarpTransaction.d.ts +34 -34
  6. package/browser/utxo/UTXOManager.d.ts +7 -7
  7. package/build/_version.d.ts +1 -1
  8. package/build/_version.js +1 -1
  9. package/build/transaction/builders/UnwrapTransaction.js +2 -2
  10. package/gulpfile.js +152 -152
  11. package/package.json +2 -1
  12. package/src/_version.ts +1 -1
  13. package/src/consensus/Consensus.ts +36 -36
  14. package/src/consensus/ConsensusConfig.ts +39 -39
  15. package/src/crypto/crypto-browser.js +75 -75
  16. package/src/generators/AddressGenerator.ts +24 -24
  17. package/src/generators/Features.ts +5 -5
  18. package/src/generators/Generator.ts +75 -75
  19. package/src/generators/builders/CalldataGenerator.ts +148 -148
  20. package/src/generators/builders/DeploymentGenerator.ts +66 -66
  21. package/src/index.ts +4 -4
  22. package/src/keypair/AddressVerificator.ts +40 -40
  23. package/src/keypair/EcKeyPair.ts +282 -282
  24. package/src/keypair/Wallet.ts +97 -97
  25. package/src/keypair/interfaces/IWallet.ts +19 -19
  26. package/src/metadata/ContractBaseMetadata.ts +23 -23
  27. package/src/metadata/contracts/wBTC.ts +45 -45
  28. package/src/metadata/tokens.ts +7 -7
  29. package/src/network/NetworkInformation.ts +7 -7
  30. package/src/opnet.ts +84 -84
  31. package/src/transaction/TransactionFactory.ts +466 -466
  32. package/src/transaction/browser/BrowserSignerBase.ts +37 -37
  33. package/src/transaction/browser/Web3Provider.ts +46 -46
  34. package/src/transaction/browser/extensions/UnisatSigner.ts +218 -218
  35. package/src/transaction/browser/types/Unisat.ts +80 -80
  36. package/src/transaction/builders/FundingTransaction.ts +40 -40
  37. package/src/transaction/builders/InteractionTransaction.ts +38 -38
  38. package/src/transaction/builders/SharedInteractionTransaction.ts +368 -368
  39. package/src/transaction/builders/TransactionBuilder.ts +665 -665
  40. package/src/transaction/builders/UnwrapTransaction.ts +2 -2
  41. package/src/transaction/interfaces/ITransactionParameters.ts +55 -55
  42. package/src/transaction/interfaces/Tap.ts +26 -26
  43. package/src/transaction/psbt/PSBTTypes.ts +3 -3
  44. package/src/transaction/shared/TweakedTransaction.ts +537 -537
  45. package/src/utxo/OPNetLimitedProvider.ts +244 -244
  46. package/src/utxo/interfaces/BroadcastResponse.ts +10 -10
  47. package/src/utxo/interfaces/IUTXO.ts +29 -29
  48. package/src/verification/TapscriptVerificator.ts +89 -89
  49. package/src/wbtc/Generate.ts +40 -40
  50. package/src/wbtc/UnwrapGeneration.ts +13 -13
  51. package/src/wbtc/WrappedGenerationParameters.ts +33 -33
  52. package/webpack.config.js +78 -78
  53. package/build/Utils.d.ts +0 -0
  54. package/build/Utils.js +0 -1
  55. package/build/consensus/metadata/RoswsellConsensus.d.ts +0 -2
  56. package/build/consensus/metadata/RoswsellConsensus.js +0 -4
  57. package/build/contracts/ContractMetadataManager.d.ts +0 -0
  58. package/build/contracts/ContractMetadataManager.js +0 -1
  59. package/build/generators/OPNetAddressGenerator.d.ts +0 -0
  60. package/build/generators/OPNetAddressGenerator.js +0 -1
  61. package/build/generators/builders/UnwrapGenerator.d.ts +0 -8
  62. package/build/generators/builders/UnwrapGenerator.js +0 -79
  63. package/build/keypair/interfaces/GeneratedWallet.d.ts +0 -5
  64. package/build/keypair/interfaces/GeneratedWallet.js +0 -1
  65. package/build/metadata/CommonContracts.d.ts +0 -6
  66. package/build/metadata/CommonContracts.js +0 -5
  67. package/build/metadata/ContractMetadataManager.d.ts +0 -1
  68. package/build/metadata/ContractMetadataManager.js +0 -9
  69. package/build/metadata/contracts/ContractBase.d.ts +0 -9
  70. package/build/metadata/contracts/ContractBase.js +0 -13
  71. package/build/metadata/contracts/ContractBaseMetadata.d.ts +0 -9
  72. package/build/metadata/contracts/ContractBaseMetadata.js +0 -13
  73. package/build/metadata/contracts/ContractMetadataManager.d.ts +0 -0
  74. package/build/metadata/contracts/ContractMetadataManager.js +0 -1
  75. package/build/network/NetworkConverter.d.ts +0 -0
  76. package/build/network/NetworkConverter.js +0 -14
  77. package/build/scripts/Regtest.d.ts +0 -2
  78. package/build/scripts/Regtest.js +0 -15
  79. package/build/scripts/test.d.ts +0 -1
  80. package/build/scripts/test.js +0 -74
  81. package/build/signer/Regtest.d.ts +0 -2
  82. package/build/signer/Regtest.js +0 -15
  83. package/build/tests/Regtest.d.ts +0 -3
  84. package/build/tests/Regtest.js +0 -29
  85. package/build/tests/adaptPSBT.d.ts +0 -1
  86. package/build/tests/adaptPSBT.js +0 -44
  87. package/build/tests/btc/send.d.ts +0 -1
  88. package/build/tests/btc/send.js +0 -35
  89. package/build/tests/btc/transfer.d.ts +0 -1
  90. package/build/tests/btc/transfer.js +0 -35
  91. package/build/tests/createPairReg.d.ts +0 -1
  92. package/build/tests/createPairReg.js +0 -73
  93. package/build/tests/deploy/deployMoto.d.ts +0 -4
  94. package/build/tests/deploy/deployMoto.js +0 -89
  95. package/build/tests/deploy/deployPool.d.ts +0 -1
  96. package/build/tests/deploy/deployPool.js +0 -5
  97. package/build/tests/deploy/deployStep1.d.ts +0 -1
  98. package/build/tests/deploy/deployStep1.js +0 -5
  99. package/build/tests/deploy/deployStep2.d.ts +0 -1
  100. package/build/tests/deploy/deployStep2.js +0 -5
  101. package/build/tests/deploy/deployStep3.d.ts +0 -1
  102. package/build/tests/deploy/deployStep3.js +0 -5
  103. package/build/tests/deploy.d.ts +0 -1
  104. package/build/tests/deploy.js +0 -41
  105. package/build/tests/deployMotoRegStep1.d.ts +0 -1
  106. package/build/tests/deployMotoRegStep1.js +0 -85
  107. package/build/tests/deployReg.d.ts +0 -1
  108. package/build/tests/deployReg.js +0 -85
  109. package/build/tests/factory/createPairReg.d.ts +0 -1
  110. package/build/tests/factory/createPairReg.js +0 -13
  111. package/build/tests/gen.d.ts +0 -1
  112. package/build/tests/gen.js +0 -19
  113. package/build/tests/interaction.d.ts +0 -5
  114. package/build/tests/interaction.js +0 -62
  115. package/build/tests/massWrapReg.d.ts +0 -1
  116. package/build/tests/massWrapReg.js +0 -105
  117. package/build/tests/mineReg.d.ts +0 -1
  118. package/build/tests/mineReg.js +0 -19
  119. package/build/tests/moto/airdropToken.d.ts +0 -1
  120. package/build/tests/moto/airdropToken.js +0 -21
  121. package/build/tests/moto/airdropTokens.d.ts +0 -1
  122. package/build/tests/moto/airdropTokens.js +0 -60
  123. package/build/tests/moto/allowance.d.ts +0 -1
  124. package/build/tests/moto/allowance.js +0 -6
  125. package/build/tests/moto/approve.d.ts +0 -1
  126. package/build/tests/moto/approve.js +0 -10
  127. package/build/tests/moto/approveWBTC.d.ts +0 -1
  128. package/build/tests/moto/approveWBTC.js +0 -12
  129. package/build/tests/moto/balanceOf.d.ts +0 -1
  130. package/build/tests/moto/balanceOf.js +0 -12
  131. package/build/tests/moto/transfer.d.ts +0 -1
  132. package/build/tests/moto/transfer.js +0 -16
  133. package/build/tests/motoswap/airdropToken.d.ts +0 -11
  134. package/build/tests/motoswap/airdropToken.js +0 -36
  135. package/build/tests/motoswap/deployMoto.d.ts +0 -4
  136. package/build/tests/motoswap/deployMoto.js +0 -89
  137. package/build/tests/motoswap/deployMotoRegStep1.d.ts +0 -1
  138. package/build/tests/motoswap/deployMotoRegStep1.js +0 -91
  139. package/build/tests/motoswap/deployMotoRegStep2.d.ts +0 -1
  140. package/build/tests/motoswap/deployMotoRegStep2.js +0 -91
  141. package/build/tests/motoswap/deployPool.d.ts +0 -1
  142. package/build/tests/motoswap/deployPool.js +0 -5
  143. package/build/tests/motoswap/deployStep1.d.ts +0 -1
  144. package/build/tests/motoswap/deployStep1.js +0 -5
  145. package/build/tests/motoswap/deployStep2.d.ts +0 -1
  146. package/build/tests/motoswap/deployStep2.js +0 -5
  147. package/build/tests/motoswap/deployStep3.d.ts +0 -1
  148. package/build/tests/motoswap/deployStep3.js +0 -5
  149. package/build/tests/motoswap/interaction.d.ts +0 -3
  150. package/build/tests/motoswap/interaction.js +0 -63
  151. package/build/tests/motoswap/routerAddLiquidity.d.ts +0 -11
  152. package/build/tests/motoswap/routerAddLiquidity.js +0 -35
  153. package/build/tests/motoswap-router/addLiquidity.d.ts +0 -11
  154. package/build/tests/motoswap-router/addLiquidity.js +0 -35
  155. package/build/tests/motoswap-router/deployMoto.d.ts +0 -4
  156. package/build/tests/motoswap-router/deployMoto.js +0 -89
  157. package/build/tests/motoswap-router/deployPool.d.ts +0 -1
  158. package/build/tests/motoswap-router/deployPool.js +0 -5
  159. package/build/tests/motoswap-router/deployStep1.d.ts +0 -1
  160. package/build/tests/motoswap-router/deployStep1.js +0 -5
  161. package/build/tests/motoswap-router/deployStep2.d.ts +0 -1
  162. package/build/tests/motoswap-router/deployStep2.js +0 -5
  163. package/build/tests/motoswap-router/deployStep3.d.ts +0 -1
  164. package/build/tests/motoswap-router/deployStep3.js +0 -5
  165. package/build/tests/motoswap-router/getAmountsOut.d.ts +0 -5
  166. package/build/tests/motoswap-router/getAmountsOut.js +0 -34
  167. package/build/tests/motoswap-router/routerAddLiquidity.d.ts +0 -11
  168. package/build/tests/motoswap-router/routerAddLiquidity.js +0 -35
  169. package/build/tests/motoswap-router/swap.d.ts +0 -8
  170. package/build/tests/motoswap-router/swap.js +0 -24
  171. package/build/tests/multisign.d.ts +0 -1
  172. package/build/tests/multisign.js +0 -47
  173. package/build/tests/multisign2.d.ts +0 -1
  174. package/build/tests/multisign2.js +0 -27
  175. package/build/tests/pool/DecodePoolAddress.d.ts +0 -6
  176. package/build/tests/pool/DecodePoolAddress.js +0 -12
  177. package/build/tests/pool/decodeReserves.d.ts +0 -5
  178. package/build/tests/pool/decodeReserves.js +0 -13
  179. package/build/tests/pool/reserves.d.ts +0 -1
  180. package/build/tests/pool/reserves.js +0 -18
  181. package/build/tests/shared/Utils.d.ts +0 -2
  182. package/build/tests/shared/Utils.js +0 -14
  183. package/build/tests/shared/interaction.d.ts +0 -7
  184. package/build/tests/shared/interaction.js +0 -85
  185. package/build/tests/shared/tokens.d.ts +0 -6
  186. package/build/tests/shared/tokens.js +0 -5
  187. package/build/tests/stakeReg.d.ts +0 -1
  188. package/build/tests/stakeReg.js +0 -73
  189. package/build/tests/stakedReg.d.ts +0 -1
  190. package/build/tests/stakedReg.js +0 -28
  191. package/build/tests/test.d.ts +0 -1
  192. package/build/tests/test.js +0 -51
  193. package/build/tests/test2.d.ts +0 -1
  194. package/build/tests/test2.js +0 -73
  195. package/build/tests/testReg.d.ts +0 -1
  196. package/build/tests/testReg.js +0 -91
  197. package/build/tests/tokens.d.ts +0 -6
  198. package/build/tests/tokens.js +0 -5
  199. package/build/tests/totalRewardReg.d.ts +0 -1
  200. package/build/tests/totalRewardReg.js +0 -28
  201. package/build/tests/transfer.d.ts +0 -1
  202. package/build/tests/transfer.js +0 -74
  203. package/build/tests/transferReg.d.ts +0 -1
  204. package/build/tests/transferReg.js +0 -74
  205. package/build/tests/unStakeReg.d.ts +0 -1
  206. package/build/tests/unStakeReg.js +0 -72
  207. package/build/tests/unwrapReg.d.ts +0 -1
  208. package/build/tests/unwrapReg.js +0 -61
  209. package/build/tests/unwrapReg2.d.ts +0 -1
  210. package/build/tests/unwrapReg2.js +0 -56
  211. package/build/tests/unwrapRegSegwit.d.ts +0 -1
  212. package/build/tests/unwrapRegSegwit.js +0 -83
  213. package/build/tests/wbtc/approve.d.ts +0 -1
  214. package/build/tests/wbtc/approve.js +0 -6
  215. package/build/tests/wbtc/approveWBTC.d.ts +0 -1
  216. package/build/tests/wbtc/approveWBTC.js +0 -12
  217. package/build/tests/wbtc/massWrapReg.d.ts +0 -1
  218. package/build/tests/wbtc/massWrapReg.js +0 -105
  219. package/build/tests/wbtc/transfer.d.ts +0 -1
  220. package/build/tests/wbtc/transfer.js +0 -16
  221. package/build/tests/wbtc/transferReg.d.ts +0 -1
  222. package/build/tests/wbtc/transferReg.js +0 -16
  223. package/build/tests/wbtc/unStakeReg.d.ts +0 -1
  224. package/build/tests/wbtc/unStakeReg.js +0 -72
  225. package/build/tests/wbtc/unwrapReg.d.ts +0 -1
  226. package/build/tests/wbtc/unwrapReg.js +0 -60
  227. package/build/tests/wbtc/unwrapRegSegwit.d.ts +0 -1
  228. package/build/tests/wbtc/unwrapRegSegwit.js +0 -83
  229. package/build/tests/wbtc/withdrawalRequestReg.d.ts +0 -1
  230. package/build/tests/wbtc/withdrawalRequestReg.js +0 -71
  231. package/build/tests/wbtc/wrapReg.d.ts +0 -1
  232. package/build/tests/wbtc/wrapReg.js +0 -65
  233. package/build/tests/wbtc/wrapTest.d.ts +0 -1
  234. package/build/tests/wbtc/wrapTest.js +0 -66
  235. package/build/tests/withdrawalRequestReg.d.ts +0 -1
  236. package/build/tests/withdrawalRequestReg.js +0 -71
  237. package/build/tests/wrap.d.ts +0 -1
  238. package/build/tests/wrap.js +0 -65
  239. package/build/tests/wrapReg.d.ts +0 -1
  240. package/build/tests/wrapReg.js +0 -68
  241. package/build/tests/wrapTest.d.ts +0 -1
  242. package/build/tests/wrapTest.js +0 -66
  243. package/build/tests/wrapTestg.d.ts +0 -1
  244. package/build/tests/wrapTestg.js +0 -66
  245. package/build/tests/writers/allowance.d.ts +0 -3
  246. package/build/tests/writers/allowance.js +0 -10
  247. package/build/tests/writers/approve.d.ts +0 -4
  248. package/build/tests/writers/approve.js +0 -11
  249. package/build/transaction/TransactionBuilder.d.ts +0 -60
  250. package/build/transaction/TransactionBuilder.js +0 -244
  251. package/build/transaction/browser/BrowserSigner.d.ts +0 -11
  252. package/build/transaction/browser/BrowserSigner.js +0 -10
  253. package/build/transaction/browser/extensions/Unisat.d.ts +0 -54
  254. package/build/transaction/browser/extensions/Unisat.js +0 -11
  255. package/build/transaction/builders/GenericTransaction.d.ts +0 -11
  256. package/build/transaction/builders/GenericTransaction.js +0 -23
  257. package/build/transaction/builders/TapUnwarpTransaction.d.ts +0 -37
  258. package/build/transaction/builders/TapUnwarpTransaction.js +0 -201
  259. package/build/transaction/builders/UnwarpSegwitTransaction.d.ts +0 -34
  260. package/build/transaction/builders/UnwarpSegwitTransaction.js +0 -184
  261. package/build/transaction/builders/UnwarpTransaction.d.ts +0 -35
  262. package/build/transaction/builders/UnwarpTransaction.js +0 -199
  263. package/build/transaction/interfaces/ITransactions.d.ts +0 -32
  264. package/build/transaction/interfaces/ITransactions.js +0 -1
  265. package/build/utxo/IUTXO.d.ts +0 -0
  266. package/build/utxo/IUTXO.js +0 -1
  267. package/build/utxo/OPNetUtils.d.ts +0 -7
  268. package/build/utxo/OPNetUtils.js +0 -47
  269. package/build/utxo/UTXOManager.d.ts +0 -7
  270. package/build/utxo/UTXOManager.js +0 -47
  271. package/build/wbtc/BroadcastResponse.d.ts +0 -0
  272. package/build/wbtc/BroadcastResponse.js +0 -1
  273. /package/build/generators/{features.d.ts → Features.d.ts} +0 -0
  274. /package/build/generators/{features.js → Features.js} +0 -0
  275. /package/build/generators/builders/{MultisignGenerator.d.ts → MultiSignGenerator.d.ts} +0 -0
  276. /package/build/generators/builders/{MultisignGenerator.js → MultiSignGenerator.js} +0 -0
@@ -1,466 +1,466 @@
1
- import { Psbt, Transaction } from 'bitcoinjs-lib';
2
- import {
3
- IDeploymentParameters,
4
- IFundingTransactionParameters,
5
- IInteractionParameters,
6
- IUnwrapParameters,
7
- IWrapParameters,
8
- } from './interfaces/ITransactionParameters.js';
9
- import { FundingTransaction } from './builders/FundingTransaction.js';
10
- import { Output } from 'bitcoinjs-lib/src/transaction.js';
11
- import { UTXO } from '../utxo/interfaces/IUTXO.js';
12
- import { InteractionTransaction } from './builders/InteractionTransaction.js';
13
- import { DeploymentTransaction } from './builders/DeploymentTransaction.js';
14
- import { Address } from '@btc-vision/bsi-binary';
15
- import { wBTC } from '../metadata/contracts/wBTC.js';
16
- import { WrapTransaction } from './builders/WrapTransaction.js';
17
- import { PSBTTypes } from './psbt/PSBTTypes.js';
18
- import { VaultUTXOs } from './processor/PsbtTransaction.js';
19
- import { UnwrapSegwitTransaction } from './builders/UnwrapSegwitTransaction.js';
20
- import { UnwrapTransaction } from './builders/UnwrapTransaction.js';
21
- import { currentConsensus, currentConsensusConfig } from '../consensus/ConsensusConfig.js';
22
-
23
- export interface DeploymentResult {
24
- readonly transaction: [string, string];
25
-
26
- readonly contractAddress: Address;
27
- readonly p2trAddress: Address;
28
- }
29
-
30
- export interface WrapResult {
31
- readonly transaction: [string, string];
32
- readonly vaultAddress: Address;
33
- readonly amount: bigint;
34
- readonly receiverAddress: Address;
35
- }
36
-
37
- export interface UnwrapResult {
38
- readonly fundingTransaction: string;
39
- readonly psbt: string;
40
-
41
- /**
42
- * @description The fee refund or loss.
43
- * @description If the amount is negative, it means that the user has to pay the difference. The difference is deducted from the amount.
44
- * @description If the amount is positive, it means that the user will be refunded the difference.
45
- * @type {bigint}
46
- */
47
- readonly feeRefundOrLoss: bigint;
48
- }
49
-
50
- export class TransactionFactory {
51
- constructor() {}
52
-
53
- /**
54
- * @description Generates the required transactions.
55
- * @returns {Promise<[string, string]>} - The signed transaction
56
- */
57
- public async signInteraction(
58
- interactionParameters: IInteractionParameters,
59
- ): Promise<[string, string, UTXO[]]> {
60
- if (!interactionParameters.to) {
61
- throw new Error('Field "to" not provided.');
62
- }
63
-
64
- if (!interactionParameters.from) {
65
- throw new Error('Field "from" not provided.');
66
- }
67
-
68
- const preTransaction: InteractionTransaction = new InteractionTransaction({
69
- ...interactionParameters,
70
- utxos: [interactionParameters.utxos[0]], // we simulate one input here.
71
- });
72
-
73
- // we don't sign that transaction, we just need the parameters.
74
-
75
- await preTransaction.generateTransactionMinimalSignatures();
76
-
77
- const parameters: IFundingTransactionParameters =
78
- await preTransaction.getFundingTransactionParameters();
79
-
80
- parameters.utxos = interactionParameters.utxos;
81
- parameters.amount = await preTransaction.estimateTransactionFees();
82
-
83
- const feeEstimationFundingTransaction = await this.createFundTransaction({ ...parameters });
84
- if (!feeEstimationFundingTransaction) {
85
- throw new Error('Could not sign funding transaction.');
86
- }
87
-
88
- parameters.estimatedFees = feeEstimationFundingTransaction.estimatedFees;
89
-
90
- const signedTransaction = await this.createFundTransaction(parameters);
91
- if (!signedTransaction) {
92
- throw new Error('Could not sign funding transaction.');
93
- }
94
-
95
- interactionParameters.utxos = this.getUTXOAsTransaction(
96
- signedTransaction.tx,
97
- interactionParameters.to,
98
- 0,
99
- );
100
-
101
- const newParams: IInteractionParameters = {
102
- ...interactionParameters,
103
- utxos: this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0), // always 0
104
- randomBytes: preTransaction.getRndBytes(),
105
- nonWitnessUtxo: signedTransaction.tx.toBuffer(),
106
- estimatedFees: preTransaction.estimatedFees,
107
- };
108
-
109
- const finalTransaction: InteractionTransaction = new InteractionTransaction(newParams);
110
-
111
- // We have to regenerate using the new utxo
112
- const outTx: Transaction = await finalTransaction.signTransaction();
113
-
114
- return [
115
- signedTransaction.tx.toHex(),
116
- outTx.toHex(),
117
- this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.from, 1), // always 1
118
- ];
119
- }
120
-
121
- /**
122
- * @description Generates the required transactions.
123
- * @param {IDeploymentParameters} deploymentParameters - The deployment parameters
124
- * @returns {Promise<DeploymentResult>} - The signed transaction
125
- */
126
- public async signDeployment(
127
- deploymentParameters: IDeploymentParameters,
128
- ): Promise<DeploymentResult> {
129
- const preTransaction: DeploymentTransaction = new DeploymentTransaction(
130
- deploymentParameters,
131
- );
132
-
133
- // Initial generation
134
- await preTransaction.signTransaction();
135
-
136
- const parameters: IFundingTransactionParameters =
137
- await preTransaction.getFundingTransactionParameters();
138
-
139
- const fundingTransaction: FundingTransaction = new FundingTransaction(parameters);
140
- const signedTransaction: Transaction = await fundingTransaction.signTransaction();
141
- if (!signedTransaction) {
142
- throw new Error('Could not sign funding transaction.');
143
- }
144
-
145
- const out: Output = signedTransaction.outs[0];
146
- const newUtxo: UTXO = {
147
- transactionId: signedTransaction.getId(),
148
- outputIndex: 0, // always 0
149
- scriptPubKey: {
150
- hex: out.script.toString('hex'),
151
- address: preTransaction.getScriptAddress(),
152
- },
153
- value: BigInt(out.value),
154
- };
155
-
156
- const newParams: IDeploymentParameters = {
157
- ...deploymentParameters,
158
- utxos: [newUtxo],
159
- randomBytes: preTransaction.getRndBytes(),
160
- nonWitnessUtxo: signedTransaction.toBuffer(),
161
- };
162
-
163
- const finalTransaction: DeploymentTransaction = new DeploymentTransaction(newParams);
164
-
165
- // We have to regenerate using the new utxo
166
- const outTx: Transaction = await finalTransaction.signTransaction();
167
-
168
- return {
169
- transaction: [signedTransaction.toHex(), outTx.toHex()],
170
- contractAddress: finalTransaction.contractAddress,
171
- p2trAddress: finalTransaction.p2trAddress,
172
- };
173
- }
174
-
175
- /**
176
- * Basically it's fun to manage UTXOs.
177
- * @param {IWrapParameters} warpParameters - The wrap parameters
178
- * @returns {Promise<WrapResult>} - The signed transaction
179
- * @throws {Error} - If the transaction could not be signed
180
- */
181
- public async wrap(warpParameters: IWrapParameters): Promise<WrapResult> {
182
- if (warpParameters.amount < currentConsensusConfig.VAULT_MINIMUM_AMOUNT) {
183
- throw new Error(
184
- `Amount is too low. Minimum consolidation is ${currentConsensusConfig.VAULT_MINIMUM_AMOUNT} sat. Received ${warpParameters.amount} sat. Make sure that you cover the unwrap consolidation fees of ${currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT}sat.`,
185
- );
186
- }
187
-
188
- const childTransactionRequiredValue: bigint =
189
- warpParameters.amount + currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT;
190
-
191
- const wbtc: wBTC = new wBTC(warpParameters.network);
192
- const to = wbtc.getAddress();
193
- const fundingParameters: IFundingTransactionParameters = {
194
- ...warpParameters,
195
- amount: childTransactionRequiredValue,
196
- to: to,
197
- };
198
-
199
- const preFundingTransaction = await this.createFundTransaction(fundingParameters);
200
- warpParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
201
-
202
- const preTransaction: WrapTransaction = new WrapTransaction(warpParameters);
203
-
204
- // Initial generation
205
- await preTransaction.signTransaction();
206
-
207
- const parameters: IFundingTransactionParameters =
208
- await preTransaction.getFundingTransactionParameters();
209
-
210
- // We add the amount
211
- parameters.amount += childTransactionRequiredValue;
212
- parameters.utxos = fundingParameters.utxos;
213
-
214
- const signedTransaction = await this.createFundTransaction(parameters);
215
- if (!signedTransaction) {
216
- throw new Error('Could not sign funding transaction.');
217
- }
218
-
219
- const newParams: IWrapParameters = {
220
- ...warpParameters,
221
- utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
222
- randomBytes: preTransaction.getRndBytes(),
223
- nonWitnessUtxo: signedTransaction.tx.toBuffer(),
224
- };
225
-
226
- const finalTransaction: WrapTransaction = new WrapTransaction(newParams);
227
-
228
- // We have to regenerate using the new utxo
229
- const outTx: Transaction = await finalTransaction.signTransaction();
230
- return {
231
- transaction: [signedTransaction.tx.toHex(), outTx.toHex()],
232
- vaultAddress: finalTransaction.vault,
233
- amount: finalTransaction.amount,
234
- receiverAddress: finalTransaction.receiver,
235
- };
236
- }
237
-
238
- /**
239
- * Unwrap bitcoin.
240
- * @param {IUnwrapParameters} unwrapParameters - The unwrap parameters
241
- * @returns {Promise<UnwrapResult>} - The signed transaction
242
- * @throws {Error} - If the transaction could not be signed
243
- * @deprecated
244
- */
245
- public async unwrapSegwit(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult> {
246
- console.error('The "unwrap" method is deprecated. Use unwrapTap instead.');
247
-
248
- const transaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction(unwrapParameters);
249
- await transaction.signTransaction();
250
-
251
- const to = transaction.toAddress();
252
- if (!to) throw new Error('To address is required');
253
-
254
- // Initial generation
255
- const estimatedGas = await transaction.estimateTransactionFees();
256
- const estimatedFees = transaction.preEstimateTransactionFees(
257
- BigInt(unwrapParameters.feeRate),
258
- this.calculateNumInputs(unwrapParameters.unwrapUTXOs),
259
- 2n,
260
- this.calculateNumSignatures(unwrapParameters.unwrapUTXOs),
261
- this.maxPubKeySize(unwrapParameters.unwrapUTXOs),
262
- );
263
-
264
- const fundingParameters: IFundingTransactionParameters = {
265
- ...unwrapParameters,
266
- amount: estimatedGas + estimatedFees,
267
- to: to,
268
- };
269
-
270
- const preFundingTransaction = await this.createFundTransaction(fundingParameters);
271
- unwrapParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
272
-
273
- const preTransaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction({
274
- ...unwrapParameters,
275
- randomBytes: transaction.getRndBytes(),
276
- });
277
-
278
- // Initial generation
279
- await preTransaction.signTransaction();
280
-
281
- const parameters: IFundingTransactionParameters =
282
- await preTransaction.getFundingTransactionParameters();
283
-
284
- parameters.utxos = fundingParameters.utxos;
285
- parameters.amount = (await preTransaction.estimateTransactionFees()) + estimatedFees;
286
-
287
- const signedTransaction = await this.createFundTransaction(parameters);
288
- if (!signedTransaction) {
289
- throw new Error('Could not sign funding transaction.');
290
- }
291
-
292
- const newParams: IUnwrapParameters = {
293
- ...unwrapParameters,
294
- utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
295
- randomBytes: preTransaction.getRndBytes(),
296
- nonWitnessUtxo: signedTransaction.tx.toBuffer(),
297
- };
298
-
299
- const finalTransaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction(newParams);
300
-
301
- // We have to regenerate using the new utxo
302
- const outTx: Psbt = await finalTransaction.signPSBT();
303
- const asBase64 = outTx.toBase64();
304
- const psbt = this.writePSBTHeader(PSBTTypes.UNWRAP, asBase64);
305
-
306
- return {
307
- fundingTransaction: signedTransaction.tx.toHex(),
308
- psbt: psbt,
309
- feeRefundOrLoss: estimatedFees,
310
- };
311
- }
312
-
313
- /**
314
- * Unwrap bitcoin via taproot.
315
- * @param {IUnwrapParameters} unwrapParameters - The unwrap parameters
316
- * @returns {Promise<UnwrapResult>} - The signed transaction
317
- * @throws {Error} - If the transaction could not be signed
318
- */
319
- public async unwrap(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult> {
320
- const transaction: UnwrapTransaction = new UnwrapTransaction(unwrapParameters);
321
- await transaction.signTransaction();
322
-
323
- const to = transaction.toAddress();
324
- if (!to) throw new Error('To address is required');
325
-
326
- // Initial generation
327
- const estimatedGas = await transaction.estimateTransactionFees();
328
- const fundingParameters: IFundingTransactionParameters = {
329
- ...unwrapParameters,
330
- amount: estimatedGas,
331
- to: to,
332
- };
333
-
334
- const preFundingTransaction = await this.createFundTransaction(fundingParameters);
335
- unwrapParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
336
-
337
- const preTransaction: UnwrapTransaction = new UnwrapTransaction({
338
- ...unwrapParameters,
339
- randomBytes: transaction.getRndBytes(),
340
- });
341
-
342
- // Initial generation
343
- await preTransaction.signTransaction();
344
-
345
- const parameters: IFundingTransactionParameters =
346
- await preTransaction.getFundingTransactionParameters();
347
-
348
- parameters.utxos = fundingParameters.utxos;
349
- parameters.amount = await preTransaction.estimateTransactionFees();
350
-
351
- const signedTransaction = await this.createFundTransaction(parameters);
352
- if (!signedTransaction) {
353
- throw new Error('Could not sign funding transaction.');
354
- }
355
-
356
- const newParams: IUnwrapParameters = {
357
- ...unwrapParameters,
358
- utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
359
- randomBytes: preTransaction.getRndBytes(),
360
- nonWitnessUtxo: signedTransaction.tx.toBuffer(),
361
- };
362
-
363
- const finalTransaction: UnwrapTransaction = new UnwrapTransaction(newParams);
364
-
365
- // We have to regenerate using the new utxo
366
- const outTx: Psbt = await finalTransaction.signPSBT();
367
- const asBase64 = outTx.toBase64();
368
- const psbt = this.writePSBTHeader(PSBTTypes.UNWRAP, asBase64);
369
-
370
- return {
371
- fundingTransaction: signedTransaction.tx.toHex(),
372
- psbt: psbt,
373
- feeRefundOrLoss: finalTransaction.getFeeLossOrRefund(),
374
- };
375
- }
376
-
377
- /**
378
- * @description Creates a funding transaction.
379
- * @param {IFundingTransactionParameters} parameters - The funding transaction parameters
380
- * @returns {Promise<{ estimatedFees: bigint; tx: string }>} - The signed transaction
381
- */
382
- public async createBTCTransfer(parameters: IFundingTransactionParameters): Promise<{
383
- estimatedFees: bigint;
384
- tx: string;
385
- }> {
386
- const resp = await this.createFundTransaction(parameters);
387
-
388
- return {
389
- estimatedFees: resp.estimatedFees,
390
- tx: resp.tx.toHex(),
391
- };
392
- }
393
-
394
- private async createFundTransaction(parameters: IFundingTransactionParameters): Promise<{
395
- tx: Transaction;
396
- original: FundingTransaction;
397
- estimatedFees: bigint;
398
- }> {
399
- const fundingTransaction: FundingTransaction = new FundingTransaction(parameters);
400
- const signedTransaction: Transaction = await fundingTransaction.signTransaction();
401
- if (!signedTransaction) {
402
- throw new Error('Could not sign funding transaction.');
403
- }
404
-
405
- return {
406
- tx: signedTransaction,
407
- original: fundingTransaction,
408
- estimatedFees: await fundingTransaction.estimateTransactionFees(),
409
- };
410
- }
411
-
412
- private calculateNumSignatures(vault: VaultUTXOs[]): bigint {
413
- let numSignatures = 0n;
414
-
415
- for (const v of vault) {
416
- numSignatures += BigInt(v.minimum * v.utxos.length);
417
- }
418
-
419
- return numSignatures;
420
- }
421
-
422
- private calculateNumInputs(vault: VaultUTXOs[]): bigint {
423
- let numSignatures = 0n;
424
-
425
- for (const v of vault) {
426
- numSignatures += BigInt(v.utxos.length);
427
- }
428
-
429
- return numSignatures;
430
- }
431
-
432
- private maxPubKeySize(vault: VaultUTXOs[]): bigint {
433
- let size = 0;
434
-
435
- for (const v of vault) {
436
- size = Math.max(size, v.publicKeys.length);
437
- }
438
-
439
- return BigInt(size);
440
- }
441
-
442
- private writePSBTHeader(type: PSBTTypes, psbt: string): string {
443
- const buf = Buffer.from(psbt, 'base64');
444
-
445
- const header = Buffer.alloc(2);
446
- header.writeUInt8(type, 0);
447
- header.writeUInt8(currentConsensus, 1);
448
-
449
- return Buffer.concat([header, buf]).toString('hex');
450
- }
451
-
452
- private getUTXOAsTransaction(tx: Transaction, to: Address, index: number): UTXO[] {
453
- const out: Output = tx.outs[index];
454
- const newUtxo: UTXO = {
455
- transactionId: tx.getId(),
456
- outputIndex: index,
457
- scriptPubKey: {
458
- hex: out.script.toString('hex'),
459
- address: to,
460
- },
461
- value: BigInt(out.value),
462
- };
463
-
464
- return [newUtxo];
465
- }
466
- }
1
+ import { Psbt, Transaction } from 'bitcoinjs-lib';
2
+ import {
3
+ IDeploymentParameters,
4
+ IFundingTransactionParameters,
5
+ IInteractionParameters,
6
+ IUnwrapParameters,
7
+ IWrapParameters,
8
+ } from './interfaces/ITransactionParameters.js';
9
+ import { FundingTransaction } from './builders/FundingTransaction.js';
10
+ import { Output } from 'bitcoinjs-lib/src/transaction.js';
11
+ import { UTXO } from '../utxo/interfaces/IUTXO.js';
12
+ import { InteractionTransaction } from './builders/InteractionTransaction.js';
13
+ import { DeploymentTransaction } from './builders/DeploymentTransaction.js';
14
+ import { Address } from '@btc-vision/bsi-binary';
15
+ import { wBTC } from '../metadata/contracts/wBTC.js';
16
+ import { WrapTransaction } from './builders/WrapTransaction.js';
17
+ import { PSBTTypes } from './psbt/PSBTTypes.js';
18
+ import { VaultUTXOs } from './processor/PsbtTransaction.js';
19
+ import { UnwrapSegwitTransaction } from './builders/UnwrapSegwitTransaction.js';
20
+ import { UnwrapTransaction } from './builders/UnwrapTransaction.js';
21
+ import { currentConsensus, currentConsensusConfig } from '../consensus/ConsensusConfig.js';
22
+
23
+ export interface DeploymentResult {
24
+ readonly transaction: [string, string];
25
+
26
+ readonly contractAddress: Address;
27
+ readonly p2trAddress: Address;
28
+ }
29
+
30
+ export interface WrapResult {
31
+ readonly transaction: [string, string];
32
+ readonly vaultAddress: Address;
33
+ readonly amount: bigint;
34
+ readonly receiverAddress: Address;
35
+ }
36
+
37
+ export interface UnwrapResult {
38
+ readonly fundingTransaction: string;
39
+ readonly psbt: string;
40
+
41
+ /**
42
+ * @description The fee refund or loss.
43
+ * @description If the amount is negative, it means that the user has to pay the difference. The difference is deducted from the amount.
44
+ * @description If the amount is positive, it means that the user will be refunded the difference.
45
+ * @type {bigint}
46
+ */
47
+ readonly feeRefundOrLoss: bigint;
48
+ }
49
+
50
+ export class TransactionFactory {
51
+ constructor() {}
52
+
53
+ /**
54
+ * @description Generates the required transactions.
55
+ * @returns {Promise<[string, string]>} - The signed transaction
56
+ */
57
+ public async signInteraction(
58
+ interactionParameters: IInteractionParameters,
59
+ ): Promise<[string, string, UTXO[]]> {
60
+ if (!interactionParameters.to) {
61
+ throw new Error('Field "to" not provided.');
62
+ }
63
+
64
+ if (!interactionParameters.from) {
65
+ throw new Error('Field "from" not provided.');
66
+ }
67
+
68
+ const preTransaction: InteractionTransaction = new InteractionTransaction({
69
+ ...interactionParameters,
70
+ utxos: [interactionParameters.utxos[0]], // we simulate one input here.
71
+ });
72
+
73
+ // we don't sign that transaction, we just need the parameters.
74
+
75
+ await preTransaction.generateTransactionMinimalSignatures();
76
+
77
+ const parameters: IFundingTransactionParameters =
78
+ await preTransaction.getFundingTransactionParameters();
79
+
80
+ parameters.utxos = interactionParameters.utxos;
81
+ parameters.amount = await preTransaction.estimateTransactionFees();
82
+
83
+ const feeEstimationFundingTransaction = await this.createFundTransaction({ ...parameters });
84
+ if (!feeEstimationFundingTransaction) {
85
+ throw new Error('Could not sign funding transaction.');
86
+ }
87
+
88
+ parameters.estimatedFees = feeEstimationFundingTransaction.estimatedFees;
89
+
90
+ const signedTransaction = await this.createFundTransaction(parameters);
91
+ if (!signedTransaction) {
92
+ throw new Error('Could not sign funding transaction.');
93
+ }
94
+
95
+ interactionParameters.utxos = this.getUTXOAsTransaction(
96
+ signedTransaction.tx,
97
+ interactionParameters.to,
98
+ 0,
99
+ );
100
+
101
+ const newParams: IInteractionParameters = {
102
+ ...interactionParameters,
103
+ utxos: this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0), // always 0
104
+ randomBytes: preTransaction.getRndBytes(),
105
+ nonWitnessUtxo: signedTransaction.tx.toBuffer(),
106
+ estimatedFees: preTransaction.estimatedFees,
107
+ };
108
+
109
+ const finalTransaction: InteractionTransaction = new InteractionTransaction(newParams);
110
+
111
+ // We have to regenerate using the new utxo
112
+ const outTx: Transaction = await finalTransaction.signTransaction();
113
+
114
+ return [
115
+ signedTransaction.tx.toHex(),
116
+ outTx.toHex(),
117
+ this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.from, 1), // always 1
118
+ ];
119
+ }
120
+
121
+ /**
122
+ * @description Generates the required transactions.
123
+ * @param {IDeploymentParameters} deploymentParameters - The deployment parameters
124
+ * @returns {Promise<DeploymentResult>} - The signed transaction
125
+ */
126
+ public async signDeployment(
127
+ deploymentParameters: IDeploymentParameters,
128
+ ): Promise<DeploymentResult> {
129
+ const preTransaction: DeploymentTransaction = new DeploymentTransaction(
130
+ deploymentParameters,
131
+ );
132
+
133
+ // Initial generation
134
+ await preTransaction.signTransaction();
135
+
136
+ const parameters: IFundingTransactionParameters =
137
+ await preTransaction.getFundingTransactionParameters();
138
+
139
+ const fundingTransaction: FundingTransaction = new FundingTransaction(parameters);
140
+ const signedTransaction: Transaction = await fundingTransaction.signTransaction();
141
+ if (!signedTransaction) {
142
+ throw new Error('Could not sign funding transaction.');
143
+ }
144
+
145
+ const out: Output = signedTransaction.outs[0];
146
+ const newUtxo: UTXO = {
147
+ transactionId: signedTransaction.getId(),
148
+ outputIndex: 0, // always 0
149
+ scriptPubKey: {
150
+ hex: out.script.toString('hex'),
151
+ address: preTransaction.getScriptAddress(),
152
+ },
153
+ value: BigInt(out.value),
154
+ };
155
+
156
+ const newParams: IDeploymentParameters = {
157
+ ...deploymentParameters,
158
+ utxos: [newUtxo],
159
+ randomBytes: preTransaction.getRndBytes(),
160
+ nonWitnessUtxo: signedTransaction.toBuffer(),
161
+ };
162
+
163
+ const finalTransaction: DeploymentTransaction = new DeploymentTransaction(newParams);
164
+
165
+ // We have to regenerate using the new utxo
166
+ const outTx: Transaction = await finalTransaction.signTransaction();
167
+
168
+ return {
169
+ transaction: [signedTransaction.toHex(), outTx.toHex()],
170
+ contractAddress: finalTransaction.contractAddress,
171
+ p2trAddress: finalTransaction.p2trAddress,
172
+ };
173
+ }
174
+
175
+ /**
176
+ * Basically it's fun to manage UTXOs.
177
+ * @param {IWrapParameters} warpParameters - The wrap parameters
178
+ * @returns {Promise<WrapResult>} - The signed transaction
179
+ * @throws {Error} - If the transaction could not be signed
180
+ */
181
+ public async wrap(warpParameters: IWrapParameters): Promise<WrapResult> {
182
+ if (warpParameters.amount < currentConsensusConfig.VAULT_MINIMUM_AMOUNT) {
183
+ throw new Error(
184
+ `Amount is too low. Minimum consolidation is ${currentConsensusConfig.VAULT_MINIMUM_AMOUNT} sat. Received ${warpParameters.amount} sat. Make sure that you cover the unwrap consolidation fees of ${currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT}sat.`,
185
+ );
186
+ }
187
+
188
+ const childTransactionRequiredValue: bigint =
189
+ warpParameters.amount + currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT;
190
+
191
+ const wbtc: wBTC = new wBTC(warpParameters.network);
192
+ const to = wbtc.getAddress();
193
+ const fundingParameters: IFundingTransactionParameters = {
194
+ ...warpParameters,
195
+ amount: childTransactionRequiredValue,
196
+ to: to,
197
+ };
198
+
199
+ const preFundingTransaction = await this.createFundTransaction(fundingParameters);
200
+ warpParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
201
+
202
+ const preTransaction: WrapTransaction = new WrapTransaction(warpParameters);
203
+
204
+ // Initial generation
205
+ await preTransaction.signTransaction();
206
+
207
+ const parameters: IFundingTransactionParameters =
208
+ await preTransaction.getFundingTransactionParameters();
209
+
210
+ // We add the amount
211
+ parameters.amount += childTransactionRequiredValue;
212
+ parameters.utxos = fundingParameters.utxos;
213
+
214
+ const signedTransaction = await this.createFundTransaction(parameters);
215
+ if (!signedTransaction) {
216
+ throw new Error('Could not sign funding transaction.');
217
+ }
218
+
219
+ const newParams: IWrapParameters = {
220
+ ...warpParameters,
221
+ utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
222
+ randomBytes: preTransaction.getRndBytes(),
223
+ nonWitnessUtxo: signedTransaction.tx.toBuffer(),
224
+ };
225
+
226
+ const finalTransaction: WrapTransaction = new WrapTransaction(newParams);
227
+
228
+ // We have to regenerate using the new utxo
229
+ const outTx: Transaction = await finalTransaction.signTransaction();
230
+ return {
231
+ transaction: [signedTransaction.tx.toHex(), outTx.toHex()],
232
+ vaultAddress: finalTransaction.vault,
233
+ amount: finalTransaction.amount,
234
+ receiverAddress: finalTransaction.receiver,
235
+ };
236
+ }
237
+
238
+ /**
239
+ * Unwrap bitcoin.
240
+ * @param {IUnwrapParameters} unwrapParameters - The unwrap parameters
241
+ * @returns {Promise<UnwrapResult>} - The signed transaction
242
+ * @throws {Error} - If the transaction could not be signed
243
+ * @deprecated
244
+ */
245
+ public async unwrapSegwit(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult> {
246
+ console.error('The "unwrap" method is deprecated. Use unwrapTap instead.');
247
+
248
+ const transaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction(unwrapParameters);
249
+ await transaction.signTransaction();
250
+
251
+ const to = transaction.toAddress();
252
+ if (!to) throw new Error('To address is required');
253
+
254
+ // Initial generation
255
+ const estimatedGas = await transaction.estimateTransactionFees();
256
+ const estimatedFees = transaction.preEstimateTransactionFees(
257
+ BigInt(unwrapParameters.feeRate),
258
+ this.calculateNumInputs(unwrapParameters.unwrapUTXOs),
259
+ 2n,
260
+ this.calculateNumSignatures(unwrapParameters.unwrapUTXOs),
261
+ this.maxPubKeySize(unwrapParameters.unwrapUTXOs),
262
+ );
263
+
264
+ const fundingParameters: IFundingTransactionParameters = {
265
+ ...unwrapParameters,
266
+ amount: estimatedGas + estimatedFees,
267
+ to: to,
268
+ };
269
+
270
+ const preFundingTransaction = await this.createFundTransaction(fundingParameters);
271
+ unwrapParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
272
+
273
+ const preTransaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction({
274
+ ...unwrapParameters,
275
+ randomBytes: transaction.getRndBytes(),
276
+ });
277
+
278
+ // Initial generation
279
+ await preTransaction.signTransaction();
280
+
281
+ const parameters: IFundingTransactionParameters =
282
+ await preTransaction.getFundingTransactionParameters();
283
+
284
+ parameters.utxos = fundingParameters.utxos;
285
+ parameters.amount = (await preTransaction.estimateTransactionFees()) + estimatedFees;
286
+
287
+ const signedTransaction = await this.createFundTransaction(parameters);
288
+ if (!signedTransaction) {
289
+ throw new Error('Could not sign funding transaction.');
290
+ }
291
+
292
+ const newParams: IUnwrapParameters = {
293
+ ...unwrapParameters,
294
+ utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
295
+ randomBytes: preTransaction.getRndBytes(),
296
+ nonWitnessUtxo: signedTransaction.tx.toBuffer(),
297
+ };
298
+
299
+ const finalTransaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction(newParams);
300
+
301
+ // We have to regenerate using the new utxo
302
+ const outTx: Psbt = await finalTransaction.signPSBT();
303
+ const asBase64 = outTx.toBase64();
304
+ const psbt = this.writePSBTHeader(PSBTTypes.UNWRAP, asBase64);
305
+
306
+ return {
307
+ fundingTransaction: signedTransaction.tx.toHex(),
308
+ psbt: psbt,
309
+ feeRefundOrLoss: estimatedFees,
310
+ };
311
+ }
312
+
313
+ /**
314
+ * Unwrap bitcoin via taproot.
315
+ * @param {IUnwrapParameters} unwrapParameters - The unwrap parameters
316
+ * @returns {Promise<UnwrapResult>} - The signed transaction
317
+ * @throws {Error} - If the transaction could not be signed
318
+ */
319
+ public async unwrap(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult> {
320
+ const transaction: UnwrapTransaction = new UnwrapTransaction(unwrapParameters);
321
+ await transaction.signTransaction();
322
+
323
+ const to = transaction.toAddress();
324
+ if (!to) throw new Error('To address is required');
325
+
326
+ // Initial generation
327
+ const estimatedGas = await transaction.estimateTransactionFees();
328
+ const fundingParameters: IFundingTransactionParameters = {
329
+ ...unwrapParameters,
330
+ amount: estimatedGas,
331
+ to: to,
332
+ };
333
+
334
+ const preFundingTransaction = await this.createFundTransaction(fundingParameters);
335
+ unwrapParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
336
+
337
+ const preTransaction: UnwrapTransaction = new UnwrapTransaction({
338
+ ...unwrapParameters,
339
+ randomBytes: transaction.getRndBytes(),
340
+ });
341
+
342
+ // Initial generation
343
+ await preTransaction.signTransaction();
344
+
345
+ const parameters: IFundingTransactionParameters =
346
+ await preTransaction.getFundingTransactionParameters();
347
+
348
+ parameters.utxos = fundingParameters.utxos;
349
+ parameters.amount = await preTransaction.estimateTransactionFees();
350
+
351
+ const signedTransaction = await this.createFundTransaction(parameters);
352
+ if (!signedTransaction) {
353
+ throw new Error('Could not sign funding transaction.');
354
+ }
355
+
356
+ const newParams: IUnwrapParameters = {
357
+ ...unwrapParameters,
358
+ utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
359
+ randomBytes: preTransaction.getRndBytes(),
360
+ nonWitnessUtxo: signedTransaction.tx.toBuffer(),
361
+ };
362
+
363
+ const finalTransaction: UnwrapTransaction = new UnwrapTransaction(newParams);
364
+
365
+ // We have to regenerate using the new utxo
366
+ const outTx: Psbt = await finalTransaction.signPSBT();
367
+ const asBase64 = outTx.toBase64();
368
+ const psbt = this.writePSBTHeader(PSBTTypes.UNWRAP, asBase64);
369
+
370
+ return {
371
+ fundingTransaction: signedTransaction.tx.toHex(),
372
+ psbt: psbt,
373
+ feeRefundOrLoss: finalTransaction.getFeeLossOrRefund(),
374
+ };
375
+ }
376
+
377
+ /**
378
+ * @description Creates a funding transaction.
379
+ * @param {IFundingTransactionParameters} parameters - The funding transaction parameters
380
+ * @returns {Promise<{ estimatedFees: bigint; tx: string }>} - The signed transaction
381
+ */
382
+ public async createBTCTransfer(parameters: IFundingTransactionParameters): Promise<{
383
+ estimatedFees: bigint;
384
+ tx: string;
385
+ }> {
386
+ const resp = await this.createFundTransaction(parameters);
387
+
388
+ return {
389
+ estimatedFees: resp.estimatedFees,
390
+ tx: resp.tx.toHex(),
391
+ };
392
+ }
393
+
394
+ private async createFundTransaction(parameters: IFundingTransactionParameters): Promise<{
395
+ tx: Transaction;
396
+ original: FundingTransaction;
397
+ estimatedFees: bigint;
398
+ }> {
399
+ const fundingTransaction: FundingTransaction = new FundingTransaction(parameters);
400
+ const signedTransaction: Transaction = await fundingTransaction.signTransaction();
401
+ if (!signedTransaction) {
402
+ throw new Error('Could not sign funding transaction.');
403
+ }
404
+
405
+ return {
406
+ tx: signedTransaction,
407
+ original: fundingTransaction,
408
+ estimatedFees: await fundingTransaction.estimateTransactionFees(),
409
+ };
410
+ }
411
+
412
+ private calculateNumSignatures(vault: VaultUTXOs[]): bigint {
413
+ let numSignatures = 0n;
414
+
415
+ for (const v of vault) {
416
+ numSignatures += BigInt(v.minimum * v.utxos.length);
417
+ }
418
+
419
+ return numSignatures;
420
+ }
421
+
422
+ private calculateNumInputs(vault: VaultUTXOs[]): bigint {
423
+ let numSignatures = 0n;
424
+
425
+ for (const v of vault) {
426
+ numSignatures += BigInt(v.utxos.length);
427
+ }
428
+
429
+ return numSignatures;
430
+ }
431
+
432
+ private maxPubKeySize(vault: VaultUTXOs[]): bigint {
433
+ let size = 0;
434
+
435
+ for (const v of vault) {
436
+ size = Math.max(size, v.publicKeys.length);
437
+ }
438
+
439
+ return BigInt(size);
440
+ }
441
+
442
+ private writePSBTHeader(type: PSBTTypes, psbt: string): string {
443
+ const buf = Buffer.from(psbt, 'base64');
444
+
445
+ const header = Buffer.alloc(2);
446
+ header.writeUInt8(type, 0);
447
+ header.writeUInt8(currentConsensus, 1);
448
+
449
+ return Buffer.concat([header, buf]).toString('hex');
450
+ }
451
+
452
+ private getUTXOAsTransaction(tx: Transaction, to: Address, index: number): UTXO[] {
453
+ const out: Output = tx.outs[index];
454
+ const newUtxo: UTXO = {
455
+ transactionId: tx.getId(),
456
+ outputIndex: index,
457
+ scriptPubKey: {
458
+ hex: out.script.toString('hex'),
459
+ address: to,
460
+ },
461
+ value: BigInt(out.value),
462
+ };
463
+
464
+ return [newUtxo];
465
+ }
466
+ }