@atomiqlabs/sdk 8.1.8 → 8.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bitcoin/coinselect2/utils.d.ts +6 -0
- 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 +8 -1
- package/dist/enums/FeeType.js +8 -1
- 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 +5 -5
- package/dist/index.js +7 -6
- package/dist/intermediaries/Intermediary.d.ts +61 -14
- package/dist/intermediaries/Intermediary.js +38 -11
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +62 -29
- package/dist/intermediaries/IntermediaryDiscovery.js +39 -24
- package/dist/prices/RedundantSwapPrice.d.ts +26 -5
- package/dist/prices/RedundantSwapPrice.js +22 -2
- package/dist/prices/SingleSwapPrice.d.ts +10 -7
- package/dist/prices/SingleSwapPrice.js +11 -8
- package/dist/prices/SwapPriceWithChain.d.ts +56 -19
- package/dist/prices/SwapPriceWithChain.js +62 -25
- package/dist/prices/abstract/IPriceProvider.d.ts +4 -4
- package/dist/prices/abstract/IPriceProvider.js +1 -1
- package/dist/prices/abstract/ISwapPrice.d.ts +95 -46
- package/dist/prices/abstract/ISwapPrice.js +104 -56
- package/dist/prices/providers/BinancePriceProvider.d.ts +8 -1
- package/dist/prices/providers/BinancePriceProvider.js +8 -1
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +7 -1
- package/dist/prices/providers/CoinGeckoPriceProvider.js +7 -1
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +7 -1
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +7 -1
- package/dist/prices/providers/CustomPriceProvider.d.ts +12 -1
- package/dist/prices/providers/CustomPriceProvider.js +12 -1
- package/dist/prices/providers/KrakenPriceProvider.d.ts +10 -1
- package/dist/prices/providers/KrakenPriceProvider.js +10 -1
- package/dist/prices/providers/OKXPriceProvider.d.ts +7 -1
- package/dist/prices/providers/OKXPriceProvider.js +7 -1
- 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 +380 -226
- package/dist/swapper/Swapper.js +383 -349
- package/dist/swapper/SwapperFactory.d.ts +66 -18
- package/dist/swapper/SwapperFactory.js +24 -3
- 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 +12 -3
- package/dist/swaps/IAddressSwap.js +3 -2
- package/dist/swaps/IBTCWalletSwap.d.ts +26 -8
- package/dist/swaps/IBTCWalletSwap.js +3 -2
- package/dist/swaps/IClaimableSwap.d.ts +38 -6
- package/dist/swaps/IClaimableSwap.js +3 -2
- package/dist/swaps/IClaimableSwapWrapper.d.ts +11 -1
- package/dist/swaps/IRefundableSwap.d.ts +31 -5
- package/dist/swaps/IRefundableSwap.js +3 -2
- package/dist/swaps/ISwap.d.ts +162 -24
- package/dist/swaps/ISwap.js +92 -35
- package/dist/swaps/ISwapWithGasDrop.d.ts +8 -2
- package/dist/swaps/ISwapWithGasDrop.js +2 -1
- package/dist/swaps/ISwapWrapper.d.ts +161 -52
- package/dist/swaps/ISwapWrapper.js +131 -73
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +51 -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 +97 -28
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +91 -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 +278 -60
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +519 -241
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +77 -26
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +132 -50
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +313 -52
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +544 -194
- 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 +222 -55
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +462 -244
- 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 +195 -58
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +324 -191
- 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 +61 -20
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +75 -32
- 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 +37 -14
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +66 -20
- 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 +350 -88
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +482 -215
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +76 -24
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +247 -124
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +148 -20
- package/dist/swaps/trusted/ln/LnForGasSwap.js +175 -45
- 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 +202 -49
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +232 -80
- 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 +8 -2
- package/dist/types/PriceInfoType.d.ts +4 -4
- package/dist/types/PriceInfoType.js +3 -3
- package/dist/types/SwapExecutionAction.d.ts +85 -4
- package/dist/types/SwapWithSigner.d.ts +5 -2
- 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 +3 -2
- package/dist/types/fees/FeeBreakdown.d.ts +3 -2
- package/dist/types/fees/PercentagePPM.d.ts +4 -2
- package/dist/types/fees/PercentagePPM.js +2 -1
- package/dist/types/lnurl/LNURLPay.d.ts +20 -12
- package/dist/types/lnurl/LNURLPay.js +8 -4
- package/dist/types/lnurl/LNURLWithdraw.d.ts +17 -10
- package/dist/types/lnurl/LNURLWithdraw.js +8 -4
- package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -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 +4 -2
- package/dist/utils/BitcoinUtils.d.ts +1 -0
- package/dist/utils/BitcoinUtils.js +5 -1
- package/dist/utils/SwapUtils.d.ts +58 -1
- package/dist/utils/SwapUtils.js +55 -1
- package/dist/utils/TokenUtils.d.ts +10 -2
- package/dist/utils/TokenUtils.js +12 -4
- package/package.json +3 -3
- package/src/bitcoin/coinselect2/utils.ts +6 -0
- 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 +8 -1
- 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 +12 -5
- package/src/intermediaries/Intermediary.ts +61 -14
- package/src/intermediaries/IntermediaryDiscovery.ts +69 -34
- package/src/prices/RedundantSwapPrice.ts +26 -6
- package/src/prices/SingleSwapPrice.ts +11 -8
- package/src/prices/SwapPriceWithChain.ts +63 -26
- package/src/prices/abstract/IPriceProvider.ts +4 -4
- package/src/prices/abstract/ISwapPrice.ts +115 -66
- package/src/prices/providers/BinancePriceProvider.ts +8 -1
- package/src/prices/providers/CoinGeckoPriceProvider.ts +7 -1
- package/src/prices/providers/CoinPaprikaPriceProvider.ts +7 -1
- package/src/prices/providers/CustomPriceProvider.ts +12 -1
- package/src/prices/providers/KrakenPriceProvider.ts +10 -1
- package/src/prices/providers/OKXPriceProvider.ts +7 -1
- 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 +599 -390
- package/src/swapper/SwapperFactory.ts +73 -24
- 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 +13 -3
- package/src/swaps/IBTCWalletSwap.ts +26 -10
- package/src/swaps/IClaimableSwap.ts +41 -6
- package/src/swaps/IClaimableSwapWrapper.ts +11 -2
- package/src/swaps/IRefundableSwap.ts +34 -5
- package/src/swaps/ISwap.ts +224 -85
- package/src/swaps/ISwapWithGasDrop.ts +8 -2
- package/src/swaps/ISwapWrapper.ts +216 -98
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +64 -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 +123 -50
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +24 -11
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +562 -258
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +156 -62
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +592 -227
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +177 -74
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +483 -245
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +141 -59
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +350 -195
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +48 -23
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +87 -40
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +110 -110
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +89 -34
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +101 -31
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +556 -259
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +292 -148
- package/src/swaps/trusted/ln/LnForGasSwap.ts +186 -47
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +34 -15
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +262 -88
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +41 -19
- package/src/types/AmountData.ts +2 -1
- package/src/types/CustomPriceFunction.ts +8 -2
- package/src/types/PriceInfoType.ts +4 -4
- package/src/types/SwapExecutionAction.ts +97 -5
- package/src/types/SwapWithSigner.ts +8 -4
- package/src/types/Token.ts +12 -5
- package/src/types/TokenAmount.ts +3 -0
- package/src/types/fees/Fee.ts +3 -2
- package/src/types/fees/FeeBreakdown.ts +3 -2
- package/src/types/fees/PercentagePPM.ts +4 -2
- package/src/types/lnurl/LNURLPay.ts +20 -12
- package/src/types/lnurl/LNURLWithdraw.ts +17 -10
- package/src/types/wallets/LightningInvoiceCreateService.ts +30 -0
- package/src/types/wallets/MinimalBitcoinWalletInterface.ts +3 -1
- package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +4 -2
- package/src/utils/BitcoinUtils.ts +5 -0
- package/src/utils/SwapUtils.ts +63 -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
|
|
23
|
-
* @category Swaps
|
|
22
|
+
* State enum for SPV vault (UTXO-controlled vault) based swaps
|
|
23
|
+
* @category Swaps/Bitcoin → Smart chain
|
|
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/Bitcoin → Smart chain
|
|
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());
|
|
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));
|
|
182
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();
|
|
@@ -394,14 +590,17 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
394
590
|
/**
|
|
395
591
|
* Returns the PSBT that is already funded with wallet's UTXOs (runs a coin-selection algorithm to choose UTXOs to use),
|
|
396
592
|
* also returns inputs indices that need to be signed by the wallet before submitting the PSBT back to the SDK with
|
|
397
|
-
*
|
|
593
|
+
* {@link submitPsbt}
|
|
594
|
+
*
|
|
595
|
+
* @remarks
|
|
596
|
+
* Note that when passing the `feeRate` argument, the fee must be at least {@link minimumBtcFeeRate} sats/vB.
|
|
398
597
|
*
|
|
399
598
|
* @param _bitcoinWallet Sender's bitcoin wallet
|
|
400
|
-
* @param feeRate Optional fee rate for the transaction
|
|
599
|
+
* @param feeRate Optional fee rate in sats/vB for the transaction
|
|
401
600
|
* @param additionalOutputs additional outputs to add to the PSBT - can be used to collect fees from users
|
|
402
601
|
*/
|
|
403
602
|
async getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs) {
|
|
404
|
-
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper.
|
|
603
|
+
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper._btcRpc, this.wrapper._options.bitcoinNetwork);
|
|
405
604
|
if (feeRate != null) {
|
|
406
605
|
if (feeRate < this.minimumBtcFeeRate)
|
|
407
606
|
throw new Error("Bitcoin tx fee needs to be at least " + this.minimumBtcFeeRate + " sats/vB");
|
|
@@ -414,7 +613,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
414
613
|
additionalOutputs.forEach(output => {
|
|
415
614
|
psbt.addOutput({
|
|
416
615
|
amount: output.amount,
|
|
417
|
-
script: output.outputScript ?? (0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
616
|
+
script: output.outputScript ?? (0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, output.address)
|
|
418
617
|
});
|
|
419
618
|
});
|
|
420
619
|
psbt = await bitcoinWallet.fundPsbt(psbt, feeRate);
|
|
@@ -433,9 +632,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
433
632
|
};
|
|
434
633
|
}
|
|
435
634
|
/**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
* @param _psbt A psbt - either a Transaction object or a hex or base64 encoded PSBT string
|
|
635
|
+
* @inheritDoc
|
|
439
636
|
*/
|
|
440
637
|
async submitPsbt(_psbt) {
|
|
441
638
|
const psbt = (0, BitcoinUtils_1.parsePsbtTransaction)(_psbt);
|
|
@@ -444,7 +641,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
444
641
|
throw new Error("Quote expired!");
|
|
445
642
|
}
|
|
446
643
|
//Ensure valid state
|
|
447
|
-
if (this.
|
|
644
|
+
if (this._state !== SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED && this._state !== SpvFromBTCSwapState.CREATED) {
|
|
448
645
|
throw new Error("Invalid swap state!");
|
|
449
646
|
}
|
|
450
647
|
if (this.url == null)
|
|
@@ -455,8 +652,8 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
455
652
|
throw new Error("Legacy (non-segwit) inputs are not allowed in the transaction!");
|
|
456
653
|
psbt.finalizeIdx(i);
|
|
457
654
|
}
|
|
458
|
-
const btcTx = await this.wrapper.
|
|
459
|
-
const data = await this.wrapper.
|
|
655
|
+
const btcTx = await this.wrapper._btcRpc.parseTransaction(buffer_1.Buffer.from(psbt.toBytes(true)).toString("hex"));
|
|
656
|
+
const data = await this.wrapper._contract.getWithdrawalData(btcTx);
|
|
460
657
|
this.logger.debug("submitPsbt(): parsed withdrawal data: ", data);
|
|
461
658
|
//Verify correct withdrawal data
|
|
462
659
|
if (!data.isRecipient(this.recipient) ||
|
|
@@ -467,7 +664,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
467
664
|
data.executionFeeRate !== this.executionFeeShare ||
|
|
468
665
|
data.getSpentVaultUtxo() !== this.vaultUtxo ||
|
|
469
666
|
BigInt(data.getNewVaultBtcAmount()) !== this.vaultUtxoValue ||
|
|
470
|
-
!data.getNewVaultScript().equals((0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
667
|
+
!data.getNewVaultScript().equals((0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, this.vaultBtcAddress)) ||
|
|
471
668
|
data.getExecutionData() != null) {
|
|
472
669
|
throw new Error("Invalid withdrawal tx data submitted!");
|
|
473
670
|
}
|
|
@@ -475,16 +672,16 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
475
672
|
const lpOutput = psbt.getOutput(2);
|
|
476
673
|
if (lpOutput.script == null ||
|
|
477
674
|
lpOutput.amount !== this.btcAmount ||
|
|
478
|
-
!(0, BitcoinUtils_1.toOutputScript)(this.wrapper.
|
|
675
|
+
!(0, BitcoinUtils_1.toOutputScript)(this.wrapper._options.bitcoinNetwork, this.btcDestinationAddress).equals(buffer_1.Buffer.from(lpOutput.script))) {
|
|
479
676
|
throw new Error("Invalid LP bitcoin output in transaction!");
|
|
480
677
|
}
|
|
481
678
|
//Verify vault utxo not spent yet
|
|
482
|
-
if (await this.wrapper.
|
|
679
|
+
if (await this.wrapper._btcRpc.isSpent(this.vaultUtxo)) {
|
|
483
680
|
throw new Error("Vault UTXO already spent, please create new swap!");
|
|
484
681
|
}
|
|
485
682
|
//Verify tx is parsable by the contract
|
|
486
683
|
try {
|
|
487
|
-
await this.wrapper.
|
|
684
|
+
await this.wrapper._contract.checkWithdrawalTx(data);
|
|
488
685
|
}
|
|
489
686
|
catch (e) {
|
|
490
687
|
throw new Error("Transaction not parsable by the contract: " + (e.message ?? e.toString()));
|
|
@@ -493,7 +690,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
493
690
|
if (this.expiry < Date.now()) {
|
|
494
691
|
throw new Error("Quote expired!");
|
|
495
692
|
}
|
|
496
|
-
this.
|
|
693
|
+
this._data = data;
|
|
497
694
|
this.initiated = true;
|
|
498
695
|
await this._saveAndEmit(SpvFromBTCSwapState.SIGNED);
|
|
499
696
|
try {
|
|
@@ -507,15 +704,21 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
507
704
|
await this._saveAndEmit(SpvFromBTCSwapState.DECLINED);
|
|
508
705
|
throw e;
|
|
509
706
|
}
|
|
510
|
-
return this.
|
|
707
|
+
return this._data.getTxId();
|
|
511
708
|
}
|
|
709
|
+
/**
|
|
710
|
+
* @inheritDoc
|
|
711
|
+
*/
|
|
512
712
|
async estimateBitcoinFee(_bitcoinWallet, feeRate) {
|
|
513
|
-
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper.
|
|
713
|
+
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper._btcRpc, this.wrapper._options.bitcoinNetwork);
|
|
514
714
|
const txFee = await bitcoinWallet.getFundedPsbtFee((await this.getPsbt()).psbt, feeRate);
|
|
515
715
|
if (txFee == null)
|
|
516
716
|
return null;
|
|
517
|
-
return (0, TokenAmount_1.toTokenAmount)(BigInt(txFee), Token_1.BitcoinTokens.BTC, this.wrapper.
|
|
717
|
+
return (0, TokenAmount_1.toTokenAmount)(BigInt(txFee), Token_1.BitcoinTokens.BTC, this.wrapper._prices, this.pricingInfo);
|
|
518
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* @inheritDoc
|
|
721
|
+
*/
|
|
519
722
|
async sendBitcoinTransaction(wallet, feeRate) {
|
|
520
723
|
const { psbt, psbtBase64, psbtHex, signInputs } = await this.getFundedPsbt(wallet, feeRate);
|
|
521
724
|
let signedPsbt;
|
|
@@ -530,40 +733,41 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
530
733
|
return await this.submitPsbt(signedPsbt);
|
|
531
734
|
}
|
|
532
735
|
/**
|
|
533
|
-
* Executes the swap with the provided bitcoin wallet
|
|
736
|
+
* Executes the swap with the provided bitcoin wallet
|
|
534
737
|
*
|
|
535
738
|
* @param wallet Bitcoin wallet to use to sign the bitcoin transaction
|
|
536
739
|
* @param callbacks Callbacks to track the progress of the swap
|
|
537
740
|
* @param options Optional options for the swap like feeRate, AbortSignal, and timeouts/intervals
|
|
538
741
|
*
|
|
539
742
|
* @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
|
|
743
|
+
* user, in case `false` is returned the user should call the {@link claim} function to settle the swap on the
|
|
744
|
+
* destination manually
|
|
541
745
|
*/
|
|
542
746
|
async execute(wallet, callbacks, options) {
|
|
543
|
-
if (this.
|
|
747
|
+
if (this._state === SpvFromBTCSwapState.CLOSED)
|
|
544
748
|
throw new Error("Swap encountered a catastrophic failure!");
|
|
545
|
-
if (this.
|
|
749
|
+
if (this._state === SpvFromBTCSwapState.FAILED)
|
|
546
750
|
throw new Error("Swap failed!");
|
|
547
|
-
if (this.
|
|
751
|
+
if (this._state === SpvFromBTCSwapState.DECLINED)
|
|
548
752
|
throw new Error("Swap execution already declined by the LP!");
|
|
549
|
-
if (this.
|
|
753
|
+
if (this._state === SpvFromBTCSwapState.QUOTE_EXPIRED)
|
|
550
754
|
throw new Error("Swap quote expired!");
|
|
551
|
-
if (this.
|
|
755
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED || this._state === SpvFromBTCSwapState.FRONTED)
|
|
552
756
|
throw new Error("Swap already settled or fronted!");
|
|
553
|
-
if (this.
|
|
757
|
+
if (this._state === SpvFromBTCSwapState.CREATED) {
|
|
554
758
|
const txId = await this.sendBitcoinTransaction(wallet, options?.feeRate);
|
|
555
759
|
if (callbacks?.onSourceTransactionSent != null)
|
|
556
760
|
callbacks.onSourceTransactionSent(txId);
|
|
557
761
|
}
|
|
558
|
-
if (this.
|
|
762
|
+
if (this._state === SpvFromBTCSwapState.POSTED || this._state === SpvFromBTCSwapState.BROADCASTED) {
|
|
559
763
|
const txId = await this.waitForBitcoinTransaction(callbacks?.onSourceTransactionConfirmationStatus, options?.btcTxCheckIntervalSeconds, options?.abortSignal);
|
|
560
764
|
if (callbacks?.onSourceTransactionConfirmed != null)
|
|
561
765
|
callbacks.onSourceTransactionConfirmed(txId);
|
|
562
766
|
}
|
|
563
767
|
// @ts-ignore
|
|
564
|
-
if (this.
|
|
768
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED || this._state === SpvFromBTCSwapState.FRONTED)
|
|
565
769
|
return true;
|
|
566
|
-
if (this.
|
|
770
|
+
if (this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
567
771
|
const success = await this.waitTillClaimedOrFronted(options?.maxWaitTillAutomaticSettlementSeconds ?? 60, options?.abortSignal);
|
|
568
772
|
if (success && callbacks?.onSwapSettled != null)
|
|
569
773
|
callbacks.onSwapSettled(this.getOutputTxId());
|
|
@@ -571,9 +775,17 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
571
775
|
}
|
|
572
776
|
throw new Error("Unexpected state reached!");
|
|
573
777
|
}
|
|
778
|
+
/**
|
|
779
|
+
* @inheritDoc
|
|
780
|
+
*
|
|
781
|
+
* @param options.bitcoinWallet Optional bitcoin wallet address specification to return a funded PSBT,
|
|
782
|
+
* if not provided a raw PSBT is returned instead which necessitates the implementor to manually add
|
|
783
|
+
* inputs to the bitcoin transaction and **set the nSequence field of the 2nd input** (input 1 -
|
|
784
|
+
* indexing from 0) to the value returned in `in1sequence`
|
|
785
|
+
*/
|
|
574
786
|
async txsExecute(options) {
|
|
575
|
-
if (this.
|
|
576
|
-
if (!await this.
|
|
787
|
+
if (this._state === SpvFromBTCSwapState.CREATED) {
|
|
788
|
+
if (!await this._verifyQuoteValid())
|
|
577
789
|
throw new Error("Quote already expired or close to expiry!");
|
|
578
790
|
return [
|
|
579
791
|
{
|
|
@@ -594,11 +806,12 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
594
806
|
//// Bitcoin tx listener
|
|
595
807
|
/**
|
|
596
808
|
* Checks whether a bitcoin payment was already made, returns the payment or null when no payment has been made.
|
|
809
|
+
* @internal
|
|
597
810
|
*/
|
|
598
811
|
async getBitcoinPayment() {
|
|
599
|
-
if (this.
|
|
812
|
+
if (this._data?.btcTx?.txid == null)
|
|
600
813
|
return null;
|
|
601
|
-
const result = await this.wrapper.
|
|
814
|
+
const result = await this.wrapper._btcRpc.getTransaction(this._data?.btcTx?.txid);
|
|
602
815
|
if (result == null)
|
|
603
816
|
return null;
|
|
604
817
|
return {
|
|
@@ -609,32 +822,30 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
609
822
|
};
|
|
610
823
|
}
|
|
611
824
|
/**
|
|
612
|
-
*
|
|
825
|
+
* @inheritDoc
|
|
613
826
|
*
|
|
614
|
-
* @
|
|
615
|
-
*
|
|
616
|
-
* @param abortSignal Abort signal
|
|
617
|
-
* @throws {Error} if in invalid state (must be CLAIM_COMMITED)
|
|
827
|
+
* @throws {Error} if in invalid state (must be {@link SpvFromBTCSwapState.POSTED} or
|
|
828
|
+
* {@link SpvFromBTCSwapState.BROADCASTED} states)
|
|
618
829
|
*/
|
|
619
830
|
async waitForBitcoinTransaction(updateCallback, checkIntervalSeconds, abortSignal) {
|
|
620
|
-
if (this.
|
|
621
|
-
this.
|
|
622
|
-
!(this.
|
|
831
|
+
if (this._state !== SpvFromBTCSwapState.POSTED &&
|
|
832
|
+
this._state !== SpvFromBTCSwapState.BROADCASTED &&
|
|
833
|
+
!(this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED && this.initiated))
|
|
623
834
|
throw new Error("Must be in POSTED or BROADCASTED state!");
|
|
624
|
-
if (this.
|
|
835
|
+
if (this._data == null)
|
|
625
836
|
throw new Error("Expected swap to have withdrawal data filled!");
|
|
626
|
-
const result = await this.wrapper.
|
|
837
|
+
const result = await this.wrapper._btcRpc.waitForTransaction(this._data.btcTx.txid, this.vaultRequiredConfirmations, (btcTx, txEtaMs) => {
|
|
627
838
|
if (updateCallback != null)
|
|
628
839
|
updateCallback(btcTx?.txid, btcTx?.confirmations, this.vaultRequiredConfirmations, txEtaMs);
|
|
629
840
|
if (btcTx == null)
|
|
630
841
|
return;
|
|
631
842
|
let save = false;
|
|
632
|
-
if (btcTx.inputAddresses != null && this.
|
|
633
|
-
this.
|
|
843
|
+
if (btcTx.inputAddresses != null && this._senderAddress == null) {
|
|
844
|
+
this._senderAddress = btcTx.inputAddresses[1];
|
|
634
845
|
save = true;
|
|
635
846
|
}
|
|
636
|
-
if (this.
|
|
637
|
-
this.
|
|
847
|
+
if (this._state === SpvFromBTCSwapState.POSTED || this._state == SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
848
|
+
this._state = SpvFromBTCSwapState.BROADCASTED;
|
|
638
849
|
save = true;
|
|
639
850
|
}
|
|
640
851
|
if (save)
|
|
@@ -643,13 +854,13 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
643
854
|
if (abortSignal != null)
|
|
644
855
|
abortSignal.throwIfAborted();
|
|
645
856
|
let save = false;
|
|
646
|
-
if (result.inputAddresses != null && this.
|
|
647
|
-
this.
|
|
857
|
+
if (result.inputAddresses != null && this._senderAddress == null) {
|
|
858
|
+
this._senderAddress = result.inputAddresses[1];
|
|
648
859
|
save = true;
|
|
649
860
|
}
|
|
650
|
-
if (this.
|
|
651
|
-
this.
|
|
652
|
-
this.
|
|
861
|
+
if (this._state !== SpvFromBTCSwapState.FRONTED &&
|
|
862
|
+
this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
863
|
+
this._state = SpvFromBTCSwapState.BTC_TX_CONFIRMED;
|
|
653
864
|
save = true;
|
|
654
865
|
}
|
|
655
866
|
if (save)
|
|
@@ -659,10 +870,16 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
659
870
|
//////////////////////////////
|
|
660
871
|
//// Claim
|
|
661
872
|
/**
|
|
662
|
-
* Returns transactions
|
|
663
|
-
*
|
|
873
|
+
* Returns transactions for settling (claiming) the swap if the swap requires manual settlement, you can check so
|
|
874
|
+
* with isClaimable. After sending the transaction manually be sure to call the waitTillClaimed function to wait
|
|
875
|
+
* till the claim transaction is observed, processed by the SDK and state of the swap properly updated.
|
|
876
|
+
*
|
|
877
|
+
* @remarks
|
|
878
|
+
* Might also return transactions necessary to sync the bitcoin light client.
|
|
664
879
|
*
|
|
665
|
-
* @
|
|
880
|
+
* @param _signer Address of the signer to create the claim transactions for, can also be different to the recipient
|
|
881
|
+
*
|
|
882
|
+
* @throws {Error} If the swap is in invalid state (must be {@link SpvFromBTCSwapState.BTC_TX_CONFIRMED})
|
|
666
883
|
*/
|
|
667
884
|
async txsClaim(_signer) {
|
|
668
885
|
let address = undefined;
|
|
@@ -674,68 +891,82 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
674
891
|
address = _signer.getAddress();
|
|
675
892
|
}
|
|
676
893
|
else {
|
|
677
|
-
address = (await this.wrapper.
|
|
894
|
+
address = (await this.wrapper._chain.wrapSigner(_signer)).getAddress();
|
|
678
895
|
}
|
|
679
896
|
}
|
|
680
897
|
if (!this.isClaimable())
|
|
681
898
|
throw new Error("Must be in BTC_TX_CONFIRMED state!");
|
|
682
|
-
if (this.
|
|
899
|
+
if (this._data == null)
|
|
683
900
|
throw new Error("Expected swap to have withdrawal data filled!");
|
|
684
|
-
const vaultData = await this.wrapper.
|
|
901
|
+
const vaultData = await this.wrapper._contract.getVaultData(this.vaultOwner, this.vaultId);
|
|
685
902
|
if (vaultData == null)
|
|
686
903
|
throw new Error(`Vault data for ${this.vaultOwner}:${this.vaultId.toString(10)} not found (already closed???)!`);
|
|
687
|
-
const btcTx = await this.wrapper.
|
|
904
|
+
const btcTx = await this.wrapper._btcRpc.getTransaction(this._data.btcTx.txid);
|
|
688
905
|
if (btcTx == null)
|
|
689
|
-
throw new Error(`Bitcoin transaction ${this.
|
|
906
|
+
throw new Error(`Bitcoin transaction ${this._data.btcTx.txid} not found!`);
|
|
690
907
|
const txs = [btcTx];
|
|
691
908
|
//Trace back from current tx to the vaultData-specified UTXO
|
|
692
909
|
const vaultUtxo = vaultData.getUtxo();
|
|
693
910
|
while (txs[0].ins[0].txid + ":" + txs[0].ins[0].vout !== vaultUtxo) {
|
|
694
|
-
const btcTx = await this.wrapper.
|
|
911
|
+
const btcTx = await this.wrapper._btcRpc.getTransaction(txs[0].ins[0].txid);
|
|
695
912
|
if (btcTx == null)
|
|
696
|
-
throw new Error(`Prior withdrawal bitcoin transaction ${this.
|
|
913
|
+
throw new Error(`Prior withdrawal bitcoin transaction ${this._data.btcTx.txid} not found!`);
|
|
697
914
|
txs.unshift(btcTx);
|
|
698
915
|
}
|
|
699
916
|
//Parse transactions to withdrawal data
|
|
700
917
|
const withdrawalData = [];
|
|
701
918
|
for (let tx of txs) {
|
|
702
|
-
withdrawalData.push(await this.wrapper.
|
|
919
|
+
withdrawalData.push(await this.wrapper._contract.getWithdrawalData(tx));
|
|
703
920
|
}
|
|
704
|
-
return await this.wrapper.
|
|
921
|
+
return await this.wrapper._contract.txsClaim(address ?? this._getInitiator(), vaultData, withdrawalData.map(tx => { return { tx }; }), this.wrapper._synchronizer, true);
|
|
705
922
|
}
|
|
706
923
|
/**
|
|
707
|
-
*
|
|
924
|
+
* Settles the swap by claiming the funds on the destination chain if the swap requires manual settlement, you can
|
|
925
|
+
* check so with isClaimable.
|
|
926
|
+
*
|
|
927
|
+
* @remarks
|
|
928
|
+
* Might also sync the bitcoin light client during the process.
|
|
708
929
|
*
|
|
709
|
-
* @param _signer Signer to
|
|
710
|
-
* @param abortSignal Abort signal
|
|
930
|
+
* @param _signer Signer to use for signing the settlement transactions, can also be different to the recipient
|
|
931
|
+
* @param abortSignal Abort signal
|
|
932
|
+
* @param onBeforeTxSent Optional callback triggered before the claim transaction is broadcasted
|
|
933
|
+
*
|
|
934
|
+
* @throws {Error} If the swap is in invalid state (must be {@link SpvFromBTCSwapState.BTC_TX_CONFIRMED})
|
|
711
935
|
*/
|
|
712
|
-
async claim(_signer, abortSignal) {
|
|
713
|
-
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.
|
|
936
|
+
async claim(_signer, abortSignal, onBeforeTxSent) {
|
|
937
|
+
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer);
|
|
714
938
|
let txIds;
|
|
715
939
|
try {
|
|
716
|
-
|
|
940
|
+
let txCount = 0;
|
|
941
|
+
const txs = await this.txsClaim(signer);
|
|
942
|
+
txIds = await this.wrapper._chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
|
|
943
|
+
txCount++;
|
|
944
|
+
if (onBeforeTxSent != null && txCount === txs.length)
|
|
945
|
+
onBeforeTxSent(txId);
|
|
946
|
+
return Promise.resolve();
|
|
947
|
+
});
|
|
717
948
|
}
|
|
718
949
|
catch (e) {
|
|
719
|
-
if (this.
|
|
950
|
+
if (this._data == null)
|
|
720
951
|
throw e;
|
|
721
952
|
this.logger.info("claim(): Failed to claim ourselves, checking swap claim state...");
|
|
722
|
-
if (this.
|
|
953
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED) {
|
|
723
954
|
this.logger.info("claim(): Transaction state is CLAIMED, swap was successfully claimed by the watchtower");
|
|
724
|
-
return this.
|
|
955
|
+
return this._claimTxId;
|
|
725
956
|
}
|
|
726
|
-
const withdrawalState = await this.wrapper.
|
|
957
|
+
const withdrawalState = await this.wrapper._contract.getWithdrawalState(this._data, this._genesisSmartChainBlockHeight);
|
|
727
958
|
if (withdrawalState != null && withdrawalState.type === base_1.SpvWithdrawalStateType.CLAIMED) {
|
|
728
959
|
this.logger.info("claim(): Transaction status is CLAIMED, swap was successfully claimed by the watchtower");
|
|
729
|
-
this.
|
|
960
|
+
this._claimTxId = withdrawalState.txId;
|
|
730
961
|
await this._saveAndEmit(SpvFromBTCSwapState.CLAIMED);
|
|
731
962
|
return withdrawalState.txId;
|
|
732
963
|
}
|
|
733
964
|
throw e;
|
|
734
965
|
}
|
|
735
|
-
this.
|
|
736
|
-
if (this.
|
|
737
|
-
this.
|
|
738
|
-
this.
|
|
966
|
+
this._claimTxId = txIds[0];
|
|
967
|
+
if (this._state === SpvFromBTCSwapState.POSTED || this._state === SpvFromBTCSwapState.BROADCASTED ||
|
|
968
|
+
this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED || this._state === SpvFromBTCSwapState.FAILED ||
|
|
969
|
+
this._state === SpvFromBTCSwapState.FRONTED) {
|
|
739
970
|
await this._saveAndEmit(SpvFromBTCSwapState.CLAIMED);
|
|
740
971
|
}
|
|
741
972
|
return txIds[0];
|
|
@@ -745,10 +976,10 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
745
976
|
*
|
|
746
977
|
* @param abortSignal
|
|
747
978
|
* @param interval How often to check (in seconds), default to 5s
|
|
748
|
-
* @
|
|
979
|
+
* @internal
|
|
749
980
|
*/
|
|
750
981
|
async watchdogWaitTillResult(abortSignal, interval = 5) {
|
|
751
|
-
if (this.
|
|
982
|
+
if (this._data == null)
|
|
752
983
|
throw new Error("Cannot await the result before the btc transaction is sent!");
|
|
753
984
|
let status = { type: base_1.SpvWithdrawalStateType.NOT_FOUND };
|
|
754
985
|
while (status.type === base_1.SpvWithdrawalStateType.NOT_FOUND) {
|
|
@@ -756,7 +987,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
756
987
|
try {
|
|
757
988
|
//Be smart about checking withdrawal state
|
|
758
989
|
if (await this._shouldCheckWithdrawalState()) {
|
|
759
|
-
status = await this.wrapper.
|
|
990
|
+
status = await this.wrapper._contract.getWithdrawalState(this._data, this._genesisSmartChainBlockHeight) ?? { type: base_1.SpvWithdrawalStateType.NOT_FOUND };
|
|
760
991
|
}
|
|
761
992
|
}
|
|
762
993
|
catch (e) {
|
|
@@ -768,17 +999,33 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
768
999
|
return status;
|
|
769
1000
|
}
|
|
770
1001
|
/**
|
|
771
|
-
* Waits till the swap is successfully
|
|
1002
|
+
* Waits till the swap is successfully settled (claimed), should be called after sending the claim (settlement)
|
|
1003
|
+
* transactions manually to wait till the SDK processes the settlement and updates the swap state accordingly.
|
|
1004
|
+
*
|
|
1005
|
+
* @remarks
|
|
1006
|
+
* This is an alias for the {@link waitTillClaimedOrFronted} function and will also resolve if the swap has
|
|
1007
|
+
* been fronted (not necessarily claimed)
|
|
1008
|
+
*
|
|
1009
|
+
* @param maxWaitTimeSeconds – Maximum time in seconds to wait for the swap to be settled
|
|
1010
|
+
* @param abortSignal – AbortSignal
|
|
1011
|
+
*
|
|
1012
|
+
* @returns Whether the swap was claimed in time or not
|
|
1013
|
+
*/
|
|
1014
|
+
waitTillClaimed(maxWaitTimeSeconds, abortSignal) {
|
|
1015
|
+
return this.waitTillClaimedOrFronted(maxWaitTimeSeconds, abortSignal);
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Waits till the swap is successfully fronted or settled on the destination chain
|
|
1019
|
+
*
|
|
1020
|
+
* @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled (by default
|
|
1021
|
+
* it waits indefinitely)
|
|
1022
|
+
* @param abortSignal Abort signal
|
|
772
1023
|
*
|
|
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
1024
|
* @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
|
|
1025
|
+
* the user can claim manually through the {@link claim} function
|
|
779
1026
|
*/
|
|
780
1027
|
async waitTillClaimedOrFronted(maxWaitTimeSeconds, abortSignal) {
|
|
781
|
-
if (this.
|
|
1028
|
+
if (this._state === SpvFromBTCSwapState.CLAIMED || this._state === SpvFromBTCSwapState.FRONTED)
|
|
782
1029
|
return Promise.resolve(true);
|
|
783
1030
|
const abortController = (0, Utils_1.extendAbortController)(abortSignal);
|
|
784
1031
|
let timedOut = false;
|
|
@@ -822,32 +1069,34 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
822
1069
|
}
|
|
823
1070
|
this.logger.debug("waitTillClaimedOrFronted(): Resolved from watchdog");
|
|
824
1071
|
if (res.type === base_1.SpvWithdrawalStateType.FRONTED) {
|
|
825
|
-
if (this.
|
|
826
|
-
this.
|
|
827
|
-
this.
|
|
1072
|
+
if (this._state !== SpvFromBTCSwapState.FRONTED ||
|
|
1073
|
+
this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
1074
|
+
this._frontTxId = res.txId;
|
|
828
1075
|
await this._saveAndEmit(SpvFromBTCSwapState.FRONTED);
|
|
829
1076
|
}
|
|
830
1077
|
}
|
|
831
1078
|
if (res.type === base_1.SpvWithdrawalStateType.CLAIMED) {
|
|
832
|
-
if (this.
|
|
833
|
-
this.
|
|
1079
|
+
if (this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
1080
|
+
this._claimTxId = res.txId;
|
|
834
1081
|
await this._saveAndEmit(SpvFromBTCSwapState.FRONTED);
|
|
835
1082
|
}
|
|
836
1083
|
}
|
|
837
1084
|
if (res.type === base_1.SpvWithdrawalStateType.CLOSED) {
|
|
838
|
-
if (this.
|
|
1085
|
+
if (this._state !== SpvFromBTCSwapState.CLOSED)
|
|
839
1086
|
await this._saveAndEmit(SpvFromBTCSwapState.CLOSED);
|
|
840
1087
|
throw new Error("Swap failed with catastrophic error!");
|
|
841
1088
|
}
|
|
842
1089
|
return true;
|
|
843
1090
|
}
|
|
844
1091
|
/**
|
|
845
|
-
* Waits till the bitcoin transaction confirms and swap
|
|
1092
|
+
* Waits till the bitcoin transaction confirms and swap settled on the destination chain
|
|
846
1093
|
*
|
|
847
|
-
* @param abortSignal Abort signal
|
|
848
|
-
* @param checkIntervalSeconds How often to check the bitcoin transaction
|
|
849
1094
|
* @param updateCallback Callback called when txId is found, and also called with subsequent confirmations
|
|
850
|
-
* @
|
|
1095
|
+
* @param checkIntervalSeconds How often to check the bitcoin transaction (5 seconds by default)
|
|
1096
|
+
* @param abortSignal Abort signal
|
|
1097
|
+
*
|
|
1098
|
+
* @throws {Error} if in invalid state (must be {@link SpvFromBTCSwapState.POSTED} or
|
|
1099
|
+
* {@link SpvFromBTCSwapState.BROADCASTED} states)
|
|
851
1100
|
*/
|
|
852
1101
|
async waitTillExecuted(updateCallback, checkIntervalSeconds, abortSignal) {
|
|
853
1102
|
await this.waitForBitcoinTransaction(updateCallback, checkIntervalSeconds, abortSignal);
|
|
@@ -855,6 +1104,9 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
855
1104
|
}
|
|
856
1105
|
//////////////////////////////
|
|
857
1106
|
//// Storage
|
|
1107
|
+
/**
|
|
1108
|
+
* @inheritDoc
|
|
1109
|
+
*/
|
|
858
1110
|
serialize() {
|
|
859
1111
|
return {
|
|
860
1112
|
...super.serialize(),
|
|
@@ -881,52 +1133,56 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
881
1133
|
callerFeeShare: this.callerFeeShare.toString(10),
|
|
882
1134
|
frontingFeeShare: this.frontingFeeShare.toString(10),
|
|
883
1135
|
executionFeeShare: this.executionFeeShare.toString(10),
|
|
884
|
-
genesisSmartChainBlockHeight: this.
|
|
1136
|
+
genesisSmartChainBlockHeight: this._genesisSmartChainBlockHeight,
|
|
885
1137
|
gasPricingInfo: (0, PriceInfoType_1.serializePriceInfoType)(this.gasPricingInfo),
|
|
886
|
-
senderAddress: this.
|
|
887
|
-
claimTxId: this.
|
|
888
|
-
frontTxId: this.
|
|
889
|
-
data: this.
|
|
1138
|
+
senderAddress: this._senderAddress,
|
|
1139
|
+
claimTxId: this._claimTxId,
|
|
1140
|
+
frontTxId: this._frontTxId,
|
|
1141
|
+
data: this._data?.serialize()
|
|
890
1142
|
};
|
|
891
1143
|
}
|
|
892
1144
|
//////////////////////////////
|
|
893
1145
|
//// Swap ticks & sync
|
|
894
1146
|
/**
|
|
895
|
-
*
|
|
1147
|
+
* Used to set the txId of the bitcoin payment from the on-chain events listener
|
|
896
1148
|
*
|
|
897
1149
|
* @param txId
|
|
1150
|
+
* @internal
|
|
898
1151
|
*/
|
|
899
1152
|
async _setBitcoinTxId(txId) {
|
|
900
|
-
if (this.
|
|
1153
|
+
if (this._data == null)
|
|
901
1154
|
return;
|
|
902
|
-
if (txId != this.
|
|
1155
|
+
if (txId != this._data.btcTx.txid)
|
|
903
1156
|
return;
|
|
904
|
-
if (this.
|
|
1157
|
+
if (this._senderAddress != null)
|
|
905
1158
|
return;
|
|
906
|
-
const btcTx = await this.wrapper.
|
|
1159
|
+
const btcTx = await this.wrapper._btcRpc.getTransaction(txId);
|
|
907
1160
|
if (btcTx == null || btcTx.inputAddresses == null)
|
|
908
1161
|
return;
|
|
909
|
-
this.
|
|
1162
|
+
this._senderAddress = btcTx.inputAddresses[1];
|
|
910
1163
|
}
|
|
1164
|
+
/**
|
|
1165
|
+
* @internal
|
|
1166
|
+
*/
|
|
911
1167
|
async _syncStateFromBitcoin(save) {
|
|
912
|
-
if (this.
|
|
1168
|
+
if (this._data?.btcTx == null)
|
|
913
1169
|
return false;
|
|
914
1170
|
//Check if bitcoin payment was confirmed
|
|
915
1171
|
const res = await this.getBitcoinPayment();
|
|
916
1172
|
if (res == null) {
|
|
917
1173
|
//Check inputs double-spent
|
|
918
|
-
for (let input of this.
|
|
919
|
-
if (await this.wrapper.
|
|
920
|
-
if (this.
|
|
921
|
-
this.
|
|
922
|
-
this.
|
|
923
|
-
this.
|
|
1174
|
+
for (let input of this._data.btcTx.ins) {
|
|
1175
|
+
if (await this.wrapper._btcRpc.isSpent(input.txid + ":" + input.vout, true)) {
|
|
1176
|
+
if (this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1177
|
+
this._state === SpvFromBTCSwapState.POSTED ||
|
|
1178
|
+
this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
1179
|
+
this._state === SpvFromBTCSwapState.DECLINED) {
|
|
924
1180
|
//One of the inputs was double-spent
|
|
925
|
-
this.
|
|
1181
|
+
this._state = SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
926
1182
|
}
|
|
927
1183
|
else {
|
|
928
1184
|
//One of the inputs was double-spent
|
|
929
|
-
this.
|
|
1185
|
+
this._state = SpvFromBTCSwapState.FAILED;
|
|
930
1186
|
}
|
|
931
1187
|
if (save)
|
|
932
1188
|
await this._saveAndEmit();
|
|
@@ -936,23 +1192,23 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
936
1192
|
}
|
|
937
1193
|
else {
|
|
938
1194
|
let needsSave = false;
|
|
939
|
-
if (res.inputAddresses != null && this.
|
|
940
|
-
this.
|
|
1195
|
+
if (res.inputAddresses != null && this._senderAddress == null) {
|
|
1196
|
+
this._senderAddress = res.inputAddresses[1];
|
|
941
1197
|
needsSave = true;
|
|
942
1198
|
}
|
|
943
1199
|
if (res.confirmations >= this.vaultRequiredConfirmations) {
|
|
944
|
-
if (this.
|
|
945
|
-
this.
|
|
946
|
-
this.
|
|
947
|
-
this.
|
|
1200
|
+
if (this._state !== SpvFromBTCSwapState.BTC_TX_CONFIRMED &&
|
|
1201
|
+
this._state !== SpvFromBTCSwapState.FRONTED &&
|
|
1202
|
+
this._state !== SpvFromBTCSwapState.CLAIMED) {
|
|
1203
|
+
this._state = SpvFromBTCSwapState.BTC_TX_CONFIRMED;
|
|
948
1204
|
needsSave = true;
|
|
949
1205
|
}
|
|
950
1206
|
}
|
|
951
|
-
else if (this.
|
|
952
|
-
this.
|
|
953
|
-
this.
|
|
954
|
-
this.
|
|
955
|
-
this.
|
|
1207
|
+
else if (this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
1208
|
+
this._state === SpvFromBTCSwapState.POSTED ||
|
|
1209
|
+
this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1210
|
+
this._state === SpvFromBTCSwapState.DECLINED) {
|
|
1211
|
+
this._state = SpvFromBTCSwapState.BROADCASTED;
|
|
956
1212
|
needsSave = true;
|
|
957
1213
|
}
|
|
958
1214
|
if (needsSave && save)
|
|
@@ -964,85 +1220,91 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
964
1220
|
/**
|
|
965
1221
|
* Checks the swap's state on-chain and compares it to its internal state, updates/changes it according to on-chain
|
|
966
1222
|
* data
|
|
967
|
-
*
|
|
968
|
-
* @private
|
|
969
1223
|
*/
|
|
970
1224
|
async syncStateFromChain() {
|
|
971
1225
|
let changed = false;
|
|
972
|
-
if (this.
|
|
973
|
-
this.
|
|
974
|
-
this.
|
|
975
|
-
this.
|
|
976
|
-
this.
|
|
977
|
-
this.
|
|
1226
|
+
if (this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1227
|
+
this._state === SpvFromBTCSwapState.POSTED ||
|
|
1228
|
+
this._state === SpvFromBTCSwapState.BROADCASTED ||
|
|
1229
|
+
this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
1230
|
+
this._state === SpvFromBTCSwapState.DECLINED ||
|
|
1231
|
+
this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
978
1232
|
//Check BTC transaction
|
|
979
1233
|
if (await this._syncStateFromBitcoin(false))
|
|
980
1234
|
changed ||= true;
|
|
981
1235
|
}
|
|
982
|
-
if (this.
|
|
1236
|
+
if (this._state === SpvFromBTCSwapState.BROADCASTED || this._state === SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
983
1237
|
if (await this._shouldCheckWithdrawalState()) {
|
|
984
|
-
const status = await this.wrapper.
|
|
985
|
-
this.logger.debug("syncStateFromChain(): status of " + this.
|
|
1238
|
+
const status = await this.wrapper._contract.getWithdrawalState(this._data, this._genesisSmartChainBlockHeight);
|
|
1239
|
+
this.logger.debug("syncStateFromChain(): status of " + this._data.btcTx.txid, status);
|
|
986
1240
|
switch (status?.type) {
|
|
987
1241
|
case base_1.SpvWithdrawalStateType.FRONTED:
|
|
988
|
-
this.
|
|
989
|
-
this.
|
|
1242
|
+
this._frontTxId = status.txId;
|
|
1243
|
+
this._state = SpvFromBTCSwapState.FRONTED;
|
|
990
1244
|
changed ||= true;
|
|
991
1245
|
break;
|
|
992
1246
|
case base_1.SpvWithdrawalStateType.CLAIMED:
|
|
993
|
-
this.
|
|
994
|
-
this.
|
|
1247
|
+
this._claimTxId = status.txId;
|
|
1248
|
+
this._state = SpvFromBTCSwapState.CLAIMED;
|
|
995
1249
|
changed ||= true;
|
|
996
1250
|
break;
|
|
997
1251
|
case base_1.SpvWithdrawalStateType.CLOSED:
|
|
998
|
-
this.
|
|
1252
|
+
this._state = SpvFromBTCSwapState.CLOSED;
|
|
999
1253
|
changed ||= true;
|
|
1000
1254
|
break;
|
|
1001
1255
|
}
|
|
1002
1256
|
}
|
|
1003
1257
|
}
|
|
1004
|
-
if (this.
|
|
1005
|
-
this.
|
|
1006
|
-
this.
|
|
1258
|
+
if (this._state === SpvFromBTCSwapState.CREATED ||
|
|
1259
|
+
this._state === SpvFromBTCSwapState.SIGNED ||
|
|
1260
|
+
this._state === SpvFromBTCSwapState.POSTED) {
|
|
1007
1261
|
if (this.expiry < Date.now()) {
|
|
1008
|
-
if (this.
|
|
1009
|
-
this.
|
|
1262
|
+
if (this._state === SpvFromBTCSwapState.CREATED) {
|
|
1263
|
+
this._state = SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
1010
1264
|
}
|
|
1011
1265
|
else {
|
|
1012
|
-
this.
|
|
1266
|
+
this._state = SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
1013
1267
|
}
|
|
1014
1268
|
changed ||= true;
|
|
1015
1269
|
}
|
|
1016
1270
|
}
|
|
1017
1271
|
return changed;
|
|
1018
1272
|
}
|
|
1273
|
+
/**
|
|
1274
|
+
* @inheritDoc
|
|
1275
|
+
* @internal
|
|
1276
|
+
*/
|
|
1019
1277
|
async _sync(save) {
|
|
1020
1278
|
const changed = await this.syncStateFromChain();
|
|
1021
1279
|
if (changed && save)
|
|
1022
1280
|
await this._saveAndEmit();
|
|
1023
1281
|
return changed;
|
|
1024
1282
|
}
|
|
1283
|
+
/**
|
|
1284
|
+
* @inheritDoc
|
|
1285
|
+
* @internal
|
|
1286
|
+
*/
|
|
1025
1287
|
async _tick(save) {
|
|
1026
|
-
if (this.
|
|
1027
|
-
this.
|
|
1288
|
+
if (this._state === SpvFromBTCSwapState.CREATED ||
|
|
1289
|
+
this._state === SpvFromBTCSwapState.SIGNED) {
|
|
1028
1290
|
if (this.getQuoteExpiry() < Date.now()) {
|
|
1029
|
-
this.
|
|
1291
|
+
this._state = SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
1030
1292
|
if (save)
|
|
1031
1293
|
await this._saveAndEmit();
|
|
1032
1294
|
return true;
|
|
1033
1295
|
}
|
|
1034
1296
|
}
|
|
1035
|
-
if (this.
|
|
1297
|
+
if (this._state === SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED && !this.initiated) {
|
|
1036
1298
|
if (this.expiry < Date.now()) {
|
|
1037
|
-
this.
|
|
1299
|
+
this._state = SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
1038
1300
|
if (save)
|
|
1039
1301
|
await this._saveAndEmit();
|
|
1040
1302
|
return true;
|
|
1041
1303
|
}
|
|
1042
1304
|
}
|
|
1043
1305
|
if (Math.floor(Date.now() / 1000) % 120 === 0) {
|
|
1044
|
-
if (this.
|
|
1045
|
-
this.
|
|
1306
|
+
if (this._state === SpvFromBTCSwapState.POSTED ||
|
|
1307
|
+
this._state === SpvFromBTCSwapState.BROADCASTED) {
|
|
1046
1308
|
try {
|
|
1047
1309
|
//Check if bitcoin payment was confirmed
|
|
1048
1310
|
return await this._syncStateFromBitcoin(save);
|
|
@@ -1054,22 +1316,27 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
1054
1316
|
}
|
|
1055
1317
|
return false;
|
|
1056
1318
|
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Checks whether an on-chain withdrawal state should be fetched for this specific swap
|
|
1321
|
+
*
|
|
1322
|
+
* @internal
|
|
1323
|
+
*/
|
|
1057
1324
|
async _shouldCheckWithdrawalState(frontingAddress, vaultDataUtxo) {
|
|
1058
1325
|
if (frontingAddress === undefined)
|
|
1059
|
-
frontingAddress = await this.wrapper.
|
|
1326
|
+
frontingAddress = await this.wrapper._contract.getFronterAddress(this.vaultOwner, this.vaultId, this._data);
|
|
1060
1327
|
if (vaultDataUtxo === undefined)
|
|
1061
|
-
vaultDataUtxo = await this.wrapper.
|
|
1328
|
+
vaultDataUtxo = await this.wrapper._contract.getVaultLatestUtxo(this.vaultOwner, this.vaultId);
|
|
1062
1329
|
if (frontingAddress != null)
|
|
1063
1330
|
return true; //In case the swap is fronted there will for sure be a fronted event
|
|
1064
1331
|
if (vaultDataUtxo == null)
|
|
1065
1332
|
return true; //Vault UTXO is null (the vault closed)
|
|
1066
1333
|
const [txId, _] = vaultDataUtxo.split(":");
|
|
1067
1334
|
//Don't check both txns if their txId is equal
|
|
1068
|
-
if (this.
|
|
1335
|
+
if (this._data.btcTx.txid === txId)
|
|
1069
1336
|
return true;
|
|
1070
1337
|
const [btcTx, latestVaultTx] = await Promise.all([
|
|
1071
|
-
this.wrapper.
|
|
1072
|
-
this.wrapper.
|
|
1338
|
+
this.wrapper._btcRpc.getTransaction(this._data.btcTx.txid),
|
|
1339
|
+
this.wrapper._btcRpc.getTransaction(txId)
|
|
1073
1340
|
]);
|
|
1074
1341
|
if (latestVaultTx == null || latestVaultTx.blockheight == null) {
|
|
1075
1342
|
//Something must've gone horribly wrong, the latest vault utxo tx of the vault either
|
|
@@ -1089,7 +1356,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
1089
1356
|
}
|
|
1090
1357
|
else {
|
|
1091
1358
|
//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.
|
|
1359
|
+
this.logger.debug(`_shouldCheckWithdrawalState(): Skipped checking withdrawal state, btc tx probably replaced or evicted: ${this._data.btcTx.txid} and not fronted`);
|
|
1093
1360
|
return false;
|
|
1094
1361
|
}
|
|
1095
1362
|
return true;
|