@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
|
@@ -13,6 +13,13 @@ const RequestError_1 = require("../../errors/RequestError");
|
|
|
13
13
|
const IntermediaryError_1 = require("../../errors/IntermediaryError");
|
|
14
14
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
15
15
|
const RetryUtils_1 = require("../../utils/RetryUtils");
|
|
16
|
+
/**
|
|
17
|
+
* New spv vault (UTXO-controlled vault) based swaps for Bitcoin -> Smart chain swaps not requiring
|
|
18
|
+
* any initiation on the destination chain, and with the added possibility for the user to receive
|
|
19
|
+
* a native token on the destination chain as part of the swap (a "gas drop" feature).
|
|
20
|
+
*
|
|
21
|
+
* @category Swaps/Bitcoin → Smart chain
|
|
22
|
+
*/
|
|
16
23
|
class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
17
24
|
/**
|
|
18
25
|
* @param chainIdentifier
|
|
@@ -30,97 +37,107 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
30
37
|
* @param events Instance to use for emitting events
|
|
31
38
|
*/
|
|
32
39
|
constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, spvWithdrawalDataDeserializer, btcRelay, synchronizer, btcRpc, options, events) {
|
|
33
|
-
if (options == null)
|
|
34
|
-
options = {};
|
|
35
|
-
options.bitcoinNetwork ??= utils_1.TEST_NETWORK;
|
|
36
|
-
options.maxConfirmations ??= 6;
|
|
37
|
-
options.bitcoinBlocktime ??= 10 * 60;
|
|
38
|
-
options.maxTransactionsDelta ??= 3;
|
|
39
|
-
options.maxRawAmountAdjustmentDifferencePPM ??= 100;
|
|
40
|
-
options.maxBtcFeeOffset ??= 5;
|
|
41
|
-
options.maxBtcFeeMultiplier ??= 1.5;
|
|
42
40
|
super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, {
|
|
43
|
-
bitcoinNetwork: options
|
|
44
|
-
maxConfirmations: options
|
|
45
|
-
bitcoinBlocktime: options
|
|
46
|
-
maxTransactionsDelta: options
|
|
47
|
-
maxRawAmountAdjustmentDifferencePPM: options
|
|
48
|
-
maxBtcFeeOffset: options
|
|
49
|
-
maxBtcFeeMultiplier: options
|
|
41
|
+
bitcoinNetwork: options?.bitcoinNetwork ?? utils_1.TEST_NETWORK,
|
|
42
|
+
maxConfirmations: options?.maxConfirmations ?? 6,
|
|
43
|
+
bitcoinBlocktime: options?.bitcoinBlocktime ?? 10 * 60,
|
|
44
|
+
maxTransactionsDelta: options?.maxTransactionsDelta ?? 3,
|
|
45
|
+
maxRawAmountAdjustmentDifferencePPM: options?.maxRawAmountAdjustmentDifferencePPM ?? 100,
|
|
46
|
+
maxBtcFeeOffset: options?.maxBtcFeeOffset ?? 10,
|
|
47
|
+
maxBtcFeeMultiplier: options?.maxBtcFeeMultiplier ?? 1.5
|
|
50
48
|
}, events);
|
|
51
|
-
this.claimableSwapStates = [SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED];
|
|
52
49
|
this.TYPE = SwapType_1.SwapType.SPV_VAULT_FROM_BTC;
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
this._claimableSwapStates = [SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED];
|
|
54
|
+
/**
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
this._swapDeserializer = SpvFromBTCSwap_1.SpvFromBTCSwap;
|
|
58
|
+
/**
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
this.tickSwapState = [
|
|
55
62
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED,
|
|
63
|
+
SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
|
|
56
64
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED,
|
|
57
65
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED,
|
|
58
|
-
SpvFromBTCSwap_1.SpvFromBTCSwapState.
|
|
59
|
-
SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED,
|
|
60
|
-
SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED,
|
|
61
|
-
SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED
|
|
66
|
+
SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED
|
|
62
67
|
];
|
|
63
|
-
|
|
68
|
+
/**
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
this._pendingSwapStates = [
|
|
64
72
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED,
|
|
65
|
-
SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
|
|
66
73
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED,
|
|
67
74
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED,
|
|
68
|
-
SpvFromBTCSwap_1.SpvFromBTCSwapState.
|
|
75
|
+
SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED,
|
|
76
|
+
SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED,
|
|
77
|
+
SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED,
|
|
78
|
+
SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED
|
|
69
79
|
];
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
80
|
+
this._spvWithdrawalDataDeserializer = spvWithdrawalDataDeserializer;
|
|
81
|
+
this._contract = contract;
|
|
72
82
|
this.btcRelay = btcRelay;
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
83
|
+
this._synchronizer = synchronizer;
|
|
84
|
+
this._btcRpc = btcRpc;
|
|
75
85
|
}
|
|
76
86
|
async processEventFront(event, swap) {
|
|
77
|
-
if (swap.
|
|
78
|
-
swap.
|
|
79
|
-
swap.
|
|
87
|
+
if (swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
|
|
88
|
+
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
|
|
89
|
+
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
90
|
+
swap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
|
|
91
|
+
swap._frontTxId = event.meta?.txId;
|
|
80
92
|
await swap._setBitcoinTxId(event.btcTxId).catch(e => {
|
|
81
93
|
this.logger.warn("processEventFront(): Failed to set bitcoin txId: ", e);
|
|
82
94
|
});
|
|
83
|
-
swap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
|
|
84
95
|
return true;
|
|
85
96
|
}
|
|
86
97
|
return false;
|
|
87
98
|
}
|
|
88
99
|
async processEventClaim(event, swap) {
|
|
89
|
-
if (swap.
|
|
90
|
-
swap.
|
|
91
|
-
swap.
|
|
100
|
+
if (swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
|
|
101
|
+
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
|
|
102
|
+
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED ||
|
|
103
|
+
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
104
|
+
swap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
|
|
105
|
+
swap._claimTxId = event.meta?.txId;
|
|
92
106
|
await swap._setBitcoinTxId(event.btcTxId).catch(e => {
|
|
93
107
|
this.logger.warn("processEventClaim(): Failed to set bitcoin txId: ", e);
|
|
94
108
|
});
|
|
95
|
-
swap.state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
|
|
96
109
|
return true;
|
|
97
110
|
}
|
|
98
111
|
return false;
|
|
99
112
|
}
|
|
100
113
|
processEventClose(event, swap) {
|
|
101
|
-
if (swap.
|
|
102
|
-
swap.
|
|
103
|
-
swap.
|
|
104
|
-
swap.
|
|
114
|
+
if (swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
|
|
115
|
+
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
|
|
116
|
+
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
117
|
+
swap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLOSED;
|
|
105
118
|
return Promise.resolve(true);
|
|
106
119
|
}
|
|
107
120
|
return Promise.resolve(false);
|
|
108
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* @inheritDoc
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
109
126
|
async processEvent(event, swap) {
|
|
110
127
|
if (swap == null)
|
|
111
128
|
return;
|
|
112
129
|
let swapChanged = false;
|
|
113
130
|
if (event instanceof base_1.SpvVaultFrontEvent) {
|
|
114
131
|
swapChanged = await this.processEventFront(event, swap);
|
|
115
|
-
if (event.meta?.txId != null && swap.
|
|
116
|
-
swap.
|
|
132
|
+
if (event.meta?.txId != null && swap._frontTxId !== event.meta.txId) {
|
|
133
|
+
swap._frontTxId = event.meta.txId;
|
|
117
134
|
swapChanged ||= true;
|
|
118
135
|
}
|
|
119
136
|
}
|
|
120
137
|
if (event instanceof base_1.SpvVaultClaimEvent) {
|
|
121
138
|
swapChanged = await this.processEventClaim(event, swap);
|
|
122
|
-
if (event.meta?.txId != null && swap.
|
|
123
|
-
swap.
|
|
139
|
+
if (event.meta?.txId != null && swap._claimTxId !== event.meta.txId) {
|
|
140
|
+
swap._claimTxId = event.meta.txId;
|
|
124
141
|
swapChanged ||= true;
|
|
125
142
|
}
|
|
126
143
|
}
|
|
@@ -140,7 +157,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
140
157
|
*/
|
|
141
158
|
async preFetchFinalizedBlockHeight(abortController) {
|
|
142
159
|
try {
|
|
143
|
-
const block = await this.
|
|
160
|
+
const block = await this._chain.getFinalizedBlock();
|
|
144
161
|
return block.height;
|
|
145
162
|
}
|
|
146
163
|
catch (e) {
|
|
@@ -167,33 +184,33 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
167
184
|
const [feePerBlock, btcRelayData, currentBtcBlock, claimFeeRate, nativeTokenPrice] = await Promise.all([
|
|
168
185
|
this.btcRelay.getFeePerBlock(),
|
|
169
186
|
this.btcRelay.getTipData(),
|
|
170
|
-
this.
|
|
171
|
-
this.
|
|
172
|
-
nativeTokenPricePrefetch ?? (amountData.token === this.
|
|
187
|
+
this._btcRpc.getTipHeight(),
|
|
188
|
+
this._contract.getClaimFee(this._chain.randomAddress()),
|
|
189
|
+
nativeTokenPricePrefetch ?? (amountData.token === this._chain.getNativeCurrencyAddress() ?
|
|
173
190
|
pricePrefetch :
|
|
174
|
-
this.
|
|
191
|
+
this._prices.preFetchPrice(this.chainIdentifier, this._chain.getNativeCurrencyAddress(), abortController.signal))
|
|
175
192
|
]);
|
|
176
193
|
if (btcRelayData == null)
|
|
177
194
|
throw new Error("Btc relay doesn't seem to be initialized!");
|
|
178
195
|
const currentBtcRelayBlock = btcRelayData.blockheight;
|
|
179
|
-
const blockDelta = Math.max(currentBtcBlock - currentBtcRelayBlock + this.
|
|
196
|
+
const blockDelta = Math.max(currentBtcBlock - currentBtcRelayBlock + this._options.maxConfirmations, 0);
|
|
180
197
|
const totalFeeInNativeToken = ((BigInt(blockDelta) * feePerBlock) +
|
|
181
|
-
(claimFeeRate * BigInt(this.
|
|
198
|
+
(claimFeeRate * BigInt(this._options.maxTransactionsDelta))) * BigInt(Math.floor(options.feeSafetyFactor * 1000000)) / 1000000n;
|
|
182
199
|
let payoutAmount;
|
|
183
200
|
if (amountData.exactIn) {
|
|
184
201
|
//Convert input amount in BTC to
|
|
185
|
-
const amountInNativeToken = await this.
|
|
202
|
+
const amountInNativeToken = await this._prices.getFromBtcSwapAmount(this.chainIdentifier, amountData.amount, this._chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
|
|
186
203
|
payoutAmount = amountInNativeToken - totalFeeInNativeToken;
|
|
187
204
|
}
|
|
188
205
|
else {
|
|
189
|
-
if (amountData.token === this.
|
|
206
|
+
if (amountData.token === this._chain.getNativeCurrencyAddress()) {
|
|
190
207
|
//Both amounts in same currency
|
|
191
208
|
payoutAmount = amountData.amount;
|
|
192
209
|
}
|
|
193
210
|
else {
|
|
194
211
|
//Need to convert both to native currency
|
|
195
|
-
const btcAmount = await this.
|
|
196
|
-
payoutAmount = await this.
|
|
212
|
+
const btcAmount = await this._prices.getToBtcSwapAmount(this.chainIdentifier, amountData.amount, amountData.token, abortController.signal, await pricePrefetch);
|
|
213
|
+
payoutAmount = await this._prices.getFromBtcSwapAmount(this.chainIdentifier, btcAmount, this._chain.getNativeCurrencyAddress(), abortController.signal, nativeTokenPrice);
|
|
197
214
|
}
|
|
198
215
|
}
|
|
199
216
|
this.logger.debug("preFetchCallerFeeShare(): Caller fee in native token: " + totalFeeInNativeToken.toString(10) + " total payout in native token: " + payoutAmount.toString(10));
|
|
@@ -225,16 +242,16 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
225
242
|
const btcFeeRate = await (0, Utils_1.throwIfUndefined)(bitcoinFeeRatePromise, "Bitcoin fee rate promise failed!");
|
|
226
243
|
abortSignal.throwIfAborted();
|
|
227
244
|
if (btcFeeRate != null && resp.btcFeeRate > btcFeeRate)
|
|
228
|
-
throw new IntermediaryError_1.IntermediaryError(
|
|
245
|
+
throw new IntermediaryError_1.IntermediaryError(`Required bitcoin fee rate returned from the LP is too high! Maximum accepted: ${btcFeeRate} sats/vB, required by LP: ${resp.btcFeeRate} sats/vB`);
|
|
229
246
|
//Vault related
|
|
230
247
|
let vaultScript;
|
|
231
248
|
let vaultAddressType;
|
|
232
249
|
let btcAddressScript;
|
|
233
250
|
//Ensure valid btc addresses returned
|
|
234
251
|
try {
|
|
235
|
-
vaultScript = (0, BitcoinUtils_1.toOutputScript)(this.
|
|
252
|
+
vaultScript = (0, BitcoinUtils_1.toOutputScript)(this._options.bitcoinNetwork, resp.vaultBtcAddress);
|
|
236
253
|
vaultAddressType = (0, BitcoinUtils_1.toCoinselectAddressType)(vaultScript);
|
|
237
|
-
btcAddressScript = (0, BitcoinUtils_1.toOutputScript)(this.
|
|
254
|
+
btcAddressScript = (0, BitcoinUtils_1.toOutputScript)(this._options.bitcoinNetwork, resp.btcAddress);
|
|
238
255
|
}
|
|
239
256
|
catch (e) {
|
|
240
257
|
throw new IntermediaryError_1.IntermediaryError("Invalid btc address data returned", e);
|
|
@@ -271,7 +288,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
271
288
|
//Fetch vault data
|
|
272
289
|
let vault;
|
|
273
290
|
try {
|
|
274
|
-
vault = await this.
|
|
291
|
+
vault = await this._contract.getVaultData(resp.address, resp.vaultId);
|
|
275
292
|
}
|
|
276
293
|
catch (e) {
|
|
277
294
|
this.logger.error("Error getting spv vault (owner: " + resp.address + " vaultId: " + resp.vaultId.toString(10) + "): ", e);
|
|
@@ -282,7 +299,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
282
299
|
if (vault == null || !vault.isOpened())
|
|
283
300
|
throw new IntermediaryError_1.IntermediaryError("Returned spv swap vault is not opened!");
|
|
284
301
|
//Make sure the vault doesn't require insane amount of confirmations
|
|
285
|
-
if (vault.getConfirmations() > this.
|
|
302
|
+
if (vault.getConfirmations() > this._options.maxConfirmations)
|
|
286
303
|
throw new IntermediaryError_1.IntermediaryError("SPV swap vault needs too many confirmations: " + vault.getConfirmations());
|
|
287
304
|
const tokenData = vault.getTokenData();
|
|
288
305
|
//Amounts - make sure the amounts match
|
|
@@ -294,7 +311,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
294
311
|
//Check the difference between amount adjusted due to scaling to raw amount
|
|
295
312
|
const adjustedAmount = amountData.amount / tokenData[0].multiplier * tokenData[0].multiplier;
|
|
296
313
|
const adjustmentPPM = (amountData.amount - adjustedAmount) * 1000000n / amountData.amount;
|
|
297
|
-
if (adjustmentPPM > this.
|
|
314
|
+
if (adjustmentPPM > this._options.maxRawAmountAdjustmentDifferencePPM)
|
|
298
315
|
throw new IntermediaryError_1.IntermediaryError("Invalid amount0 multiplier used, rawAmount diff too high");
|
|
299
316
|
if (resp.total !== adjustedAmount)
|
|
300
317
|
throw new IntermediaryError_1.IntermediaryError("Invalid total returned");
|
|
@@ -307,7 +324,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
307
324
|
//Check the difference between amount adjusted due to scaling to raw amount
|
|
308
325
|
const adjustedGasAmount = options.gasAmount / tokenData[0].multiplier * tokenData[0].multiplier;
|
|
309
326
|
const adjustmentPPM = (options.gasAmount - adjustedGasAmount) * 1000000n / options.gasAmount;
|
|
310
|
-
if (adjustmentPPM > this.
|
|
327
|
+
if (adjustmentPPM > this._options.maxRawAmountAdjustmentDifferencePPM)
|
|
311
328
|
throw new IntermediaryError_1.IntermediaryError("Invalid amount1 multiplier used, rawAmount diff too high");
|
|
312
329
|
if (resp.totalGas !== adjustedGasAmount)
|
|
313
330
|
throw new IntermediaryError_1.IntermediaryError("Invalid gas total returned");
|
|
@@ -316,7 +333,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
316
333
|
})(),
|
|
317
334
|
(async () => {
|
|
318
335
|
//Require the vault UTXO to have at least 1 confirmation
|
|
319
|
-
let btcTx = await this.
|
|
336
|
+
let btcTx = await this._btcRpc.getTransaction(txId);
|
|
320
337
|
if (btcTx == null)
|
|
321
338
|
throw new IntermediaryError_1.IntermediaryError("Invalid UTXO, doesn't exist (txId)");
|
|
322
339
|
abortController.signal.throwIfAborted();
|
|
@@ -330,7 +347,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
330
347
|
})(),
|
|
331
348
|
(async () => {
|
|
332
349
|
//Require vault UTXO is unspent
|
|
333
|
-
if (await this.
|
|
350
|
+
if (await this._btcRpc.isSpent(utxo))
|
|
334
351
|
throw new IntermediaryError_1.IntermediaryError("Returned spv vault UTXO is already spent", null, true);
|
|
335
352
|
abortController.signal.throwIfAborted();
|
|
336
353
|
})()
|
|
@@ -345,18 +362,18 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
345
362
|
const [txId, voutStr] = utxo.split(":");
|
|
346
363
|
//Such that 1st tx isn't fetched twice
|
|
347
364
|
if (btcTx.txid !== txId) {
|
|
348
|
-
const _btcTx = await this.
|
|
365
|
+
const _btcTx = await this._btcRpc.getTransaction(txId);
|
|
349
366
|
if (_btcTx == null)
|
|
350
367
|
throw new IntermediaryError_1.IntermediaryError("Invalid ancestor transaction (not found)");
|
|
351
368
|
btcTx = _btcTx;
|
|
352
369
|
}
|
|
353
|
-
const withdrawalData = await this.
|
|
370
|
+
const withdrawalData = await this._contract.getWithdrawalData(btcTx);
|
|
354
371
|
abortSignal.throwIfAborted();
|
|
355
372
|
pendingWithdrawals.unshift(withdrawalData);
|
|
356
373
|
utxo = pendingWithdrawals[0].getSpentVaultUtxo();
|
|
357
374
|
this.logger.debug("verifyReturnedData(): Vault UTXO: " + vault.getUtxo() + " current utxo: " + utxo);
|
|
358
|
-
if (pendingWithdrawals.length >= this.
|
|
359
|
-
throw new IntermediaryError_1.IntermediaryError("BTC <> SC state difference too deep, maximum: " + this.
|
|
375
|
+
if (pendingWithdrawals.length >= this._options.maxTransactionsDelta)
|
|
376
|
+
throw new IntermediaryError_1.IntermediaryError("BTC <> SC state difference too deep, maximum: " + this._options.maxTransactionsDelta);
|
|
360
377
|
}
|
|
361
378
|
//Verify that the vault has enough balance after processing all pending withdrawals
|
|
362
379
|
let vaultBalances;
|
|
@@ -376,7 +393,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
376
393
|
//Also verify that all the withdrawal txns are valid, this is an extra sanity check
|
|
377
394
|
try {
|
|
378
395
|
for (let withdrawal of pendingWithdrawals) {
|
|
379
|
-
await this.
|
|
396
|
+
await this._contract.checkWithdrawalTx(withdrawal);
|
|
380
397
|
}
|
|
381
398
|
}
|
|
382
399
|
catch (e) {
|
|
@@ -390,16 +407,18 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
390
407
|
};
|
|
391
408
|
}
|
|
392
409
|
/**
|
|
393
|
-
* Returns a newly created swap
|
|
410
|
+
* Returns a newly created Bitcoin -> Smart chain swap using the SPV vault (UTXO-controlled vault) swap protocol,
|
|
411
|
+
* with the passed amount. Also allows specifying additional "gas drop" native token that the receipient receives
|
|
412
|
+
* on the destination chain in the `options` argument.
|
|
394
413
|
*
|
|
395
|
-
* @param
|
|
396
|
-
* @param amountData
|
|
397
|
-
* @param lps
|
|
398
|
-
* @param options
|
|
399
|
-
* @param additionalParams
|
|
400
|
-
* @param abortSignal
|
|
414
|
+
* @param recipient Recipient address on the destination smart chain
|
|
415
|
+
* @param amountData Amount, token and exact input/output data for to swap
|
|
416
|
+
* @param lps An array of intermediaries (LPs) to get the quotes from
|
|
417
|
+
* @param options Optional additional quote options
|
|
418
|
+
* @param additionalParams Optional additional parameters sent to the LP when creating the swap
|
|
419
|
+
* @param abortSignal Abort signal
|
|
401
420
|
*/
|
|
402
|
-
create(
|
|
421
|
+
create(recipient, amountData, lps, options, additionalParams, abortSignal) {
|
|
403
422
|
const _options = {
|
|
404
423
|
gasAmount: options?.gasAmount ?? 0n,
|
|
405
424
|
unsafeZeroWatchtowerFee: options?.unsafeZeroWatchtowerFee ?? false,
|
|
@@ -410,14 +429,14 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
410
429
|
const pricePrefetchPromise = this.preFetchPrice(amountData, _abortController.signal);
|
|
411
430
|
const usdPricePrefetchPromise = this.preFetchUsdPrice(_abortController.signal);
|
|
412
431
|
const finalizedBlockHeightPrefetchPromise = this.preFetchFinalizedBlockHeight(_abortController);
|
|
413
|
-
const nativeTokenAddress = this.
|
|
432
|
+
const nativeTokenAddress = this._chain.getNativeCurrencyAddress();
|
|
414
433
|
const gasTokenPricePrefetchPromise = _options.gasAmount === 0n ?
|
|
415
434
|
undefined :
|
|
416
435
|
this.preFetchPrice({ token: nativeTokenAddress }, _abortController.signal);
|
|
417
436
|
const callerFeePrefetchPromise = this.preFetchCallerFeeShare(amountData, _options, pricePrefetchPromise, gasTokenPricePrefetchPromise, _abortController);
|
|
418
437
|
const bitcoinFeeRatePromise = _options.maxAllowedNetworkFeeRate != Infinity ?
|
|
419
438
|
Promise.resolve(_options.maxAllowedNetworkFeeRate) :
|
|
420
|
-
this.
|
|
439
|
+
this._btcRpc.getFeeRate().then(x => this._options.maxBtcFeeOffset + (x * this._options.maxBtcFeeMultiplier)).catch(e => {
|
|
421
440
|
_abortController.abort(e);
|
|
422
441
|
return undefined;
|
|
423
442
|
});
|
|
@@ -431,7 +450,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
431
450
|
try {
|
|
432
451
|
const resp = await (0, RetryUtils_1.tryWithRetries)(async (retryCount) => {
|
|
433
452
|
return await IntermediaryAPI_1.IntermediaryAPI.prepareSpvFromBTC(this.chainIdentifier, lp.url, {
|
|
434
|
-
address:
|
|
453
|
+
address: recipient,
|
|
435
454
|
amount: amountData.amount,
|
|
436
455
|
token: amountData.token.toString(),
|
|
437
456
|
exactOut: !amountData.exactIn,
|
|
@@ -440,7 +459,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
440
459
|
callerFeeRate: (0, Utils_1.throwIfUndefined)(callerFeePrefetchPromise, "Caller fee prefetch failed!"),
|
|
441
460
|
frontingFeeRate: 0n,
|
|
442
461
|
additionalParams
|
|
443
|
-
}, this.
|
|
462
|
+
}, this._options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
|
|
444
463
|
}, undefined, e => e instanceof RequestError_1.RequestError, abortController.signal);
|
|
445
464
|
this.logger.debug("create(" + lp.url + "): LP response: ", resp);
|
|
446
465
|
const callerFeeShare = (await callerFeePrefetchPromise);
|
|
@@ -458,7 +477,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
458
477
|
swapFeeBtc: resp.swapFeeBtc,
|
|
459
478
|
exactIn: amountData.exactIn ?? true,
|
|
460
479
|
quoteId: resp.quoteId,
|
|
461
|
-
recipient
|
|
480
|
+
recipient,
|
|
462
481
|
vaultOwner: resp.address,
|
|
463
482
|
vaultId: resp.vaultId,
|
|
464
483
|
vaultRequiredConfirmations: vault.getConfirmations(),
|
|
@@ -495,11 +514,114 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
495
514
|
};
|
|
496
515
|
});
|
|
497
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* Recovers an SPV vault (UTXO-controlled vault) based swap from smart chain on-chain data
|
|
519
|
+
*
|
|
520
|
+
* @param state State of the spv vault withdrawal recovered from on-chain data
|
|
521
|
+
* @param vault SPV vault processing the swap
|
|
522
|
+
* @param lp Intermediary (LP) used as a counterparty for the swap
|
|
523
|
+
*/
|
|
524
|
+
async recoverFromState(state, vault, lp) {
|
|
525
|
+
//Get the vault
|
|
526
|
+
vault ??= await this._contract.getVaultData(state.owner, state.vaultId);
|
|
527
|
+
if (vault == null)
|
|
528
|
+
return null;
|
|
529
|
+
if (state.btcTxId == null)
|
|
530
|
+
return null;
|
|
531
|
+
const btcTx = await this._btcRpc.getTransaction(state.btcTxId);
|
|
532
|
+
if (btcTx == null)
|
|
533
|
+
return null;
|
|
534
|
+
const withdrawalData = await this._contract.getWithdrawalData(btcTx)
|
|
535
|
+
.catch(e => {
|
|
536
|
+
this.logger.warn(`Error parsing withdrawal data for tx ${btcTx.txid}: `, e);
|
|
537
|
+
return null;
|
|
538
|
+
});
|
|
539
|
+
if (withdrawalData == null)
|
|
540
|
+
return null;
|
|
541
|
+
const vaultTokens = vault.getTokenData();
|
|
542
|
+
const withdrawalDataOutputs = withdrawalData.getTotalOutput();
|
|
543
|
+
const txBlock = await state.getTxBlock?.();
|
|
544
|
+
const swapInit = {
|
|
545
|
+
pricingInfo: {
|
|
546
|
+
isValid: true,
|
|
547
|
+
satsBaseFee: 0n,
|
|
548
|
+
swapPriceUSatPerToken: 100000000000000n,
|
|
549
|
+
realPriceUSatPerToken: 100000000000000n,
|
|
550
|
+
differencePPM: 0n,
|
|
551
|
+
feePPM: 0n,
|
|
552
|
+
},
|
|
553
|
+
url: lp?.url,
|
|
554
|
+
expiry: 0,
|
|
555
|
+
swapFee: 0n,
|
|
556
|
+
swapFeeBtc: 0n,
|
|
557
|
+
exactIn: true,
|
|
558
|
+
//Use bitcoin tx id as quote id, even though this is not strictly correct as this
|
|
559
|
+
// is an off-chain identifier presented by the LP that cannot be recovered from on-chain
|
|
560
|
+
// data
|
|
561
|
+
quoteId: btcTx.txid,
|
|
562
|
+
recipient: state.recipient,
|
|
563
|
+
vaultOwner: state.owner,
|
|
564
|
+
vaultId: state.vaultId,
|
|
565
|
+
vaultRequiredConfirmations: vault.getConfirmations(),
|
|
566
|
+
vaultTokenMultipliers: vault.getTokenData().map(val => val.multiplier),
|
|
567
|
+
vaultBtcAddress: (0, BitcoinUtils_1.fromOutputScript)(this._options.bitcoinNetwork, withdrawalData.getNewVaultScript().toString("hex")),
|
|
568
|
+
vaultUtxo: withdrawalData.getSpentVaultUtxo(),
|
|
569
|
+
vaultUtxoValue: BigInt(withdrawalData.getNewVaultBtcAmount()),
|
|
570
|
+
btcDestinationAddress: (0, BitcoinUtils_1.fromOutputScript)(this._options.bitcoinNetwork, btcTx.outs[2].scriptPubKey.hex),
|
|
571
|
+
btcAmount: BigInt(btcTx.outs[2].value),
|
|
572
|
+
btcAmountSwap: BigInt(btcTx.outs[2].value),
|
|
573
|
+
btcAmountGas: 0n,
|
|
574
|
+
minimumBtcFeeRate: 0,
|
|
575
|
+
outputTotalSwap: withdrawalDataOutputs[0] * vaultTokens[0].multiplier,
|
|
576
|
+
outputSwapToken: vaultTokens[0].token,
|
|
577
|
+
outputTotalGas: withdrawalDataOutputs[1] * vaultTokens[1].multiplier,
|
|
578
|
+
outputGasToken: vaultTokens[1].token,
|
|
579
|
+
gasSwapFeeBtc: 0n,
|
|
580
|
+
gasSwapFee: 0n,
|
|
581
|
+
gasPricingInfo: {
|
|
582
|
+
isValid: true,
|
|
583
|
+
satsBaseFee: 0n,
|
|
584
|
+
swapPriceUSatPerToken: 100000000000000n,
|
|
585
|
+
realPriceUSatPerToken: 100000000000000n,
|
|
586
|
+
differencePPM: 0n,
|
|
587
|
+
feePPM: 0n,
|
|
588
|
+
},
|
|
589
|
+
callerFeeShare: withdrawalData.callerFeeRate,
|
|
590
|
+
frontingFeeShare: withdrawalData.frontingFeeRate,
|
|
591
|
+
executionFeeShare: withdrawalData.executionFeeRate,
|
|
592
|
+
genesisSmartChainBlockHeight: txBlock?.blockHeight ?? 0
|
|
593
|
+
};
|
|
594
|
+
const quote = new SpvFromBTCSwap_1.SpvFromBTCSwap(this, swapInit);
|
|
595
|
+
quote._data = withdrawalData;
|
|
596
|
+
if (txBlock != null) {
|
|
597
|
+
quote.createdAt = txBlock.blockTime * 1000;
|
|
598
|
+
}
|
|
599
|
+
else if (btcTx.blockhash == null) {
|
|
600
|
+
quote.createdAt = Date.now();
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
const blockHeader = await this._btcRpc.getBlockHeader(btcTx.blockhash);
|
|
604
|
+
quote.createdAt = blockHeader == null ? Date.now() : blockHeader.getTimestamp() * 1000;
|
|
605
|
+
}
|
|
606
|
+
quote._setInitiated();
|
|
607
|
+
if (btcTx.inputAddresses != null)
|
|
608
|
+
quote._senderAddress = btcTx.inputAddresses[1];
|
|
609
|
+
if (state.type === base_1.SpvWithdrawalStateType.FRONTED) {
|
|
610
|
+
quote._frontTxId = state.txId;
|
|
611
|
+
quote._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
quote._claimTxId = state.txId;
|
|
615
|
+
quote._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
|
|
616
|
+
}
|
|
617
|
+
await quote._save();
|
|
618
|
+
return quote;
|
|
619
|
+
}
|
|
498
620
|
/**
|
|
499
621
|
* Returns a random dummy PSBT that can be used for fee estimation, the last output (the LP output) is omitted
|
|
500
622
|
* to allow for coinselection algorithm to determine maximum sendable amount there
|
|
501
623
|
*
|
|
502
|
-
* @param includeGasToken
|
|
624
|
+
* @param includeGasToken Whether to return the PSBT also with the gas token amount (increases the vSize by 8)
|
|
503
625
|
*/
|
|
504
626
|
getDummySwapPsbt(includeGasToken = false) {
|
|
505
627
|
//Construct dummy swap psbt
|
|
@@ -521,7 +643,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
521
643
|
script: randomVaultOutScript,
|
|
522
644
|
amount: 600n
|
|
523
645
|
});
|
|
524
|
-
const opReturnData = this.
|
|
646
|
+
const opReturnData = this._contract.toOpReturnData(this._chain.randomAddress(), includeGasToken ? [0xffffffffffffffffn, 0xffffffffffffffffn] : [0xffffffffffffffffn]);
|
|
525
647
|
psbt.addOutput({
|
|
526
648
|
script: Buffer.concat([
|
|
527
649
|
opReturnData.length <= 75 ? Buffer.from([0x6a, opReturnData.length]) : Buffer.from([0x6a, 0x4c, opReturnData.length]),
|
|
@@ -531,31 +653,35 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
531
653
|
});
|
|
532
654
|
return psbt;
|
|
533
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* @inheritDoc
|
|
658
|
+
* @internal
|
|
659
|
+
*/
|
|
534
660
|
async _checkPastSwaps(pastSwaps) {
|
|
535
661
|
const changedSwaps = new Set();
|
|
536
662
|
const removeSwaps = [];
|
|
537
663
|
const broadcastedOrConfirmedSwaps = [];
|
|
538
664
|
for (let pastSwap of pastSwaps) {
|
|
539
665
|
let changed = false;
|
|
540
|
-
if (pastSwap.
|
|
541
|
-
pastSwap.
|
|
542
|
-
pastSwap.
|
|
543
|
-
pastSwap.
|
|
544
|
-
pastSwap.
|
|
545
|
-
pastSwap.
|
|
666
|
+
if (pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED ||
|
|
667
|
+
pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED ||
|
|
668
|
+
pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED ||
|
|
669
|
+
pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
670
|
+
pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
|
|
671
|
+
pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
546
672
|
//Check BTC transaction
|
|
547
673
|
if (await pastSwap._syncStateFromBitcoin(false))
|
|
548
674
|
changed ||= true;
|
|
549
675
|
}
|
|
550
|
-
if (pastSwap.
|
|
551
|
-
pastSwap.
|
|
552
|
-
pastSwap.
|
|
553
|
-
if (pastSwap.
|
|
554
|
-
if (pastSwap.
|
|
555
|
-
pastSwap.
|
|
676
|
+
if (pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED ||
|
|
677
|
+
pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED ||
|
|
678
|
+
pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED) {
|
|
679
|
+
if (await pastSwap._verifyQuoteDefinitelyExpired()) {
|
|
680
|
+
if (pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.CREATED) {
|
|
681
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_EXPIRED;
|
|
556
682
|
}
|
|
557
683
|
else {
|
|
558
|
-
pastSwap.
|
|
684
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
559
685
|
}
|
|
560
686
|
changed ||= true;
|
|
561
687
|
}
|
|
@@ -566,56 +692,53 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
566
692
|
}
|
|
567
693
|
if (changed)
|
|
568
694
|
changedSwaps.add(pastSwap);
|
|
569
|
-
if (pastSwap.
|
|
570
|
-
if (pastSwap.
|
|
695
|
+
if (pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
696
|
+
if (pastSwap._data != null)
|
|
571
697
|
broadcastedOrConfirmedSwaps.push(pastSwap);
|
|
572
698
|
}
|
|
573
699
|
}
|
|
574
700
|
const checkWithdrawalStateSwaps = [];
|
|
575
|
-
const _fronts = await this.
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
withdrawal: val.data
|
|
579
|
-
})));
|
|
580
|
-
const _vaultUtxos = await this.contract.getVaultLatestUtxos(broadcastedOrConfirmedSwaps.map(val => ({
|
|
581
|
-
owner: val.vaultOwner,
|
|
582
|
-
vaultId: val.vaultId
|
|
701
|
+
const _fronts = await this._contract.getFronterAddresses(broadcastedOrConfirmedSwaps.map(val => ({
|
|
702
|
+
...val.getSpvVaultData(),
|
|
703
|
+
withdrawal: val._data
|
|
583
704
|
})));
|
|
705
|
+
const _vaultUtxos = await this._contract.getVaultLatestUtxos(broadcastedOrConfirmedSwaps.map(val => val.getSpvVaultData()));
|
|
584
706
|
for (const pastSwap of broadcastedOrConfirmedSwaps) {
|
|
585
|
-
const fronterAddress = _fronts[pastSwap.
|
|
586
|
-
const
|
|
707
|
+
const fronterAddress = _fronts[pastSwap._data.getTxId()];
|
|
708
|
+
const vault = pastSwap.getSpvVaultData();
|
|
709
|
+
const latestVaultUtxo = _vaultUtxos[vault.owner]?.[vault.vaultId.toString(10)];
|
|
587
710
|
if (fronterAddress === undefined)
|
|
588
|
-
this.logger.warn(`_checkPastSwaps(): No fronter address returned for ${pastSwap.
|
|
711
|
+
this.logger.warn(`_checkPastSwaps(): No fronter address returned for ${pastSwap._data.getTxId()}`);
|
|
589
712
|
if (latestVaultUtxo === undefined)
|
|
590
|
-
this.logger.warn(`_checkPastSwaps(): No last vault utxo returned for ${pastSwap.
|
|
713
|
+
this.logger.warn(`_checkPastSwaps(): No last vault utxo returned for ${pastSwap._data.getTxId()}`);
|
|
591
714
|
if (await pastSwap._shouldCheckWithdrawalState(fronterAddress, latestVaultUtxo))
|
|
592
715
|
checkWithdrawalStateSwaps.push(pastSwap);
|
|
593
716
|
}
|
|
594
|
-
const withdrawalStates = await this.
|
|
595
|
-
withdrawal: val.
|
|
596
|
-
scStartBlockheight: val.
|
|
717
|
+
const withdrawalStates = await this._contract.getWithdrawalStates(checkWithdrawalStateSwaps.map(val => ({
|
|
718
|
+
withdrawal: val._data,
|
|
719
|
+
scStartBlockheight: val._genesisSmartChainBlockHeight
|
|
597
720
|
})));
|
|
598
721
|
for (const pastSwap of checkWithdrawalStateSwaps) {
|
|
599
|
-
const status = withdrawalStates[pastSwap.
|
|
722
|
+
const status = withdrawalStates[pastSwap._data.getTxId()];
|
|
600
723
|
if (status == null) {
|
|
601
|
-
this.logger.warn(`_checkPastSwaps(): No withdrawal state returned for ${pastSwap.
|
|
724
|
+
this.logger.warn(`_checkPastSwaps(): No withdrawal state returned for ${pastSwap._data.getTxId()}`);
|
|
602
725
|
continue;
|
|
603
726
|
}
|
|
604
|
-
this.logger.debug("syncStateFromChain(): status of " + pastSwap.
|
|
727
|
+
this.logger.debug("syncStateFromChain(): status of " + pastSwap._data.btcTx.txid, status?.type);
|
|
605
728
|
let changed = false;
|
|
606
729
|
switch (status.type) {
|
|
607
730
|
case base_1.SpvWithdrawalStateType.FRONTED:
|
|
608
|
-
pastSwap.
|
|
609
|
-
pastSwap.
|
|
731
|
+
pastSwap._frontTxId = status.txId;
|
|
732
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
|
|
610
733
|
changed ||= true;
|
|
611
734
|
break;
|
|
612
735
|
case base_1.SpvWithdrawalStateType.CLAIMED:
|
|
613
|
-
pastSwap.
|
|
614
|
-
pastSwap.
|
|
736
|
+
pastSwap._claimTxId = status.txId;
|
|
737
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
|
|
615
738
|
changed ||= true;
|
|
616
739
|
break;
|
|
617
740
|
case base_1.SpvWithdrawalStateType.CLOSED:
|
|
618
|
-
pastSwap.
|
|
741
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLOSED;
|
|
619
742
|
changed ||= true;
|
|
620
743
|
break;
|
|
621
744
|
}
|