@atomiqlabs/sdk 8.1.8 → 8.3.1
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.
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +41 -5
- package/dist/bitcoin/wallet/BitcoinWallet.js +36 -1
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +52 -2
- package/dist/bitcoin/wallet/IBitcoinWallet.js +2 -1
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +42 -7
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +36 -1
- package/dist/enums/FeeType.d.ts +7 -0
- package/dist/enums/FeeType.js +7 -0
- package/dist/enums/SwapAmountType.d.ts +7 -0
- package/dist/enums/SwapAmountType.js +7 -0
- package/dist/enums/SwapDirection.d.ts +7 -0
- package/dist/enums/SwapDirection.js +7 -0
- package/dist/enums/SwapType.d.ts +62 -1
- package/dist/enums/SwapType.js +62 -1
- package/dist/errors/IntermediaryError.d.ts +4 -0
- package/dist/errors/IntermediaryError.js +1 -0
- package/dist/errors/RequestError.d.ts +15 -1
- package/dist/errors/RequestError.js +8 -0
- package/dist/errors/UserError.d.ts +1 -0
- package/dist/errors/UserError.js +1 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.js +3 -4
- package/dist/intermediaries/Intermediary.d.ts +57 -10
- package/dist/intermediaries/Intermediary.js +37 -10
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +55 -22
- package/dist/intermediaries/IntermediaryDiscovery.js +35 -22
- package/dist/prices/RedundantSwapPrice.d.ts +24 -3
- package/dist/prices/RedundantSwapPrice.js +21 -1
- package/dist/prices/SingleSwapPrice.d.ts +9 -6
- package/dist/prices/SingleSwapPrice.js +10 -7
- package/dist/prices/SwapPriceWithChain.d.ts +54 -16
- package/dist/prices/SwapPriceWithChain.js +58 -20
- package/dist/prices/abstract/ISwapPrice.d.ts +94 -45
- package/dist/prices/abstract/ISwapPrice.js +103 -55
- package/dist/prices/providers/BinancePriceProvider.d.ts +7 -0
- package/dist/prices/providers/BinancePriceProvider.js +7 -0
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +6 -0
- package/dist/prices/providers/CoinGeckoPriceProvider.js +6 -0
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +6 -0
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +6 -0
- package/dist/prices/providers/CustomPriceProvider.d.ts +11 -0
- package/dist/prices/providers/CustomPriceProvider.js +11 -0
- package/dist/prices/providers/KrakenPriceProvider.d.ts +9 -0
- package/dist/prices/providers/KrakenPriceProvider.js +9 -0
- package/dist/prices/providers/OKXPriceProvider.d.ts +6 -0
- package/dist/prices/providers/OKXPriceProvider.js +6 -0
- package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +3 -0
- package/dist/prices/providers/abstract/ExchangePriceProvider.js +3 -0
- package/dist/storage/IUnifiedStorage.d.ts +19 -7
- package/dist/storage/UnifiedSwapStorage.d.ts +33 -3
- package/dist/storage/UnifiedSwapStorage.js +29 -1
- package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +31 -7
- package/dist/storage-browser/IndexedDBUnifiedStorage.js +29 -6
- package/dist/storage-browser/LocalStorageManager.d.ts +25 -1
- package/dist/storage-browser/LocalStorageManager.js +25 -1
- package/dist/swapper/Swapper.d.ts +302 -221
- package/dist/swapper/Swapper.js +376 -344
- package/dist/swapper/SwapperFactory.d.ts +41 -17
- package/dist/swapper/SwapperFactory.js +23 -2
- package/dist/swapper/SwapperUtils.d.ts +75 -28
- package/dist/swapper/SwapperUtils.js +107 -60
- package/dist/swapper/SwapperWithChain.d.ts +286 -91
- package/dist/swapper/SwapperWithChain.js +218 -64
- package/dist/swapper/SwapperWithSigner.d.ts +229 -80
- package/dist/swapper/SwapperWithSigner.js +190 -44
- package/dist/swaps/IAddressSwap.d.ts +10 -1
- package/dist/swaps/IAddressSwap.js +2 -1
- package/dist/swaps/IBTCWalletSwap.d.ts +24 -6
- package/dist/swaps/IBTCWalletSwap.js +2 -1
- package/dist/swaps/IClaimableSwap.d.ts +36 -4
- package/dist/swaps/IClaimableSwap.js +2 -1
- package/dist/swaps/IClaimableSwapWrapper.d.ts +11 -1
- package/dist/swaps/IRefundableSwap.d.ts +29 -3
- package/dist/swaps/IRefundableSwap.js +2 -1
- package/dist/swaps/ISwap.d.ts +159 -21
- package/dist/swaps/ISwap.js +90 -33
- package/dist/swaps/ISwapWithGasDrop.d.ts +6 -0
- package/dist/swaps/ISwapWithGasDrop.js +1 -0
- package/dist/swaps/ISwapWrapper.d.ts +157 -48
- package/dist/swaps/ISwapWrapper.js +130 -72
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +49 -6
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +22 -12
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +65 -12
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +38 -19
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +39 -9
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +30 -21
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +31 -15
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +33 -18
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +94 -29
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +90 -27
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +22 -9
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +24 -11
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +275 -58
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +516 -239
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +76 -25
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +131 -49
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +311 -51
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +542 -193
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +87 -26
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +147 -58
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +209 -53
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +449 -242
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +77 -23
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +116 -46
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +197 -56
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +326 -189
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +30 -5
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +44 -19
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +60 -19
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +74 -31
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +76 -50
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +106 -101
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +36 -13
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +65 -19
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +46 -17
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +82 -27
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +328 -92
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +460 -219
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +76 -24
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +244 -124
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +146 -18
- package/dist/swaps/trusted/ln/LnForGasSwap.js +173 -43
- package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +29 -10
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +30 -11
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +200 -47
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +230 -78
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +34 -12
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +33 -14
- package/dist/types/AmountData.d.ts +2 -1
- package/dist/types/CustomPriceFunction.d.ts +7 -1
- package/dist/types/SwapExecutionAction.d.ts +74 -4
- package/dist/types/SwapWithSigner.d.ts +4 -1
- package/dist/types/SwapWithSigner.js +5 -2
- package/dist/types/Token.d.ts +11 -5
- package/dist/types/Token.js +6 -3
- package/dist/types/TokenAmount.d.ts +3 -0
- package/dist/types/TokenAmount.js +2 -0
- package/dist/types/fees/Fee.d.ts +2 -1
- package/dist/types/fees/FeeBreakdown.d.ts +2 -1
- package/dist/types/fees/PercentagePPM.d.ts +2 -0
- package/dist/types/fees/PercentagePPM.js +1 -0
- package/dist/types/lnurl/LNURLPay.d.ts +14 -6
- package/dist/types/lnurl/LNURLPay.js +6 -2
- package/dist/types/lnurl/LNURLWithdraw.d.ts +12 -5
- package/dist/types/lnurl/LNURLWithdraw.js +6 -2
- package/dist/types/wallets/LightningInvoiceCreateService.d.ts +20 -0
- package/dist/types/wallets/LightningInvoiceCreateService.js +15 -0
- package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +3 -1
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +3 -1
- package/dist/utils/BitcoinUtils.d.ts +1 -0
- package/dist/utils/BitcoinUtils.js +5 -1
- package/dist/utils/SwapUtils.d.ts +56 -1
- package/dist/utils/SwapUtils.js +53 -1
- package/dist/utils/TokenUtils.d.ts +10 -2
- package/dist/utils/TokenUtils.js +12 -4
- package/package.json +3 -3
- package/src/bitcoin/wallet/BitcoinWallet.ts +41 -5
- package/src/bitcoin/wallet/IBitcoinWallet.ts +57 -2
- package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +42 -6
- package/src/enums/FeeType.ts +7 -0
- package/src/enums/SwapAmountType.ts +7 -0
- package/src/enums/SwapDirection.ts +7 -0
- package/src/enums/SwapType.ts +62 -2
- package/src/errors/IntermediaryError.ts +4 -0
- package/src/errors/RequestError.ts +15 -1
- package/src/errors/UserError.ts +1 -0
- package/src/index.ts +6 -5
- package/src/intermediaries/Intermediary.ts +57 -10
- package/src/intermediaries/IntermediaryDiscovery.ts +60 -27
- package/src/prices/RedundantSwapPrice.ts +24 -4
- package/src/prices/SingleSwapPrice.ts +10 -7
- package/src/prices/SwapPriceWithChain.ts +59 -21
- package/src/prices/abstract/ISwapPrice.ts +114 -65
- package/src/prices/providers/BinancePriceProvider.ts +7 -0
- package/src/prices/providers/CoinGeckoPriceProvider.ts +6 -0
- package/src/prices/providers/CoinPaprikaPriceProvider.ts +6 -0
- package/src/prices/providers/CustomPriceProvider.ts +11 -0
- package/src/prices/providers/KrakenPriceProvider.ts +9 -0
- package/src/prices/providers/OKXPriceProvider.ts +6 -0
- package/src/prices/providers/abstract/ExchangePriceProvider.ts +3 -0
- package/src/storage/IUnifiedStorage.ts +19 -7
- package/src/storage/UnifiedSwapStorage.ts +33 -3
- package/src/storage-browser/IndexedDBUnifiedStorage.ts +31 -8
- package/src/storage-browser/LocalStorageManager.ts +25 -1
- package/src/swapper/Swapper.ts +512 -378
- package/src/swapper/SwapperFactory.ts +44 -21
- package/src/swapper/SwapperUtils.ts +107 -60
- package/src/swapper/SwapperWithChain.ts +320 -81
- package/src/swapper/SwapperWithSigner.ts +263 -56
- package/src/swaps/IAddressSwap.ts +11 -1
- package/src/swaps/IBTCWalletSwap.ts +24 -8
- package/src/swaps/IClaimableSwap.ts +39 -4
- package/src/swaps/IClaimableSwapWrapper.ts +11 -2
- package/src/swaps/IRefundableSwap.ts +32 -3
- package/src/swaps/ISwap.ts +221 -82
- package/src/swaps/ISwapWithGasDrop.ts +6 -0
- package/src/swaps/ISwapWrapper.ts +212 -94
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +62 -18
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +83 -37
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +61 -30
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +37 -19
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +120 -51
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +24 -11
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +559 -256
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +155 -61
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +590 -226
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +177 -74
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +470 -243
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +141 -59
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +352 -193
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +48 -23
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +86 -39
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +110 -110
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +88 -33
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +101 -31
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +534 -263
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +289 -148
- package/src/swaps/trusted/ln/LnForGasSwap.ts +184 -45
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +34 -15
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +260 -86
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +41 -19
- package/src/types/AmountData.ts +2 -1
- package/src/types/CustomPriceFunction.ts +7 -1
- package/src/types/SwapExecutionAction.ts +84 -5
- package/src/types/SwapWithSigner.ts +7 -3
- package/src/types/Token.ts +12 -5
- package/src/types/TokenAmount.ts +3 -0
- package/src/types/fees/Fee.ts +2 -1
- package/src/types/fees/FeeBreakdown.ts +2 -1
- package/src/types/fees/PercentagePPM.ts +2 -0
- package/src/types/lnurl/LNURLPay.ts +14 -6
- package/src/types/lnurl/LNURLWithdraw.ts +12 -5
- package/src/types/wallets/LightningInvoiceCreateService.ts +26 -0
- package/src/types/wallets/MinimalBitcoinWalletInterface.ts +3 -1
- package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +3 -1
- package/src/utils/BitcoinUtils.ts +5 -0
- package/src/utils/SwapUtils.ts +61 -1
- package/src/utils/TokenUtils.ts +12 -4
- package/dist/bitcoin/BitcoinRpcWithAddressIndex.d.ts +0 -68
- package/dist/bitcoin/BitcoinRpcWithAddressIndex.js +0 -2
- package/dist/bitcoin/LightningNetworkApi.d.ts +0 -12
- package/dist/bitcoin/LightningNetworkApi.js +0 -2
- package/dist/bitcoin/mempool/MempoolApi.d.ts +0 -350
- package/dist/bitcoin/mempool/MempoolApi.js +0 -311
- package/dist/bitcoin/mempool/MempoolBitcoinBlock.d.ts +0 -44
- package/dist/bitcoin/mempool/MempoolBitcoinBlock.js +0 -48
- package/dist/bitcoin/mempool/MempoolBitcoinRpc.d.ts +0 -119
- package/dist/bitcoin/mempool/MempoolBitcoinRpc.js +0 -361
- package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.d.ts +0 -22
- package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.js +0 -105
- package/dist/errors/PaymentAuthError.d.ts +0 -11
- package/dist/errors/PaymentAuthError.js +0 -23
- package/src/errors/PaymentAuthError.ts +0 -26
|
@@ -19,23 +19,73 @@ const TimeoutUtils_1 = require("../../utils/TimeoutUtils");
|
|
|
19
19
|
const PriceInfoType_1 = require("../../types/PriceInfoType");
|
|
20
20
|
const BitcoinWalletUtils_1 = require("../../utils/BitcoinWalletUtils");
|
|
21
21
|
/**
|
|
22
|
-
* State enum for SPV
|
|
22
|
+
* State enum for SPV vault (UTXO-controlled vault) based swaps
|
|
23
23
|
* @category Swaps
|
|
24
24
|
*/
|
|
25
25
|
var SpvFromBTCSwapState;
|
|
26
26
|
(function (SpvFromBTCSwapState) {
|
|
27
|
+
/**
|
|
28
|
+
* Catastrophic failure has occurred when processing the swap on the smart chain side,
|
|
29
|
+
* this implies a bug in the smart contract code or the user and intermediary deliberately
|
|
30
|
+
* creating a bitcoin transaction with invalid format unparsable by the smart contract.
|
|
31
|
+
*/
|
|
27
32
|
SpvFromBTCSwapState[SpvFromBTCSwapState["CLOSED"] = -5] = "CLOSED";
|
|
33
|
+
/**
|
|
34
|
+
* Some of the bitcoin swap transaction inputs were double-spent, this means the swap
|
|
35
|
+
* has failed and no BTC was sent
|
|
36
|
+
*/
|
|
28
37
|
SpvFromBTCSwapState[SpvFromBTCSwapState["FAILED"] = -4] = "FAILED";
|
|
38
|
+
/**
|
|
39
|
+
* The intermediary (LP) declined to co-sign the submitted PSBT, hence the swap failed
|
|
40
|
+
*/
|
|
29
41
|
SpvFromBTCSwapState[SpvFromBTCSwapState["DECLINED"] = -3] = "DECLINED";
|
|
42
|
+
/**
|
|
43
|
+
* Swap has expired for good and there is no way how it can be executed anymore
|
|
44
|
+
*/
|
|
30
45
|
SpvFromBTCSwapState[SpvFromBTCSwapState["QUOTE_EXPIRED"] = -2] = "QUOTE_EXPIRED";
|
|
46
|
+
/**
|
|
47
|
+
* A swap is almost expired, and it should be presented to the user as expired, though
|
|
48
|
+
* there is still a chance that it will be processed
|
|
49
|
+
*/
|
|
31
50
|
SpvFromBTCSwapState[SpvFromBTCSwapState["QUOTE_SOFT_EXPIRED"] = -1] = "QUOTE_SOFT_EXPIRED";
|
|
51
|
+
/**
|
|
52
|
+
* Swap was created, use the {@link SpvFromBTCSwap.getFundedPsbt} or {@link SpvFromBTCSwap.getPsbt} functions
|
|
53
|
+
* to get the bitcoin swap PSBT that should be signed by the user's wallet and then submitted via the
|
|
54
|
+
* {@link SpvFromBTCSwap.submitPsbt} function.
|
|
55
|
+
*/
|
|
32
56
|
SpvFromBTCSwapState[SpvFromBTCSwapState["CREATED"] = 0] = "CREATED";
|
|
57
|
+
/**
|
|
58
|
+
* Swap bitcoin PSBT was submitted by the client to the SDK
|
|
59
|
+
*/
|
|
33
60
|
SpvFromBTCSwapState[SpvFromBTCSwapState["SIGNED"] = 1] = "SIGNED";
|
|
61
|
+
/**
|
|
62
|
+
* Swap bitcoin PSBT sent to the intermediary (LP), waiting for the intermediary co-sign
|
|
63
|
+
* it and broadcast. You can use the {@link SpvFromBTCSwap.waitTillClaimedOrFronted}
|
|
64
|
+
* function to wait till the intermediary broadcasts the transaction and the transaction
|
|
65
|
+
* confirms.
|
|
66
|
+
*/
|
|
34
67
|
SpvFromBTCSwapState[SpvFromBTCSwapState["POSTED"] = 2] = "POSTED";
|
|
68
|
+
/**
|
|
69
|
+
* Intermediary (LP) has co-signed and broadcasted the bitcoin transaction. You can use the
|
|
70
|
+
* {@link SpvFromBTCSwap.waitTillClaimedOrFronted} function to wait till the transaction
|
|
71
|
+
* confirms.
|
|
72
|
+
*/
|
|
35
73
|
SpvFromBTCSwapState[SpvFromBTCSwapState["BROADCASTED"] = 3] = "BROADCASTED";
|
|
74
|
+
/**
|
|
75
|
+
* Settlement on the destination smart chain was fronted and funds were already received
|
|
76
|
+
* by the user, even before the final settlement.
|
|
77
|
+
*/
|
|
36
78
|
SpvFromBTCSwapState[SpvFromBTCSwapState["FRONTED"] = 4] = "FRONTED";
|
|
79
|
+
/**
|
|
80
|
+
* Bitcoin transaction confirmed with necessary amount of confirmations, wait for automatic
|
|
81
|
+
* settlement by the watchtower with the {@link waitTillClaimedOrFronted} function, or settle manually
|
|
82
|
+
* using the {@link FromBTCSwap.claim} or {@link FromBTCSwap.txsClaim} function.
|
|
83
|
+
*/
|
|
37
84
|
SpvFromBTCSwapState[SpvFromBTCSwapState["BTC_TX_CONFIRMED"] = 5] = "BTC_TX_CONFIRMED";
|
|
38
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Swap settled on the smart chain and funds received
|
|
87
|
+
*/
|
|
88
|
+
SpvFromBTCSwapState[SpvFromBTCSwapState["CLAIMED"] = 6] = "CLAIMED";
|
|
39
89
|
})(SpvFromBTCSwapState = exports.SpvFromBTCSwapState || (exports.SpvFromBTCSwapState = {}));
|
|
40
90
|
function isSpvFromBTCSwapInit(obj) {
|
|
41
91
|
return typeof obj === "object" &&
|
|
@@ -67,6 +117,13 @@ function isSpvFromBTCSwapInit(obj) {
|
|
|
67
117
|
(0, ISwap_1.isISwapInit)(obj);
|
|
68
118
|
}
|
|
69
119
|
exports.isSpvFromBTCSwapInit = isSpvFromBTCSwapInit;
|
|
120
|
+
/**
|
|
121
|
+
* New spv vault (UTXO-controlled vault) based swaps for Bitcoin -> Smart chain swaps not requiring
|
|
122
|
+
* any initiation on the destination chain, and with the added possibility for the user to receive
|
|
123
|
+
* a native token on the destination chain as part of the swap (a "gas drop" feature).
|
|
124
|
+
*
|
|
125
|
+
* @category Swaps
|
|
126
|
+
*/
|
|
70
127
|
class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
71
128
|
constructor(wrapper, initOrObject) {
|
|
72
129
|
if (isSpvFromBTCSwapInit(initOrObject) && initOrObject.url != null)
|
|
@@ -74,7 +131,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
74
131
|
super(wrapper, initOrObject);
|
|
75
132
|
this.TYPE = SwapType_1.SwapType.SPV_VAULT_FROM_BTC;
|
|
76
133
|
if (isSpvFromBTCSwapInit(initOrObject)) {
|
|
77
|
-
this.
|
|
134
|
+
this._state = SpvFromBTCSwapState.CREATED;
|
|
78
135
|
this.quoteId = initOrObject.quoteId;
|
|
79
136
|
this.recipient = initOrObject.recipient;
|
|
80
137
|
this.vaultOwner = initOrObject.vaultOwner;
|
|
@@ -98,9 +155,9 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
98
155
|
this.callerFeeShare = initOrObject.callerFeeShare;
|
|
99
156
|
this.frontingFeeShare = initOrObject.frontingFeeShare;
|
|
100
157
|
this.executionFeeShare = initOrObject.executionFeeShare;
|
|
101
|
-
this.
|
|
158
|
+
this._genesisSmartChainBlockHeight = initOrObject.genesisSmartChainBlockHeight;
|
|
102
159
|
this.gasPricingInfo = initOrObject.gasPricingInfo;
|
|
103
|
-
const vaultAddressType = (0, BitcoinUtils_1.toCoinselectAddressType)((0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
160
|
+
const vaultAddressType = (0, BitcoinUtils_1.toCoinselectAddressType)((0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, this.vaultBtcAddress));
|
|
104
161
|
if (vaultAddressType !== "p2tr" && vaultAddressType !== "p2wpkh" && vaultAddressType !== "p2wsh")
|
|
105
162
|
throw new Error("Vault address type must be of witness type: p2tr, p2wpkh, p2wsh");
|
|
106
163
|
}
|
|
@@ -128,21 +185,25 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
128
185
|
this.callerFeeShare = BigInt(initOrObject.callerFeeShare);
|
|
129
186
|
this.frontingFeeShare = BigInt(initOrObject.frontingFeeShare);
|
|
130
187
|
this.executionFeeShare = BigInt(initOrObject.executionFeeShare);
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
134
|
-
this.
|
|
188
|
+
this._genesisSmartChainBlockHeight = initOrObject.genesisSmartChainBlockHeight;
|
|
189
|
+
this._senderAddress = initOrObject.senderAddress;
|
|
190
|
+
this._claimTxId = initOrObject.claimTxId;
|
|
191
|
+
this._frontTxId = initOrObject.frontTxId;
|
|
135
192
|
this.gasPricingInfo = (0, PriceInfoType_1.deserializePriceInfoType)(initOrObject.gasPricingInfo);
|
|
136
193
|
if (initOrObject.data != null)
|
|
137
|
-
this.
|
|
194
|
+
this._data = new this.wrapper._spvWithdrawalDataDeserializer(initOrObject.data);
|
|
138
195
|
}
|
|
139
196
|
this.tryCalculateSwapFee();
|
|
140
197
|
this.logger = (0, Logger_1.getLogger)("SPVFromBTC(" + this.getId() + "): ");
|
|
141
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* @inheritDoc
|
|
201
|
+
* @internal
|
|
202
|
+
*/
|
|
142
203
|
upgradeVersion() { }
|
|
143
204
|
/**
|
|
144
|
-
*
|
|
145
|
-
* @
|
|
205
|
+
* @inheritDoc
|
|
206
|
+
* @internal
|
|
146
207
|
*/
|
|
147
208
|
tryCalculateSwapFee() {
|
|
148
209
|
if (this.swapFeeBtc == null && this.swapFee != null) {
|
|
@@ -150,138 +211,248 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
150
211
|
}
|
|
151
212
|
if (this.pricingInfo != null && this.pricingInfo.swapPriceUSatPerToken == null) {
|
|
152
213
|
const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
153
|
-
this.pricingInfo = this.wrapper.
|
|
214
|
+
this.pricingInfo = this.wrapper._prices.recomputePriceInfoReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputWithoutFee().rawAmount, this.outputSwapToken);
|
|
154
215
|
this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
|
|
155
216
|
}
|
|
156
217
|
}
|
|
157
218
|
//////////////////////////////
|
|
158
219
|
//// Pricing
|
|
220
|
+
/**
|
|
221
|
+
* @inheritDoc
|
|
222
|
+
*/
|
|
159
223
|
async refreshPriceData() {
|
|
160
224
|
if (this.pricingInfo == null)
|
|
161
225
|
return;
|
|
162
226
|
const usdPricePerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
163
|
-
this.pricingInfo = await this.wrapper.
|
|
227
|
+
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputWithoutFee().rawAmount, this.outputSwapToken);
|
|
164
228
|
this.pricingInfo.realPriceUsdPerBitcoin = usdPricePerBtc;
|
|
165
229
|
}
|
|
166
230
|
//////////////////////////////
|
|
167
231
|
//// Getters & utils
|
|
232
|
+
/**
|
|
233
|
+
* @inheritDoc
|
|
234
|
+
* @internal
|
|
235
|
+
*/
|
|
168
236
|
_getInitiator() {
|
|
169
237
|
return this.recipient;
|
|
170
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* @inheritDoc
|
|
241
|
+
* @internal
|
|
242
|
+
*/
|
|
171
243
|
_getEscrowHash() {
|
|
172
|
-
return this.
|
|
244
|
+
return this._data?.btcTx?.txid ?? null;
|
|
173
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* @inheritDoc
|
|
248
|
+
*/
|
|
174
249
|
getId() {
|
|
175
|
-
return this.quoteId + this.
|
|
250
|
+
return this.quoteId + this._randomNonce;
|
|
176
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* @inheritDoc
|
|
254
|
+
*/
|
|
177
255
|
getQuoteExpiry() {
|
|
178
256
|
return this.expiry - 20 * 1000;
|
|
179
257
|
}
|
|
180
|
-
|
|
181
|
-
|
|
258
|
+
/**
|
|
259
|
+
* @inheritDoc
|
|
260
|
+
* @internal
|
|
261
|
+
*/
|
|
262
|
+
_verifyQuoteDefinitelyExpired() {
|
|
263
|
+
return Promise.resolve(this.expiry < Date.now());
|
|
182
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* @inheritDoc
|
|
267
|
+
* @internal
|
|
268
|
+
*/
|
|
269
|
+
_verifyQuoteValid() {
|
|
270
|
+
return Promise.resolve(this.expiry > Date.now() && (this._state === SpvFromBTCSwapState.CREATED || this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED));
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* @inheritDoc
|
|
274
|
+
*/
|
|
183
275
|
getOutputAddress() {
|
|
184
276
|
return this.recipient;
|
|
185
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* @inheritDoc
|
|
280
|
+
*/
|
|
186
281
|
getOutputTxId() {
|
|
187
|
-
return this.
|
|
282
|
+
return this._frontTxId ?? this._claimTxId ?? null;
|
|
188
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* @inheritDoc
|
|
286
|
+
*/
|
|
189
287
|
getInputAddress() {
|
|
190
|
-
return this.
|
|
288
|
+
return this._senderAddress ?? null;
|
|
191
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* @inheritDoc
|
|
292
|
+
*/
|
|
192
293
|
getInputTxId() {
|
|
193
|
-
return this.
|
|
294
|
+
return this._data?.btcTx?.txid ?? null;
|
|
194
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* @inheritDoc
|
|
298
|
+
*/
|
|
195
299
|
requiresAction() {
|
|
196
|
-
return this.
|
|
300
|
+
return this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED;
|
|
197
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* @inheritDoc
|
|
304
|
+
*/
|
|
198
305
|
isFinished() {
|
|
199
|
-
return this.
|
|
306
|
+
return this._state === SpvFromBTCSwapState.CLAIMED || this._state === SpvFromBTCSwapState.QUOTE_EXPIRED || this._state === SpvFromBTCSwapState.FAILED;
|
|
200
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* @inheritDoc
|
|
310
|
+
*/
|
|
201
311
|
isClaimable() {
|
|
202
|
-
return this.
|
|
312
|
+
return this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED;
|
|
203
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* @inheritDoc
|
|
316
|
+
*/
|
|
204
317
|
isSuccessful() {
|
|
205
|
-
return this.
|
|
318
|
+
return this._state === SpvFromBTCSwapState.FRONTED || this._state === SpvFromBTCSwapState.CLAIMED;
|
|
206
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* @inheritDoc
|
|
322
|
+
*/
|
|
207
323
|
isFailed() {
|
|
208
|
-
return this.
|
|
324
|
+
return this._state === SpvFromBTCSwapState.FAILED || this._state === SpvFromBTCSwapState.DECLINED || this._state === SpvFromBTCSwapState.CLOSED;
|
|
209
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* @inheritDoc
|
|
328
|
+
*/
|
|
210
329
|
isQuoteExpired() {
|
|
211
|
-
return this.
|
|
330
|
+
return this._state === SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
212
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* @inheritDoc
|
|
334
|
+
*/
|
|
213
335
|
isQuoteSoftExpired() {
|
|
214
|
-
return this.
|
|
336
|
+
return this._state === SpvFromBTCSwapState.QUOTE_EXPIRED || this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Returns the data about used spv vault (UTXO-controlled vault) to perform the swap
|
|
340
|
+
*/
|
|
341
|
+
getSpvVaultData() {
|
|
342
|
+
return {
|
|
343
|
+
owner: this.vaultOwner,
|
|
344
|
+
vaultId: this.vaultId,
|
|
345
|
+
utxo: this.vaultUtxo
|
|
346
|
+
};
|
|
215
347
|
}
|
|
216
348
|
//////////////////////////////
|
|
217
349
|
//// Amounts & fees
|
|
350
|
+
/**
|
|
351
|
+
* Returns the input BTC amount in sats without any fees
|
|
352
|
+
*
|
|
353
|
+
* @internal
|
|
354
|
+
*/
|
|
218
355
|
getInputSwapAmountWithoutFee() {
|
|
219
356
|
return (this.btcAmountSwap - this.swapFeeBtc) * 100000n / (100000n + this.callerFeeShare + this.frontingFeeShare + this.executionFeeShare);
|
|
220
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Returns the input gas BTC amount in sats without any fees
|
|
360
|
+
*
|
|
361
|
+
* @internal
|
|
362
|
+
*/
|
|
221
363
|
getInputGasAmountWithoutFee() {
|
|
222
364
|
return (this.btcAmountGas - this.gasSwapFeeBtc) * 100000n / (100000n + this.callerFeeShare + this.frontingFeeShare);
|
|
223
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* Returns to total input BTC amount in sats without any fees (this is BTC amount for the swap + BTC amount
|
|
368
|
+
* for the gas drop).
|
|
369
|
+
*
|
|
370
|
+
* @internal
|
|
371
|
+
*/
|
|
224
372
|
getInputAmountWithoutFee() {
|
|
225
373
|
return this.getInputSwapAmountWithoutFee() + this.getInputGasAmountWithoutFee();
|
|
226
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Returns the swap output amount without any fees, this value is therefore always higher than
|
|
377
|
+
* the actual received output.
|
|
378
|
+
*
|
|
379
|
+
* @internal
|
|
380
|
+
*/
|
|
227
381
|
getOutputWithoutFee() {
|
|
228
|
-
return (0, TokenAmount_1.toTokenAmount)((this.outputTotalSwap * (100000n + this.callerFeeShare + this.frontingFeeShare + this.executionFeeShare) / 100000n) + (this.swapFee ?? 0n), this.wrapper.
|
|
382
|
+
return (0, TokenAmount_1.toTokenAmount)((this.outputTotalSwap * (100000n + this.callerFeeShare + this.frontingFeeShare + this.executionFeeShare) / 100000n) + (this.swapFee ?? 0n), this.wrapper._tokens[this.outputSwapToken], this.wrapper._prices, this.pricingInfo);
|
|
229
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Returns the swap fee charged by the intermediary (LP) on this swap
|
|
386
|
+
*
|
|
387
|
+
* @internal
|
|
388
|
+
*/
|
|
230
389
|
getSwapFee() {
|
|
231
390
|
if (this.pricingInfo == null)
|
|
232
391
|
throw new Error("No pricing info known, cannot estimate fee!");
|
|
233
|
-
const outputToken = this.wrapper.
|
|
392
|
+
const outputToken = this.wrapper._tokens[this.outputSwapToken];
|
|
234
393
|
const gasSwapFeeInOutputToken = this.gasSwapFeeBtc
|
|
235
394
|
* (10n ** BigInt(outputToken.decimals))
|
|
236
395
|
* 1000000n
|
|
237
396
|
/ this.pricingInfo.swapPriceUSatPerToken;
|
|
238
397
|
const feeWithoutBaseFee = this.swapFeeBtc - this.pricingInfo.satsBaseFee;
|
|
239
398
|
const swapFeePPM = feeWithoutBaseFee * 1000000n / (this.btcAmount - this.swapFeeBtc - this.gasSwapFeeBtc);
|
|
240
|
-
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(this.swapFeeBtc + this.gasSwapFeeBtc, Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
399
|
+
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(this.swapFeeBtc + this.gasSwapFeeBtc, Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo);
|
|
241
400
|
return {
|
|
242
401
|
amountInSrcToken,
|
|
243
|
-
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee + gasSwapFeeInOutputToken, outputToken, this.wrapper.
|
|
402
|
+
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee + gasSwapFeeInOutputToken, outputToken, this.wrapper._prices, this.pricingInfo),
|
|
244
403
|
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
245
404
|
usdValue: amountInSrcToken.usdValue,
|
|
246
405
|
pastUsdValue: amountInSrcToken.pastUsdValue,
|
|
247
406
|
composition: {
|
|
248
|
-
base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
407
|
+
base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo),
|
|
249
408
|
percentage: (0, PercentagePPM_1.ppmToPercentage)(swapFeePPM)
|
|
250
409
|
}
|
|
251
410
|
};
|
|
252
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Returns the fee to be paid to watchtowers on the destination chain to automatically
|
|
414
|
+
* process and settle this swap without requiring any user interaction
|
|
415
|
+
*
|
|
416
|
+
* @internal
|
|
417
|
+
*/
|
|
253
418
|
getWatchtowerFee() {
|
|
254
419
|
if (this.pricingInfo == null)
|
|
255
420
|
throw new Error("No pricing info known, cannot estimate fee!");
|
|
256
421
|
const totalFeeShare = this.callerFeeShare + this.frontingFeeShare;
|
|
257
|
-
const outputToken = this.wrapper.
|
|
422
|
+
const outputToken = this.wrapper._tokens[this.outputSwapToken];
|
|
258
423
|
const watchtowerFeeInOutputToken = this.getInputGasAmountWithoutFee() * totalFeeShare
|
|
259
424
|
* (10n ** BigInt(outputToken.decimals))
|
|
260
425
|
* 1000000n
|
|
261
426
|
/ this.pricingInfo.swapPriceUSatPerToken
|
|
262
427
|
/ 100000n;
|
|
263
428
|
const feeBtc = this.getInputAmountWithoutFee() * (totalFeeShare + this.executionFeeShare) / 100000n;
|
|
264
|
-
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(feeBtc, Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
429
|
+
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(feeBtc, Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo);
|
|
265
430
|
return {
|
|
266
431
|
amountInSrcToken,
|
|
267
|
-
amountInDstToken: (0, TokenAmount_1.toTokenAmount)((this.outputTotalSwap * (totalFeeShare + this.executionFeeShare) / 100000n) + watchtowerFeeInOutputToken, outputToken, this.wrapper.
|
|
432
|
+
amountInDstToken: (0, TokenAmount_1.toTokenAmount)((this.outputTotalSwap * (totalFeeShare + this.executionFeeShare) / 100000n) + watchtowerFeeInOutputToken, outputToken, this.wrapper._prices, this.pricingInfo),
|
|
268
433
|
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
269
434
|
usdValue: amountInSrcToken.usdValue,
|
|
270
435
|
pastUsdValue: amountInSrcToken.pastUsdValue
|
|
271
436
|
};
|
|
272
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* @inheritDoc
|
|
440
|
+
*/
|
|
273
441
|
getFee() {
|
|
274
442
|
const swapFee = this.getSwapFee();
|
|
275
443
|
const watchtowerFee = this.getWatchtowerFee();
|
|
276
|
-
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(swapFee.amountInSrcToken.rawAmount + watchtowerFee.amountInSrcToken.rawAmount, Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
444
|
+
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(swapFee.amountInSrcToken.rawAmount + watchtowerFee.amountInSrcToken.rawAmount, Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo);
|
|
277
445
|
return {
|
|
278
446
|
amountInSrcToken,
|
|
279
|
-
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(swapFee.amountInDstToken.rawAmount + watchtowerFee.amountInDstToken.rawAmount, this.wrapper.
|
|
447
|
+
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(swapFee.amountInDstToken.rawAmount + watchtowerFee.amountInDstToken.rawAmount, this.wrapper._tokens[this.outputSwapToken], this.wrapper._prices, this.pricingInfo),
|
|
280
448
|
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
281
449
|
usdValue: amountInSrcToken.usdValue,
|
|
282
450
|
pastUsdValue: amountInSrcToken.pastUsdValue
|
|
283
451
|
};
|
|
284
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* @inheritDoc
|
|
455
|
+
*/
|
|
285
456
|
getFeeBreakdown() {
|
|
286
457
|
return [
|
|
287
458
|
{
|
|
@@ -294,34 +465,59 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
294
465
|
}
|
|
295
466
|
];
|
|
296
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* @inheritDoc
|
|
470
|
+
*/
|
|
297
471
|
getOutputToken() {
|
|
298
|
-
return this.wrapper.
|
|
472
|
+
return this.wrapper._tokens[this.outputSwapToken];
|
|
299
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* @inheritDoc
|
|
476
|
+
*/
|
|
300
477
|
getOutput() {
|
|
301
|
-
return (0, TokenAmount_1.toTokenAmount)(this.outputTotalSwap, this.wrapper.
|
|
478
|
+
return (0, TokenAmount_1.toTokenAmount)(this.outputTotalSwap, this.wrapper._tokens[this.outputSwapToken], this.wrapper._prices, this.pricingInfo);
|
|
302
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* @inheritDoc
|
|
482
|
+
*/
|
|
303
483
|
getGasDropOutput() {
|
|
304
|
-
return (0, TokenAmount_1.toTokenAmount)(this.outputTotalGas, this.wrapper.
|
|
484
|
+
return (0, TokenAmount_1.toTokenAmount)(this.outputTotalGas, this.wrapper._tokens[this.outputGasToken], this.wrapper._prices, this.gasPricingInfo);
|
|
305
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* @inheritDoc
|
|
488
|
+
*/
|
|
306
489
|
getInputWithoutFee() {
|
|
307
|
-
return (0, TokenAmount_1.toTokenAmount)(this.getInputAmountWithoutFee(), Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
490
|
+
return (0, TokenAmount_1.toTokenAmount)(this.getInputAmountWithoutFee(), Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo);
|
|
308
491
|
}
|
|
492
|
+
/**
|
|
493
|
+
* @inheritDoc
|
|
494
|
+
*/
|
|
309
495
|
getInputToken() {
|
|
310
496
|
return Token_1.BitcoinTokens.BTC;
|
|
311
497
|
}
|
|
498
|
+
/**
|
|
499
|
+
* @inheritDoc
|
|
500
|
+
*/
|
|
312
501
|
getInput() {
|
|
313
|
-
return (0, TokenAmount_1.toTokenAmount)(this.btcAmount, Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
502
|
+
return (0, TokenAmount_1.toTokenAmount)(this.btcAmount, Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo);
|
|
314
503
|
}
|
|
315
504
|
//////////////////////////////
|
|
316
505
|
//// Bitcoin tx
|
|
506
|
+
/**
|
|
507
|
+
* @inheritDoc
|
|
508
|
+
*/
|
|
317
509
|
getRequiredConfirmationsCount() {
|
|
318
510
|
return this.vaultRequiredConfirmations;
|
|
319
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* Returns raw transaction details that can be used to manually create a swap PSBT. It is better to use
|
|
514
|
+
* the {@link getPsbt} or {@link getFundedPsbt} function retrieve an already prepared PSBT.
|
|
515
|
+
*/
|
|
320
516
|
async getTransactionDetails() {
|
|
321
517
|
const [txId, voutStr] = this.vaultUtxo.split(":");
|
|
322
|
-
const vaultScript = (0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
323
|
-
const out2script = (0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
324
|
-
const opReturnData = this.wrapper.
|
|
518
|
+
const vaultScript = (0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, this.vaultBtcAddress);
|
|
519
|
+
const out2script = (0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, this.btcDestinationAddress);
|
|
520
|
+
const opReturnData = this.wrapper._contract.toOpReturnData(this.recipient, [
|
|
325
521
|
this.outputTotalSwap / this.vaultTokenMultipliers[0],
|
|
326
522
|
this.outputTotalGas / this.vaultTokenMultipliers[1]
|
|
327
523
|
]);
|
|
@@ -351,9 +547,9 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
351
547
|
};
|
|
352
548
|
}
|
|
353
549
|
/**
|
|
354
|
-
* Returns the raw PSBT (not funded), the wallet should fund the PSBT (add its inputs)
|
|
355
|
-
* 2nd input (input 1 - indexing from 0) to the value returned in `in1sequence`, sign the PSBT and then pass
|
|
356
|
-
* it back to the
|
|
550
|
+
* Returns the raw PSBT (not funded), the wallet should fund the PSBT (add its inputs) and importantly **set the nSequence field of the
|
|
551
|
+
* 2nd input** (input 1 - indexing from 0) to the value returned in `in1sequence`, sign the PSBT and then pass
|
|
552
|
+
* it back to the swap with {@link submitPsbt} function.
|
|
357
553
|
*/
|
|
358
554
|
async getPsbt() {
|
|
359
555
|
const res = await this.getTransactionDetails();
|
|
@@ -392,16 +588,12 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
392
588
|
};
|
|
393
589
|
}
|
|
394
590
|
/**
|
|
395
|
-
*
|
|
396
|
-
* also returns inputs indices that need to be signed by the wallet before submitting the PSBT back to the SDK with
|
|
397
|
-
* `swap.submitPsbt()`
|
|
591
|
+
* Note that when passing the `feeRate` argument, the fee must be at least {@link minimumBtcFeeRate} sats/vB.
|
|
398
592
|
*
|
|
399
|
-
* @
|
|
400
|
-
* @param feeRate Optional fee rate for the transaction, needs to be at least as big as {minimumBtcFeeRate} field
|
|
401
|
-
* @param additionalOutputs additional outputs to add to the PSBT - can be used to collect fees from users
|
|
593
|
+
* @inheritDoc
|
|
402
594
|
*/
|
|
403
595
|
async getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs) {
|
|
404
|
-
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper.
|
|
596
|
+
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper._btcRpc, this.wrapper._options.bitcoinNetwork);
|
|
405
597
|
if (feeRate != null) {
|
|
406
598
|
if (feeRate < this.minimumBtcFeeRate)
|
|
407
599
|
throw new Error("Bitcoin tx fee needs to be at least " + this.minimumBtcFeeRate + " sats/vB");
|
|
@@ -414,7 +606,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
414
606
|
additionalOutputs.forEach(output => {
|
|
415
607
|
psbt.addOutput({
|
|
416
608
|
amount: output.amount,
|
|
417
|
-
script: output.outputScript ?? (0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
609
|
+
script: output.outputScript ?? (0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, output.address)
|
|
418
610
|
});
|
|
419
611
|
});
|
|
420
612
|
psbt = await bitcoinWallet.fundPsbt(psbt, feeRate);
|
|
@@ -433,9 +625,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
433
625
|
};
|
|
434
626
|
}
|
|
435
627
|
/**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
* @param _psbt A psbt - either a Transaction object or a hex or base64 encoded PSBT string
|
|
628
|
+
* @inheritDoc
|
|
439
629
|
*/
|
|
440
630
|
async submitPsbt(_psbt) {
|
|
441
631
|
const psbt = (0, BitcoinUtils_1.parsePsbtTransaction)(_psbt);
|
|
@@ -444,7 +634,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
444
634
|
throw new Error("Quote expired!");
|
|
445
635
|
}
|
|
446
636
|
//Ensure valid state
|
|
447
|
-
if (this.
|
|
637
|
+
if (this._state !== SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED && this._state !== SpvFromBTCSwapState.CREATED) {
|
|
448
638
|
throw new Error("Invalid swap state!");
|
|
449
639
|
}
|
|
450
640
|
if (this.url == null)
|
|
@@ -455,8 +645,8 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
455
645
|
throw new Error("Legacy (non-segwit) inputs are not allowed in the transaction!");
|
|
456
646
|
psbt.finalizeIdx(i);
|
|
457
647
|
}
|
|
458
|
-
const btcTx = await this.wrapper.
|
|
459
|
-
const data = await this.wrapper.
|
|
648
|
+
const btcTx = await this.wrapper._btcRpc.parseTransaction(buffer_1.Buffer.from(psbt.toBytes(true)).toString("hex"));
|
|
649
|
+
const data = await this.wrapper._contract.getWithdrawalData(btcTx);
|
|
460
650
|
this.logger.debug("submitPsbt(): parsed withdrawal data: ", data);
|
|
461
651
|
//Verify correct withdrawal data
|
|
462
652
|
if (!data.isRecipient(this.recipient) ||
|
|
@@ -467,7 +657,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
467
657
|
data.executionFeeRate !== this.executionFeeShare ||
|
|
468
658
|
data.getSpentVaultUtxo() !== this.vaultUtxo ||
|
|
469
659
|
BigInt(data.getNewVaultBtcAmount()) !== this.vaultUtxoValue ||
|
|
470
|
-
!data.getNewVaultScript().equals((0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
660
|
+
!data.getNewVaultScript().equals((0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, this.vaultBtcAddress)) ||
|
|
471
661
|
data.getExecutionData() != null) {
|
|
472
662
|
throw new Error("Invalid withdrawal tx data submitted!");
|
|
473
663
|
}
|
|
@@ -475,16 +665,16 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
475
665
|
const lpOutput = psbt.getOutput(2);
|
|
476
666
|
if (lpOutput.script == null ||
|
|
477
667
|
lpOutput.amount !== this.btcAmount ||
|
|
478
|
-
!(0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
668
|
+
!(0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, this.btcDestinationAddress).equals(buffer_1.Buffer.from(lpOutput.script))) {
|
|
479
669
|
throw new Error("Invalid LP bitcoin output in transaction!");
|
|
480
670
|
}
|
|
481
671
|
//Verify vault utxo not spent yet
|
|
482
|
-
if (await this.wrapper.
|
|
672
|
+
if (await this.wrapper._btcRpc.isSpent(this.vaultUtxo)) {
|
|
483
673
|
throw new Error("Vault UTXO already spent, please create new swap!");
|
|
484
674
|
}
|
|
485
675
|
//Verify tx is parsable by the contract
|
|
486
676
|
try {
|
|
487
|
-
await this.wrapper.
|
|
677
|
+
await this.wrapper._contract.checkWithdrawalTx(data);
|
|
488
678
|
}
|
|
489
679
|
catch (e) {
|
|
490
680
|
throw new Error("Transaction not parsable by the contract: " + (e.message ?? e.toString()));
|
|
@@ -493,7 +683,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
493
683
|
if (this.expiry < Date.now()) {
|
|
494
684
|
throw new Error("Quote expired!");
|
|
495
685
|
}
|
|
496
|
-
this.
|
|
686
|
+
this._data = data;
|
|
497
687
|
this.initiated = true;
|
|
498
688
|
await this._saveAndEmit(SpvFromBTCSwapState.SIGNED);
|
|
499
689
|
try {
|
|
@@ -507,15 +697,21 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
507
697
|
await this._saveAndEmit(SpvFromBTCSwapState.DECLINED);
|
|
508
698
|
throw e;
|
|
509
699
|
}
|
|
510
|
-
return this.
|
|
700
|
+
return this._data.getTxId();
|
|
511
701
|
}
|
|
702
|
+
/**
|
|
703
|
+
* @inheritDoc
|
|
704
|
+
*/
|
|
512
705
|
async estimateBitcoinFee(_bitcoinWallet, feeRate) {
|
|
513
|
-
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper.
|
|
706
|
+
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper._btcRpc, this.wrapper._options.bitcoinNetwork);
|
|
514
707
|
const txFee = await bitcoinWallet.getFundedPsbtFee((await this.getPsbt()).psbt, feeRate);
|
|
515
708
|
if (txFee == null)
|
|
516
709
|
return null;
|
|
517
|
-
return (0, TokenAmount_1.toTokenAmount)(BigInt(txFee), Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
710
|
+
return (0, TokenAmount_1.toTokenAmount)(BigInt(txFee), Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo);
|
|
518
711
|
}
|
|
712
|
+
/**
|
|
713
|
+
* @inheritDoc
|
|
714
|
+
*/
|
|
519
715
|
async sendBitcoinTransaction(wallet, feeRate) {
|
|
520
716
|
const { psbt, psbtBase64, psbtHex, signInputs } = await this.getFundedPsbt(wallet, feeRate);
|
|
521
717
|
let signedPsbt;
|
|
@@ -530,40 +726,41 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
530
726
|
return await this.submitPsbt(signedPsbt);
|
|
531
727
|
}
|
|
532
728
|
/**
|
|
533
|
-
* Executes the swap with the provided bitcoin wallet
|
|
729
|
+
* Executes the swap with the provided bitcoin wallet
|
|
534
730
|
*
|
|
535
731
|
* @param wallet Bitcoin wallet to use to sign the bitcoin transaction
|
|
536
732
|
* @param callbacks Callbacks to track the progress of the swap
|
|
537
733
|
* @param options Optional options for the swap like feeRate, AbortSignal, and timeouts/intervals
|
|
538
734
|
*
|
|
539
735
|
* @returns {boolean} Whether a swap was settled automatically by swap watchtowers or requires manual claim by the
|
|
540
|
-
* user, in case `false` is returned the user should call
|
|
736
|
+
* user, in case `false` is returned the user should call the {@link claim} function to settle the swap on the
|
|
737
|
+
* destination manually
|
|
541
738
|
*/
|
|
542
739
|
async execute(wallet, callbacks, options) {
|
|
543
|
-
if (this.
|
|
740
|
+
if (this._state === SpvFromBTCSwapState.CLOSED)
|
|
544
741
|
throw new Error("Swap encountered a catastrophic failure!");
|
|
545
|
-
if (this.
|
|
742
|
+
if (this._state === SpvFromBTCSwapState.FAILED)
|
|
546
743
|
throw new Error("Swap failed!");
|
|
547
|
-
if (this.
|
|
744
|
+
if (this._state === SpvFromBTCSwapState.DECLINED)
|
|
548
745
|
throw new Error("Swap execution already declined by the LP!");
|
|
549
|
-
if (this.
|
|
746
|
+
if (this._state === SpvFromBTCSwapState.QUOTE_EXPIRED)
|
|
550
747
|
throw new Error("Swap quote expired!");
|
|
551
|
-
if (this.
|
|
748
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED || this._state === SpvFromBTCSwapState.FRONTED)
|
|
552
749
|
throw new Error("Swap already settled or fronted!");
|
|
553
|
-
if (this.
|
|
750
|
+
if (this._state === SpvFromBTCSwapState.CREATED) {
|
|
554
751
|
const txId = await this.sendBitcoinTransaction(wallet, options?.feeRate);
|
|
555
752
|
if (callbacks?.onSourceTransactionSent != null)
|
|
556
753
|
callbacks.onSourceTransactionSent(txId);
|
|
557
754
|
}
|
|
558
|
-
if (this.
|
|
755
|
+
if (this._state === SpvFromBTCSwapState.POSTED || this._state === SpvFromBTCSwapState.BROADCASTED) {
|
|
559
756
|
const txId = await this.waitForBitcoinTransaction(callbacks?.onSourceTransactionConfirmationStatus, options?.btcTxCheckIntervalSeconds, options?.abortSignal);
|
|
560
757
|
if (callbacks?.onSourceTransactionConfirmed != null)
|
|
561
758
|
callbacks.onSourceTransactionConfirmed(txId);
|
|
562
759
|
}
|
|
563
760
|
// @ts-ignore
|
|
564
|
-
if (this.
|
|
761
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED || this._state === SpvFromBTCSwapState.FRONTED)
|
|
565
762
|
return true;
|
|
566
|
-
if (this.
|
|
763
|
+
if (this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
567
764
|
const success = await this.waitTillClaimedOrFronted(options?.maxWaitTillAutomaticSettlementSeconds ?? 60, options?.abortSignal);
|
|
568
765
|
if (success && callbacks?.onSwapSettled != null)
|
|
569
766
|
callbacks.onSwapSettled(this.getOutputTxId());
|
|
@@ -571,9 +768,17 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
571
768
|
}
|
|
572
769
|
throw new Error("Unexpected state reached!");
|
|
573
770
|
}
|
|
771
|
+
/**
|
|
772
|
+
* @inheritDoc
|
|
773
|
+
*
|
|
774
|
+
* @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
|
|
775
|
+
* if not provided a raw PSBT is returned instead which necessitates the implementor to manually add
|
|
776
|
+
* inputs to the bitcoin transaction and **set the nSequence field of the 2nd input** (input 1 -
|
|
777
|
+
* indexing from 0) to the value returned in `in1sequence`
|
|
778
|
+
*/
|
|
574
779
|
async txsExecute(options) {
|
|
575
|
-
if (this.
|
|
576
|
-
if (!await this.
|
|
780
|
+
if (this._state === SpvFromBTCSwapState.CREATED) {
|
|
781
|
+
if (!await this._verifyQuoteValid())
|
|
577
782
|
throw new Error("Quote already expired or close to expiry!");
|
|
578
783
|
return [
|
|
579
784
|
{
|
|
@@ -594,11 +799,12 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
594
799
|
//// Bitcoin tx listener
|
|
595
800
|
/**
|
|
596
801
|
* Checks whether a bitcoin payment was already made, returns the payment or null when no payment has been made.
|
|
802
|
+
* @internal
|
|
597
803
|
*/
|
|
598
804
|
async getBitcoinPayment() {
|
|
599
|
-
if (this.
|
|
805
|
+
if (this._data?.btcTx?.txid == null)
|
|
600
806
|
return null;
|
|
601
|
-
const result = await this.wrapper.
|
|
807
|
+
const result = await this.wrapper._btcRpc.getTransaction(this._data?.btcTx?.txid);
|
|
602
808
|
if (result == null)
|
|
603
809
|
return null;
|
|
604
810
|
return {
|
|
@@ -609,32 +815,29 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
609
815
|
};
|
|
610
816
|
}
|
|
611
817
|
/**
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
* @param checkIntervalSeconds How often to check the bitcoin transaction
|
|
616
|
-
* @param abortSignal Abort signal
|
|
617
|
-
* @throws {Error} if in invalid state (must be CLAIM_COMMITED)
|
|
818
|
+
* @inheritDoc
|
|
819
|
+
* @throws {Error} if in invalid state (must be {@link SpvFromBTCSwapState.POSTED} or
|
|
820
|
+
* {@link SpvFromBTCSwapState.BROADCASTED} states)
|
|
618
821
|
*/
|
|
619
822
|
async waitForBitcoinTransaction(updateCallback, checkIntervalSeconds, abortSignal) {
|
|
620
|
-
if (this.
|
|
621
|
-
this.
|
|
622
|
-
!(this.
|
|
823
|
+
if (this._state !== SpvFromBTCSwapState.POSTED &&
|
|
824
|
+
this._state !== SpvFromBTCSwapState.BROADCASTED &&
|
|
825
|
+
!(this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED && this.initiated))
|
|
623
826
|
throw new Error("Must be in POSTED or BROADCASTED state!");
|
|
624
|
-
if (this.
|
|
827
|
+
if (this._data == null)
|
|
625
828
|
throw new Error("Expected swap to have withdrawal data filled!");
|
|
626
|
-
const result = await this.wrapper.
|
|
829
|
+
const result = await this.wrapper._btcRpc.waitForTransaction(this._data.btcTx.txid, this.vaultRequiredConfirmations, (btcTx, txEtaMs) => {
|
|
627
830
|
if (updateCallback != null)
|
|
628
831
|
updateCallback(btcTx?.txid, btcTx?.confirmations, this.vaultRequiredConfirmations, txEtaMs);
|
|
629
832
|
if (btcTx == null)
|
|
630
833
|
return;
|
|
631
834
|
let save = false;
|
|
632
|
-
if (btcTx.inputAddresses != null && this.
|
|
633
|
-
this.
|
|
835
|
+
if (btcTx.inputAddresses != null && this._senderAddress == null) {
|
|
836
|
+
this._senderAddress = btcTx.inputAddresses[1];
|
|
634
837
|
save = true;
|
|
635
838
|
}
|
|
636
|
-
if (this.
|
|
637
|
-
this.
|
|
839
|
+
if (this._state === SpvFromBTCSwapState.POSTED || this._state == SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
840
|
+
this._state = SpvFromBTCSwapState.BROADCASTED;
|
|
638
841
|
save = true;
|
|
639
842
|
}
|
|
640
843
|
if (save)
|
|
@@ -643,13 +846,13 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
643
846
|
if (abortSignal != null)
|
|
644
847
|
abortSignal.throwIfAborted();
|
|
645
848
|
let save = false;
|
|
646
|
-
if (result.inputAddresses != null && this.
|
|
647
|
-
this.
|
|
849
|
+
if (result.inputAddresses != null && this._senderAddress == null) {
|
|
850
|
+
this._senderAddress = result.inputAddresses[1];
|
|
648
851
|
save = true;
|
|
649
852
|
}
|
|
650
|
-
if (this.
|
|
651
|
-
this.
|
|
652
|
-
this.
|
|
853
|
+
if (this._state !== SpvFromBTCSwapState.FRONTED &&
|
|
854
|
+
this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
855
|
+
this._state = SpvFromBTCSwapState.BTC_TX_CONFIRMED;
|
|
653
856
|
save = true;
|
|
654
857
|
}
|
|
655
858
|
if (save)
|
|
@@ -659,10 +862,11 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
659
862
|
//////////////////////////////
|
|
660
863
|
//// Claim
|
|
661
864
|
/**
|
|
662
|
-
*
|
|
663
|
-
*
|
|
865
|
+
* Also possibly also syncs the bitcoin light client if necessary
|
|
866
|
+
*
|
|
867
|
+
* @inheritDoc
|
|
664
868
|
*
|
|
665
|
-
* @throws {Error} If the swap is in invalid state (must be BTC_TX_CONFIRMED)
|
|
869
|
+
* @throws {Error} If the swap is in invalid state (must be {@link SpvFromBTCSwapState.BTC_TX_CONFIRMED})
|
|
666
870
|
*/
|
|
667
871
|
async txsClaim(_signer) {
|
|
668
872
|
let address = undefined;
|
|
@@ -674,68 +878,76 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
674
878
|
address = _signer.getAddress();
|
|
675
879
|
}
|
|
676
880
|
else {
|
|
677
|
-
address = (await this.wrapper.
|
|
881
|
+
address = (await this.wrapper._chain.wrapSigner(_signer)).getAddress();
|
|
678
882
|
}
|
|
679
883
|
}
|
|
680
884
|
if (!this.isClaimable())
|
|
681
885
|
throw new Error("Must be in BTC_TX_CONFIRMED state!");
|
|
682
|
-
if (this.
|
|
886
|
+
if (this._data == null)
|
|
683
887
|
throw new Error("Expected swap to have withdrawal data filled!");
|
|
684
|
-
const vaultData = await this.wrapper.
|
|
888
|
+
const vaultData = await this.wrapper._contract.getVaultData(this.vaultOwner, this.vaultId);
|
|
685
889
|
if (vaultData == null)
|
|
686
890
|
throw new Error(`Vault data for ${this.vaultOwner}:${this.vaultId.toString(10)} not found (already closed???)!`);
|
|
687
|
-
const btcTx = await this.wrapper.
|
|
891
|
+
const btcTx = await this.wrapper._btcRpc.getTransaction(this._data.btcTx.txid);
|
|
688
892
|
if (btcTx == null)
|
|
689
|
-
throw new Error(`Bitcoin transaction ${this.
|
|
893
|
+
throw new Error(`Bitcoin transaction ${this._data.btcTx.txid} not found!`);
|
|
690
894
|
const txs = [btcTx];
|
|
691
895
|
//Trace back from current tx to the vaultData-specified UTXO
|
|
692
896
|
const vaultUtxo = vaultData.getUtxo();
|
|
693
897
|
while (txs[0].ins[0].txid + ":" + txs[0].ins[0].vout !== vaultUtxo) {
|
|
694
|
-
const btcTx = await this.wrapper.
|
|
898
|
+
const btcTx = await this.wrapper._btcRpc.getTransaction(txs[0].ins[0].txid);
|
|
695
899
|
if (btcTx == null)
|
|
696
|
-
throw new Error(`Prior withdrawal bitcoin transaction ${this.
|
|
900
|
+
throw new Error(`Prior withdrawal bitcoin transaction ${this._data.btcTx.txid} not found!`);
|
|
697
901
|
txs.unshift(btcTx);
|
|
698
902
|
}
|
|
699
903
|
//Parse transactions to withdrawal data
|
|
700
904
|
const withdrawalData = [];
|
|
701
905
|
for (let tx of txs) {
|
|
702
|
-
withdrawalData.push(await this.wrapper.
|
|
906
|
+
withdrawalData.push(await this.wrapper._contract.getWithdrawalData(tx));
|
|
703
907
|
}
|
|
704
|
-
return await this.wrapper.
|
|
908
|
+
return await this.wrapper._contract.txsClaim(address ?? this._getInitiator(), vaultData, withdrawalData.map(tx => { return { tx }; }), this.wrapper._synchronizer, true);
|
|
705
909
|
}
|
|
706
910
|
/**
|
|
707
|
-
*
|
|
911
|
+
* Also possibly also syncs the bitcoin light client if necessary
|
|
708
912
|
*
|
|
709
|
-
* @
|
|
710
|
-
*
|
|
913
|
+
* @inheritDoc
|
|
914
|
+
*
|
|
915
|
+
* @throws {Error} If the swap is in invalid state (must be {@link SpvFromBTCSwapState.BTC_TX_CONFIRMED})
|
|
711
916
|
*/
|
|
712
|
-
async claim(_signer, abortSignal) {
|
|
713
|
-
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.
|
|
917
|
+
async claim(_signer, abortSignal, onBeforeTxSent) {
|
|
918
|
+
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer);
|
|
714
919
|
let txIds;
|
|
715
920
|
try {
|
|
716
|
-
|
|
921
|
+
let txCount = 0;
|
|
922
|
+
const txs = await this.txsClaim(signer);
|
|
923
|
+
txIds = await this.wrapper._chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
|
|
924
|
+
txCount++;
|
|
925
|
+
if (onBeforeTxSent != null && txCount === txs.length)
|
|
926
|
+
onBeforeTxSent(txId);
|
|
927
|
+
return Promise.resolve();
|
|
928
|
+
});
|
|
717
929
|
}
|
|
718
930
|
catch (e) {
|
|
719
|
-
if (this.
|
|
931
|
+
if (this._data == null)
|
|
720
932
|
throw e;
|
|
721
933
|
this.logger.info("claim(): Failed to claim ourselves, checking swap claim state...");
|
|
722
|
-
if (this.
|
|
934
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED) {
|
|
723
935
|
this.logger.info("claim(): Transaction state is CLAIMED, swap was successfully claimed by the watchtower");
|
|
724
|
-
return this.
|
|
936
|
+
return this._claimTxId;
|
|
725
937
|
}
|
|
726
|
-
const withdrawalState = await this.wrapper.
|
|
938
|
+
const withdrawalState = await this.wrapper._contract.getWithdrawalState(this._data, this._genesisSmartChainBlockHeight);
|
|
727
939
|
if (withdrawalState != null && withdrawalState.type === base_1.SpvWithdrawalStateType.CLAIMED) {
|
|
728
940
|
this.logger.info("claim(): Transaction status is CLAIMED, swap was successfully claimed by the watchtower");
|
|
729
|
-
this.
|
|
941
|
+
this._claimTxId = withdrawalState.txId;
|
|
730
942
|
await this._saveAndEmit(SpvFromBTCSwapState.CLAIMED);
|
|
731
943
|
return withdrawalState.txId;
|
|
732
944
|
}
|
|
733
945
|
throw e;
|
|
734
946
|
}
|
|
735
|
-
this.
|
|
736
|
-
if (this.
|
|
737
|
-
this.
|
|
738
|
-
this.
|
|
947
|
+
this._claimTxId = txIds[0];
|
|
948
|
+
if (this._state === SpvFromBTCSwapState.POSTED || this._state === SpvFromBTCSwapState.BROADCASTED ||
|
|
949
|
+
this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED || this._state === SpvFromBTCSwapState.FAILED ||
|
|
950
|
+
this._state === SpvFromBTCSwapState.FRONTED) {
|
|
739
951
|
await this._saveAndEmit(SpvFromBTCSwapState.CLAIMED);
|
|
740
952
|
}
|
|
741
953
|
return txIds[0];
|
|
@@ -745,10 +957,10 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
745
957
|
*
|
|
746
958
|
* @param abortSignal
|
|
747
959
|
* @param interval How often to check (in seconds), default to 5s
|
|
748
|
-
* @
|
|
960
|
+
* @internal
|
|
749
961
|
*/
|
|
750
962
|
async watchdogWaitTillResult(abortSignal, interval = 5) {
|
|
751
|
-
if (this.
|
|
963
|
+
if (this._data == null)
|
|
752
964
|
throw new Error("Cannot await the result before the btc transaction is sent!");
|
|
753
965
|
let status = { type: base_1.SpvWithdrawalStateType.NOT_FOUND };
|
|
754
966
|
while (status.type === base_1.SpvWithdrawalStateType.NOT_FOUND) {
|
|
@@ -756,7 +968,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
756
968
|
try {
|
|
757
969
|
//Be smart about checking withdrawal state
|
|
758
970
|
if (await this._shouldCheckWithdrawalState()) {
|
|
759
|
-
status = await this.wrapper.
|
|
971
|
+
status = await this.wrapper._contract.getWithdrawalState(this._data, this._genesisSmartChainBlockHeight) ?? { type: base_1.SpvWithdrawalStateType.NOT_FOUND };
|
|
760
972
|
}
|
|
761
973
|
}
|
|
762
974
|
catch (e) {
|
|
@@ -768,17 +980,26 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
768
980
|
return status;
|
|
769
981
|
}
|
|
770
982
|
/**
|
|
771
|
-
*
|
|
983
|
+
* This is an alias for the {@link waitTillClaimedOrFronted} function and will
|
|
984
|
+
* also resolve if the swap has been fronted (not necessarily claimed)
|
|
985
|
+
*
|
|
986
|
+
* @inheritDoc
|
|
987
|
+
*/
|
|
988
|
+
waitTillClaimed(maxWaitTimeSeconds, abortSignal) {
|
|
989
|
+
return this.waitTillClaimedOrFronted(maxWaitTimeSeconds, abortSignal);
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Waits till the swap is successfully fronted or settled on the destination chain
|
|
993
|
+
*
|
|
994
|
+
* @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled (by default
|
|
995
|
+
* it waits indefinitely)
|
|
996
|
+
* @param abortSignal Abort signal
|
|
772
997
|
*
|
|
773
|
-
* @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled
|
|
774
|
-
* @param abortSignal
|
|
775
|
-
* @throws {Error} If swap is in invalid state (must be BTC_TX_CONFIRMED)
|
|
776
|
-
* @throws {Error} If the LP refunded sooner than we were able to claim
|
|
777
998
|
* @returns {boolean} whether the swap was claimed or fronted automatically or not, if the swap was not claimed
|
|
778
|
-
* the user can claim manually through
|
|
999
|
+
* the user can claim manually through the {@link claim} function
|
|
779
1000
|
*/
|
|
780
1001
|
async waitTillClaimedOrFronted(maxWaitTimeSeconds, abortSignal) {
|
|
781
|
-
if (this.
|
|
1002
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED || this._state === SpvFromBTCSwapState.FRONTED)
|
|
782
1003
|
return Promise.resolve(true);
|
|
783
1004
|
const abortController = (0, Utils_1.extendAbortController)(abortSignal);
|
|
784
1005
|
let timedOut = false;
|
|
@@ -822,32 +1043,34 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
822
1043
|
}
|
|
823
1044
|
this.logger.debug("waitTillClaimedOrFronted(): Resolved from watchdog");
|
|
824
1045
|
if (res.type === base_1.SpvWithdrawalStateType.FRONTED) {
|
|
825
|
-
if (this.
|
|
826
|
-
this.
|
|
827
|
-
this.
|
|
1046
|
+
if (this._state !== SpvFromBTCSwapState.FRONTED ||
|
|
1047
|
+
this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
1048
|
+
this._frontTxId = res.txId;
|
|
828
1049
|
await this._saveAndEmit(SpvFromBTCSwapState.FRONTED);
|
|
829
1050
|
}
|
|
830
1051
|
}
|
|
831
1052
|
if (res.type === base_1.SpvWithdrawalStateType.CLAIMED) {
|
|
832
|
-
if (this.
|
|
833
|
-
this.
|
|
1053
|
+
if (this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
1054
|
+
this._claimTxId = res.txId;
|
|
834
1055
|
await this._saveAndEmit(SpvFromBTCSwapState.FRONTED);
|
|
835
1056
|
}
|
|
836
1057
|
}
|
|
837
1058
|
if (res.type === base_1.SpvWithdrawalStateType.CLOSED) {
|
|
838
|
-
if (this.
|
|
1059
|
+
if (this._state !== SpvFromBTCSwapState.CLOSED)
|
|
839
1060
|
await this._saveAndEmit(SpvFromBTCSwapState.CLOSED);
|
|
840
1061
|
throw new Error("Swap failed with catastrophic error!");
|
|
841
1062
|
}
|
|
842
1063
|
return true;
|
|
843
1064
|
}
|
|
844
1065
|
/**
|
|
845
|
-
* Waits till the bitcoin transaction confirms and swap
|
|
1066
|
+
* Waits till the bitcoin transaction confirms and swap settled on the destination chain
|
|
846
1067
|
*
|
|
847
|
-
* @param abortSignal Abort signal
|
|
848
|
-
* @param checkIntervalSeconds How often to check the bitcoin transaction
|
|
849
1068
|
* @param updateCallback Callback called when txId is found, and also called with subsequent confirmations
|
|
850
|
-
* @
|
|
1069
|
+
* @param checkIntervalSeconds How often to check the bitcoin transaction (5 seconds by default)
|
|
1070
|
+
* @param abortSignal Abort signal
|
|
1071
|
+
*
|
|
1072
|
+
* @throws {Error} if in invalid state (must be {@link SpvFromBTCSwapState.POSTED} or
|
|
1073
|
+
* {@link SpvFromBTCSwapState.BROADCASTED} states)
|
|
851
1074
|
*/
|
|
852
1075
|
async waitTillExecuted(updateCallback, checkIntervalSeconds, abortSignal) {
|
|
853
1076
|
await this.waitForBitcoinTransaction(updateCallback, checkIntervalSeconds, abortSignal);
|
|
@@ -855,6 +1078,9 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
855
1078
|
}
|
|
856
1079
|
//////////////////////////////
|
|
857
1080
|
//// Storage
|
|
1081
|
+
/**
|
|
1082
|
+
* @inheritDoc
|
|
1083
|
+
*/
|
|
858
1084
|
serialize() {
|
|
859
1085
|
return {
|
|
860
1086
|
...super.serialize(),
|
|
@@ -881,52 +1107,56 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
881
1107
|
callerFeeShare: this.callerFeeShare.toString(10),
|
|
882
1108
|
frontingFeeShare: this.frontingFeeShare.toString(10),
|
|
883
1109
|
executionFeeShare: this.executionFeeShare.toString(10),
|
|
884
|
-
genesisSmartChainBlockHeight: this.
|
|
1110
|
+
genesisSmartChainBlockHeight: this._genesisSmartChainBlockHeight,
|
|
885
1111
|
gasPricingInfo: (0, PriceInfoType_1.serializePriceInfoType)(this.gasPricingInfo),
|
|
886
|
-
senderAddress: this.
|
|
887
|
-
claimTxId: this.
|
|
888
|
-
frontTxId: this.
|
|
889
|
-
data: this.
|
|
1112
|
+
senderAddress: this._senderAddress,
|
|
1113
|
+
claimTxId: this._claimTxId,
|
|
1114
|
+
frontTxId: this._frontTxId,
|
|
1115
|
+
data: this._data?.serialize()
|
|
890
1116
|
};
|
|
891
1117
|
}
|
|
892
1118
|
//////////////////////////////
|
|
893
1119
|
//// Swap ticks & sync
|
|
894
1120
|
/**
|
|
895
|
-
*
|
|
1121
|
+
* Used to set the txId of the bitcoin payment from the on-chain events listener
|
|
896
1122
|
*
|
|
897
1123
|
* @param txId
|
|
1124
|
+
* @internal
|
|
898
1125
|
*/
|
|
899
1126
|
async _setBitcoinTxId(txId) {
|
|
900
|
-
if (this.
|
|
1127
|
+
if (this._data == null)
|
|
901
1128
|
return;
|
|
902
|
-
if (txId != this.
|
|
1129
|
+
if (txId != this._data.btcTx.txid)
|
|
903
1130
|
return;
|
|
904
|
-
if (this.
|
|
1131
|
+
if (this._senderAddress != null)
|
|
905
1132
|
return;
|
|
906
|
-
const btcTx = await this.wrapper.
|
|
1133
|
+
const btcTx = await this.wrapper._btcRpc.getTransaction(txId);
|
|
907
1134
|
if (btcTx == null || btcTx.inputAddresses == null)
|
|
908
1135
|
return;
|
|
909
|
-
this.
|
|
1136
|
+
this._senderAddress = btcTx.inputAddresses[1];
|
|
910
1137
|
}
|
|
1138
|
+
/**
|
|
1139
|
+
* @internal
|
|
1140
|
+
*/
|
|
911
1141
|
async _syncStateFromBitcoin(save) {
|
|
912
|
-
if (this.
|
|
1142
|
+
if (this._data?.btcTx == null)
|
|
913
1143
|
return false;
|
|
914
1144
|
//Check if bitcoin payment was confirmed
|
|
915
1145
|
const res = await this.getBitcoinPayment();
|
|
916
1146
|
if (res == null) {
|
|
917
1147
|
//Check inputs double-spent
|
|
918
|
-
for (let input of this.
|
|
919
|
-
if (await this.wrapper.
|
|
920
|
-
if (this.
|
|
921
|
-
this.
|
|
922
|
-
this.
|
|
923
|
-
this.
|
|
1148
|
+
for (let input of this._data.btcTx.ins) {
|
|
1149
|
+
if (await this.wrapper._btcRpc.isSpent(input.txid + ":" + input.vout, true)) {
|
|
1150
|
+
if (this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1151
|
+
this._state === SpvFromBTCSwapState.POSTED ||
|
|
1152
|
+
this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
1153
|
+
this._state === SpvFromBTCSwapState.DECLINED) {
|
|
924
1154
|
//One of the inputs was double-spent
|
|
925
|
-
this.
|
|
1155
|
+
this._state = SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
926
1156
|
}
|
|
927
1157
|
else {
|
|
928
1158
|
//One of the inputs was double-spent
|
|
929
|
-
this.
|
|
1159
|
+
this._state = SpvFromBTCSwapState.FAILED;
|
|
930
1160
|
}
|
|
931
1161
|
if (save)
|
|
932
1162
|
await this._saveAndEmit();
|
|
@@ -936,23 +1166,23 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
936
1166
|
}
|
|
937
1167
|
else {
|
|
938
1168
|
let needsSave = false;
|
|
939
|
-
if (res.inputAddresses != null && this.
|
|
940
|
-
this.
|
|
1169
|
+
if (res.inputAddresses != null && this._senderAddress == null) {
|
|
1170
|
+
this._senderAddress = res.inputAddresses[1];
|
|
941
1171
|
needsSave = true;
|
|
942
1172
|
}
|
|
943
1173
|
if (res.confirmations >= this.vaultRequiredConfirmations) {
|
|
944
|
-
if (this.
|
|
945
|
-
this.
|
|
946
|
-
this.
|
|
947
|
-
this.
|
|
1174
|
+
if (this._state !== SpvFromBTCSwapState.BTC_TX_CONFIRMED &&
|
|
1175
|
+
this._state !== SpvFromBTCSwapState.FRONTED &&
|
|
1176
|
+
this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
1177
|
+
this._state = SpvFromBTCSwapState.BTC_TX_CONFIRMED;
|
|
948
1178
|
needsSave = true;
|
|
949
1179
|
}
|
|
950
1180
|
}
|
|
951
|
-
else if (this.
|
|
952
|
-
this.
|
|
953
|
-
this.
|
|
954
|
-
this.
|
|
955
|
-
this.
|
|
1181
|
+
else if (this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
1182
|
+
this._state === SpvFromBTCSwapState.POSTED ||
|
|
1183
|
+
this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1184
|
+
this._state === SpvFromBTCSwapState.DECLINED) {
|
|
1185
|
+
this._state = SpvFromBTCSwapState.BROADCASTED;
|
|
956
1186
|
needsSave = true;
|
|
957
1187
|
}
|
|
958
1188
|
if (needsSave && save)
|
|
@@ -964,85 +1194,91 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
964
1194
|
/**
|
|
965
1195
|
* Checks the swap's state on-chain and compares it to its internal state, updates/changes it according to on-chain
|
|
966
1196
|
* data
|
|
967
|
-
*
|
|
968
|
-
* @private
|
|
969
1197
|
*/
|
|
970
1198
|
async syncStateFromChain() {
|
|
971
1199
|
let changed = false;
|
|
972
|
-
if (this.
|
|
973
|
-
this.
|
|
974
|
-
this.
|
|
975
|
-
this.
|
|
976
|
-
this.
|
|
977
|
-
this.
|
|
1200
|
+
if (this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1201
|
+
this._state === SpvFromBTCSwapState.POSTED ||
|
|
1202
|
+
this._state === SpvFromBTCSwapState.BROADCASTED ||
|
|
1203
|
+
this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
1204
|
+
this._state === SpvFromBTCSwapState.DECLINED ||
|
|
1205
|
+
this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
978
1206
|
//Check BTC transaction
|
|
979
1207
|
if (await this._syncStateFromBitcoin(false))
|
|
980
1208
|
changed ||= true;
|
|
981
1209
|
}
|
|
982
|
-
if (this.
|
|
1210
|
+
if (this._state === SpvFromBTCSwapState.BROADCASTED || this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
983
1211
|
if (await this._shouldCheckWithdrawalState()) {
|
|
984
|
-
const status = await this.wrapper.
|
|
985
|
-
this.logger.debug("syncStateFromChain(): status of " + this.
|
|
1212
|
+
const status = await this.wrapper._contract.getWithdrawalState(this._data, this._genesisSmartChainBlockHeight);
|
|
1213
|
+
this.logger.debug("syncStateFromChain(): status of " + this._data.btcTx.txid, status);
|
|
986
1214
|
switch (status?.type) {
|
|
987
1215
|
case base_1.SpvWithdrawalStateType.FRONTED:
|
|
988
|
-
this.
|
|
989
|
-
this.
|
|
1216
|
+
this._frontTxId = status.txId;
|
|
1217
|
+
this._state = SpvFromBTCSwapState.FRONTED;
|
|
990
1218
|
changed ||= true;
|
|
991
1219
|
break;
|
|
992
1220
|
case base_1.SpvWithdrawalStateType.CLAIMED:
|
|
993
|
-
this.
|
|
994
|
-
this.
|
|
1221
|
+
this._claimTxId = status.txId;
|
|
1222
|
+
this._state = SpvFromBTCSwapState.CLAIMED;
|
|
995
1223
|
changed ||= true;
|
|
996
1224
|
break;
|
|
997
1225
|
case base_1.SpvWithdrawalStateType.CLOSED:
|
|
998
|
-
this.
|
|
1226
|
+
this._state = SpvFromBTCSwapState.CLOSED;
|
|
999
1227
|
changed ||= true;
|
|
1000
1228
|
break;
|
|
1001
1229
|
}
|
|
1002
1230
|
}
|
|
1003
1231
|
}
|
|
1004
|
-
if (this.
|
|
1005
|
-
this.
|
|
1006
|
-
this.
|
|
1232
|
+
if (this._state === SpvFromBTCSwapState.CREATED ||
|
|
1233
|
+
this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1234
|
+
this._state === SpvFromBTCSwapState.POSTED) {
|
|
1007
1235
|
if (this.expiry < Date.now()) {
|
|
1008
|
-
if (this.
|
|
1009
|
-
this.
|
|
1236
|
+
if (this._state === SpvFromBTCSwapState.CREATED) {
|
|
1237
|
+
this._state = SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
1010
1238
|
}
|
|
1011
1239
|
else {
|
|
1012
|
-
this.
|
|
1240
|
+
this._state = SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
1013
1241
|
}
|
|
1014
1242
|
changed ||= true;
|
|
1015
1243
|
}
|
|
1016
1244
|
}
|
|
1017
1245
|
return changed;
|
|
1018
1246
|
}
|
|
1247
|
+
/**
|
|
1248
|
+
* @inheritDoc
|
|
1249
|
+
* @internal
|
|
1250
|
+
*/
|
|
1019
1251
|
async _sync(save) {
|
|
1020
1252
|
const changed = await this.syncStateFromChain();
|
|
1021
1253
|
if (changed && save)
|
|
1022
1254
|
await this._saveAndEmit();
|
|
1023
1255
|
return changed;
|
|
1024
1256
|
}
|
|
1257
|
+
/**
|
|
1258
|
+
* @inheritDoc
|
|
1259
|
+
* @internal
|
|
1260
|
+
*/
|
|
1025
1261
|
async _tick(save) {
|
|
1026
|
-
if (this.
|
|
1027
|
-
this.
|
|
1262
|
+
if (this._state === SpvFromBTCSwapState.CREATED ||
|
|
1263
|
+
this._state === SpvFromBTCSwapState.SIGNED) {
|
|
1028
1264
|
if (this.getQuoteExpiry() < Date.now()) {
|
|
1029
|
-
this.
|
|
1265
|
+
this._state = SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
1030
1266
|
if (save)
|
|
1031
1267
|
await this._saveAndEmit();
|
|
1032
1268
|
return true;
|
|
1033
1269
|
}
|
|
1034
1270
|
}
|
|
1035
|
-
if (this.
|
|
1271
|
+
if (this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED && !this.initiated) {
|
|
1036
1272
|
if (this.expiry < Date.now()) {
|
|
1037
|
-
this.
|
|
1273
|
+
this._state = SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
1038
1274
|
if (save)
|
|
1039
1275
|
await this._saveAndEmit();
|
|
1040
1276
|
return true;
|
|
1041
1277
|
}
|
|
1042
1278
|
}
|
|
1043
1279
|
if (Math.floor(Date.now() / 1000) % 120 === 0) {
|
|
1044
|
-
if (this.
|
|
1045
|
-
this.
|
|
1280
|
+
if (this._state === SpvFromBTCSwapState.POSTED ||
|
|
1281
|
+
this._state === SpvFromBTCSwapState.BROADCASTED) {
|
|
1046
1282
|
try {
|
|
1047
1283
|
//Check if bitcoin payment was confirmed
|
|
1048
1284
|
return await this._syncStateFromBitcoin(save);
|
|
@@ -1054,22 +1290,27 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
1054
1290
|
}
|
|
1055
1291
|
return false;
|
|
1056
1292
|
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Checks whether an on-chain withdrawal state should be fetched for this specific swap
|
|
1295
|
+
*
|
|
1296
|
+
* @internal
|
|
1297
|
+
*/
|
|
1057
1298
|
async _shouldCheckWithdrawalState(frontingAddress, vaultDataUtxo) {
|
|
1058
1299
|
if (frontingAddress === undefined)
|
|
1059
|
-
frontingAddress = await this.wrapper.
|
|
1300
|
+
frontingAddress = await this.wrapper._contract.getFronterAddress(this.vaultOwner, this.vaultId, this._data);
|
|
1060
1301
|
if (vaultDataUtxo === undefined)
|
|
1061
|
-
vaultDataUtxo = await this.wrapper.
|
|
1302
|
+
vaultDataUtxo = await this.wrapper._contract.getVaultLatestUtxo(this.vaultOwner, this.vaultId);
|
|
1062
1303
|
if (frontingAddress != null)
|
|
1063
1304
|
return true; //In case the swap is fronted there will for sure be a fronted event
|
|
1064
1305
|
if (vaultDataUtxo == null)
|
|
1065
1306
|
return true; //Vault UTXO is null (the vault closed)
|
|
1066
1307
|
const [txId, _] = vaultDataUtxo.split(":");
|
|
1067
1308
|
//Don't check both txns if their txId is equal
|
|
1068
|
-
if (this.
|
|
1309
|
+
if (this._data.btcTx.txid === txId)
|
|
1069
1310
|
return true;
|
|
1070
1311
|
const [btcTx, latestVaultTx] = await Promise.all([
|
|
1071
|
-
this.wrapper.
|
|
1072
|
-
this.wrapper.
|
|
1312
|
+
this.wrapper._btcRpc.getTransaction(this._data.btcTx.txid),
|
|
1313
|
+
this.wrapper._btcRpc.getTransaction(txId)
|
|
1073
1314
|
]);
|
|
1074
1315
|
if (latestVaultTx == null || latestVaultTx.blockheight == null) {
|
|
1075
1316
|
//Something must've gone horribly wrong, the latest vault utxo tx of the vault either
|
|
@@ -1089,7 +1330,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
1089
1330
|
}
|
|
1090
1331
|
else {
|
|
1091
1332
|
//Definitely not claimed because the transaction was probably double-spent (or evicted from mempool)
|
|
1092
|
-
this.logger.debug(`_shouldCheckWithdrawalState(): Skipped checking withdrawal state, btc tx probably replaced or evicted: ${this.
|
|
1333
|
+
this.logger.debug(`_shouldCheckWithdrawalState(): Skipped checking withdrawal state, btc tx probably replaced or evicted: ${this._data.btcTx.txid} and not fronted`);
|
|
1093
1334
|
return false;
|
|
1094
1335
|
}
|
|
1095
1336
|
return true;
|