@atomiqlabs/sdk 7.0.12 → 8.0.7
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/README.md +45 -29
- package/dist/SmartChainAssets.d.ts +11 -3
- package/dist/SmartChainAssets.js +7 -3
- package/dist/bitcoin/BitcoinRpcWithAddressIndex.d.ts +68 -0
- package/dist/bitcoin/BitcoinRpcWithAddressIndex.js +2 -0
- package/dist/bitcoin/LightningNetworkApi.d.ts +12 -0
- package/dist/bitcoin/LightningNetworkApi.js +2 -0
- package/dist/bitcoin/coinselect2/accumulative.d.ts +6 -0
- package/dist/bitcoin/coinselect2/accumulative.js +52 -0
- package/dist/bitcoin/coinselect2/blackjack.d.ts +6 -0
- package/dist/bitcoin/coinselect2/blackjack.js +38 -0
- package/dist/bitcoin/coinselect2/index.d.ts +19 -0
- package/dist/bitcoin/coinselect2/index.js +69 -0
- package/dist/bitcoin/coinselect2/utils.d.ts +71 -0
- package/dist/bitcoin/coinselect2/utils.js +123 -0
- package/dist/bitcoin/mempool/MempoolApi.d.ts +350 -0
- package/dist/bitcoin/mempool/MempoolApi.js +311 -0
- package/dist/bitcoin/mempool/MempoolBitcoinBlock.d.ts +44 -0
- package/dist/bitcoin/mempool/MempoolBitcoinBlock.js +48 -0
- package/dist/bitcoin/mempool/MempoolBitcoinRpc.d.ts +119 -0
- package/dist/bitcoin/mempool/MempoolBitcoinRpc.js +361 -0
- package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.d.ts +22 -0
- package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.js +105 -0
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +93 -0
- package/dist/bitcoin/wallet/BitcoinWallet.js +273 -0
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +28 -0
- package/dist/bitcoin/wallet/IBitcoinWallet.js +20 -0
- package/dist/bitcoin/wallet/MinimalBitcoinWalletInterface.d.ts +21 -0
- package/dist/bitcoin/wallet/MinimalBitcoinWalletInterface.js +2 -0
- package/dist/bitcoin/wallet/MinimalLightningNetworkWalletInterface.d.ts +7 -0
- package/dist/bitcoin/wallet/MinimalLightningNetworkWalletInterface.js +2 -0
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +40 -0
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +86 -0
- package/dist/enums/FeeType.d.ts +8 -0
- package/dist/enums/FeeType.js +12 -0
- package/dist/enums/SwapAmountType.d.ts +8 -0
- package/dist/enums/SwapAmountType.js +12 -0
- package/dist/enums/SwapDirection.d.ts +8 -0
- package/dist/enums/SwapDirection.js +12 -0
- package/dist/enums/SwapType.d.ts +14 -0
- package/dist/enums/SwapType.js +18 -0
- package/dist/errors/IntermediaryError.d.ts +9 -0
- package/dist/errors/IntermediaryError.js +26 -0
- package/dist/errors/PaymentAuthError.d.ts +11 -0
- package/dist/errors/PaymentAuthError.js +23 -0
- package/dist/errors/RequestError.d.ts +18 -0
- package/dist/errors/RequestError.js +46 -0
- package/dist/errors/UserError.d.ts +7 -0
- package/dist/errors/UserError.js +15 -0
- package/dist/events/UnifiedSwapEventListener.d.ts +23 -0
- package/dist/events/UnifiedSwapEventListener.js +130 -0
- package/dist/http/HttpUtils.d.ts +27 -0
- package/dist/http/HttpUtils.js +91 -0
- package/dist/http/paramcoders/IParamReader.d.ts +8 -0
- package/dist/http/paramcoders/IParamReader.js +2 -0
- package/dist/http/paramcoders/ParamDecoder.d.ts +44 -0
- package/dist/http/paramcoders/ParamDecoder.js +132 -0
- package/dist/http/paramcoders/ParamEncoder.d.ts +20 -0
- package/dist/http/paramcoders/ParamEncoder.js +31 -0
- package/dist/http/paramcoders/SchemaVerifier.d.ts +26 -0
- package/dist/http/paramcoders/SchemaVerifier.js +145 -0
- package/dist/http/paramcoders/client/ResponseParamDecoder.d.ts +11 -0
- package/dist/http/paramcoders/client/ResponseParamDecoder.js +57 -0
- package/dist/http/paramcoders/client/StreamParamEncoder.d.ts +13 -0
- package/dist/http/paramcoders/client/StreamParamEncoder.js +26 -0
- package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +16 -0
- package/dist/http/paramcoders/client/StreamingFetchPromise.js +174 -0
- package/dist/index.d.ts +82 -4
- package/dist/index.js +128 -4
- package/dist/intermediaries/Intermediary.d.ts +111 -0
- package/dist/intermediaries/Intermediary.js +115 -0
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +166 -0
- package/dist/intermediaries/IntermediaryDiscovery.js +390 -0
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +436 -0
- package/dist/intermediaries/apis/IntermediaryAPI.js +600 -0
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.d.ts +154 -0
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.js +136 -0
- package/dist/lnurl/LNURL.d.ts +102 -0
- package/dist/lnurl/LNURL.js +321 -0
- package/dist/prices/RedundantSwapPrice.d.ts +89 -0
- package/dist/prices/RedundantSwapPrice.js +202 -0
- package/dist/prices/SingleSwapPrice.d.ts +31 -0
- package/dist/prices/SingleSwapPrice.js +41 -0
- package/dist/prices/SwapPriceWithChain.d.ts +70 -0
- package/dist/prices/SwapPriceWithChain.js +91 -0
- package/dist/prices/abstract/ICachedSwapPrice.d.ts +28 -0
- package/dist/prices/abstract/ICachedSwapPrice.js +62 -0
- package/dist/prices/abstract/IPriceProvider.d.ts +81 -0
- package/dist/prices/abstract/IPriceProvider.js +74 -0
- package/dist/prices/abstract/ISwapPrice.d.ts +117 -0
- package/dist/prices/abstract/ISwapPrice.js +219 -0
- package/dist/prices/providers/BinancePriceProvider.d.ts +16 -0
- package/dist/prices/providers/BinancePriceProvider.js +23 -0
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +17 -0
- package/dist/prices/providers/CoinGeckoPriceProvider.js +23 -0
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +19 -0
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +23 -0
- package/dist/prices/providers/CustomPriceProvider.d.ts +13 -0
- package/dist/prices/providers/CustomPriceProvider.js +24 -0
- package/dist/prices/providers/KrakenPriceProvider.d.ts +29 -0
- package/dist/prices/providers/KrakenPriceProvider.js +36 -0
- package/dist/prices/providers/OKXPriceProvider.d.ts +28 -0
- package/dist/prices/providers/OKXPriceProvider.js +23 -0
- package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +14 -0
- package/dist/prices/providers/abstract/ExchangePriceProvider.js +18 -0
- package/dist/prices/providers/abstract/HttpPriceProvider.d.ts +7 -0
- package/dist/prices/providers/abstract/HttpPriceProvider.js +12 -0
- package/dist/storage/IUnifiedStorage.d.ts +73 -0
- package/dist/storage/IUnifiedStorage.js +2 -0
- package/dist/storage/UnifiedSwapStorage.d.ts +82 -0
- package/dist/storage/UnifiedSwapStorage.js +83 -0
- package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +39 -0
- package/dist/storage-browser/IndexedDBUnifiedStorage.js +275 -0
- package/dist/{storage → storage-browser}/LocalStorageManager.d.ts +1 -0
- package/dist/{storage → storage-browser}/LocalStorageManager.js +2 -1
- package/dist/swapper/Swapper.d.ts +533 -0
- package/dist/swapper/Swapper.js +1566 -0
- package/dist/swapper/SwapperFactory.d.ts +87 -0
- package/dist/{SwapperFactory.js → swapper/SwapperFactory.js} +37 -19
- package/dist/swapper/SwapperUtils.d.ts +153 -0
- package/dist/swapper/SwapperUtils.js +420 -0
- package/dist/swapper/SwapperWithChain.d.ts +214 -0
- package/dist/swapper/SwapperWithChain.js +315 -0
- package/dist/swapper/SwapperWithSigner.d.ts +178 -0
- package/dist/swapper/SwapperWithSigner.js +172 -0
- package/dist/swaps/IAddressSwap.d.ts +13 -0
- package/dist/swaps/IAddressSwap.js +13 -0
- package/dist/swaps/IBTCWalletSwap.d.ts +55 -0
- package/dist/swaps/IBTCWalletSwap.js +17 -0
- package/dist/swaps/IClaimableSwap.d.ts +17 -0
- package/dist/swaps/IClaimableSwap.js +14 -0
- package/dist/swaps/IClaimableSwapWrapper.d.ts +5 -0
- package/dist/swaps/IClaimableSwapWrapper.js +2 -0
- package/dist/swaps/IRefundableSwap.d.ts +17 -0
- package/dist/swaps/IRefundableSwap.js +13 -0
- package/dist/swaps/ISwap.d.ts +207 -0
- package/dist/swaps/ISwap.js +264 -0
- package/dist/swaps/ISwapWithGasDrop.d.ts +15 -0
- package/dist/swaps/ISwapWithGasDrop.js +11 -0
- package/dist/swaps/ISwapWrapper.d.ts +153 -0
- package/dist/swaps/ISwapWrapper.js +227 -0
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +53 -0
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +116 -0
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +70 -0
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +132 -0
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +85 -0
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +122 -0
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +86 -0
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +115 -0
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +93 -0
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +121 -0
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +45 -0
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +65 -0
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +263 -0
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +933 -0
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +110 -0
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +307 -0
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +236 -0
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +898 -0
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +125 -0
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +393 -0
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +245 -0
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +841 -0
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +120 -0
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +294 -0
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +228 -0
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +721 -0
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +37 -0
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +93 -0
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +86 -0
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +213 -0
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +170 -0
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +520 -0
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +50 -0
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +109 -0
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +93 -0
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +217 -0
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +315 -0
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1098 -0
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +125 -0
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +631 -0
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +107 -0
- package/dist/swaps/trusted/ln/LnForGasSwap.js +343 -0
- package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +21 -0
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +62 -0
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +164 -0
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +520 -0
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +48 -0
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +74 -0
- package/dist/types/AmountData.d.ts +9 -0
- package/dist/types/AmountData.js +2 -0
- package/dist/types/CustomPriceFunction.d.ts +5 -0
- package/dist/types/CustomPriceFunction.js +2 -0
- package/dist/types/PriceInfoType.d.ts +28 -0
- package/dist/types/PriceInfoType.js +57 -0
- package/dist/types/SwapExecutionAction.d.ts +7 -0
- package/dist/types/SwapExecutionAction.js +2 -0
- package/dist/types/SwapWithSigner.d.ts +14 -0
- package/dist/types/SwapWithSigner.js +40 -0
- package/dist/types/Token.d.ts +53 -0
- package/dist/types/Token.js +58 -0
- package/dist/types/TokenAmount.d.ts +57 -0
- package/dist/types/TokenAmount.js +47 -0
- package/dist/types/fees/Fee.d.ts +49 -0
- package/dist/types/fees/Fee.js +2 -0
- package/dist/types/fees/FeeBreakdown.d.ts +10 -0
- package/dist/types/fees/FeeBreakdown.js +2 -0
- package/dist/types/fees/PercentagePPM.d.ts +15 -0
- package/dist/types/fees/PercentagePPM.js +17 -0
- package/dist/types/lnurl/LNURLPay.d.ts +54 -0
- package/dist/types/lnurl/LNURLPay.js +28 -0
- package/dist/types/lnurl/LNURLWithdraw.d.ts +42 -0
- package/dist/types/lnurl/LNURLWithdraw.js +24 -0
- package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -0
- package/dist/utils/AutomaticClockDriftCorrection.js +70 -0
- package/dist/utils/BitcoinUtils.d.ts +13 -0
- package/dist/utils/BitcoinUtils.js +98 -0
- package/dist/utils/BitcoinWalletUtils.d.ts +7 -0
- package/dist/utils/BitcoinWalletUtils.js +14 -0
- package/dist/utils/Logger.d.ts +7 -0
- package/dist/utils/Logger.js +12 -0
- package/dist/utils/RetryUtils.d.ts +21 -0
- package/dist/utils/RetryUtils.js +66 -0
- package/dist/utils/SwapUtils.d.ts +31 -0
- package/dist/utils/SwapUtils.js +18 -0
- package/dist/{Utils.d.ts → utils/TimeoutUtils.d.ts} +9 -3
- package/dist/utils/TimeoutUtils.js +55 -0
- package/dist/utils/TokenUtils.d.ts +11 -0
- package/dist/utils/TokenUtils.js +29 -0
- package/dist/utils/TypeUtils.d.ts +7 -0
- package/dist/utils/TypeUtils.js +2 -0
- package/dist/utils/Utils.d.ts +57 -0
- package/dist/utils/Utils.js +178 -0
- package/package.json +14 -6
- package/src/SmartChainAssets.ts +11 -3
- package/src/bitcoin/BitcoinRpcWithAddressIndex.ts +87 -0
- package/src/bitcoin/LightningNetworkApi.ts +16 -0
- package/src/bitcoin/coinselect2/accumulative.ts +68 -0
- package/src/bitcoin/coinselect2/blackjack.ts +49 -0
- package/src/bitcoin/coinselect2/index.ts +92 -0
- package/src/bitcoin/coinselect2/utils.ts +189 -0
- package/src/bitcoin/mempool/MempoolApi.ts +554 -0
- package/src/bitcoin/mempool/MempoolBitcoinBlock.ts +88 -0
- package/src/bitcoin/mempool/MempoolBitcoinRpc.ts +437 -0
- package/src/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.ts +134 -0
- package/src/bitcoin/wallet/BitcoinWallet.ts +375 -0
- package/src/bitcoin/wallet/IBitcoinWallet.ts +44 -0
- package/src/bitcoin/wallet/MinimalBitcoinWalletInterface.ts +19 -0
- package/src/bitcoin/wallet/MinimalLightningNetworkWalletInterface.ts +7 -0
- package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +108 -0
- package/src/enums/FeeType.ts +9 -0
- package/src/enums/SwapAmountType.ts +9 -0
- package/src/enums/SwapDirection.ts +9 -0
- package/src/enums/SwapType.ts +15 -0
- package/src/errors/IntermediaryError.ts +24 -0
- package/src/errors/PaymentAuthError.ts +26 -0
- package/src/errors/RequestError.ts +51 -0
- package/src/errors/UserError.ts +14 -0
- package/src/events/UnifiedSwapEventListener.ts +171 -0
- package/src/http/HttpUtils.ts +92 -0
- package/src/http/paramcoders/IParamReader.ts +10 -0
- package/src/http/paramcoders/ParamDecoder.ts +142 -0
- package/src/http/paramcoders/ParamEncoder.ts +37 -0
- package/src/http/paramcoders/SchemaVerifier.ts +153 -0
- package/src/http/paramcoders/client/ResponseParamDecoder.ts +58 -0
- package/src/http/paramcoders/client/StreamParamEncoder.ts +29 -0
- package/src/http/paramcoders/client/StreamingFetchPromise.ts +193 -0
- package/src/index.ts +102 -4
- package/src/intermediaries/Intermediary.ts +204 -0
- package/src/intermediaries/IntermediaryDiscovery.ts +485 -0
- package/src/intermediaries/apis/IntermediaryAPI.ts +940 -0
- package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +257 -0
- package/src/lnurl/LNURL.ts +403 -0
- package/src/prices/RedundantSwapPrice.ts +245 -0
- package/src/prices/SingleSwapPrice.ts +47 -0
- package/src/prices/SwapPriceWithChain.ts +157 -0
- package/src/prices/abstract/ICachedSwapPrice.ts +86 -0
- package/src/prices/abstract/IPriceProvider.ts +128 -0
- package/src/prices/abstract/ISwapPrice.ts +328 -0
- package/src/prices/providers/BinancePriceProvider.ts +41 -0
- package/src/prices/providers/CoinGeckoPriceProvider.ts +40 -0
- package/src/prices/providers/CoinPaprikaPriceProvider.ts +44 -0
- package/src/prices/providers/CustomPriceProvider.ts +29 -0
- package/src/prices/providers/KrakenPriceProvider.ts +74 -0
- package/src/prices/providers/OKXPriceProvider.ts +53 -0
- package/src/prices/providers/abstract/ExchangePriceProvider.ts +29 -0
- package/src/prices/providers/abstract/HttpPriceProvider.ts +15 -0
- package/src/storage/IUnifiedStorage.ts +83 -0
- package/src/storage/UnifiedSwapStorage.ts +104 -0
- package/src/storage-browser/IndexedDBUnifiedStorage.ts +328 -0
- package/src/{storage → storage-browser}/LocalStorageManager.ts +2 -1
- package/src/swapper/Swapper.ts +2107 -0
- package/src/{SwapperFactory.ts → swapper/SwapperFactory.ts} +113 -72
- package/src/swapper/SwapperUtils.ts +510 -0
- package/src/swapper/SwapperWithChain.ts +464 -0
- package/src/swapper/SwapperWithSigner.ts +300 -0
- package/src/swaps/IAddressSwap.ts +20 -0
- package/src/swaps/IBTCWalletSwap.ts +77 -0
- package/src/swaps/IClaimableSwap.ts +30 -0
- package/src/swaps/IClaimableSwapWrapper.ts +9 -0
- package/src/swaps/IRefundableSwap.ts +29 -0
- package/src/swaps/ISwap.ts +490 -0
- package/src/swaps/ISwapWithGasDrop.ts +19 -0
- package/src/swaps/ISwapWrapper.ts +344 -0
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +168 -0
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +197 -0
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +210 -0
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +150 -0
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +219 -0
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +84 -0
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +1082 -0
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +429 -0
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +1078 -0
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +549 -0
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +974 -0
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +443 -0
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +860 -0
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +104 -0
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +256 -0
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +716 -0
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +151 -0
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +299 -0
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +1394 -0
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +796 -0
- package/src/swaps/trusted/ln/LnForGasSwap.ts +402 -0
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +70 -0
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +633 -0
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +110 -0
- package/src/types/AmountData.ts +9 -0
- package/src/types/CustomPriceFunction.ts +5 -0
- package/src/types/PriceInfoType.ts +67 -0
- package/src/types/SwapExecutionAction.ts +8 -0
- package/src/types/SwapWithSigner.ts +57 -0
- package/src/types/Token.ts +90 -0
- package/src/types/TokenAmount.ts +110 -0
- package/src/types/fees/Fee.ts +55 -0
- package/src/types/fees/FeeBreakdown.ts +11 -0
- package/src/types/fees/PercentagePPM.ts +24 -0
- package/src/types/lnurl/LNURLPay.ts +72 -0
- package/src/types/lnurl/LNURLWithdraw.ts +55 -0
- package/src/utils/AutomaticClockDriftCorrection.ts +71 -0
- package/src/utils/BitcoinUtils.ts +86 -0
- package/src/utils/BitcoinWalletUtils.ts +16 -0
- package/src/utils/Logger.ts +15 -0
- package/src/utils/RetryUtils.ts +71 -0
- package/src/utils/SwapUtils.ts +38 -0
- package/src/utils/TimeoutUtils.ts +50 -0
- package/src/utils/TokenUtils.ts +25 -0
- package/src/utils/TypeUtils.ts +9 -0
- package/src/utils/Utils.ts +182 -0
- package/dist/SwapperFactory.d.ts +0 -52
- package/dist/Utils.js +0 -37
- package/dist/fs-storage/FileSystemStorageManager.d.ts +0 -15
- package/dist/fs-storage/FileSystemStorageManager.js +0 -60
- package/dist/fs-storage/index.d.ts +0 -1
- package/dist/fs-storage/index.js +0 -17
- package/src/SmartChainAssets.js +0 -75
- package/src/SwapperFactory.js +0 -120
- package/src/Utils.js +0 -37
- package/src/Utils.ts +0 -31
- package/src/fs-storage/FileSystemStorageManager.ts +0 -71
- package/src/fs-storage/index.ts +0 -1
- package/src/index.js +0 -21
- package/src/storage/LocalStorageManager.js +0 -72
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FromBTCSwap = exports.isFromBTCSwapInit = exports.FromBTCSwapState = void 0;
|
|
4
|
+
const IFromBTCSelfInitSwap_1 = require("../IFromBTCSelfInitSwap");
|
|
5
|
+
const SwapType_1 = require("../../../../enums/SwapType");
|
|
6
|
+
const base_1 = require("@atomiqlabs/base");
|
|
7
|
+
const buffer_1 = require("buffer");
|
|
8
|
+
const Utils_1 = require("../../../../utils/Utils");
|
|
9
|
+
const BitcoinUtils_1 = require("../../../../utils/BitcoinUtils");
|
|
10
|
+
const IBitcoinWallet_1 = require("../../../../bitcoin/wallet/IBitcoinWallet");
|
|
11
|
+
const btc_signer_1 = require("@scure/btc-signer");
|
|
12
|
+
const SingleAddressBitcoinWallet_1 = require("../../../../bitcoin/wallet/SingleAddressBitcoinWallet");
|
|
13
|
+
const IEscrowSelfInitSwap_1 = require("../../IEscrowSelfInitSwap");
|
|
14
|
+
const TokenAmount_1 = require("../../../../types/TokenAmount");
|
|
15
|
+
const Token_1 = require("../../../../types/Token");
|
|
16
|
+
const Logger_1 = require("../../../../utils/Logger");
|
|
17
|
+
const BitcoinWalletUtils_1 = require("../../../../utils/BitcoinWalletUtils");
|
|
18
|
+
/**
|
|
19
|
+
* State enum for FromBTC swaps
|
|
20
|
+
* @category Swaps
|
|
21
|
+
*/
|
|
22
|
+
var FromBTCSwapState;
|
|
23
|
+
(function (FromBTCSwapState) {
|
|
24
|
+
FromBTCSwapState[FromBTCSwapState["FAILED"] = -4] = "FAILED";
|
|
25
|
+
FromBTCSwapState[FromBTCSwapState["EXPIRED"] = -3] = "EXPIRED";
|
|
26
|
+
FromBTCSwapState[FromBTCSwapState["QUOTE_EXPIRED"] = -2] = "QUOTE_EXPIRED";
|
|
27
|
+
FromBTCSwapState[FromBTCSwapState["QUOTE_SOFT_EXPIRED"] = -1] = "QUOTE_SOFT_EXPIRED";
|
|
28
|
+
FromBTCSwapState[FromBTCSwapState["PR_CREATED"] = 0] = "PR_CREATED";
|
|
29
|
+
FromBTCSwapState[FromBTCSwapState["CLAIM_COMMITED"] = 1] = "CLAIM_COMMITED";
|
|
30
|
+
FromBTCSwapState[FromBTCSwapState["BTC_TX_CONFIRMED"] = 2] = "BTC_TX_CONFIRMED";
|
|
31
|
+
FromBTCSwapState[FromBTCSwapState["CLAIM_CLAIMED"] = 3] = "CLAIM_CLAIMED";
|
|
32
|
+
})(FromBTCSwapState = exports.FromBTCSwapState || (exports.FromBTCSwapState = {}));
|
|
33
|
+
function isFromBTCSwapInit(obj) {
|
|
34
|
+
return typeof (obj.address) === "string" &&
|
|
35
|
+
typeof (obj.amount) === "bigint" &&
|
|
36
|
+
typeof (obj.data) === "object" &&
|
|
37
|
+
typeof (obj.requiredConfirmations) === "number" &&
|
|
38
|
+
(0, IEscrowSelfInitSwap_1.isIEscrowSelfInitSwapInit)(obj);
|
|
39
|
+
}
|
|
40
|
+
exports.isFromBTCSwapInit = isFromBTCSwapInit;
|
|
41
|
+
class FromBTCSwap extends IFromBTCSelfInitSwap_1.IFromBTCSelfInitSwap {
|
|
42
|
+
constructor(wrapper, initOrObject) {
|
|
43
|
+
if (isFromBTCSwapInit(initOrObject) && initOrObject.url != null)
|
|
44
|
+
initOrObject.url += "/frombtc";
|
|
45
|
+
super(wrapper, initOrObject);
|
|
46
|
+
this.inputToken = Token_1.BitcoinTokens.BTC;
|
|
47
|
+
this.TYPE = SwapType_1.SwapType.FROM_BTC;
|
|
48
|
+
if (isFromBTCSwapInit(initOrObject)) {
|
|
49
|
+
this.state = FromBTCSwapState.PR_CREATED;
|
|
50
|
+
this.data = initOrObject.data;
|
|
51
|
+
this.feeRate = initOrObject.feeRate;
|
|
52
|
+
this.address = initOrObject.address;
|
|
53
|
+
this.amount = initOrObject.amount;
|
|
54
|
+
this.requiredConfirmations = initOrObject.requiredConfirmations;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.address = initOrObject.address;
|
|
58
|
+
this.amount = BigInt(initOrObject.amount);
|
|
59
|
+
this.senderAddress = initOrObject.senderAddress;
|
|
60
|
+
this.txId = initOrObject.txId;
|
|
61
|
+
this.vout = initOrObject.vout;
|
|
62
|
+
this.requiredConfirmations = initOrObject.requiredConfirmations ?? this.data.getConfirmationsHint();
|
|
63
|
+
}
|
|
64
|
+
this.tryRecomputeSwapPrice();
|
|
65
|
+
this.logger = (0, Logger_1.getLogger)("FromBTC(" + this.getIdentifierHashString() + "): ");
|
|
66
|
+
}
|
|
67
|
+
getSwapData() {
|
|
68
|
+
return this.data;
|
|
69
|
+
}
|
|
70
|
+
upgradeVersion() {
|
|
71
|
+
if (this.version == null) {
|
|
72
|
+
switch (this.state) {
|
|
73
|
+
case -2:
|
|
74
|
+
this.state = FromBTCSwapState.FAILED;
|
|
75
|
+
break;
|
|
76
|
+
case -1:
|
|
77
|
+
this.state = FromBTCSwapState.QUOTE_EXPIRED;
|
|
78
|
+
break;
|
|
79
|
+
case 0:
|
|
80
|
+
this.state = FromBTCSwapState.PR_CREATED;
|
|
81
|
+
break;
|
|
82
|
+
case 1:
|
|
83
|
+
this.state = FromBTCSwapState.CLAIM_COMMITED;
|
|
84
|
+
break;
|
|
85
|
+
case 2:
|
|
86
|
+
this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
|
|
87
|
+
break;
|
|
88
|
+
case 3:
|
|
89
|
+
this.state = FromBTCSwapState.CLAIM_CLAIMED;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
this.version = 1;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//////////////////////////////
|
|
96
|
+
//// Getters & utils
|
|
97
|
+
/**
|
|
98
|
+
* Returns bitcoin address where the on-chain BTC should be sent to
|
|
99
|
+
*/
|
|
100
|
+
getAddress() {
|
|
101
|
+
if (this.state === FromBTCSwapState.PR_CREATED)
|
|
102
|
+
throw new Error("Cannot get bitcoin address of non-committed swap");
|
|
103
|
+
return this.address;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Unsafe bitcoin hyperlink getter, returns the address even before the swap is committed!
|
|
107
|
+
*
|
|
108
|
+
* @private
|
|
109
|
+
*/
|
|
110
|
+
_getHyperlink() {
|
|
111
|
+
return "bitcoin:" + this.address + "?amount=" + encodeURIComponent((Number(this.amount) / 100000000).toString(10));
|
|
112
|
+
}
|
|
113
|
+
getHyperlink() {
|
|
114
|
+
if (this.state === FromBTCSwapState.PR_CREATED)
|
|
115
|
+
throw new Error("Cannot get bitcoin address of non-committed swap");
|
|
116
|
+
return this._getHyperlink();
|
|
117
|
+
}
|
|
118
|
+
getInputAddress() {
|
|
119
|
+
return this.senderAddress ?? null;
|
|
120
|
+
}
|
|
121
|
+
getInputTxId() {
|
|
122
|
+
return this.txId ?? null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Returns timeout time (in UNIX milliseconds) when the on-chain address will expire and no funds should be sent
|
|
126
|
+
* to that address anymore
|
|
127
|
+
*/
|
|
128
|
+
getTimeoutTime() {
|
|
129
|
+
return Number(this.wrapper.getOnchainSendTimeout(this.data, this.requiredConfirmations)) * 1000;
|
|
130
|
+
}
|
|
131
|
+
requiresAction() {
|
|
132
|
+
return this.isClaimable() || (this.state === FromBTCSwapState.CLAIM_COMMITED && this.getTimeoutTime() > Date.now() && this.txId == null);
|
|
133
|
+
}
|
|
134
|
+
isFinished() {
|
|
135
|
+
return this.state === FromBTCSwapState.CLAIM_CLAIMED || this.state === FromBTCSwapState.QUOTE_EXPIRED || this.state === FromBTCSwapState.FAILED;
|
|
136
|
+
}
|
|
137
|
+
isClaimable() {
|
|
138
|
+
return this.state === FromBTCSwapState.BTC_TX_CONFIRMED;
|
|
139
|
+
}
|
|
140
|
+
isSuccessful() {
|
|
141
|
+
return this.state === FromBTCSwapState.CLAIM_CLAIMED;
|
|
142
|
+
}
|
|
143
|
+
isFailed() {
|
|
144
|
+
return this.state === FromBTCSwapState.FAILED || this.state === FromBTCSwapState.EXPIRED;
|
|
145
|
+
}
|
|
146
|
+
isQuoteExpired() {
|
|
147
|
+
return this.state === FromBTCSwapState.QUOTE_EXPIRED;
|
|
148
|
+
}
|
|
149
|
+
isQuoteSoftExpired() {
|
|
150
|
+
return this.state === FromBTCSwapState.QUOTE_EXPIRED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
151
|
+
}
|
|
152
|
+
canCommit() {
|
|
153
|
+
if (this.state !== FromBTCSwapState.PR_CREATED)
|
|
154
|
+
return false;
|
|
155
|
+
const expiry = this.wrapper.getOnchainSendTimeout(this.data, this.requiredConfirmations);
|
|
156
|
+
const currentTimestamp = BigInt(Math.floor(Date.now() / 1000));
|
|
157
|
+
return (expiry - currentTimestamp) >= this.wrapper.options.minSendWindow;
|
|
158
|
+
}
|
|
159
|
+
//////////////////////////////
|
|
160
|
+
//// Amounts & fees
|
|
161
|
+
getInputToken() {
|
|
162
|
+
return Token_1.BitcoinTokens.BTC;
|
|
163
|
+
}
|
|
164
|
+
getInput() {
|
|
165
|
+
return (0, TokenAmount_1.toTokenAmount)(this.amount, this.inputToken, this.wrapper.prices);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Returns claimer bounty, acting as a reward for watchtowers to claim the swap automatically
|
|
169
|
+
*/
|
|
170
|
+
getClaimerBounty() {
|
|
171
|
+
return (0, TokenAmount_1.toTokenAmount)(this.data.getClaimerBounty(), this.wrapper.tokens[this.data.getDepositToken()], this.wrapper.prices);
|
|
172
|
+
}
|
|
173
|
+
//////////////////////////////
|
|
174
|
+
//// Bitcoin tx
|
|
175
|
+
getRequiredConfirmationsCount() {
|
|
176
|
+
return this.requiredConfirmations;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Checks whether a bitcoin payment was already made, returns the payment or null when no payment has been made.
|
|
180
|
+
*/
|
|
181
|
+
async getBitcoinPayment() {
|
|
182
|
+
const txoHashHint = this.data.getTxoHashHint();
|
|
183
|
+
if (txoHashHint == null)
|
|
184
|
+
throw new Error("Swap data don't include the txo hash hint! Cannot check btc transaction!");
|
|
185
|
+
const result = await this.wrapper.btcRpc.checkAddressTxos(this.address, buffer_1.Buffer.from(txoHashHint, "hex"));
|
|
186
|
+
if (result == null)
|
|
187
|
+
return null;
|
|
188
|
+
return {
|
|
189
|
+
inputAddresses: result.tx.inputAddresses,
|
|
190
|
+
txId: result.tx.txid,
|
|
191
|
+
vout: result.vout,
|
|
192
|
+
confirmations: result.tx.confirmations ?? 0,
|
|
193
|
+
targetConfirmations: this.requiredConfirmations
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* For internal use! Used to set the txId of the bitcoin payment from the on-chain events listener
|
|
198
|
+
*
|
|
199
|
+
* @param txId
|
|
200
|
+
*/
|
|
201
|
+
async _setBitcoinTxId(txId) {
|
|
202
|
+
if (this.txId !== txId || this.address == null || this.vout == null || this.senderAddress == null || this.amount == null) {
|
|
203
|
+
const btcTx = await this.wrapper.btcRpc.getTransaction(txId);
|
|
204
|
+
if (btcTx == null)
|
|
205
|
+
return;
|
|
206
|
+
const txoHashHint = this.data.getTxoHashHint();
|
|
207
|
+
if (txoHashHint != null) {
|
|
208
|
+
const expectedTxoHash = buffer_1.Buffer.from(txoHashHint, "hex");
|
|
209
|
+
const vout = btcTx.outs.findIndex(out => (0, Utils_1.getTxoHash)(out.scriptPubKey.hex, out.value).equals(expectedTxoHash));
|
|
210
|
+
if (vout !== -1) {
|
|
211
|
+
this.vout = vout;
|
|
212
|
+
//If amount or address are not known, parse them from the bitcoin tx
|
|
213
|
+
// this can happen if the swap is recovered from on-chain data and
|
|
214
|
+
// hence doesn't contain the address and amount data
|
|
215
|
+
if (this.amount == null)
|
|
216
|
+
this.amount = BigInt(btcTx.outs[vout].value);
|
|
217
|
+
if (this.address == null)
|
|
218
|
+
try {
|
|
219
|
+
const addressData = btc_signer_1.OutScript.decode(buffer_1.Buffer.from(btcTx.outs[vout].scriptPubKey.hex, "hex"));
|
|
220
|
+
this.address = (0, btc_signer_1.Address)(this.wrapper.options.bitcoinNetwork).encode(addressData);
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
this.logger.warn("_setBitcoinTxId(): Failed to parse address from output script: ", e);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (btcTx.inputAddresses != null) {
|
|
228
|
+
this.senderAddress = btcTx.inputAddresses[0];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
this.txId = txId;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Waits till the bitcoin transaction confirms and swap becomes claimable
|
|
235
|
+
*
|
|
236
|
+
* @param updateCallback Callback called when txId is found, and also called with subsequent confirmations
|
|
237
|
+
* @param checkIntervalSeconds How often to check the bitcoin transaction
|
|
238
|
+
* @param abortSignal Abort signal
|
|
239
|
+
* @throws {Error} if in invalid state (must be CLAIM_COMMITED)
|
|
240
|
+
*/
|
|
241
|
+
async waitForBitcoinTransaction(updateCallback, checkIntervalSeconds, abortSignal) {
|
|
242
|
+
if (this.state !== FromBTCSwapState.CLAIM_COMMITED && this.state !== FromBTCSwapState.EXPIRED)
|
|
243
|
+
throw new Error("Must be in COMMITED state!");
|
|
244
|
+
const txoHashHint = this.data.getTxoHashHint();
|
|
245
|
+
if (txoHashHint == null)
|
|
246
|
+
throw new Error("Swap data don't include the txo hash hint! Cannot check btc transaction!");
|
|
247
|
+
const result = await this.wrapper.btcRpc.waitForAddressTxo(this.address, buffer_1.Buffer.from(txoHashHint, "hex"), this.requiredConfirmations, (btcTx, vout, txEtaMs) => {
|
|
248
|
+
if (updateCallback != null)
|
|
249
|
+
updateCallback(btcTx?.txid, btcTx == null ? undefined : (btcTx?.confirmations ?? 0), this.requiredConfirmations, txEtaMs);
|
|
250
|
+
if (btcTx != null && btcTx.txid !== this.txId) {
|
|
251
|
+
this.txId = btcTx.txid;
|
|
252
|
+
this.vout = vout;
|
|
253
|
+
if (btcTx.inputAddresses != null)
|
|
254
|
+
this.senderAddress = btcTx.inputAddresses[0];
|
|
255
|
+
this._saveAndEmit().catch(e => {
|
|
256
|
+
this.logger.error("waitForBitcoinTransaction(): Failed to save swap from within waitForAddressTxo callback:", e);
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}, abortSignal, checkIntervalSeconds);
|
|
260
|
+
if (abortSignal != null)
|
|
261
|
+
abortSignal.throwIfAborted();
|
|
262
|
+
this.txId = result.tx.txid;
|
|
263
|
+
this.vout = result.vout;
|
|
264
|
+
if (result.tx.inputAddresses != null)
|
|
265
|
+
this.senderAddress = result.tx.inputAddresses[0];
|
|
266
|
+
if (this.state !== FromBTCSwapState.CLAIM_CLAIMED &&
|
|
267
|
+
this.state !== FromBTCSwapState.FAILED) {
|
|
268
|
+
this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
|
|
269
|
+
}
|
|
270
|
+
await this._saveAndEmit();
|
|
271
|
+
return result.tx.txid;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Returns the PSBT that is already funded with wallet's UTXOs (runs a coin-selection algorithm to choose UTXOs to use),
|
|
275
|
+
* also returns inputs indices that need to be signed by the wallet before submitting the PSBT back to the SDK with
|
|
276
|
+
* `swap.submitPsbt()`
|
|
277
|
+
*
|
|
278
|
+
* @param _bitcoinWallet Sender's bitcoin wallet
|
|
279
|
+
* @param feeRate Optional fee rate for the transaction, needs to be at least as big as {minimumBtcFeeRate} field
|
|
280
|
+
* @param additionalOutputs additional outputs to add to the PSBT - can be used to collect fees from users
|
|
281
|
+
*/
|
|
282
|
+
getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs) {
|
|
283
|
+
if (this.state !== FromBTCSwapState.CLAIM_COMMITED)
|
|
284
|
+
throw new Error("Swap not committed yet, please initiate the swap first with commit() call!");
|
|
285
|
+
return this._getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs);
|
|
286
|
+
}
|
|
287
|
+
async _getFundedPsbt(_bitcoinWallet, feeRate, additionalOutputs) {
|
|
288
|
+
let bitcoinWallet;
|
|
289
|
+
if ((0, IBitcoinWallet_1.isIBitcoinWallet)(_bitcoinWallet)) {
|
|
290
|
+
bitcoinWallet = _bitcoinWallet;
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
bitcoinWallet = new SingleAddressBitcoinWallet_1.SingleAddressBitcoinWallet(this.wrapper.btcRpc, this.wrapper.options.bitcoinNetwork, _bitcoinWallet);
|
|
294
|
+
}
|
|
295
|
+
//TODO: Maybe re-introduce fee rate check here if passed from the user
|
|
296
|
+
if (feeRate == null) {
|
|
297
|
+
feeRate = await bitcoinWallet.getFeeRate();
|
|
298
|
+
}
|
|
299
|
+
const basePsbt = new btc_signer_1.Transaction({
|
|
300
|
+
allowUnknownOutputs: true,
|
|
301
|
+
allowLegacyWitnessUtxo: true
|
|
302
|
+
});
|
|
303
|
+
basePsbt.addOutput({
|
|
304
|
+
amount: this.amount,
|
|
305
|
+
script: (0, BitcoinUtils_1.toOutputScript)(this.wrapper.options.bitcoinNetwork, this.address)
|
|
306
|
+
});
|
|
307
|
+
if (additionalOutputs != null)
|
|
308
|
+
additionalOutputs.forEach(output => {
|
|
309
|
+
basePsbt.addOutput({
|
|
310
|
+
amount: output.amount,
|
|
311
|
+
script: output.outputScript ?? (0, BitcoinUtils_1.toOutputScript)(this.wrapper.options.bitcoinNetwork, output.address)
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
const psbt = await bitcoinWallet.fundPsbt(basePsbt, feeRate);
|
|
315
|
+
//Sign every input
|
|
316
|
+
const signInputs = [];
|
|
317
|
+
for (let i = 0; i < psbt.inputsLength; i++) {
|
|
318
|
+
signInputs.push(i);
|
|
319
|
+
}
|
|
320
|
+
const serializedPsbt = buffer_1.Buffer.from(psbt.toPSBT());
|
|
321
|
+
return {
|
|
322
|
+
psbt,
|
|
323
|
+
psbtHex: serializedPsbt.toString("hex"),
|
|
324
|
+
psbtBase64: serializedPsbt.toString("base64"),
|
|
325
|
+
signInputs
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Submits a PSBT signed by the wallet back to the SDK
|
|
330
|
+
*
|
|
331
|
+
* @param _psbt A psbt - either a Transaction object or a hex or base64 encoded PSBT string
|
|
332
|
+
*/
|
|
333
|
+
async submitPsbt(_psbt) {
|
|
334
|
+
const psbt = (0, BitcoinUtils_1.parsePsbtTransaction)(_psbt);
|
|
335
|
+
if (this.state !== FromBTCSwapState.CLAIM_COMMITED)
|
|
336
|
+
throw new Error("Swap not committed yet, please initiate the swap first with commit() call!");
|
|
337
|
+
//Ensure not expired
|
|
338
|
+
if (this.getTimeoutTime() < Date.now()) {
|
|
339
|
+
throw new Error("Swap address expired!");
|
|
340
|
+
}
|
|
341
|
+
const output0 = psbt.getOutput(0);
|
|
342
|
+
if (output0.amount !== this.amount)
|
|
343
|
+
throw new Error("PSBT output amount invalid, expected: " + this.amount + " got: " + output0.amount);
|
|
344
|
+
const expectedOutputScript = (0, BitcoinUtils_1.toOutputScript)(this.wrapper.options.bitcoinNetwork, this.address);
|
|
345
|
+
if (output0.script == null || !expectedOutputScript.equals(output0.script))
|
|
346
|
+
throw new Error("PSBT output script invalid!");
|
|
347
|
+
if (!psbt.isFinal)
|
|
348
|
+
psbt.finalize();
|
|
349
|
+
return await this.wrapper.btcRpc.sendRawTransaction(buffer_1.Buffer.from(psbt.toBytes(true, true)).toString("hex"));
|
|
350
|
+
}
|
|
351
|
+
async estimateBitcoinFee(_bitcoinWallet, feeRate) {
|
|
352
|
+
const bitcoinWallet = (0, BitcoinWalletUtils_1.toBitcoinWallet)(_bitcoinWallet, this.wrapper.btcRpc, this.wrapper.options.bitcoinNetwork);
|
|
353
|
+
const txFee = await bitcoinWallet.getTransactionFee(this.address, this.amount, feeRate);
|
|
354
|
+
if (txFee == null)
|
|
355
|
+
return null;
|
|
356
|
+
return (0, TokenAmount_1.toTokenAmount)(BigInt(txFee), Token_1.BitcoinTokens.BTC, this.wrapper.prices);
|
|
357
|
+
}
|
|
358
|
+
async sendBitcoinTransaction(wallet, feeRate) {
|
|
359
|
+
if (this.state !== FromBTCSwapState.CLAIM_COMMITED)
|
|
360
|
+
throw new Error("Swap not committed yet, please initiate the swap first with commit() call!");
|
|
361
|
+
//Ensure not expired
|
|
362
|
+
if (this.getTimeoutTime() < Date.now()) {
|
|
363
|
+
throw new Error("Swap address expired!");
|
|
364
|
+
}
|
|
365
|
+
if ((0, IBitcoinWallet_1.isIBitcoinWallet)(wallet)) {
|
|
366
|
+
return await wallet.sendTransaction(this.address, this.amount, feeRate);
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
const { psbt, psbtHex, psbtBase64, signInputs } = await this.getFundedPsbt(wallet, feeRate);
|
|
370
|
+
const signedPsbt = await wallet.signPsbt({
|
|
371
|
+
psbt, psbtHex, psbtBase64
|
|
372
|
+
}, signInputs);
|
|
373
|
+
return await this.submitPsbt(signedPsbt);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
//////////////////////////////
|
|
377
|
+
//// Execution
|
|
378
|
+
/**
|
|
379
|
+
* Executes the swap with the provided bitcoin wallet,
|
|
380
|
+
*
|
|
381
|
+
* @param dstSigner Signer on the destination network, needs to have the same address as the one specified when
|
|
382
|
+
* quote was created, this is required for legacy swaps because the destination wallet needs to actively open
|
|
383
|
+
* a bitcoin swap address to which the BTC is then sent, this means that the address also needs to have enough
|
|
384
|
+
* native tokens to pay for gas on the destination network
|
|
385
|
+
* @param wallet Bitcoin wallet to use to sign the bitcoin transaction, can also be null - then the execution waits
|
|
386
|
+
* till a transaction is received from an external wallet
|
|
387
|
+
* @param callbacks Callbacks to track the progress of the swap
|
|
388
|
+
* @param options Optional options for the swap like feeRate, AbortSignal, and timeouts/intervals
|
|
389
|
+
*
|
|
390
|
+
* @returns {boolean} Whether a swap was settled automatically by swap watchtowers or requires manual claim by the
|
|
391
|
+
* user, in case `false` is returned the user should call `swap.claim()` to settle the swap on the destination manually
|
|
392
|
+
*/
|
|
393
|
+
async execute(dstSigner, wallet, callbacks, options) {
|
|
394
|
+
if (this.state === FromBTCSwapState.FAILED)
|
|
395
|
+
throw new Error("Swap failed!");
|
|
396
|
+
if (this.state === FromBTCSwapState.EXPIRED)
|
|
397
|
+
throw new Error("Swap address expired!");
|
|
398
|
+
if (this.state === FromBTCSwapState.QUOTE_EXPIRED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED)
|
|
399
|
+
throw new Error("Swap quote expired!");
|
|
400
|
+
if (this.state === FromBTCSwapState.CLAIM_CLAIMED)
|
|
401
|
+
throw new Error("Swap already settled!");
|
|
402
|
+
if (this.state === FromBTCSwapState.PR_CREATED) {
|
|
403
|
+
await this.commit(dstSigner, options?.abortSignal, undefined, callbacks?.onDestinationCommitSent);
|
|
404
|
+
}
|
|
405
|
+
if (this.state === FromBTCSwapState.CLAIM_COMMITED) {
|
|
406
|
+
if (wallet != null) {
|
|
407
|
+
const bitcoinPaymentSent = await this.getBitcoinPayment();
|
|
408
|
+
if (bitcoinPaymentSent == null) {
|
|
409
|
+
//Send btc tx
|
|
410
|
+
const txId = await this.sendBitcoinTransaction(wallet, options?.feeRate);
|
|
411
|
+
if (callbacks?.onSourceTransactionSent != null)
|
|
412
|
+
callbacks.onSourceTransactionSent(txId);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const txId = await this.waitForBitcoinTransaction(callbacks?.onSourceTransactionConfirmationStatus, options?.btcTxCheckIntervalSeconds, options?.abortSignal);
|
|
416
|
+
if (callbacks?.onSourceTransactionConfirmed != null)
|
|
417
|
+
callbacks.onSourceTransactionConfirmed(txId);
|
|
418
|
+
}
|
|
419
|
+
// @ts-ignore
|
|
420
|
+
if (this.state === FromBTCSwapState.CLAIM_CLAIMED)
|
|
421
|
+
return true;
|
|
422
|
+
if (this.state === FromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
423
|
+
const success = await this.waitTillClaimed(options?.maxWaitTillAutomaticSettlementSeconds ?? 60, options?.abortSignal);
|
|
424
|
+
if (success && callbacks?.onSwapSettled != null)
|
|
425
|
+
callbacks.onSwapSettled(this.getOutputTxId());
|
|
426
|
+
return success;
|
|
427
|
+
}
|
|
428
|
+
throw new Error("Invalid state reached!");
|
|
429
|
+
}
|
|
430
|
+
async txsExecute(options) {
|
|
431
|
+
if (this.state === FromBTCSwapState.PR_CREATED) {
|
|
432
|
+
if (!await this.verifyQuoteValid())
|
|
433
|
+
throw new Error("Quote already expired or close to expiry!");
|
|
434
|
+
if (this.getTimeoutTime() < Date.now())
|
|
435
|
+
throw new Error("Swap address already expired or close to expiry!");
|
|
436
|
+
return [
|
|
437
|
+
{
|
|
438
|
+
name: "Commit",
|
|
439
|
+
description: `Opens up the bitcoin swap address on the ${this.chainIdentifier} side`,
|
|
440
|
+
chain: this.chainIdentifier,
|
|
441
|
+
txs: await this.txsCommit(options?.skipChecks)
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
name: "Payment",
|
|
445
|
+
description: "Send funds to the bitcoin swap address",
|
|
446
|
+
chain: "BITCOIN",
|
|
447
|
+
txs: [
|
|
448
|
+
options?.bitcoinWallet == null ? {
|
|
449
|
+
address: this.address,
|
|
450
|
+
amount: Number(this.amount),
|
|
451
|
+
hyperlink: this._getHyperlink(),
|
|
452
|
+
type: "ADDRESS"
|
|
453
|
+
} : {
|
|
454
|
+
...await this.getFundedPsbt(options.bitcoinWallet),
|
|
455
|
+
type: "FUNDED_PSBT"
|
|
456
|
+
}
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
];
|
|
460
|
+
}
|
|
461
|
+
if (this.state === FromBTCSwapState.CLAIM_COMMITED) {
|
|
462
|
+
if (this.getTimeoutTime() < Date.now())
|
|
463
|
+
throw new Error("Swap address already expired or close to expiry!");
|
|
464
|
+
return [
|
|
465
|
+
{
|
|
466
|
+
name: "Payment",
|
|
467
|
+
description: "Send funds to the bitcoin swap address",
|
|
468
|
+
chain: "BITCOIN",
|
|
469
|
+
txs: [
|
|
470
|
+
options?.bitcoinWallet == null ? {
|
|
471
|
+
address: this.address,
|
|
472
|
+
amount: Number(this.amount),
|
|
473
|
+
hyperlink: this._getHyperlink(),
|
|
474
|
+
type: "ADDRESS"
|
|
475
|
+
} : {
|
|
476
|
+
...await this.getFundedPsbt(options.bitcoinWallet),
|
|
477
|
+
type: "FUNDED_PSBT"
|
|
478
|
+
}
|
|
479
|
+
]
|
|
480
|
+
}
|
|
481
|
+
];
|
|
482
|
+
}
|
|
483
|
+
throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED or CLAIM_COMMITED");
|
|
484
|
+
}
|
|
485
|
+
//////////////////////////////
|
|
486
|
+
//// Commit
|
|
487
|
+
/**
|
|
488
|
+
* Commits the swap on-chain, locking the tokens from the intermediary in a PTLC
|
|
489
|
+
*
|
|
490
|
+
* @param _signer Signer to sign the transactions with, must be the same as used in the initialization
|
|
491
|
+
* @param abortSignal Abort signal to stop waiting for the transaction confirmation and abort
|
|
492
|
+
* @param skipChecks Skip checks like making sure init signature is still valid and swap wasn't commited yet
|
|
493
|
+
* (this is handled when swap is created (quoted), if you commit right after quoting, you can use skipChecks=true)
|
|
494
|
+
* @param onBeforeTxSent
|
|
495
|
+
* @throws {Error} If invalid signer is provided that doesn't match the swap data
|
|
496
|
+
*/
|
|
497
|
+
async commit(_signer, abortSignal, skipChecks, onBeforeTxSent) {
|
|
498
|
+
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.chain.wrapSigner(_signer);
|
|
499
|
+
this.checkSigner(signer);
|
|
500
|
+
let txCount = 0;
|
|
501
|
+
const txs = await this.txsCommit(skipChecks);
|
|
502
|
+
const result = await this.wrapper.chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
|
|
503
|
+
txCount++;
|
|
504
|
+
if (onBeforeTxSent != null && txCount === txs.length)
|
|
505
|
+
onBeforeTxSent(txId);
|
|
506
|
+
return Promise.resolve();
|
|
507
|
+
});
|
|
508
|
+
this.commitTxId = result[result.length - 1];
|
|
509
|
+
if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
510
|
+
await this._saveAndEmit(FromBTCSwapState.CLAIM_COMMITED);
|
|
511
|
+
}
|
|
512
|
+
return this.commitTxId;
|
|
513
|
+
}
|
|
514
|
+
async waitTillCommited(abortSignal) {
|
|
515
|
+
if (this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.CLAIM_CLAIMED)
|
|
516
|
+
return Promise.resolve();
|
|
517
|
+
if (this.state !== FromBTCSwapState.PR_CREATED && this.state !== FromBTCSwapState.QUOTE_SOFT_EXPIRED)
|
|
518
|
+
throw new Error("Invalid state");
|
|
519
|
+
const abortController = (0, Utils_1.extendAbortController)(abortSignal);
|
|
520
|
+
const result = await Promise.race([
|
|
521
|
+
this.watchdogWaitTillCommited(undefined, abortController.signal),
|
|
522
|
+
this.waitTillState(FromBTCSwapState.CLAIM_COMMITED, "gte", abortController.signal).then(() => 0)
|
|
523
|
+
]);
|
|
524
|
+
abortController.abort();
|
|
525
|
+
if (result === 0)
|
|
526
|
+
this.logger.debug("waitTillCommited(): Resolved from state changed");
|
|
527
|
+
if (result === true)
|
|
528
|
+
this.logger.debug("waitTillCommited(): Resolved from watchdog - commited");
|
|
529
|
+
if (result === false) {
|
|
530
|
+
this.logger.debug("waitTillCommited(): Resolved from watchdog - signature expired");
|
|
531
|
+
if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
532
|
+
await this._saveAndEmit(FromBTCSwapState.QUOTE_EXPIRED);
|
|
533
|
+
}
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
537
|
+
await this._saveAndEmit(FromBTCSwapState.CLAIM_COMMITED);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
//////////////////////////////
|
|
541
|
+
//// Claim
|
|
542
|
+
/**
|
|
543
|
+
* Returns transactions required to claim the swap on-chain (and possibly also sync the bitcoin light client)
|
|
544
|
+
* after a bitcoin transaction was sent and confirmed
|
|
545
|
+
*
|
|
546
|
+
* @throws {Error} If the swap is in invalid state (must be BTC_TX_CONFIRMED)
|
|
547
|
+
*/
|
|
548
|
+
async txsClaim(_signer) {
|
|
549
|
+
let signer = undefined;
|
|
550
|
+
if (_signer != null) {
|
|
551
|
+
if (typeof (_signer) === "string") {
|
|
552
|
+
signer = _signer;
|
|
553
|
+
}
|
|
554
|
+
else if ((0, base_1.isAbstractSigner)(_signer)) {
|
|
555
|
+
signer = _signer;
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
signer = await this.wrapper.chain.wrapSigner(_signer);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
if (this.state !== FromBTCSwapState.BTC_TX_CONFIRMED)
|
|
562
|
+
throw new Error("Must be in BTC_TX_CONFIRMED state!");
|
|
563
|
+
if (this.txId == null || this.vout == null)
|
|
564
|
+
throw new Error("Bitcoin transaction ID not known!");
|
|
565
|
+
const tx = await this.wrapper.btcRpc.getTransaction(this.txId);
|
|
566
|
+
if (tx == null)
|
|
567
|
+
throw new Error("Bitcoin transaction not found on the network!");
|
|
568
|
+
if (tx.blockhash == null || tx.confirmations == null || tx.blockheight == null || tx.confirmations < this.requiredConfirmations)
|
|
569
|
+
throw new Error("Bitcoin transaction not confirmed yet!");
|
|
570
|
+
return await this.wrapper.contract.txsClaimWithTxData(signer ?? this._getInitiator(), this.data, {
|
|
571
|
+
blockhash: tx.blockhash,
|
|
572
|
+
confirmations: tx.confirmations,
|
|
573
|
+
txid: tx.txid,
|
|
574
|
+
hex: tx.hex,
|
|
575
|
+
height: tx.blockheight
|
|
576
|
+
}, this.requiredConfirmations, this.vout, undefined, this.wrapper.synchronizer, true);
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Claims and finishes the swap
|
|
580
|
+
*
|
|
581
|
+
* @param _signer Signer to sign the transactions with, can also be different to the initializer
|
|
582
|
+
* @param abortSignal Abort signal to stop waiting for transaction confirmation
|
|
583
|
+
* @param onBeforeTxSent
|
|
584
|
+
*/
|
|
585
|
+
async claim(_signer, abortSignal, onBeforeTxSent) {
|
|
586
|
+
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.chain.wrapSigner(_signer);
|
|
587
|
+
let txIds;
|
|
588
|
+
try {
|
|
589
|
+
let txCount = 0;
|
|
590
|
+
const txs = await this.txsClaim(signer);
|
|
591
|
+
txIds = await this.wrapper.chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
|
|
592
|
+
txCount++;
|
|
593
|
+
if (onBeforeTxSent != null && txCount === txs.length)
|
|
594
|
+
onBeforeTxSent(txId);
|
|
595
|
+
return Promise.resolve();
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
catch (e) {
|
|
599
|
+
this.logger.info("claim(): Failed to claim ourselves, checking swap claim state...");
|
|
600
|
+
if (this.state === FromBTCSwapState.CLAIM_CLAIMED) {
|
|
601
|
+
this.logger.info("claim(): Transaction state is CLAIM_CLAIMED, swap was successfully claimed by the watchtower");
|
|
602
|
+
return this.claimTxId;
|
|
603
|
+
}
|
|
604
|
+
const status = await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
|
|
605
|
+
if (status?.type === base_1.SwapCommitStateType.PAID) {
|
|
606
|
+
this.logger.info("claim(): Transaction commit status is PAID, swap was successfully claimed by the watchtower");
|
|
607
|
+
if (this.claimTxId == null)
|
|
608
|
+
this.claimTxId = await status.getClaimTxId();
|
|
609
|
+
const txId = buffer_1.Buffer.from(await status.getClaimResult(), "hex").reverse().toString("hex");
|
|
610
|
+
await this._setBitcoinTxId(txId);
|
|
611
|
+
await this._saveAndEmit(FromBTCSwapState.CLAIM_CLAIMED);
|
|
612
|
+
return this.claimTxId;
|
|
613
|
+
}
|
|
614
|
+
throw e;
|
|
615
|
+
}
|
|
616
|
+
this.claimTxId = txIds[txIds.length - 1];
|
|
617
|
+
if (this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.BTC_TX_CONFIRMED ||
|
|
618
|
+
this.state === FromBTCSwapState.EXPIRED || this.state === FromBTCSwapState.FAILED) {
|
|
619
|
+
await this._saveAndEmit(FromBTCSwapState.CLAIM_CLAIMED);
|
|
620
|
+
}
|
|
621
|
+
return txIds[txIds.length - 1];
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Waits till the swap is successfully claimed
|
|
625
|
+
*
|
|
626
|
+
* @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled
|
|
627
|
+
* @param abortSignal AbortSignal
|
|
628
|
+
* @throws {Error} If swap is in invalid state (must be BTC_TX_CONFIRMED)
|
|
629
|
+
* @throws {Error} If the LP refunded sooner than we were able to claim
|
|
630
|
+
* @returns {boolean} whether the swap was claimed in time or not
|
|
631
|
+
*/
|
|
632
|
+
async waitTillClaimed(maxWaitTimeSeconds, abortSignal) {
|
|
633
|
+
if (this.state === FromBTCSwapState.CLAIM_CLAIMED)
|
|
634
|
+
return Promise.resolve(true);
|
|
635
|
+
if (this.state !== FromBTCSwapState.BTC_TX_CONFIRMED)
|
|
636
|
+
throw new Error("Invalid state (not BTC_TX_CONFIRMED)");
|
|
637
|
+
const abortController = (0, Utils_1.extendAbortController)(abortSignal);
|
|
638
|
+
let timedOut = false;
|
|
639
|
+
if (maxWaitTimeSeconds != null) {
|
|
640
|
+
const timeout = setTimeout(() => {
|
|
641
|
+
timedOut = true;
|
|
642
|
+
abortController.abort();
|
|
643
|
+
}, maxWaitTimeSeconds * 1000);
|
|
644
|
+
abortController.signal.addEventListener("abort", () => clearTimeout(timeout));
|
|
645
|
+
}
|
|
646
|
+
let res;
|
|
647
|
+
try {
|
|
648
|
+
res = await Promise.race([
|
|
649
|
+
this.watchdogWaitTillResult(undefined, abortController.signal),
|
|
650
|
+
this.waitTillState(FromBTCSwapState.CLAIM_CLAIMED, "eq", abortController.signal).then(() => 0),
|
|
651
|
+
this.waitTillState(FromBTCSwapState.FAILED, "eq", abortController.signal).then(() => 1),
|
|
652
|
+
]);
|
|
653
|
+
abortController.abort();
|
|
654
|
+
}
|
|
655
|
+
catch (e) {
|
|
656
|
+
abortController.abort();
|
|
657
|
+
if (timedOut)
|
|
658
|
+
return false;
|
|
659
|
+
throw e;
|
|
660
|
+
}
|
|
661
|
+
if (res === 0) {
|
|
662
|
+
this.logger.debug("waitTillClaimed(): Resolved from state change (CLAIM_CLAIMED)");
|
|
663
|
+
return true;
|
|
664
|
+
}
|
|
665
|
+
if (res === 1) {
|
|
666
|
+
this.logger.debug("waitTillClaimed(): Resolved from state change (FAILED)");
|
|
667
|
+
throw new Error("Offerer refunded during claiming");
|
|
668
|
+
}
|
|
669
|
+
this.logger.debug("waitTillClaimed(): Resolved from watchdog");
|
|
670
|
+
if (res?.type === base_1.SwapCommitStateType.PAID) {
|
|
671
|
+
if (this.state !== FromBTCSwapState.CLAIM_CLAIMED) {
|
|
672
|
+
if (this.claimTxId == null)
|
|
673
|
+
this.claimTxId = await res.getClaimTxId();
|
|
674
|
+
const txId = buffer_1.Buffer.from(await res.getClaimResult(), "hex").reverse().toString("hex");
|
|
675
|
+
await this._setBitcoinTxId(txId);
|
|
676
|
+
await this._saveAndEmit(FromBTCSwapState.CLAIM_CLAIMED);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (res?.type === base_1.SwapCommitStateType.NOT_COMMITED || res?.type === base_1.SwapCommitStateType.EXPIRED) {
|
|
680
|
+
if (this.state !== FromBTCSwapState.CLAIM_CLAIMED &&
|
|
681
|
+
this.state !== FromBTCSwapState.FAILED) {
|
|
682
|
+
if (res.getRefundTxId != null)
|
|
683
|
+
this.refundTxId = await res.getRefundTxId();
|
|
684
|
+
await this._saveAndEmit(FromBTCSwapState.FAILED);
|
|
685
|
+
}
|
|
686
|
+
throw new Error("Swap expired while waiting for claim!");
|
|
687
|
+
}
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
//////////////////////////////
|
|
691
|
+
//// Storage
|
|
692
|
+
serialize() {
|
|
693
|
+
return {
|
|
694
|
+
...super.serialize(),
|
|
695
|
+
address: this.address,
|
|
696
|
+
amount: this.amount.toString(10),
|
|
697
|
+
requiredConfirmations: this.requiredConfirmations,
|
|
698
|
+
senderAddress: this.senderAddress,
|
|
699
|
+
txId: this.txId,
|
|
700
|
+
vout: this.vout
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
//////////////////////////////
|
|
704
|
+
//// Swap ticks & sync
|
|
705
|
+
/**
|
|
706
|
+
* Checks the swap's state on-chain and compares it to its internal state, updates/changes it according to on-chain
|
|
707
|
+
* data
|
|
708
|
+
*
|
|
709
|
+
* @private
|
|
710
|
+
*/
|
|
711
|
+
async syncStateFromChain(quoteDefinitelyExpired, commitStatus) {
|
|
712
|
+
if (this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
713
|
+
const quoteExpired = quoteDefinitelyExpired ?? await this._verifyQuoteDefinitelyExpired(); //Make sure we check for expiry here, to prevent race conditions
|
|
714
|
+
const status = commitStatus ?? await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
|
|
715
|
+
switch (status?.type) {
|
|
716
|
+
case base_1.SwapCommitStateType.COMMITED:
|
|
717
|
+
this.state = FromBTCSwapState.CLAIM_COMMITED;
|
|
718
|
+
return true;
|
|
719
|
+
case base_1.SwapCommitStateType.EXPIRED:
|
|
720
|
+
if (this.refundTxId == null && status.getRefundTxId)
|
|
721
|
+
this.refundTxId = await status.getRefundTxId();
|
|
722
|
+
this.state = FromBTCSwapState.QUOTE_EXPIRED;
|
|
723
|
+
return true;
|
|
724
|
+
case base_1.SwapCommitStateType.PAID:
|
|
725
|
+
if (this.claimTxId == null)
|
|
726
|
+
this.claimTxId = await status.getClaimTxId();
|
|
727
|
+
const txId = buffer_1.Buffer.from(await status.getClaimResult(), "hex").reverse().toString("hex");
|
|
728
|
+
await this._setBitcoinTxId(txId);
|
|
729
|
+
this.state = FromBTCSwapState.CLAIM_CLAIMED;
|
|
730
|
+
return true;
|
|
731
|
+
}
|
|
732
|
+
if (quoteExpired) {
|
|
733
|
+
this.state = FromBTCSwapState.QUOTE_EXPIRED;
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
return false;
|
|
737
|
+
}
|
|
738
|
+
if (this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.BTC_TX_CONFIRMED || this.state === FromBTCSwapState.EXPIRED) {
|
|
739
|
+
const status = commitStatus ?? await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
|
|
740
|
+
switch (status?.type) {
|
|
741
|
+
case base_1.SwapCommitStateType.PAID:
|
|
742
|
+
if (this.claimTxId == null)
|
|
743
|
+
this.claimTxId = await status.getClaimTxId();
|
|
744
|
+
const txId = buffer_1.Buffer.from(await status.getClaimResult(), "hex").reverse().toString("hex");
|
|
745
|
+
await this._setBitcoinTxId(txId);
|
|
746
|
+
this.state = FromBTCSwapState.CLAIM_CLAIMED;
|
|
747
|
+
return true;
|
|
748
|
+
case base_1.SwapCommitStateType.NOT_COMMITED:
|
|
749
|
+
case base_1.SwapCommitStateType.EXPIRED:
|
|
750
|
+
if (this.refundTxId == null && status.getRefundTxId)
|
|
751
|
+
this.refundTxId = await status.getRefundTxId();
|
|
752
|
+
this.state = FromBTCSwapState.FAILED;
|
|
753
|
+
return true;
|
|
754
|
+
case base_1.SwapCommitStateType.COMMITED:
|
|
755
|
+
const res = await this.getBitcoinPayment();
|
|
756
|
+
if (res != null) {
|
|
757
|
+
let save = false;
|
|
758
|
+
if (this.txId !== res.txId) {
|
|
759
|
+
if (res.inputAddresses != null)
|
|
760
|
+
this.senderAddress = res.inputAddresses[0];
|
|
761
|
+
this.txId = res.txId;
|
|
762
|
+
this.vout = res.vout;
|
|
763
|
+
save = true;
|
|
764
|
+
}
|
|
765
|
+
if (res.confirmations >= this.requiredConfirmations) {
|
|
766
|
+
this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
|
|
767
|
+
save = true;
|
|
768
|
+
}
|
|
769
|
+
return save;
|
|
770
|
+
}
|
|
771
|
+
break;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
_shouldFetchCommitStatus() {
|
|
777
|
+
return this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED ||
|
|
778
|
+
this.state === FromBTCSwapState.CLAIM_COMMITED || this.state === FromBTCSwapState.BTC_TX_CONFIRMED ||
|
|
779
|
+
this.state === FromBTCSwapState.EXPIRED;
|
|
780
|
+
}
|
|
781
|
+
_shouldFetchExpiryStatus() {
|
|
782
|
+
return this.state === FromBTCSwapState.PR_CREATED || this.state === FromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
783
|
+
}
|
|
784
|
+
async _sync(save, quoteDefinitelyExpired, commitStatus) {
|
|
785
|
+
const changed = await this.syncStateFromChain(quoteDefinitelyExpired, commitStatus);
|
|
786
|
+
if (changed && save)
|
|
787
|
+
await this._saveAndEmit();
|
|
788
|
+
return changed;
|
|
789
|
+
}
|
|
790
|
+
async _tick(save) {
|
|
791
|
+
switch (this.state) {
|
|
792
|
+
case FromBTCSwapState.PR_CREATED:
|
|
793
|
+
if (this.expiry < Date.now()) {
|
|
794
|
+
this.state = FromBTCSwapState.QUOTE_SOFT_EXPIRED;
|
|
795
|
+
if (save)
|
|
796
|
+
await this._saveAndEmit();
|
|
797
|
+
return true;
|
|
798
|
+
}
|
|
799
|
+
break;
|
|
800
|
+
case FromBTCSwapState.CLAIM_COMMITED:
|
|
801
|
+
if (this.getTimeoutTime() < Date.now()) {
|
|
802
|
+
this.state = FromBTCSwapState.EXPIRED;
|
|
803
|
+
if (save)
|
|
804
|
+
await this._saveAndEmit();
|
|
805
|
+
return true;
|
|
806
|
+
}
|
|
807
|
+
case FromBTCSwapState.EXPIRED:
|
|
808
|
+
//Check if bitcoin payment was received every 2 minutes
|
|
809
|
+
if (Math.floor(Date.now() / 1000) % 120 === 0) {
|
|
810
|
+
try {
|
|
811
|
+
const res = await this.getBitcoinPayment();
|
|
812
|
+
if (res != null) {
|
|
813
|
+
let shouldSave = false;
|
|
814
|
+
if (this.txId !== res.txId) {
|
|
815
|
+
this.txId = res.txId;
|
|
816
|
+
this.vout = res.vout;
|
|
817
|
+
if (res.inputAddresses != null)
|
|
818
|
+
this.senderAddress = res.inputAddresses[0];
|
|
819
|
+
shouldSave = true;
|
|
820
|
+
}
|
|
821
|
+
if (res.confirmations >= this.requiredConfirmations) {
|
|
822
|
+
this.state = FromBTCSwapState.BTC_TX_CONFIRMED;
|
|
823
|
+
if (save)
|
|
824
|
+
await this._saveAndEmit();
|
|
825
|
+
shouldSave = true;
|
|
826
|
+
}
|
|
827
|
+
if (shouldSave && save)
|
|
828
|
+
await this._saveAndEmit();
|
|
829
|
+
return shouldSave;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
catch (e) {
|
|
833
|
+
this.logger.warn("tickSwap(" + this.getIdentifierHashString() + "): ", e);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
break;
|
|
837
|
+
}
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
exports.FromBTCSwap = FromBTCSwap;
|