@atomiqlabs/lp-lib 13.0.0-beta.9 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/LICENSE +201 -201
  2. package/dist/fees/IBtcFeeEstimator.d.ts +3 -3
  3. package/dist/fees/IBtcFeeEstimator.js +2 -2
  4. package/dist/index.d.ts +40 -40
  5. package/dist/index.js +56 -56
  6. package/dist/info/InfoHandler.d.ts +17 -17
  7. package/dist/info/InfoHandler.js +61 -61
  8. package/dist/plugins/IPlugin.d.ts +143 -143
  9. package/dist/plugins/IPlugin.js +34 -34
  10. package/dist/plugins/PluginManager.d.ts +112 -112
  11. package/dist/plugins/PluginManager.js +259 -259
  12. package/dist/prices/BinanceSwapPrice.d.ts +26 -26
  13. package/dist/prices/BinanceSwapPrice.js +92 -92
  14. package/dist/prices/CoinGeckoSwapPrice.d.ts +30 -30
  15. package/dist/prices/CoinGeckoSwapPrice.js +64 -64
  16. package/dist/prices/ISwapPrice.d.ts +43 -43
  17. package/dist/prices/ISwapPrice.js +55 -55
  18. package/dist/prices/OKXSwapPrice.d.ts +26 -26
  19. package/dist/prices/OKXSwapPrice.js +92 -92
  20. package/dist/storage/IIntermediaryStorage.d.ts +18 -18
  21. package/dist/storage/IIntermediaryStorage.js +2 -2
  22. package/dist/storagemanager/IntermediaryStorageManager.d.ts +18 -18
  23. package/dist/storagemanager/IntermediaryStorageManager.js +104 -104
  24. package/dist/storagemanager/StorageManager.d.ts +12 -12
  25. package/dist/storagemanager/StorageManager.js +57 -57
  26. package/dist/swaps/SwapHandler.d.ts +156 -156
  27. package/dist/swaps/SwapHandler.js +163 -163
  28. package/dist/swaps/SwapHandlerSwap.d.ts +79 -79
  29. package/dist/swaps/SwapHandlerSwap.js +78 -78
  30. package/dist/swaps/assertions/AmountAssertions.d.ts +28 -28
  31. package/dist/swaps/assertions/AmountAssertions.js +72 -72
  32. package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +76 -76
  33. package/dist/swaps/assertions/FromBtcAmountAssertions.js +172 -172
  34. package/dist/swaps/assertions/LightningAssertions.d.ts +44 -44
  35. package/dist/swaps/assertions/LightningAssertions.js +86 -86
  36. package/dist/swaps/assertions/ToBtcAmountAssertions.d.ts +53 -53
  37. package/dist/swaps/assertions/ToBtcAmountAssertions.js +150 -150
  38. package/dist/swaps/escrow/EscrowHandler.d.ts +51 -51
  39. package/dist/swaps/escrow/EscrowHandler.js +158 -158
  40. package/dist/swaps/escrow/EscrowHandlerSwap.d.ts +35 -35
  41. package/dist/swaps/escrow/EscrowHandlerSwap.js +69 -69
  42. package/dist/swaps/escrow/FromBtcBaseSwap.d.ts +14 -14
  43. package/dist/swaps/escrow/FromBtcBaseSwap.js +32 -32
  44. package/dist/swaps/escrow/FromBtcBaseSwapHandler.d.ts +101 -101
  45. package/dist/swaps/escrow/FromBtcBaseSwapHandler.js +207 -207
  46. package/dist/swaps/escrow/ToBtcBaseSwap.d.ts +36 -36
  47. package/dist/swaps/escrow/ToBtcBaseSwap.js +67 -67
  48. package/dist/swaps/escrow/ToBtcBaseSwapHandler.d.ts +53 -53
  49. package/dist/swaps/escrow/ToBtcBaseSwapHandler.js +81 -81
  50. package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.d.ts +83 -83
  51. package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.js +318 -318
  52. package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.d.ts +21 -21
  53. package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.js +50 -50
  54. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.d.ts +107 -107
  55. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.js +648 -648
  56. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +32 -32
  57. package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.js +88 -88
  58. package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.d.ts +171 -171
  59. package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +702 -702
  60. package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.d.ts +26 -26
  61. package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.js +62 -62
  62. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.d.ts +177 -177
  63. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.js +857 -857
  64. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +23 -23
  65. package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.js +56 -56
  66. package/dist/swaps/spv_vault_swap/SpvVault.d.ts +41 -41
  67. package/dist/swaps/spv_vault_swap/SpvVault.js +111 -111
  68. package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +67 -67
  69. package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +158 -158
  70. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.d.ts +68 -68
  71. package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +488 -478
  72. package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +57 -57
  73. package/dist/swaps/spv_vault_swap/SpvVaults.js +369 -369
  74. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.d.ts +51 -51
  75. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +650 -650
  76. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.d.ts +52 -52
  77. package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.js +118 -118
  78. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.d.ts +76 -76
  79. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.js +495 -495
  80. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +34 -34
  81. package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.js +81 -81
  82. package/dist/utils/Utils.d.ts +29 -29
  83. package/dist/utils/Utils.js +88 -88
  84. package/dist/utils/paramcoders/IParamReader.d.ts +5 -5
  85. package/dist/utils/paramcoders/IParamReader.js +2 -2
  86. package/dist/utils/paramcoders/IParamWriter.d.ts +4 -4
  87. package/dist/utils/paramcoders/IParamWriter.js +2 -2
  88. package/dist/utils/paramcoders/LegacyParamEncoder.d.ts +10 -10
  89. package/dist/utils/paramcoders/LegacyParamEncoder.js +22 -22
  90. package/dist/utils/paramcoders/ParamDecoder.d.ts +25 -25
  91. package/dist/utils/paramcoders/ParamDecoder.js +222 -222
  92. package/dist/utils/paramcoders/ParamEncoder.d.ts +9 -9
  93. package/dist/utils/paramcoders/ParamEncoder.js +22 -22
  94. package/dist/utils/paramcoders/SchemaVerifier.d.ts +21 -21
  95. package/dist/utils/paramcoders/SchemaVerifier.js +84 -84
  96. package/dist/utils/paramcoders/server/ServerParamDecoder.d.ts +8 -8
  97. package/dist/utils/paramcoders/server/ServerParamDecoder.js +105 -105
  98. package/dist/utils/paramcoders/server/ServerParamEncoder.d.ts +11 -11
  99. package/dist/utils/paramcoders/server/ServerParamEncoder.js +65 -65
  100. package/dist/wallets/IBitcoinWallet.d.ts +67 -67
  101. package/dist/wallets/IBitcoinWallet.js +2 -2
  102. package/dist/wallets/ILightningWallet.d.ts +117 -117
  103. package/dist/wallets/ILightningWallet.js +37 -37
  104. package/dist/wallets/ISpvVaultSigner.d.ts +7 -7
  105. package/dist/wallets/ISpvVaultSigner.js +2 -2
  106. package/dist/wallets/ISpvVaultWallet.d.ts +42 -42
  107. package/dist/wallets/ISpvVaultWallet.js +2 -2
  108. package/package.json +36 -36
  109. package/src/fees/IBtcFeeEstimator.ts +6 -6
  110. package/src/index.ts +51 -51
  111. package/src/info/InfoHandler.ts +106 -106
  112. package/src/plugins/IPlugin.ts +168 -168
  113. package/src/plugins/PluginManager.ts +336 -336
  114. package/src/prices/BinanceSwapPrice.ts +113 -113
  115. package/src/prices/CoinGeckoSwapPrice.ts +87 -87
  116. package/src/prices/ISwapPrice.ts +88 -88
  117. package/src/prices/OKXSwapPrice.ts +113 -113
  118. package/src/storage/IIntermediaryStorage.ts +19 -19
  119. package/src/storagemanager/IntermediaryStorageManager.ts +109 -109
  120. package/src/storagemanager/StorageManager.ts +68 -68
  121. package/src/swaps/SwapHandler.ts +280 -280
  122. package/src/swaps/SwapHandlerSwap.ts +141 -141
  123. package/src/swaps/assertions/AmountAssertions.ts +76 -76
  124. package/src/swaps/assertions/FromBtcAmountAssertions.ts +238 -238
  125. package/src/swaps/assertions/LightningAssertions.ts +103 -103
  126. package/src/swaps/assertions/ToBtcAmountAssertions.ts +203 -203
  127. package/src/swaps/escrow/EscrowHandler.ts +179 -179
  128. package/src/swaps/escrow/EscrowHandlerSwap.ts +86 -86
  129. package/src/swaps/escrow/FromBtcBaseSwap.ts +38 -38
  130. package/src/swaps/escrow/FromBtcBaseSwapHandler.ts +283 -283
  131. package/src/swaps/escrow/ToBtcBaseSwap.ts +85 -85
  132. package/src/swaps/escrow/ToBtcBaseSwapHandler.ts +129 -129
  133. package/src/swaps/escrow/frombtc_abstract/FromBtcAbs.ts +452 -452
  134. package/src/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.ts +61 -61
  135. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.ts +828 -828
  136. package/src/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.ts +137 -137
  137. package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +876 -876
  138. package/src/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.ts +102 -102
  139. package/src/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.ts +1107 -1107
  140. package/src/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.ts +77 -77
  141. package/src/swaps/spv_vault_swap/SpvVault.ts +143 -143
  142. package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +225 -225
  143. package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +624 -613
  144. package/src/swaps/spv_vault_swap/SpvVaults.ts +440 -440
  145. package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +747 -747
  146. package/src/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.ts +185 -185
  147. package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.ts +592 -592
  148. package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.ts +121 -121
  149. package/src/utils/Utils.ts +102 -102
  150. package/src/utils/paramcoders/IParamReader.ts +7 -7
  151. package/src/utils/paramcoders/IParamWriter.ts +8 -8
  152. package/src/utils/paramcoders/LegacyParamEncoder.ts +27 -27
  153. package/src/utils/paramcoders/ParamDecoder.ts +218 -218
  154. package/src/utils/paramcoders/ParamEncoder.ts +29 -29
  155. package/src/utils/paramcoders/SchemaVerifier.ts +96 -96
  156. package/src/utils/paramcoders/server/ServerParamDecoder.ts +115 -115
  157. package/src/utils/paramcoders/server/ServerParamEncoder.ts +75 -75
  158. package/src/wallets/IBitcoinWallet.ts +68 -68
  159. package/src/wallets/ILightningWallet.ts +178 -178
  160. package/src/wallets/ISpvVaultSigner.ts +10 -10
@@ -1,369 +1,369 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SpvVaults = exports.VAULT_DUST_AMOUNT = void 0;
4
- const SpvVault_1 = require("./SpvVault");
5
- const Utils_1 = require("../../utils/Utils");
6
- const PluginManager_1 = require("../../plugins/PluginManager");
7
- const AmountAssertions_1 = require("../assertions/AmountAssertions");
8
- const btc_signer_1 = require("@scure/btc-signer");
9
- exports.VAULT_DUST_AMOUNT = 600;
10
- const VAULT_INIT_CONFIRMATIONS = 2;
11
- const BTC_FINALIZATION_CONFIRMATIONS = 6;
12
- class SpvVaults {
13
- constructor(vaultStorage, bitcoin, vaultSigner, bitcoinRpc, getChain, config) {
14
- this.logger = {
15
- debug: (msg, ...args) => console.debug("SpvVaults: " + msg, ...args),
16
- info: (msg, ...args) => console.info("SpvVaults: " + msg, ...args),
17
- warn: (msg, ...args) => console.warn("SpvVaults: " + msg, ...args),
18
- error: (msg, ...args) => console.error("SpvVaults: " + msg, ...args)
19
- };
20
- this.vaultStorage = vaultStorage;
21
- this.bitcoin = bitcoin;
22
- this.vaultSigner = vaultSigner;
23
- this.bitcoinRpc = bitcoinRpc;
24
- this.getChain = getChain;
25
- this.config = config;
26
- }
27
- async processDepositEvent(vault, event) {
28
- vault.update(event);
29
- await this.saveVault(vault);
30
- }
31
- async processOpenEvent(vault, event) {
32
- if (vault.state === SpvVault_1.SpvVaultState.BTC_CONFIRMED) {
33
- vault.state = SpvVault_1.SpvVaultState.OPENED;
34
- }
35
- vault.update(event);
36
- await this.saveVault(vault);
37
- }
38
- async processCloseEvent(vault, event) {
39
- if (vault.state === SpvVault_1.SpvVaultState.OPENED) {
40
- vault.state = SpvVault_1.SpvVaultState.CLOSED;
41
- }
42
- vault.update(event);
43
- await this.saveVault(vault);
44
- }
45
- async processClaimEvent(vault, swap, event) {
46
- //Update vault
47
- const foundPendingWithdrawal = vault.pendingWithdrawals.findIndex(val => val.btcTx.txid === event.btcTxId);
48
- if (foundPendingWithdrawal !== -1)
49
- vault.pendingWithdrawals.splice(foundPendingWithdrawal, 1);
50
- vault.update(event);
51
- await this.saveVault(vault);
52
- }
53
- async createVaults(chainId, count, token, confirmations = 2, feeRate) {
54
- const { signer, chainInterface, tokenMultipliers, spvVaultContract } = this.getChain(chainId);
55
- const signerAddress = signer.getAddress();
56
- //Check vaultId of the latest saved vault
57
- let latestVaultId = -1n;
58
- for (let key in this.vaultStorage.data) {
59
- const vault = this.vaultStorage.data[key];
60
- if (vault.chainId !== chainId)
61
- continue;
62
- if (vault.data.getOwner() !== signerAddress)
63
- continue;
64
- if (vault.data.getVaultId() > latestVaultId)
65
- latestVaultId = vault.data.getVaultId();
66
- }
67
- latestVaultId++;
68
- const vaultAddreses = [];
69
- for (let i = 0; i < count; i++) {
70
- const vaultId = latestVaultId + BigInt(i);
71
- const address = await this.vaultSigner.getAddress(chainId, vaultId);
72
- vaultAddreses.push({ vaultId, address });
73
- }
74
- //Construct transaction
75
- const txResult = await this.bitcoin.getSignedMultiTransaction(vaultAddreses.map(val => {
76
- return { address: val.address, amount: exports.VAULT_DUST_AMOUNT };
77
- }), feeRate);
78
- const nativeToken = chainInterface.getNativeCurrencyAddress();
79
- const vaults = await Promise.all(vaultAddreses.map(async (val, index) => {
80
- const vaultData = await spvVaultContract.createVaultData(signerAddress, val.vaultId, txResult.txId + ":" + index, confirmations, [
81
- { token, multiplier: tokenMultipliers?.[token] ?? 1n },
82
- { token: nativeToken, multiplier: tokenMultipliers?.[nativeToken] ?? 1n }
83
- ]);
84
- return new SpvVault_1.SpvVault(chainId, vaultData, val.address);
85
- }));
86
- //Save vaults
87
- if (this.vaultStorage.saveDataArr != null) {
88
- await this.vaultStorage.saveDataArr(vaults.map(val => {
89
- return { id: val.getIdentifier(), object: val };
90
- }));
91
- }
92
- else {
93
- for (let vault of vaults) {
94
- await this.vaultStorage.saveData(vault.getIdentifier(), vault);
95
- }
96
- }
97
- //Send bitcoin tx
98
- await this.bitcoin.sendRawTransaction(txResult.raw);
99
- this.logger.info("createVaults(): Funding " + count + " vaults, bitcoin txId: " + txResult.txId);
100
- return {
101
- vaultsCreated: vaults.map(val => val.data.getVaultId()),
102
- btcTxId: txResult.txId
103
- };
104
- }
105
- async listVaults(chainId, token) {
106
- return Object.keys(this.vaultStorage.data)
107
- .map(key => this.vaultStorage.data[key])
108
- .filter(val => chainId == null ? true : val.chainId === chainId)
109
- .filter(val => val.data.getOwner() === this.getChain(val.chainId)?.signer?.getAddress())
110
- .filter(val => token == null ? true : val.data.getTokenData()[0].token === token);
111
- }
112
- async fundVault(vault, tokenAmounts) {
113
- if (vault.state !== SpvVault_1.SpvVaultState.OPENED)
114
- throw new Error("Vault not opened!");
115
- this.logger.info("fundVault(): Depositing tokens to the vault " + vault.data.getVaultId().toString(10) + ", amounts: " + tokenAmounts.map(val => val.toString(10)).join(", "));
116
- const { signer, spvVaultContract } = this.getChain(vault.chainId);
117
- const txId = await spvVaultContract.deposit(signer, vault.data, tokenAmounts, { waitForConfirmation: true });
118
- this.logger.info("fundVault(): Tokens deposited to vault " + vault.data.getVaultId().toString(10) + ", amounts: " + tokenAmounts.map(val => val.toString(10)).join(", ") + ", txId: " + txId);
119
- return txId;
120
- }
121
- async withdrawFromVault(vault, tokenAmounts, feeRate) {
122
- tokenAmounts.forEach((rawAmount, index) => {
123
- if (vault.balances[index] == null)
124
- throw new Error("Token not found in the vault");
125
- if (vault.balances[index].rawAmount < rawAmount)
126
- throw new Error("Not enough balance in the vault");
127
- });
128
- if (!vault.isReady())
129
- throw new Error("Vault not ready, wait for the latest swap to get at least 1 confirmation!");
130
- const { signer, spvVaultContract } = this.getChain(vault.chainId);
131
- const latestUtxo = vault.getLatestUtxo();
132
- const [txId, voutStr] = latestUtxo.split(":");
133
- const opReturnData = spvVaultContract.toOpReturnData(signer.getAddress(), tokenAmounts);
134
- let opReturnScript;
135
- if (opReturnData.length < 76) {
136
- opReturnScript = Buffer.concat([
137
- Buffer.from([0x6a, opReturnData.length]),
138
- opReturnData
139
- ]);
140
- }
141
- else {
142
- opReturnScript = Buffer.concat([
143
- Buffer.from([0x6a, 0x4c, opReturnData.length]),
144
- opReturnData
145
- ]);
146
- }
147
- let psbt = new btc_signer_1.Transaction({
148
- allowUnknownOutputs: true
149
- });
150
- psbt.addInput({
151
- txid: txId,
152
- index: parseInt(voutStr),
153
- witnessUtxo: {
154
- amount: BigInt(exports.VAULT_DUST_AMOUNT),
155
- script: this.bitcoin.toOutputScript(vault.btcAddress)
156
- }
157
- });
158
- psbt.addOutput({
159
- amount: BigInt(exports.VAULT_DUST_AMOUNT),
160
- script: this.bitcoin.toOutputScript(vault.btcAddress)
161
- });
162
- psbt.addOutput({
163
- amount: 0n,
164
- script: opReturnScript
165
- });
166
- psbt = await this.bitcoin.fundPsbt(psbt, feeRate);
167
- if (psbt.inputsLength < 2)
168
- throw new Error("PSBT needs at least 2 inputs!");
169
- psbt.updateInput(0, { sequence: 0x80000000 });
170
- psbt.updateInput(1, { sequence: 0x80000000 });
171
- psbt = await this.vaultSigner.signPsbt(vault.chainId, vault.data.getVaultId(), psbt, [0]);
172
- const res = await this.bitcoin.signPsbt(psbt);
173
- const parsedTransaction = await this.bitcoinRpc.parseTransaction(res.raw);
174
- const withdrawalData = await spvVaultContract.getWithdrawalData(parsedTransaction);
175
- if (withdrawalData.getSpentVaultUtxo() !== vault.getLatestUtxo()) {
176
- throw new Error("Latest vault UTXO already spent! Please try again later.");
177
- }
178
- vault.addWithdrawal(withdrawalData);
179
- await this.saveVault(vault);
180
- try {
181
- await this.bitcoin.sendRawTransaction(res.raw);
182
- }
183
- catch (e) {
184
- vault.removeWithdrawal(withdrawalData);
185
- await this.saveVault(vault);
186
- throw e;
187
- }
188
- return res.txId;
189
- }
190
- async checkVaults() {
191
- const vaults = Object.keys(this.vaultStorage.data).map(key => this.vaultStorage.data[key]);
192
- const claimWithdrawals = [];
193
- for (let vault of vaults) {
194
- const { signer, spvVaultContract, chainInterface } = this.getChain(vault.chainId);
195
- if (vault.data.getOwner() !== signer.getAddress())
196
- continue;
197
- if (vault.state === SpvVault_1.SpvVaultState.BTC_INITIATED) {
198
- //Check if btc tx confirmed
199
- const txId = vault.initialUtxo.split(":")[0];
200
- const btcTx = await this.bitcoinRpc.getTransaction(txId);
201
- if (btcTx.confirmations >= VAULT_INIT_CONFIRMATIONS) {
202
- //Double-check the state here to prevent race condition
203
- if (vault.state === SpvVault_1.SpvVaultState.BTC_INITIATED) {
204
- vault.state = SpvVault_1.SpvVaultState.BTC_CONFIRMED;
205
- await this.saveVault(vault);
206
- }
207
- this.logger.info("checkVaults(): Vault ID " + vault.data.getVaultId().toString(10) + " confirmed on bitcoin, opening vault on " + vault.chainId);
208
- }
209
- }
210
- if (vault.state === SpvVault_1.SpvVaultState.BTC_CONFIRMED) {
211
- //Check if open txs were sent already
212
- if (vault.scOpenTx != null) {
213
- //Check if confirmed
214
- const status = await chainInterface.getTxStatus(vault.scOpenTx.rawTx);
215
- if (status === "pending")
216
- return;
217
- if (status === "success") {
218
- vault.state = SpvVault_1.SpvVaultState.OPENED;
219
- await this.saveVault(vault);
220
- return;
221
- }
222
- }
223
- const txs = await spvVaultContract.txsOpen(signer.getAddress(), vault.data);
224
- let numTx = 0;
225
- const txIds = await chainInterface.sendAndConfirm(signer, txs, true, undefined, false, async (txId, rawTx) => {
226
- numTx++;
227
- if (numTx === txs.length) {
228
- //Final tx
229
- vault.scOpenTx = { txId, rawTx };
230
- await this.saveVault(vault);
231
- }
232
- });
233
- this.logger.info("checkVaults(): Vault ID " + vault.data.getVaultId().toString(10) + " opened on " + vault.chainId + " txId: " + txIds.join(", "));
234
- vault.state = SpvVault_1.SpvVaultState.OPENED;
235
- await this.saveVault(vault);
236
- }
237
- if (vault.state === SpvVault_1.SpvVaultState.OPENED) {
238
- let changed = false;
239
- //Check if some of the pendingWithdrawals got confirmed
240
- let latestOwnWithdrawalIndex = -1;
241
- let latestConfirmedWithdrawalIndex = -1;
242
- for (let i = 0; i < vault.pendingWithdrawals.length; i++) {
243
- const pendingWithdrawal = vault.pendingWithdrawals[i];
244
- //Check all the pending withdrawals that were not finalized yet
245
- if (pendingWithdrawal.btcTx.confirmations == null || pendingWithdrawal.btcTx.confirmations < BTC_FINALIZATION_CONFIRMATIONS) {
246
- const btcTx = await this.bitcoinRpc.getTransaction(pendingWithdrawal.btcTx.txid);
247
- if (btcTx == null) {
248
- //Probable double-spend, remove from pending withdrawals
249
- const index = vault.pendingWithdrawals.indexOf(pendingWithdrawal);
250
- if (index === -1) {
251
- this.logger.warn("checkVaults(): Tried to remove pending withdrawal txId: " + pendingWithdrawal.btcTx.txid + ", but doesn't exist anymore!");
252
- }
253
- else {
254
- vault.pendingWithdrawals.splice(index, 1);
255
- }
256
- changed = true;
257
- }
258
- else {
259
- //Update confirmations count
260
- if (pendingWithdrawal.btcTx.confirmations !== btcTx.confirmations ||
261
- pendingWithdrawal.btcTx.blockhash !== btcTx.blockhash) {
262
- pendingWithdrawal.btcTx.confirmations = btcTx.confirmations;
263
- pendingWithdrawal.btcTx.blockhash = btcTx.blockhash;
264
- changed = true;
265
- }
266
- }
267
- }
268
- //Check it has enough confirmations
269
- if (pendingWithdrawal.btcTx.confirmations >= vault.data.getConfirmations()) {
270
- latestConfirmedWithdrawalIndex = i;
271
- //Check if the pending withdrawals contain a withdrawal to our own address
272
- if (pendingWithdrawal.isRecipient(signer.getAddress())) {
273
- latestOwnWithdrawalIndex = i;
274
- }
275
- }
276
- }
277
- if (changed) {
278
- await this.saveVault(vault);
279
- }
280
- if (this.config.maxUnclaimedWithdrawals != null && latestConfirmedWithdrawalIndex + 1 >= this.config.maxUnclaimedWithdrawals) {
281
- this.logger.info("checkVaults(): Processing withdrawals by self, because a lot of them are unclaimed!");
282
- claimWithdrawals.push({ vault, withdrawals: vault.pendingWithdrawals.slice(0, latestConfirmedWithdrawalIndex + 1) });
283
- }
284
- else if (latestOwnWithdrawalIndex !== -1) {
285
- claimWithdrawals.push({ vault, withdrawals: vault.pendingWithdrawals.slice(0, latestOwnWithdrawalIndex + 1) });
286
- }
287
- }
288
- }
289
- for (let { vault, withdrawals } of claimWithdrawals) {
290
- if (!await this.claimWithdrawals(vault, withdrawals)) {
291
- this.logger.error("checkVaults(): Cannot process withdrawals " + withdrawals.map(val => val.btcTx.txid).join(", ") + " for vault: " + vault.data.getVaultId());
292
- break;
293
- }
294
- }
295
- }
296
- async claimWithdrawals(vault, withdrawal) {
297
- const { signer, spvVaultContract } = this.getChain(vault.chainId);
298
- try {
299
- const txId = await spvVaultContract.claim(signer, vault.data, withdrawal.map(tx => {
300
- return { tx };
301
- }), undefined, true, { waitForConfirmation: true });
302
- this.logger.info("claimWithdrawal(): Successfully claimed withdrawals, btcTxIds: " + withdrawal.map(val => val.btcTx.txid).join(", ") + " smartChainTxId: " + txId);
303
- return true;
304
- }
305
- catch (e) {
306
- this.logger.error("claimWithdrawal(): Tried to claim but got error: ", e);
307
- return false;
308
- }
309
- }
310
- async getVault(chainId, owner, vaultId) {
311
- return this.vaultStorage.data[chainId + "_" + owner + "_" + vaultId.toString(10)];
312
- }
313
- /**
314
- * Returns a ready-to-use vault for a specific request
315
- *
316
- * @param chainIdentifier
317
- * @param totalSats
318
- * @param token
319
- * @param amount
320
- * @param gasToken
321
- * @param gasTokenAmount
322
- * @protected
323
- */
324
- async findVaultForSwap(chainIdentifier, totalSats, token, amount, gasToken, gasTokenAmount) {
325
- const { signer } = this.getChain(chainIdentifier);
326
- const pluginResponse = await PluginManager_1.PluginManager.onVaultSelection(chainIdentifier, totalSats, { token, amount }, { token: gasToken, amount: gasTokenAmount });
327
- if (pluginResponse != null) {
328
- AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(pluginResponse);
329
- return pluginResponse;
330
- }
331
- const candidates = Object.keys(this.vaultStorage.data)
332
- .map(key => this.vaultStorage.data[key])
333
- .filter(vault => vault.chainId === chainIdentifier && vault.data.getOwner() === signer.getAddress() && vault.isReady())
334
- .filter(vault => {
335
- const token0 = vault.balances[0];
336
- if (token0.token !== token || token0.scaledAmount < amount)
337
- return false;
338
- if (gasToken != null && gasTokenAmount !== 0n) {
339
- const token1 = vault.balances[1];
340
- if (token1.token !== gasToken || token1.scaledAmount < gasTokenAmount)
341
- return false;
342
- }
343
- return true;
344
- });
345
- candidates.sort((a, b) => (0, Utils_1.bigIntSorter)(a.balances[0].scaledAmount, b.balances[0].scaledAmount));
346
- const result = candidates[0];
347
- if (result == null)
348
- throw {
349
- code: 20301,
350
- msg: "No suitable swap vault found, try again later!"
351
- };
352
- return result;
353
- }
354
- saveVault(vault) {
355
- return this.vaultStorage.saveData(vault.getIdentifier(), vault);
356
- }
357
- async startVaultsWatchdog() {
358
- let rerun;
359
- rerun = async () => {
360
- await this.checkVaults().catch(e => console.error(e));
361
- setTimeout(rerun, this.config.vaultsCheckInterval);
362
- };
363
- await rerun();
364
- }
365
- async init() {
366
- const vaults = await this.vaultStorage.loadData(SpvVault_1.SpvVault);
367
- }
368
- }
369
- exports.SpvVaults = SpvVaults;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpvVaults = exports.VAULT_DUST_AMOUNT = void 0;
4
+ const SpvVault_1 = require("./SpvVault");
5
+ const Utils_1 = require("../../utils/Utils");
6
+ const PluginManager_1 = require("../../plugins/PluginManager");
7
+ const AmountAssertions_1 = require("../assertions/AmountAssertions");
8
+ const btc_signer_1 = require("@scure/btc-signer");
9
+ exports.VAULT_DUST_AMOUNT = 600;
10
+ const VAULT_INIT_CONFIRMATIONS = 2;
11
+ const BTC_FINALIZATION_CONFIRMATIONS = 6;
12
+ class SpvVaults {
13
+ constructor(vaultStorage, bitcoin, vaultSigner, bitcoinRpc, getChain, config) {
14
+ this.logger = {
15
+ debug: (msg, ...args) => console.debug("SpvVaults: " + msg, ...args),
16
+ info: (msg, ...args) => console.info("SpvVaults: " + msg, ...args),
17
+ warn: (msg, ...args) => console.warn("SpvVaults: " + msg, ...args),
18
+ error: (msg, ...args) => console.error("SpvVaults: " + msg, ...args)
19
+ };
20
+ this.vaultStorage = vaultStorage;
21
+ this.bitcoin = bitcoin;
22
+ this.vaultSigner = vaultSigner;
23
+ this.bitcoinRpc = bitcoinRpc;
24
+ this.getChain = getChain;
25
+ this.config = config;
26
+ }
27
+ async processDepositEvent(vault, event) {
28
+ vault.update(event);
29
+ await this.saveVault(vault);
30
+ }
31
+ async processOpenEvent(vault, event) {
32
+ if (vault.state === SpvVault_1.SpvVaultState.BTC_CONFIRMED) {
33
+ vault.state = SpvVault_1.SpvVaultState.OPENED;
34
+ }
35
+ vault.update(event);
36
+ await this.saveVault(vault);
37
+ }
38
+ async processCloseEvent(vault, event) {
39
+ if (vault.state === SpvVault_1.SpvVaultState.OPENED) {
40
+ vault.state = SpvVault_1.SpvVaultState.CLOSED;
41
+ }
42
+ vault.update(event);
43
+ await this.saveVault(vault);
44
+ }
45
+ async processClaimEvent(vault, swap, event) {
46
+ //Update vault
47
+ const foundPendingWithdrawal = vault.pendingWithdrawals.findIndex(val => val.btcTx.txid === event.btcTxId);
48
+ if (foundPendingWithdrawal !== -1)
49
+ vault.pendingWithdrawals.splice(foundPendingWithdrawal, 1);
50
+ vault.update(event);
51
+ await this.saveVault(vault);
52
+ }
53
+ async createVaults(chainId, count, token, confirmations = 2, feeRate) {
54
+ const { signer, chainInterface, tokenMultipliers, spvVaultContract } = this.getChain(chainId);
55
+ const signerAddress = signer.getAddress();
56
+ //Check vaultId of the latest saved vault
57
+ let latestVaultId = -1n;
58
+ for (let key in this.vaultStorage.data) {
59
+ const vault = this.vaultStorage.data[key];
60
+ if (vault.chainId !== chainId)
61
+ continue;
62
+ if (vault.data.getOwner() !== signerAddress)
63
+ continue;
64
+ if (vault.data.getVaultId() > latestVaultId)
65
+ latestVaultId = vault.data.getVaultId();
66
+ }
67
+ latestVaultId++;
68
+ const vaultAddreses = [];
69
+ for (let i = 0; i < count; i++) {
70
+ const vaultId = latestVaultId + BigInt(i);
71
+ const address = await this.vaultSigner.getAddress(chainId, vaultId);
72
+ vaultAddreses.push({ vaultId, address });
73
+ }
74
+ //Construct transaction
75
+ const txResult = await this.bitcoin.getSignedMultiTransaction(vaultAddreses.map(val => {
76
+ return { address: val.address, amount: exports.VAULT_DUST_AMOUNT };
77
+ }), feeRate);
78
+ const nativeToken = chainInterface.getNativeCurrencyAddress();
79
+ const vaults = await Promise.all(vaultAddreses.map(async (val, index) => {
80
+ const vaultData = await spvVaultContract.createVaultData(signerAddress, val.vaultId, txResult.txId + ":" + index, confirmations, [
81
+ { token, multiplier: tokenMultipliers?.[token] ?? 1n },
82
+ { token: nativeToken, multiplier: tokenMultipliers?.[nativeToken] ?? 1n }
83
+ ]);
84
+ return new SpvVault_1.SpvVault(chainId, vaultData, val.address);
85
+ }));
86
+ //Save vaults
87
+ if (this.vaultStorage.saveDataArr != null) {
88
+ await this.vaultStorage.saveDataArr(vaults.map(val => {
89
+ return { id: val.getIdentifier(), object: val };
90
+ }));
91
+ }
92
+ else {
93
+ for (let vault of vaults) {
94
+ await this.vaultStorage.saveData(vault.getIdentifier(), vault);
95
+ }
96
+ }
97
+ //Send bitcoin tx
98
+ await this.bitcoin.sendRawTransaction(txResult.raw);
99
+ this.logger.info("createVaults(): Funding " + count + " vaults, bitcoin txId: " + txResult.txId);
100
+ return {
101
+ vaultsCreated: vaults.map(val => val.data.getVaultId()),
102
+ btcTxId: txResult.txId
103
+ };
104
+ }
105
+ async listVaults(chainId, token) {
106
+ return Object.keys(this.vaultStorage.data)
107
+ .map(key => this.vaultStorage.data[key])
108
+ .filter(val => chainId == null ? true : val.chainId === chainId)
109
+ .filter(val => val.data.getOwner() === this.getChain(val.chainId)?.signer?.getAddress())
110
+ .filter(val => token == null ? true : val.data.getTokenData()[0].token === token);
111
+ }
112
+ async fundVault(vault, tokenAmounts) {
113
+ if (vault.state !== SpvVault_1.SpvVaultState.OPENED)
114
+ throw new Error("Vault not opened!");
115
+ this.logger.info("fundVault(): Depositing tokens to the vault " + vault.data.getVaultId().toString(10) + ", amounts: " + tokenAmounts.map(val => val.toString(10)).join(", "));
116
+ const { signer, spvVaultContract } = this.getChain(vault.chainId);
117
+ const txId = await spvVaultContract.deposit(signer, vault.data, tokenAmounts, { waitForConfirmation: true });
118
+ this.logger.info("fundVault(): Tokens deposited to vault " + vault.data.getVaultId().toString(10) + ", amounts: " + tokenAmounts.map(val => val.toString(10)).join(", ") + ", txId: " + txId);
119
+ return txId;
120
+ }
121
+ async withdrawFromVault(vault, tokenAmounts, feeRate) {
122
+ tokenAmounts.forEach((rawAmount, index) => {
123
+ if (vault.balances[index] == null)
124
+ throw new Error("Token not found in the vault");
125
+ if (vault.balances[index].rawAmount < rawAmount)
126
+ throw new Error("Not enough balance in the vault");
127
+ });
128
+ if (!vault.isReady())
129
+ throw new Error("Vault not ready, wait for the latest swap to get at least 1 confirmation!");
130
+ const { signer, spvVaultContract } = this.getChain(vault.chainId);
131
+ const latestUtxo = vault.getLatestUtxo();
132
+ const [txId, voutStr] = latestUtxo.split(":");
133
+ const opReturnData = spvVaultContract.toOpReturnData(signer.getAddress(), tokenAmounts);
134
+ let opReturnScript;
135
+ if (opReturnData.length < 76) {
136
+ opReturnScript = Buffer.concat([
137
+ Buffer.from([0x6a, opReturnData.length]),
138
+ opReturnData
139
+ ]);
140
+ }
141
+ else {
142
+ opReturnScript = Buffer.concat([
143
+ Buffer.from([0x6a, 0x4c, opReturnData.length]),
144
+ opReturnData
145
+ ]);
146
+ }
147
+ let psbt = new btc_signer_1.Transaction({
148
+ allowUnknownOutputs: true
149
+ });
150
+ psbt.addInput({
151
+ txid: txId,
152
+ index: parseInt(voutStr),
153
+ witnessUtxo: {
154
+ amount: BigInt(exports.VAULT_DUST_AMOUNT),
155
+ script: this.bitcoin.toOutputScript(vault.btcAddress)
156
+ }
157
+ });
158
+ psbt.addOutput({
159
+ amount: BigInt(exports.VAULT_DUST_AMOUNT),
160
+ script: this.bitcoin.toOutputScript(vault.btcAddress)
161
+ });
162
+ psbt.addOutput({
163
+ amount: 0n,
164
+ script: opReturnScript
165
+ });
166
+ psbt = await this.bitcoin.fundPsbt(psbt, feeRate);
167
+ if (psbt.inputsLength < 2)
168
+ throw new Error("PSBT needs at least 2 inputs!");
169
+ psbt.updateInput(0, { sequence: 0x80000000 });
170
+ psbt.updateInput(1, { sequence: 0x80000000 });
171
+ psbt = await this.vaultSigner.signPsbt(vault.chainId, vault.data.getVaultId(), psbt, [0]);
172
+ const res = await this.bitcoin.signPsbt(psbt);
173
+ const parsedTransaction = await this.bitcoinRpc.parseTransaction(res.raw);
174
+ const withdrawalData = await spvVaultContract.getWithdrawalData(parsedTransaction);
175
+ if (withdrawalData.getSpentVaultUtxo() !== vault.getLatestUtxo()) {
176
+ throw new Error("Latest vault UTXO already spent! Please try again later.");
177
+ }
178
+ vault.addWithdrawal(withdrawalData);
179
+ await this.saveVault(vault);
180
+ try {
181
+ await this.bitcoin.sendRawTransaction(res.raw);
182
+ }
183
+ catch (e) {
184
+ vault.removeWithdrawal(withdrawalData);
185
+ await this.saveVault(vault);
186
+ throw e;
187
+ }
188
+ return res.txId;
189
+ }
190
+ async checkVaults() {
191
+ const vaults = Object.keys(this.vaultStorage.data).map(key => this.vaultStorage.data[key]);
192
+ const claimWithdrawals = [];
193
+ for (let vault of vaults) {
194
+ const { signer, spvVaultContract, chainInterface } = this.getChain(vault.chainId);
195
+ if (vault.data.getOwner() !== signer.getAddress())
196
+ continue;
197
+ if (vault.state === SpvVault_1.SpvVaultState.BTC_INITIATED) {
198
+ //Check if btc tx confirmed
199
+ const txId = vault.initialUtxo.split(":")[0];
200
+ const btcTx = await this.bitcoinRpc.getTransaction(txId);
201
+ if (btcTx.confirmations >= VAULT_INIT_CONFIRMATIONS) {
202
+ //Double-check the state here to prevent race condition
203
+ if (vault.state === SpvVault_1.SpvVaultState.BTC_INITIATED) {
204
+ vault.state = SpvVault_1.SpvVaultState.BTC_CONFIRMED;
205
+ await this.saveVault(vault);
206
+ }
207
+ this.logger.info("checkVaults(): Vault ID " + vault.data.getVaultId().toString(10) + " confirmed on bitcoin, opening vault on " + vault.chainId);
208
+ }
209
+ }
210
+ if (vault.state === SpvVault_1.SpvVaultState.BTC_CONFIRMED) {
211
+ //Check if open txs were sent already
212
+ if (vault.scOpenTx != null) {
213
+ //Check if confirmed
214
+ const status = await chainInterface.getTxStatus(vault.scOpenTx.rawTx);
215
+ if (status === "pending")
216
+ return;
217
+ if (status === "success") {
218
+ vault.state = SpvVault_1.SpvVaultState.OPENED;
219
+ await this.saveVault(vault);
220
+ return;
221
+ }
222
+ }
223
+ const txs = await spvVaultContract.txsOpen(signer.getAddress(), vault.data);
224
+ let numTx = 0;
225
+ const txIds = await chainInterface.sendAndConfirm(signer, txs, true, undefined, false, async (txId, rawTx) => {
226
+ numTx++;
227
+ if (numTx === txs.length) {
228
+ //Final tx
229
+ vault.scOpenTx = { txId, rawTx };
230
+ await this.saveVault(vault);
231
+ }
232
+ });
233
+ this.logger.info("checkVaults(): Vault ID " + vault.data.getVaultId().toString(10) + " opened on " + vault.chainId + " txId: " + txIds.join(", "));
234
+ vault.state = SpvVault_1.SpvVaultState.OPENED;
235
+ await this.saveVault(vault);
236
+ }
237
+ if (vault.state === SpvVault_1.SpvVaultState.OPENED) {
238
+ let changed = false;
239
+ //Check if some of the pendingWithdrawals got confirmed
240
+ let latestOwnWithdrawalIndex = -1;
241
+ let latestConfirmedWithdrawalIndex = -1;
242
+ for (let i = 0; i < vault.pendingWithdrawals.length; i++) {
243
+ const pendingWithdrawal = vault.pendingWithdrawals[i];
244
+ //Check all the pending withdrawals that were not finalized yet
245
+ if (pendingWithdrawal.btcTx.confirmations == null || pendingWithdrawal.btcTx.confirmations < BTC_FINALIZATION_CONFIRMATIONS) {
246
+ const btcTx = await this.bitcoinRpc.getTransaction(pendingWithdrawal.btcTx.txid);
247
+ if (btcTx == null) {
248
+ //Probable double-spend, remove from pending withdrawals
249
+ const index = vault.pendingWithdrawals.indexOf(pendingWithdrawal);
250
+ if (index === -1) {
251
+ this.logger.warn("checkVaults(): Tried to remove pending withdrawal txId: " + pendingWithdrawal.btcTx.txid + ", but doesn't exist anymore!");
252
+ }
253
+ else {
254
+ vault.pendingWithdrawals.splice(index, 1);
255
+ }
256
+ changed = true;
257
+ }
258
+ else {
259
+ //Update confirmations count
260
+ if (pendingWithdrawal.btcTx.confirmations !== btcTx.confirmations ||
261
+ pendingWithdrawal.btcTx.blockhash !== btcTx.blockhash) {
262
+ pendingWithdrawal.btcTx.confirmations = btcTx.confirmations;
263
+ pendingWithdrawal.btcTx.blockhash = btcTx.blockhash;
264
+ changed = true;
265
+ }
266
+ }
267
+ }
268
+ //Check it has enough confirmations
269
+ if (pendingWithdrawal.btcTx.confirmations >= vault.data.getConfirmations()) {
270
+ latestConfirmedWithdrawalIndex = i;
271
+ //Check if the pending withdrawals contain a withdrawal to our own address
272
+ if (pendingWithdrawal.isRecipient(signer.getAddress())) {
273
+ latestOwnWithdrawalIndex = i;
274
+ }
275
+ }
276
+ }
277
+ if (changed) {
278
+ await this.saveVault(vault);
279
+ }
280
+ if (this.config.maxUnclaimedWithdrawals != null && latestConfirmedWithdrawalIndex + 1 >= this.config.maxUnclaimedWithdrawals) {
281
+ this.logger.info("checkVaults(): Processing withdrawals by self, because a lot of them are unclaimed!");
282
+ claimWithdrawals.push({ vault, withdrawals: vault.pendingWithdrawals.slice(0, latestConfirmedWithdrawalIndex + 1) });
283
+ }
284
+ else if (latestOwnWithdrawalIndex !== -1) {
285
+ claimWithdrawals.push({ vault, withdrawals: vault.pendingWithdrawals.slice(0, latestOwnWithdrawalIndex + 1) });
286
+ }
287
+ }
288
+ }
289
+ for (let { vault, withdrawals } of claimWithdrawals) {
290
+ if (!await this.claimWithdrawals(vault, withdrawals)) {
291
+ this.logger.error("checkVaults(): Cannot process withdrawals " + withdrawals.map(val => val.btcTx.txid).join(", ") + " for vault: " + vault.data.getVaultId());
292
+ break;
293
+ }
294
+ }
295
+ }
296
+ async claimWithdrawals(vault, withdrawal) {
297
+ const { signer, spvVaultContract } = this.getChain(vault.chainId);
298
+ try {
299
+ const txId = await spvVaultContract.claim(signer, vault.data, withdrawal.map(tx => {
300
+ return { tx };
301
+ }), undefined, true, { waitForConfirmation: true });
302
+ this.logger.info("claimWithdrawal(): Successfully claimed withdrawals, btcTxIds: " + withdrawal.map(val => val.btcTx.txid).join(", ") + " smartChainTxId: " + txId);
303
+ return true;
304
+ }
305
+ catch (e) {
306
+ this.logger.error("claimWithdrawal(): Tried to claim but got error: ", e);
307
+ return false;
308
+ }
309
+ }
310
+ async getVault(chainId, owner, vaultId) {
311
+ return this.vaultStorage.data[chainId + "_" + owner + "_" + vaultId.toString(10)];
312
+ }
313
+ /**
314
+ * Returns a ready-to-use vault for a specific request
315
+ *
316
+ * @param chainIdentifier
317
+ * @param totalSats
318
+ * @param token
319
+ * @param amount
320
+ * @param gasToken
321
+ * @param gasTokenAmount
322
+ * @protected
323
+ */
324
+ async findVaultForSwap(chainIdentifier, totalSats, token, amount, gasToken, gasTokenAmount) {
325
+ const { signer } = this.getChain(chainIdentifier);
326
+ const pluginResponse = await PluginManager_1.PluginManager.onVaultSelection(chainIdentifier, totalSats, { token, amount }, { token: gasToken, amount: gasTokenAmount });
327
+ if (pluginResponse != null) {
328
+ AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(pluginResponse);
329
+ return pluginResponse;
330
+ }
331
+ const candidates = Object.keys(this.vaultStorage.data)
332
+ .map(key => this.vaultStorage.data[key])
333
+ .filter(vault => vault.chainId === chainIdentifier && vault.data.getOwner() === signer.getAddress() && vault.isReady())
334
+ .filter(vault => {
335
+ const token0 = vault.balances[0];
336
+ if (token0.token !== token || token0.scaledAmount < amount)
337
+ return false;
338
+ if (gasToken != null && gasTokenAmount !== 0n) {
339
+ const token1 = vault.balances[1];
340
+ if (token1.token !== gasToken || token1.scaledAmount < gasTokenAmount)
341
+ return false;
342
+ }
343
+ return true;
344
+ });
345
+ candidates.sort((a, b) => (0, Utils_1.bigIntSorter)(a.balances[0].scaledAmount, b.balances[0].scaledAmount));
346
+ const result = candidates[0];
347
+ if (result == null)
348
+ throw {
349
+ code: 20301,
350
+ msg: "No suitable swap vault found, try again later!"
351
+ };
352
+ return result;
353
+ }
354
+ saveVault(vault) {
355
+ return this.vaultStorage.saveData(vault.getIdentifier(), vault);
356
+ }
357
+ async startVaultsWatchdog() {
358
+ let rerun;
359
+ rerun = async () => {
360
+ await this.checkVaults().catch(e => console.error(e));
361
+ setTimeout(rerun, this.config.vaultsCheckInterval);
362
+ };
363
+ await rerun();
364
+ }
365
+ async init() {
366
+ const vaults = await this.vaultStorage.loadData(SpvVault_1.SpvVault);
367
+ }
368
+ }
369
+ exports.SpvVaults = SpvVaults;