@atomiqlabs/sdk 8.7.7 → 8.8.4
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/LICENSE +201 -201
- package/README.md +1760 -1760
- package/dist/SmartChainAssets.d.ts +181 -181
- package/dist/SmartChainAssets.js +181 -181
- package/dist/bitcoin/coinselect2/accumulative.d.ts +7 -6
- package/dist/bitcoin/coinselect2/accumulative.js +52 -52
- package/dist/bitcoin/coinselect2/blackjack.d.ts +7 -6
- package/dist/bitcoin/coinselect2/blackjack.js +38 -38
- package/dist/bitcoin/coinselect2/index.d.ts +20 -19
- package/dist/bitcoin/coinselect2/index.js +69 -69
- package/dist/bitcoin/coinselect2/utils.d.ts +82 -77
- package/dist/bitcoin/coinselect2/utils.js +158 -123
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +113 -130
- package/dist/bitcoin/wallet/BitcoinWallet.js +335 -322
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +116 -78
- package/dist/bitcoin/wallet/IBitcoinWallet.js +21 -21
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +106 -101
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +196 -190
- package/dist/enums/FeeType.d.ts +15 -15
- package/dist/enums/FeeType.js +19 -19
- package/dist/enums/SwapAmountType.d.ts +15 -15
- package/dist/enums/SwapAmountType.js +19 -19
- package/dist/enums/SwapDirection.d.ts +15 -15
- package/dist/enums/SwapDirection.js +19 -19
- package/dist/enums/SwapSide.d.ts +15 -15
- package/dist/enums/SwapSide.js +19 -19
- package/dist/enums/SwapType.d.ts +75 -75
- package/dist/enums/SwapType.js +79 -79
- package/dist/errors/IntermediaryError.d.ts +13 -13
- package/dist/errors/IntermediaryError.js +27 -27
- package/dist/errors/RequestError.d.ts +32 -32
- package/dist/errors/RequestError.js +54 -54
- package/dist/errors/UserError.d.ts +8 -8
- package/dist/errors/UserError.js +16 -16
- package/dist/events/UnifiedSwapEventListener.d.ts +23 -23
- package/dist/events/UnifiedSwapEventListener.js +132 -132
- package/dist/http/HttpUtils.d.ts +27 -27
- package/dist/http/HttpUtils.js +91 -91
- package/dist/http/paramcoders/IParamReader.d.ts +8 -8
- package/dist/http/paramcoders/IParamReader.js +2 -2
- package/dist/http/paramcoders/ParamDecoder.d.ts +44 -44
- package/dist/http/paramcoders/ParamDecoder.js +137 -137
- package/dist/http/paramcoders/ParamEncoder.d.ts +20 -20
- package/dist/http/paramcoders/ParamEncoder.js +36 -36
- package/dist/http/paramcoders/SchemaVerifier.d.ts +26 -26
- package/dist/http/paramcoders/SchemaVerifier.js +145 -145
- package/dist/http/paramcoders/client/ResponseParamDecoder.d.ts +11 -11
- package/dist/http/paramcoders/client/ResponseParamDecoder.js +57 -57
- package/dist/http/paramcoders/client/StreamParamEncoder.d.ts +13 -13
- package/dist/http/paramcoders/client/StreamParamEncoder.js +26 -26
- package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +16 -16
- package/dist/http/paramcoders/client/StreamingFetchPromise.js +174 -174
- package/dist/index.d.ts +85 -85
- package/dist/index.js +158 -158
- package/dist/intermediaries/Intermediary.d.ts +178 -178
- package/dist/intermediaries/Intermediary.js +166 -166
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +211 -211
- package/dist/intermediaries/IntermediaryDiscovery.js +424 -424
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +450 -440
- package/dist/intermediaries/apis/IntermediaryAPI.js +618 -603
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.d.ts +155 -155
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.js +137 -137
- package/dist/lnurl/LNURL.d.ts +102 -102
- package/dist/lnurl/LNURL.js +321 -321
- package/dist/prices/RedundantSwapPrice.d.ts +110 -110
- package/dist/prices/RedundantSwapPrice.js +222 -222
- package/dist/prices/SingleSwapPrice.d.ts +34 -34
- package/dist/prices/SingleSwapPrice.js +44 -44
- package/dist/prices/SwapPriceWithChain.d.ts +107 -107
- package/dist/prices/SwapPriceWithChain.js +128 -128
- package/dist/prices/abstract/ICachedSwapPrice.d.ts +28 -28
- package/dist/prices/abstract/ICachedSwapPrice.js +62 -62
- package/dist/prices/abstract/IPriceProvider.d.ts +81 -81
- package/dist/prices/abstract/IPriceProvider.js +74 -74
- package/dist/prices/abstract/ISwapPrice.d.ts +168 -168
- package/dist/prices/abstract/ISwapPrice.js +279 -279
- package/dist/prices/providers/BinancePriceProvider.d.ts +23 -23
- package/dist/prices/providers/BinancePriceProvider.js +30 -30
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +23 -23
- package/dist/prices/providers/CoinGeckoPriceProvider.js +29 -29
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +25 -25
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +29 -29
- package/dist/prices/providers/CustomPriceProvider.d.ts +24 -24
- package/dist/prices/providers/CustomPriceProvider.js +35 -35
- package/dist/prices/providers/KrakenPriceProvider.d.ts +38 -38
- package/dist/prices/providers/KrakenPriceProvider.js +45 -45
- package/dist/prices/providers/OKXPriceProvider.d.ts +34 -34
- package/dist/prices/providers/OKXPriceProvider.js +29 -29
- package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +17 -17
- package/dist/prices/providers/abstract/ExchangePriceProvider.js +21 -21
- package/dist/prices/providers/abstract/HttpPriceProvider.d.ts +7 -7
- package/dist/prices/providers/abstract/HttpPriceProvider.js +12 -12
- package/dist/storage/IUnifiedStorage.d.ts +85 -85
- package/dist/storage/IUnifiedStorage.js +2 -2
- package/dist/storage/UnifiedSwapStorage.d.ts +114 -114
- package/dist/storage/UnifiedSwapStorage.js +116 -116
- package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +63 -63
- package/dist/storage-browser/IndexedDBUnifiedStorage.js +298 -298
- package/dist/storage-browser/LocalStorageManager.d.ts +49 -49
- package/dist/storage-browser/LocalStorageManager.js +93 -93
- package/dist/swapper/Swapper.d.ts +732 -692
- package/dist/swapper/Swapper.js +1713 -1657
- package/dist/swapper/SwapperFactory.d.ts +135 -135
- package/dist/swapper/SwapperFactory.js +162 -162
- package/dist/swapper/SwapperUtils.d.ts +206 -206
- package/dist/swapper/SwapperUtils.js +481 -481
- package/dist/swapper/SwapperWithChain.d.ts +404 -404
- package/dist/swapper/SwapperWithChain.js +469 -469
- package/dist/swapper/SwapperWithSigner.d.ts +322 -322
- package/dist/swapper/SwapperWithSigner.js +318 -318
- package/dist/swaps/IAddressSwap.d.ts +22 -22
- package/dist/swaps/IAddressSwap.js +14 -14
- package/dist/swaps/IBTCWalletSwap.d.ts +73 -73
- package/dist/swaps/IBTCWalletSwap.js +18 -18
- package/dist/swaps/IClaimableSwap.d.ts +49 -49
- package/dist/swaps/IClaimableSwap.js +15 -15
- package/dist/swaps/IClaimableSwapWrapper.d.ts +15 -15
- package/dist/swaps/IClaimableSwapWrapper.js +2 -2
- package/dist/swaps/IRefundableSwap.d.ts +43 -43
- package/dist/swaps/IRefundableSwap.js +14 -14
- package/dist/swaps/ISwap.d.ts +392 -392
- package/dist/swaps/ISwap.js +349 -349
- package/dist/swaps/ISwapWithGasDrop.d.ts +21 -21
- package/dist/swaps/ISwapWithGasDrop.js +12 -12
- package/dist/swaps/ISwapWrapper.d.ts +285 -285
- package/dist/swaps/ISwapWrapper.js +353 -353
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +98 -98
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +126 -126
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +139 -139
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +170 -170
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +128 -128
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +167 -167
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +105 -105
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +129 -129
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +162 -162
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +190 -190
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +64 -64
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +82 -82
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +531 -531
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +1285 -1285
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +190 -190
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +432 -432
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +583 -583
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +1371 -1371
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +235 -235
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +525 -525
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +458 -458
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +1126 -1126
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +202 -202
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +406 -406
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +403 -403
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +924 -924
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +68 -68
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +117 -117
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +127 -127
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +256 -256
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +251 -251
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +536 -536
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +73 -73
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +155 -155
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +132 -132
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +286 -286
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +637 -631
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1448 -1444
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +257 -225
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +947 -822
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +261 -261
- package/dist/swaps/trusted/ln/LnForGasSwap.js +511 -511
- package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +40 -40
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +83 -83
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +342 -342
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +715 -715
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +69 -69
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +93 -93
- package/dist/types/AmountData.d.ts +10 -10
- package/dist/types/AmountData.js +2 -2
- package/dist/types/CustomPriceFunction.d.ts +11 -11
- package/dist/types/CustomPriceFunction.js +2 -2
- package/dist/types/PriceInfoType.d.ts +28 -28
- package/dist/types/PriceInfoType.js +57 -57
- package/dist/types/SwapExecutionAction.d.ts +88 -88
- package/dist/types/SwapExecutionAction.js +2 -2
- package/dist/types/SwapStateInfo.d.ts +5 -5
- package/dist/types/SwapStateInfo.js +2 -2
- package/dist/types/SwapWithSigner.d.ts +17 -17
- package/dist/types/SwapWithSigner.js +43 -43
- package/dist/types/Token.d.ts +99 -99
- package/dist/types/Token.js +76 -76
- package/dist/types/TokenAmount.d.ts +69 -69
- package/dist/types/TokenAmount.js +60 -60
- package/dist/types/fees/Fee.d.ts +50 -50
- package/dist/types/fees/Fee.js +2 -2
- package/dist/types/fees/FeeBreakdown.d.ts +11 -11
- package/dist/types/fees/FeeBreakdown.js +2 -2
- package/dist/types/fees/PercentagePPM.d.ts +17 -17
- package/dist/types/fees/PercentagePPM.js +18 -18
- package/dist/types/lnurl/LNURLPay.d.ts +61 -61
- package/dist/types/lnurl/LNURLPay.js +31 -31
- package/dist/types/lnurl/LNURLWithdraw.d.ts +48 -48
- package/dist/types/lnurl/LNURLWithdraw.js +27 -27
- package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -24
- package/dist/types/wallets/LightningInvoiceCreateService.js +15 -15
- package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +23 -23
- package/dist/types/wallets/MinimalBitcoinWalletInterface.js +2 -2
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +9 -9
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.js +2 -2
- package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -1
- package/dist/utils/AutomaticClockDriftCorrection.js +70 -70
- package/dist/utils/BitcoinUtils.d.ts +16 -14
- package/dist/utils/BitcoinUtils.js +141 -102
- package/dist/utils/BitcoinWalletUtils.d.ts +7 -7
- package/dist/utils/BitcoinWalletUtils.js +14 -14
- package/dist/utils/Logger.d.ts +7 -7
- package/dist/utils/Logger.js +12 -12
- package/dist/utils/RetryUtils.d.ts +22 -22
- package/dist/utils/RetryUtils.js +67 -67
- package/dist/utils/SwapUtils.d.ts +88 -88
- package/dist/utils/SwapUtils.js +72 -72
- package/dist/utils/TimeoutUtils.d.ts +17 -17
- package/dist/utils/TimeoutUtils.js +55 -55
- package/dist/utils/TokenUtils.d.ts +19 -19
- package/dist/utils/TokenUtils.js +37 -37
- package/dist/utils/TypeUtils.d.ts +7 -7
- package/dist/utils/TypeUtils.js +2 -2
- package/dist/utils/Utils.d.ts +67 -67
- package/dist/utils/Utils.js +208 -208
- package/package.json +43 -43
- package/src/SmartChainAssets.ts +186 -186
- package/src/bitcoin/coinselect2/accumulative.ts +69 -68
- package/src/bitcoin/coinselect2/blackjack.ts +50 -49
- package/src/bitcoin/coinselect2/index.ts +93 -92
- package/src/bitcoin/coinselect2/utils.ts +236 -195
- package/src/bitcoin/wallet/BitcoinWallet.ts +439 -427
- package/src/bitcoin/wallet/IBitcoinWallet.ts +140 -99
- package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +225 -217
- package/src/enums/FeeType.ts +15 -15
- package/src/enums/SwapAmountType.ts +16 -16
- package/src/enums/SwapDirection.ts +15 -15
- package/src/enums/SwapSide.ts +16 -16
- package/src/enums/SwapType.ts +75 -75
- package/src/errors/IntermediaryError.ts +28 -28
- package/src/errors/RequestError.ts +64 -64
- package/src/errors/UserError.ts +15 -15
- package/src/events/UnifiedSwapEventListener.ts +173 -173
- package/src/http/HttpUtils.ts +91 -91
- package/src/http/paramcoders/IParamReader.ts +9 -9
- package/src/http/paramcoders/ParamDecoder.ts +145 -145
- package/src/http/paramcoders/ParamEncoder.ts +40 -40
- package/src/http/paramcoders/SchemaVerifier.ts +153 -153
- package/src/http/paramcoders/client/ResponseParamDecoder.ts +57 -57
- package/src/http/paramcoders/client/StreamParamEncoder.ts +28 -28
- package/src/http/paramcoders/client/StreamingFetchPromise.ts +192 -192
- package/src/index.ts +140 -140
- package/src/intermediaries/Intermediary.ts +280 -280
- package/src/intermediaries/IntermediaryDiscovery.ts +541 -541
- package/src/intermediaries/apis/IntermediaryAPI.ts +963 -947
- package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +257 -257
- package/src/lnurl/LNURL.ts +402 -402
- package/src/prices/RedundantSwapPrice.ts +264 -264
- package/src/prices/SingleSwapPrice.ts +50 -50
- package/src/prices/SwapPriceWithChain.ts +194 -194
- package/src/prices/abstract/ICachedSwapPrice.ts +85 -85
- package/src/prices/abstract/IPriceProvider.ts +127 -127
- package/src/prices/abstract/ISwapPrice.ts +390 -390
- package/src/prices/providers/BinancePriceProvider.ts +48 -48
- package/src/prices/providers/CoinGeckoPriceProvider.ts +46 -46
- package/src/prices/providers/CoinPaprikaPriceProvider.ts +49 -49
- package/src/prices/providers/CustomPriceProvider.ts +40 -40
- package/src/prices/providers/KrakenPriceProvider.ts +83 -83
- package/src/prices/providers/OKXPriceProvider.ts +59 -59
- package/src/prices/providers/abstract/ExchangePriceProvider.ts +31 -31
- package/src/prices/providers/abstract/HttpPriceProvider.ts +14 -14
- package/src/storage/IUnifiedStorage.ts +95 -95
- package/src/storage/UnifiedSwapStorage.ts +141 -141
- package/src/storage-browser/IndexedDBUnifiedStorage.ts +350 -350
- package/src/storage-browser/LocalStorageManager.ts +106 -106
- package/src/swapper/Swapper.ts +2488 -2416
- package/src/swapper/SwapperFactory.ts +307 -307
- package/src/swapper/SwapperUtils.ts +570 -570
- package/src/swapper/SwapperWithChain.ts +707 -707
- package/src/swapper/SwapperWithSigner.ts +511 -511
- package/src/swaps/IAddressSwap.ts +30 -30
- package/src/swaps/IBTCWalletSwap.ts +92 -92
- package/src/swaps/IClaimableSwap.ts +65 -65
- package/src/swaps/IClaimableSwapWrapper.ts +17 -17
- package/src/swaps/IRefundableSwap.ts +58 -58
- package/src/swaps/ISwap.ts +703 -703
- package/src/swaps/ISwapWithGasDrop.ts +25 -25
- package/src/swaps/ISwapWrapper.ts +539 -539
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +217 -217
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +269 -269
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +282 -282
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +169 -169
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +300 -300
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +107 -107
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +1473 -1474
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +601 -601
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +1582 -1582
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +750 -750
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +1299 -1299
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +610 -610
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +1096 -1096
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +138 -138
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +304 -304
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +786 -786
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +206 -206
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +401 -401
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +1812 -1799
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +1236 -1060
- package/src/swaps/trusted/ln/LnForGasSwap.ts +589 -589
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +91 -91
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +862 -862
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +131 -131
- package/src/types/AmountData.ts +9 -9
- package/src/types/CustomPriceFunction.ts +11 -11
- package/src/types/PriceInfoType.ts +66 -66
- package/src/types/SwapExecutionAction.ts +99 -99
- package/src/types/SwapStateInfo.ts +6 -6
- package/src/types/SwapWithSigner.ts +61 -61
- package/src/types/Token.ts +163 -163
- package/src/types/TokenAmount.ts +132 -132
- package/src/types/fees/Fee.ts +56 -56
- package/src/types/fees/FeeBreakdown.ts +11 -11
- package/src/types/fees/PercentagePPM.ts +26 -26
- package/src/types/lnurl/LNURLPay.ts +79 -79
- package/src/types/lnurl/LNURLWithdraw.ts +61 -61
- package/src/types/wallets/LightningInvoiceCreateService.ts +30 -30
- package/src/types/wallets/MinimalBitcoinWalletInterface.ts +21 -21
- package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +9 -9
- package/src/utils/AutomaticClockDriftCorrection.ts +71 -71
- package/src/utils/BitcoinUtils.ts +132 -91
- package/src/utils/BitcoinWalletUtils.ts +15 -15
- package/src/utils/Logger.ts +14 -14
- package/src/utils/RetryUtils.ts +78 -78
- package/src/utils/SwapUtils.ts +99 -99
- package/src/utils/TimeoutUtils.ts +49 -49
- package/src/utils/TokenUtils.ts +33 -33
- package/src/utils/TypeUtils.ts +8 -8
- package/src/utils/Utils.ts +212 -212
|
@@ -1,610 +1,610 @@
|
|
|
1
|
-
import {IFromBTCWrapper} from "../IFromBTCWrapper";
|
|
2
|
-
import {FromBTCSwap, FromBTCSwapInit, FromBTCSwapState} from "./FromBTCSwap";
|
|
3
|
-
import {
|
|
4
|
-
ChainSwapType,
|
|
5
|
-
ChainType,
|
|
6
|
-
ClaimEvent,
|
|
7
|
-
InitializeEvent,
|
|
8
|
-
RefundEvent,
|
|
9
|
-
RelaySynchronizer,
|
|
10
|
-
SwapData,
|
|
11
|
-
BtcRelay, BitcoinRpcWithAddressIndex, SwapCommitState
|
|
12
|
-
} from "@atomiqlabs/base";
|
|
13
|
-
import {EventEmitter} from "events";
|
|
14
|
-
import {Intermediary} from "../../../../intermediaries/Intermediary";
|
|
15
|
-
import {ISwapPrice} from "../../../../prices/abstract/ISwapPrice";
|
|
16
|
-
import {ISwapWrapperOptions, WrapperCtorTokens} from "../../../ISwapWrapper";
|
|
17
|
-
import {Buffer} from "buffer";
|
|
18
|
-
import {IntermediaryError} from "../../../../errors/IntermediaryError";
|
|
19
|
-
import {SwapType} from "../../../../enums/SwapType";
|
|
20
|
-
import {
|
|
21
|
-
extendAbortController, mapArrayToObject,
|
|
22
|
-
randomBytes,
|
|
23
|
-
throwIfUndefined
|
|
24
|
-
} from "../../../../utils/Utils";
|
|
25
|
-
import { toOutputScript} from "../../../../utils/BitcoinUtils";
|
|
26
|
-
import {FromBTCResponseType, IntermediaryAPI} from "../../../../intermediaries/apis/IntermediaryAPI";
|
|
27
|
-
import {RequestError} from "../../../../errors/RequestError";
|
|
28
|
-
import {BTC_NETWORK, TEST_NETWORK} from "@scure/btc-signer/utils";
|
|
29
|
-
import {UnifiedSwapEventListener} from "../../../../events/UnifiedSwapEventListener";
|
|
30
|
-
import {UnifiedSwapStorage} from "../../../../storage/UnifiedSwapStorage";
|
|
31
|
-
import {ISwap} from "../../../ISwap";
|
|
32
|
-
import {IClaimableSwapWrapper} from "../../../IClaimableSwapWrapper";
|
|
33
|
-
import {IFromBTCSelfInitDefinition} from "../IFromBTCSelfInitSwap";
|
|
34
|
-
import {AmountData} from "../../../../types/AmountData";
|
|
35
|
-
import {tryWithRetries} from "../../../../utils/RetryUtils";
|
|
36
|
-
import {AllOptional} from "../../../../utils/TypeUtils";
|
|
37
|
-
import {UserError} from "../../../../errors/UserError";
|
|
38
|
-
|
|
39
|
-
export type FromBTCOptions = {
|
|
40
|
-
/**
|
|
41
|
-
* A flag to attach 0 watchtower fee to the swap, this would make the settlement unattractive for the watchtowers
|
|
42
|
-
* and therefore automatic settlement for such swaps will not be possible, you will have to settle manually
|
|
43
|
-
* with {@link FromBTCLNSwap.claim} or {@link FromBTCLNSwap.txsClaim} functions.
|
|
44
|
-
*/
|
|
45
|
-
unsafeZeroWatchtowerFee?: boolean,
|
|
46
|
-
/**
|
|
47
|
-
* A safety factor to use when estimating the watchtower fee to attach to the swap (this has to cover the gas fee
|
|
48
|
-
* of watchtowers settling the swap). A higher multiple here would mean that a swap is more attractive for
|
|
49
|
-
* watchtowers to settle automatically.
|
|
50
|
-
*
|
|
51
|
-
* Uses a `1.5` multiple by default (i.e. the current network fee is multiplied by 1.5 and then used to estimate
|
|
52
|
-
* the settlement gas fee cost).
|
|
53
|
-
*
|
|
54
|
-
* Also accepts `bigint` for legacy reasons.
|
|
55
|
-
*/
|
|
56
|
-
feeSafetyFactor?: number | bigint,
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @deprecated Removed as it is deemed not necessary
|
|
60
|
-
*/
|
|
61
|
-
blockSafetyFactor?: number
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export type FromBTCWrapperOptions = ISwapWrapperOptions & {
|
|
65
|
-
safetyFactor: number,
|
|
66
|
-
blocksTillTxConfirms: number,
|
|
67
|
-
maxConfirmations: number,
|
|
68
|
-
minSendWindow: number,
|
|
69
|
-
bitcoinNetwork: BTC_NETWORK,
|
|
70
|
-
bitcoinBlocktime: number
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export type FromBTCDefinition<T extends ChainType> = IFromBTCSelfInitDefinition<T, FromBTCWrapper<T>, FromBTCSwap<T>>;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Legacy escrow (PrTLC) based swap for Bitcoin -> Smart chains, requires manual initiation
|
|
77
|
-
* of the swap escrow on the destination chain.
|
|
78
|
-
*
|
|
79
|
-
* @category Swaps/Legacy/Bitcoin → Smart chain
|
|
80
|
-
*/
|
|
81
|
-
export class FromBTCWrapper<
|
|
82
|
-
T extends ChainType
|
|
83
|
-
> extends IFromBTCWrapper<T, FromBTCDefinition<T>, FromBTCWrapperOptions> implements IClaimableSwapWrapper<FromBTCSwap<T>> {
|
|
84
|
-
public readonly TYPE: SwapType.FROM_BTC = SwapType.FROM_BTC;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @internal
|
|
88
|
-
*/
|
|
89
|
-
protected readonly tickSwapState = [FromBTCSwapState.PR_CREATED, FromBTCSwapState.CLAIM_COMMITED, FromBTCSwapState.EXPIRED];
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @internal
|
|
93
|
-
*/
|
|
94
|
-
readonly _pendingSwapStates = [
|
|
95
|
-
FromBTCSwapState.PR_CREATED,
|
|
96
|
-
FromBTCSwapState.QUOTE_SOFT_EXPIRED,
|
|
97
|
-
FromBTCSwapState.CLAIM_COMMITED,
|
|
98
|
-
FromBTCSwapState.BTC_TX_CONFIRMED,
|
|
99
|
-
FromBTCSwapState.EXPIRED
|
|
100
|
-
];
|
|
101
|
-
/**
|
|
102
|
-
* @internal
|
|
103
|
-
*/
|
|
104
|
-
readonly _claimableSwapStates = [FromBTCSwapState.BTC_TX_CONFIRMED];
|
|
105
|
-
/**
|
|
106
|
-
* @internal
|
|
107
|
-
*/
|
|
108
|
-
readonly _swapDeserializer = FromBTCSwap;
|
|
109
|
-
/**
|
|
110
|
-
* @internal
|
|
111
|
-
*/
|
|
112
|
-
readonly _synchronizer: (version?: string) => RelaySynchronizer<any, T["TX"], any> = (version?: string) => {
|
|
113
|
-
const _version = version ?? "v1";
|
|
114
|
-
const data = this.versionedSynchronizer[_version];
|
|
115
|
-
if(data==null) throw new Error(`Invalid contract version ${_version} requested`);
|
|
116
|
-
return data.synchronizer;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* @internal
|
|
121
|
-
*/
|
|
122
|
-
readonly _btcRpc: BitcoinRpcWithAddressIndex<any>;
|
|
123
|
-
|
|
124
|
-
private readonly btcRelay: (version?: string) => BtcRelay<any, T["TX"], any> = (version?: string) => {
|
|
125
|
-
const _version = version ?? "v1";
|
|
126
|
-
const data = this.versionedBtcRelay[_version];
|
|
127
|
-
if(data==null) throw new Error(`Invalid contract version ${_version} requested`);
|
|
128
|
-
return data.btcRelay;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
private readonly versionedBtcRelay: {
|
|
132
|
-
[version: string]: {
|
|
133
|
-
btcRelay: BtcRelay<any, T["TX"], any>
|
|
134
|
-
}
|
|
135
|
-
}= {};
|
|
136
|
-
|
|
137
|
-
private readonly versionedSynchronizer: {
|
|
138
|
-
[version: string]: {
|
|
139
|
-
synchronizer: RelaySynchronizer<any, T["TX"], any>
|
|
140
|
-
}
|
|
141
|
-
}= {};
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* @param chainIdentifier
|
|
145
|
-
* @param unifiedStorage Storage interface for the current environment
|
|
146
|
-
* @param unifiedChainEvents On-chain event listener
|
|
147
|
-
* @param chain
|
|
148
|
-
* @param prices Pricing to use
|
|
149
|
-
* @param tokens
|
|
150
|
-
* @param versionedContracts
|
|
151
|
-
* @param versionedSynchronizer
|
|
152
|
-
* @param btcRpc Bitcoin RPC which also supports getting transactions by txoHash
|
|
153
|
-
* @param options
|
|
154
|
-
* @param events Instance to use for emitting events
|
|
155
|
-
*/
|
|
156
|
-
constructor(
|
|
157
|
-
chainIdentifier: string,
|
|
158
|
-
unifiedStorage: UnifiedSwapStorage<T>,
|
|
159
|
-
unifiedChainEvents: UnifiedSwapEventListener<T>,
|
|
160
|
-
chain: T["ChainInterface"],
|
|
161
|
-
prices: ISwapPrice,
|
|
162
|
-
tokens: WrapperCtorTokens,
|
|
163
|
-
versionedContracts: {
|
|
164
|
-
[version: string]: {
|
|
165
|
-
swapContract: T["Contract"],
|
|
166
|
-
swapDataConstructor: new (data: any) => T["Data"],
|
|
167
|
-
btcRelay: BtcRelay<any, T["TX"], any>
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
versionedSynchronizer: {
|
|
171
|
-
[version: string]: {
|
|
172
|
-
synchronizer: RelaySynchronizer<any, T["TX"], any>
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
btcRpc: BitcoinRpcWithAddressIndex<any>,
|
|
176
|
-
options?: AllOptional<FromBTCWrapperOptions>,
|
|
177
|
-
events?: EventEmitter<{swapState: [ISwap]}>
|
|
178
|
-
) {
|
|
179
|
-
super(
|
|
180
|
-
chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens,
|
|
181
|
-
{
|
|
182
|
-
...options,
|
|
183
|
-
bitcoinNetwork: options?.bitcoinNetwork ?? TEST_NETWORK,
|
|
184
|
-
safetyFactor: options?.safetyFactor ?? 2,
|
|
185
|
-
blocksTillTxConfirms: options?.blocksTillTxConfirms ?? 12,
|
|
186
|
-
maxConfirmations: options?.maxConfirmations ?? 6,
|
|
187
|
-
minSendWindow: options?.minSendWindow ?? 30*60, //Minimum time window for user to send in the on-chain funds for From BTC swap
|
|
188
|
-
bitcoinBlocktime: options?.bitcoinBlocktime ?? 10*60
|
|
189
|
-
},
|
|
190
|
-
versionedContracts,
|
|
191
|
-
events
|
|
192
|
-
);
|
|
193
|
-
this._btcRpc = btcRpc;
|
|
194
|
-
this.versionedBtcRelay = versionedContracts;
|
|
195
|
-
this.versionedSynchronizer = versionedSynchronizer;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* @inheritDoc
|
|
200
|
-
* @internal
|
|
201
|
-
*/
|
|
202
|
-
protected processEventInitialize(swap: FromBTCSwap<T>, event: InitializeEvent<T["Data"]>): Promise<boolean> {
|
|
203
|
-
if(swap._state===FromBTCSwapState.PR_CREATED || swap._state===FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
204
|
-
swap._state = FromBTCSwapState.CLAIM_COMMITED;
|
|
205
|
-
return Promise.resolve(true);
|
|
206
|
-
}
|
|
207
|
-
return Promise.resolve(false);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* @inheritDoc
|
|
212
|
-
* @internal
|
|
213
|
-
*/
|
|
214
|
-
protected async processEventClaim(swap: FromBTCSwap<T>, event: ClaimEvent<T["Data"]>): Promise<boolean> {
|
|
215
|
-
if(swap._state!==FromBTCSwapState.FAILED && swap._state!==FromBTCSwapState.CLAIM_CLAIMED) {
|
|
216
|
-
await swap._setBitcoinTxId(Buffer.from(event.result, "hex").reverse().toString("hex")).catch(e => {
|
|
217
|
-
this.logger.warn("processEventClaim(): Error setting bitcoin txId: ", e);
|
|
218
|
-
});
|
|
219
|
-
swap._state = FromBTCSwapState.CLAIM_CLAIMED;
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
return false;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* @inheritDoc
|
|
227
|
-
* @internal
|
|
228
|
-
*/
|
|
229
|
-
protected processEventRefund(swap: FromBTCSwap<T>, event: RefundEvent<T["Data"]>): Promise<boolean> {
|
|
230
|
-
if(swap._state!==FromBTCSwapState.CLAIM_CLAIMED && swap._state!==FromBTCSwapState.FAILED) {
|
|
231
|
-
swap._state = FromBTCSwapState.FAILED;
|
|
232
|
-
return Promise.resolve(true);
|
|
233
|
-
}
|
|
234
|
-
return Promise.resolve(false);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Returns the swap expiry, leaving enough time for the user to send a transaction and for it to confirm
|
|
239
|
-
*
|
|
240
|
-
* @param data Swap data
|
|
241
|
-
* @param requiredConfirmations Confirmations required on the bitcoin side to settle the swap
|
|
242
|
-
*
|
|
243
|
-
* @internal
|
|
244
|
-
*/
|
|
245
|
-
_getOnchainSendTimeout(data: SwapData, requiredConfirmations: number): bigint {
|
|
246
|
-
const tsDelta = (this._options.blocksTillTxConfirms + requiredConfirmations) * this._options.bitcoinBlocktime * this._options.safetyFactor;
|
|
247
|
-
return data.getExpiry() - BigInt(tsDelta);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Pre-fetches claimer (watchtower) bounty data for the swap. Doesn't throw, instead returns null and aborts the
|
|
252
|
-
* provided abortController
|
|
253
|
-
*
|
|
254
|
-
* @param signer Smartchain signer address initiating the swap
|
|
255
|
-
* @param amountData
|
|
256
|
-
* @param options Options as passed to the swap creation function
|
|
257
|
-
* @param abortController
|
|
258
|
-
* @param contractVersion
|
|
259
|
-
*
|
|
260
|
-
* @private
|
|
261
|
-
*/
|
|
262
|
-
private async preFetchClaimerBounty(
|
|
263
|
-
signer: string,
|
|
264
|
-
amountData: AmountData,
|
|
265
|
-
options: {
|
|
266
|
-
feeSafetyFactorPPM: bigint,
|
|
267
|
-
blockSafetyFactor: bigint,
|
|
268
|
-
unsafeZeroWatchtowerFee: boolean
|
|
269
|
-
},
|
|
270
|
-
abortController: AbortController,
|
|
271
|
-
contractVersion: string
|
|
272
|
-
): Promise<{
|
|
273
|
-
feePerBlock: bigint,
|
|
274
|
-
safetyFactor: bigint,
|
|
275
|
-
startTimestamp: bigint,
|
|
276
|
-
addBlock: bigint,
|
|
277
|
-
addFee: bigint
|
|
278
|
-
} | undefined> {
|
|
279
|
-
const startTimestamp = BigInt(Math.floor(Date.now()/1000));
|
|
280
|
-
|
|
281
|
-
if(options.unsafeZeroWatchtowerFee) {
|
|
282
|
-
return {
|
|
283
|
-
feePerBlock: 0n,
|
|
284
|
-
safetyFactor: options.blockSafetyFactor,
|
|
285
|
-
startTimestamp: startTimestamp,
|
|
286
|
-
addBlock: 0n,
|
|
287
|
-
addFee: 0n
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const dummyAmount = BigInt(Math.floor(Math.random()* 0x1000000));
|
|
292
|
-
const dummySwapData = await this._contract(contractVersion).createSwapData(
|
|
293
|
-
ChainSwapType.CHAIN, signer, signer, amountData.token,
|
|
294
|
-
dummyAmount, this._contract(contractVersion).getHashForOnchain(randomBytes(20), dummyAmount, 3).toString("hex"),
|
|
295
|
-
this.getRandomSequence(), startTimestamp, false, true,
|
|
296
|
-
BigInt(Math.floor(Math.random() * 0x10000)), BigInt(Math.floor(Math.random() * 0x10000))
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
const [feePerBlock, btcRelayData, currentBtcBlock, claimFeeRate] = await Promise.all([
|
|
301
|
-
this.btcRelay(contractVersion).getFeePerBlock(),
|
|
302
|
-
this.btcRelay(contractVersion).getTipData(),
|
|
303
|
-
this._btcRpc.getTipHeight(),
|
|
304
|
-
this._contract(contractVersion).getClaimFee(signer, dummySwapData)
|
|
305
|
-
]);
|
|
306
|
-
|
|
307
|
-
if(btcRelayData==null) throw new Error("Btc relay not initialized!");
|
|
308
|
-
|
|
309
|
-
const currentBtcRelayBlock = btcRelayData.blockheight;
|
|
310
|
-
const addBlock = Math.max(currentBtcBlock-currentBtcRelayBlock, 0);
|
|
311
|
-
return {
|
|
312
|
-
feePerBlock: feePerBlock * options.feeSafetyFactorPPM / 1_000_000n,
|
|
313
|
-
safetyFactor: options.blockSafetyFactor,
|
|
314
|
-
startTimestamp: startTimestamp,
|
|
315
|
-
addBlock: BigInt(addBlock),
|
|
316
|
-
addFee: claimFeeRate * options.feeSafetyFactorPPM / 1_000_000n
|
|
317
|
-
}
|
|
318
|
-
} catch (e) {
|
|
319
|
-
abortController.abort(e);
|
|
320
|
-
return undefined;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Returns calculated claimer bounty calculated from the claimer bounty data as fetched from preFetchClaimerBounty()
|
|
326
|
-
*
|
|
327
|
-
* @param data Parsed swap data returned from the intermediary
|
|
328
|
-
* @param options Options as passed to the swap creation function
|
|
329
|
-
* @param claimerBounty Claimer bounty data as fetched from {@link preFetchClaimerBounty} function
|
|
330
|
-
*
|
|
331
|
-
* @private
|
|
332
|
-
*/
|
|
333
|
-
private getClaimerBounty(
|
|
334
|
-
data: T["Data"],
|
|
335
|
-
options: {
|
|
336
|
-
blockSafetyFactor: bigint
|
|
337
|
-
},
|
|
338
|
-
claimerBounty: {
|
|
339
|
-
feePerBlock: bigint,
|
|
340
|
-
safetyFactor: bigint,
|
|
341
|
-
startTimestamp: bigint,
|
|
342
|
-
addBlock: bigint,
|
|
343
|
-
addFee: bigint
|
|
344
|
-
}
|
|
345
|
-
) : bigint {
|
|
346
|
-
const tsDelta = data.getExpiry() - claimerBounty.startTimestamp;
|
|
347
|
-
const blocksDelta = tsDelta / BigInt(this._options.bitcoinBlocktime) * options.blockSafetyFactor;
|
|
348
|
-
const totalBlock = blocksDelta + claimerBounty.addBlock;
|
|
349
|
-
return claimerBounty.addFee + (totalBlock * claimerBounty.feePerBlock);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Verifies response returned from intermediary
|
|
354
|
-
*
|
|
355
|
-
* @param signer
|
|
356
|
-
* @param resp Response as returned by the intermediary
|
|
357
|
-
* @param amountData
|
|
358
|
-
* @param lp Intermediary
|
|
359
|
-
* @param options Options as passed to the swap creation function
|
|
360
|
-
* @param data Parsed swap data returned by the intermediary
|
|
361
|
-
* @param sequence Required swap sequence
|
|
362
|
-
* @param claimerBounty Claimer bount data as returned from the preFetchClaimerBounty() pre-fetch promise
|
|
363
|
-
* @param depositToken
|
|
364
|
-
*
|
|
365
|
-
* @throws {IntermediaryError} in case the response is invalid
|
|
366
|
-
*
|
|
367
|
-
* @private
|
|
368
|
-
*/
|
|
369
|
-
private verifyReturnedData(
|
|
370
|
-
signer: string,
|
|
371
|
-
resp: FromBTCResponseType,
|
|
372
|
-
amountData: AmountData,
|
|
373
|
-
lp: Intermediary,
|
|
374
|
-
options: {
|
|
375
|
-
blockSafetyFactor: bigint
|
|
376
|
-
},
|
|
377
|
-
data: T["Data"],
|
|
378
|
-
sequence: bigint,
|
|
379
|
-
claimerBounty: {
|
|
380
|
-
feePerBlock: bigint,
|
|
381
|
-
safetyFactor: bigint,
|
|
382
|
-
startTimestamp: bigint,
|
|
383
|
-
addBlock: bigint,
|
|
384
|
-
addFee: bigint
|
|
385
|
-
},
|
|
386
|
-
depositToken: string
|
|
387
|
-
): void {
|
|
388
|
-
if(amountData.exactIn) {
|
|
389
|
-
if(resp.amount !== amountData.amount) throw new IntermediaryError("Invalid amount returned");
|
|
390
|
-
} else {
|
|
391
|
-
if(resp.total !== amountData.amount) throw new IntermediaryError("Invalid total returned");
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
const requiredConfirmations = resp.confirmations;
|
|
395
|
-
if(requiredConfirmations>this._options.maxConfirmations) throw new IntermediaryError("Requires too many confirmations");
|
|
396
|
-
|
|
397
|
-
const totalClaimerBounty = this.getClaimerBounty(data, options, claimerBounty);
|
|
398
|
-
|
|
399
|
-
if(
|
|
400
|
-
data.getClaimerBounty() !== totalClaimerBounty ||
|
|
401
|
-
data.getType()!=ChainSwapType.CHAIN ||
|
|
402
|
-
data.getSequence() !== sequence ||
|
|
403
|
-
data.getAmount() !== resp.total ||
|
|
404
|
-
data.isPayIn() ||
|
|
405
|
-
!data.isToken(amountData.token) ||
|
|
406
|
-
!data.isOfferer(lp.getAddress(this.chainIdentifier)) ||
|
|
407
|
-
!data.isClaimer(signer) ||
|
|
408
|
-
!data.isDepositToken(depositToken) ||
|
|
409
|
-
data.hasSuccessAction()
|
|
410
|
-
) {
|
|
411
|
-
throw new IntermediaryError("Invalid data returned");
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
//Check that we have enough time to send the TX and for it to confirm
|
|
415
|
-
const expiry = this._getOnchainSendTimeout(data, requiredConfirmations);
|
|
416
|
-
const currentTimestamp = BigInt(Math.floor(Date.now()/1000));
|
|
417
|
-
if((expiry - currentTimestamp) < BigInt(this._options.minSendWindow)) {
|
|
418
|
-
throw new IntermediaryError("Send window too low");
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
const version = lp.getContractVersion(this.chainIdentifier);
|
|
422
|
-
|
|
423
|
-
const lockingScript = toOutputScript(this._options.bitcoinNetwork, resp.btcAddress);
|
|
424
|
-
const desiredExtraData = this._contract(version).getExtraData(lockingScript, resp.amount, requiredConfirmations);
|
|
425
|
-
const desiredClaimHash = this._contract(version).getHashForOnchain(lockingScript, resp.amount, requiredConfirmations);
|
|
426
|
-
if(!desiredClaimHash.equals(Buffer.from(data.getClaimHash(), "hex"))) {
|
|
427
|
-
throw new IntermediaryError("Invalid claim hash returned!");
|
|
428
|
-
}
|
|
429
|
-
const extraData = data.getExtraData();
|
|
430
|
-
if(extraData==null || !desiredExtraData.equals(Buffer.from(extraData, "hex"))) {
|
|
431
|
-
throw new IntermediaryError("Invalid extra data returned!");
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Returns a newly created legacy Bitcoin -> Smart chain swap using the PrTLC based escrow swap protocol,
|
|
437
|
-
* with the passed amount.
|
|
438
|
-
*
|
|
439
|
-
* @param recipient Smart chain signer's address on the destination chain
|
|
440
|
-
* @param amountData Amount, token and exact input/output data for to swap
|
|
441
|
-
* @param lps An array of intermediaries (LPs) to get the quotes from
|
|
442
|
-
* @param options Optional additional quote options
|
|
443
|
-
* @param additionalParams Optional additional parameters sent to the LP when creating the swap
|
|
444
|
-
* @param abortSignal Abort signal
|
|
445
|
-
*/
|
|
446
|
-
create(
|
|
447
|
-
recipient: string,
|
|
448
|
-
amountData: AmountData,
|
|
449
|
-
lps: Intermediary[],
|
|
450
|
-
options?: FromBTCOptions,
|
|
451
|
-
additionalParams?: Record<string, any>,
|
|
452
|
-
abortSignal?: AbortSignal
|
|
453
|
-
): {
|
|
454
|
-
quote: Promise<FromBTCSwap<T>>,
|
|
455
|
-
intermediary: Intermediary
|
|
456
|
-
}[] {
|
|
457
|
-
let feeSafetyFactorPPM: bigint = 1_500_000n;
|
|
458
|
-
if(typeof(options?.feeSafetyFactor)==="bigint") {
|
|
459
|
-
feeSafetyFactorPPM = options.feeSafetyFactor * 1_000_000n;
|
|
460
|
-
} else if(typeof(options?.feeSafetyFactor)==="number") {
|
|
461
|
-
feeSafetyFactorPPM = BigInt(Math.floor(options.feeSafetyFactor * 1_000_000));
|
|
462
|
-
}
|
|
463
|
-
const lpVersions = Intermediary.getContractVersionsForLps(this.chainIdentifier, lps);
|
|
464
|
-
|
|
465
|
-
const _options = {
|
|
466
|
-
blockSafetyFactor: options?.blockSafetyFactor!=null ? BigInt(options.blockSafetyFactor) : 1n,
|
|
467
|
-
feeSafetyFactorPPM,
|
|
468
|
-
unsafeZeroWatchtowerFee: options?.unsafeZeroWatchtowerFee ?? false
|
|
469
|
-
};
|
|
470
|
-
|
|
471
|
-
const sequence: bigint = this.getRandomSequence();
|
|
472
|
-
|
|
473
|
-
const _abortController = extendAbortController(abortSignal);
|
|
474
|
-
const pricePrefetchPromise: Promise<bigint | undefined> = this.preFetchPrice(amountData, _abortController.signal);
|
|
475
|
-
const usdPricePrefetchPromise: Promise<number | undefined> = this.preFetchUsdPrice(_abortController.signal);
|
|
476
|
-
const claimerBountyPrefetchPromise = mapArrayToObject(lpVersions, (contractVersion: string) => {
|
|
477
|
-
return this.preFetchClaimerBounty(recipient, amountData, _options, _abortController, contractVersion);
|
|
478
|
-
});
|
|
479
|
-
const nativeTokenAddress = this._chain.getNativeCurrencyAddress();
|
|
480
|
-
const feeRatePromise = this.preFetchFeeRate(recipient, amountData, undefined, _abortController, lpVersions);
|
|
481
|
-
|
|
482
|
-
const _signDataPromise = mapArrayToObject(lpVersions, (contractVersion: string) => {
|
|
483
|
-
return this._contract(contractVersion).preFetchBlockDataForSignatures == null ?
|
|
484
|
-
this.preFetchSignData(Promise.resolve(true), contractVersion) :
|
|
485
|
-
undefined;
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
return lps.map(lp => {
|
|
489
|
-
return {
|
|
490
|
-
intermediary: lp,
|
|
491
|
-
quote: (async () => {
|
|
492
|
-
if(lp.services[SwapType.FROM_BTC]==null) throw new Error("LP service for processing from btc swaps not found!");
|
|
493
|
-
const version = lp.getContractVersion(this.chainIdentifier);
|
|
494
|
-
|
|
495
|
-
const abortController = extendAbortController(_abortController.signal);
|
|
496
|
-
const liquidityPromise: Promise<bigint | undefined> = this.preFetchIntermediaryLiquidity(amountData, lp, abortController, version);
|
|
497
|
-
|
|
498
|
-
try {
|
|
499
|
-
const {signDataPromise, resp} = await tryWithRetries(async(retryCount: number) => {
|
|
500
|
-
const {signDataPrefetch, response} = IntermediaryAPI.initFromBTC(
|
|
501
|
-
this.chainIdentifier, lp.url, nativeTokenAddress,
|
|
502
|
-
{
|
|
503
|
-
claimer: recipient,
|
|
504
|
-
amount: amountData.amount,
|
|
505
|
-
token: amountData.token.toString(),
|
|
506
|
-
|
|
507
|
-
exactOut: !amountData.exactIn,
|
|
508
|
-
sequence,
|
|
509
|
-
|
|
510
|
-
claimerBounty: throwIfUndefined(claimerBountyPrefetchPromise[version]),
|
|
511
|
-
feeRate: throwIfUndefined(feeRatePromise[version]),
|
|
512
|
-
additionalParams
|
|
513
|
-
},
|
|
514
|
-
this._options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined
|
|
515
|
-
);
|
|
516
|
-
|
|
517
|
-
let signDataPromise = _signDataPromise[version];
|
|
518
|
-
if(signDataPromise==null) {
|
|
519
|
-
signDataPromise = this.preFetchSignData(signDataPrefetch, version);
|
|
520
|
-
} else signDataPrefetch.catch(() => {});
|
|
521
|
-
|
|
522
|
-
return {
|
|
523
|
-
signDataPromise,
|
|
524
|
-
resp: await response
|
|
525
|
-
};
|
|
526
|
-
}, undefined, e => e instanceof RequestError, abortController.signal);
|
|
527
|
-
|
|
528
|
-
const data: T["Data"] = new (this._swapDataDeserializer(version))(resp.data);
|
|
529
|
-
data.setClaimer(recipient);
|
|
530
|
-
|
|
531
|
-
const swapFeeBtc = resp.swapFee * resp.amount / (data.getAmount() + resp.swapFee);
|
|
532
|
-
|
|
533
|
-
this.verifyReturnedData(recipient, resp, amountData, lp, _options, data, sequence, (await claimerBountyPrefetchPromise[version])!, nativeTokenAddress);
|
|
534
|
-
const [pricingInfo, signatureExpiry] = await Promise.all([
|
|
535
|
-
//Get intermediary's liquidity
|
|
536
|
-
this.verifyReturnedPrice(
|
|
537
|
-
lp.services[SwapType.FROM_BTC], false, resp.amount, resp.total,
|
|
538
|
-
amountData.token, {swapFeeBtc}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
539
|
-
),
|
|
540
|
-
this.verifyReturnedSignature(recipient, data, resp, feeRatePromise[version], signDataPromise, version, abortController.signal),
|
|
541
|
-
this.verifyIntermediaryLiquidity(data.getAmount(), throwIfUndefined(liquidityPromise)),
|
|
542
|
-
]);
|
|
543
|
-
|
|
544
|
-
const quote = new FromBTCSwap<T>(this, {
|
|
545
|
-
pricingInfo,
|
|
546
|
-
url: lp.url,
|
|
547
|
-
expiry: signatureExpiry,
|
|
548
|
-
swapFee: resp.swapFee,
|
|
549
|
-
swapFeeBtc,
|
|
550
|
-
feeRate: (await feeRatePromise[version])!,
|
|
551
|
-
signatureData: resp,
|
|
552
|
-
data,
|
|
553
|
-
address: resp.btcAddress,
|
|
554
|
-
amount: resp.amount,
|
|
555
|
-
exactIn: amountData.exactIn ?? true,
|
|
556
|
-
requiredConfirmations: resp.confirmations,
|
|
557
|
-
contractVersion: version
|
|
558
|
-
} as FromBTCSwapInit<T["Data"]>);
|
|
559
|
-
return quote;
|
|
560
|
-
} catch (e) {
|
|
561
|
-
abortController.abort(e);
|
|
562
|
-
throw e;
|
|
563
|
-
}
|
|
564
|
-
})()
|
|
565
|
-
}
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* @inheritDoc
|
|
571
|
-
*/
|
|
572
|
-
async recoverFromSwapDataAndState(
|
|
573
|
-
init: {data: T["Data"], getInitTxId: () => Promise<string>, getTxBlock: () => Promise<{blockTime: number, blockHeight: number}>},
|
|
574
|
-
state: SwapCommitState,
|
|
575
|
-
contractVersion: string,
|
|
576
|
-
lp?: Intermediary
|
|
577
|
-
): Promise<FromBTCSwap<T> | null> {
|
|
578
|
-
const data = init.data;
|
|
579
|
-
|
|
580
|
-
const swapInit: FromBTCSwapInit<T["Data"]> = {
|
|
581
|
-
pricingInfo: {
|
|
582
|
-
isValid: true,
|
|
583
|
-
satsBaseFee: 0n,
|
|
584
|
-
swapPriceUSatPerToken: 100_000_000_000_000n,
|
|
585
|
-
realPriceUSatPerToken: 100_000_000_000_000n,
|
|
586
|
-
differencePPM: 0n,
|
|
587
|
-
feePPM: 0n,
|
|
588
|
-
},
|
|
589
|
-
url: lp?.url,
|
|
590
|
-
expiry: 0,
|
|
591
|
-
swapFee: 0n,
|
|
592
|
-
swapFeeBtc: 0n,
|
|
593
|
-
feeRate: "",
|
|
594
|
-
signatureData: undefined,
|
|
595
|
-
data,
|
|
596
|
-
exactIn: false,
|
|
597
|
-
contractVersion
|
|
598
|
-
}
|
|
599
|
-
const swap = new FromBTCSwap(this, swapInit);
|
|
600
|
-
swap._commitTxId = await init.getInitTxId();
|
|
601
|
-
const blockData = await init.getTxBlock();
|
|
602
|
-
swap.createdAt = blockData.blockTime * 1000;
|
|
603
|
-
swap._setInitiated();
|
|
604
|
-
swap._state = FromBTCSwapState.CLAIM_COMMITED;
|
|
605
|
-
await swap._sync(false, false, state);
|
|
606
|
-
await swap._save();
|
|
607
|
-
return swap;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
}
|
|
1
|
+
import {IFromBTCWrapper} from "../IFromBTCWrapper";
|
|
2
|
+
import {FromBTCSwap, FromBTCSwapInit, FromBTCSwapState} from "./FromBTCSwap";
|
|
3
|
+
import {
|
|
4
|
+
ChainSwapType,
|
|
5
|
+
ChainType,
|
|
6
|
+
ClaimEvent,
|
|
7
|
+
InitializeEvent,
|
|
8
|
+
RefundEvent,
|
|
9
|
+
RelaySynchronizer,
|
|
10
|
+
SwapData,
|
|
11
|
+
BtcRelay, BitcoinRpcWithAddressIndex, SwapCommitState
|
|
12
|
+
} from "@atomiqlabs/base";
|
|
13
|
+
import {EventEmitter} from "events";
|
|
14
|
+
import {Intermediary} from "../../../../intermediaries/Intermediary";
|
|
15
|
+
import {ISwapPrice} from "../../../../prices/abstract/ISwapPrice";
|
|
16
|
+
import {ISwapWrapperOptions, WrapperCtorTokens} from "../../../ISwapWrapper";
|
|
17
|
+
import {Buffer} from "buffer";
|
|
18
|
+
import {IntermediaryError} from "../../../../errors/IntermediaryError";
|
|
19
|
+
import {SwapType} from "../../../../enums/SwapType";
|
|
20
|
+
import {
|
|
21
|
+
extendAbortController, mapArrayToObject,
|
|
22
|
+
randomBytes,
|
|
23
|
+
throwIfUndefined
|
|
24
|
+
} from "../../../../utils/Utils";
|
|
25
|
+
import { toOutputScript} from "../../../../utils/BitcoinUtils";
|
|
26
|
+
import {FromBTCResponseType, IntermediaryAPI} from "../../../../intermediaries/apis/IntermediaryAPI";
|
|
27
|
+
import {RequestError} from "../../../../errors/RequestError";
|
|
28
|
+
import {BTC_NETWORK, TEST_NETWORK} from "@scure/btc-signer/utils";
|
|
29
|
+
import {UnifiedSwapEventListener} from "../../../../events/UnifiedSwapEventListener";
|
|
30
|
+
import {UnifiedSwapStorage} from "../../../../storage/UnifiedSwapStorage";
|
|
31
|
+
import {ISwap} from "../../../ISwap";
|
|
32
|
+
import {IClaimableSwapWrapper} from "../../../IClaimableSwapWrapper";
|
|
33
|
+
import {IFromBTCSelfInitDefinition} from "../IFromBTCSelfInitSwap";
|
|
34
|
+
import {AmountData} from "../../../../types/AmountData";
|
|
35
|
+
import {tryWithRetries} from "../../../../utils/RetryUtils";
|
|
36
|
+
import {AllOptional} from "../../../../utils/TypeUtils";
|
|
37
|
+
import {UserError} from "../../../../errors/UserError";
|
|
38
|
+
|
|
39
|
+
export type FromBTCOptions = {
|
|
40
|
+
/**
|
|
41
|
+
* A flag to attach 0 watchtower fee to the swap, this would make the settlement unattractive for the watchtowers
|
|
42
|
+
* and therefore automatic settlement for such swaps will not be possible, you will have to settle manually
|
|
43
|
+
* with {@link FromBTCLNSwap.claim} or {@link FromBTCLNSwap.txsClaim} functions.
|
|
44
|
+
*/
|
|
45
|
+
unsafeZeroWatchtowerFee?: boolean,
|
|
46
|
+
/**
|
|
47
|
+
* A safety factor to use when estimating the watchtower fee to attach to the swap (this has to cover the gas fee
|
|
48
|
+
* of watchtowers settling the swap). A higher multiple here would mean that a swap is more attractive for
|
|
49
|
+
* watchtowers to settle automatically.
|
|
50
|
+
*
|
|
51
|
+
* Uses a `1.5` multiple by default (i.e. the current network fee is multiplied by 1.5 and then used to estimate
|
|
52
|
+
* the settlement gas fee cost).
|
|
53
|
+
*
|
|
54
|
+
* Also accepts `bigint` for legacy reasons.
|
|
55
|
+
*/
|
|
56
|
+
feeSafetyFactor?: number | bigint,
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @deprecated Removed as it is deemed not necessary
|
|
60
|
+
*/
|
|
61
|
+
blockSafetyFactor?: number
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export type FromBTCWrapperOptions = ISwapWrapperOptions & {
|
|
65
|
+
safetyFactor: number,
|
|
66
|
+
blocksTillTxConfirms: number,
|
|
67
|
+
maxConfirmations: number,
|
|
68
|
+
minSendWindow: number,
|
|
69
|
+
bitcoinNetwork: BTC_NETWORK,
|
|
70
|
+
bitcoinBlocktime: number
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type FromBTCDefinition<T extends ChainType> = IFromBTCSelfInitDefinition<T, FromBTCWrapper<T>, FromBTCSwap<T>>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Legacy escrow (PrTLC) based swap for Bitcoin -> Smart chains, requires manual initiation
|
|
77
|
+
* of the swap escrow on the destination chain.
|
|
78
|
+
*
|
|
79
|
+
* @category Swaps/Legacy/Bitcoin → Smart chain
|
|
80
|
+
*/
|
|
81
|
+
export class FromBTCWrapper<
|
|
82
|
+
T extends ChainType
|
|
83
|
+
> extends IFromBTCWrapper<T, FromBTCDefinition<T>, FromBTCWrapperOptions> implements IClaimableSwapWrapper<FromBTCSwap<T>> {
|
|
84
|
+
public readonly TYPE: SwapType.FROM_BTC = SwapType.FROM_BTC;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
protected readonly tickSwapState = [FromBTCSwapState.PR_CREATED, FromBTCSwapState.CLAIM_COMMITED, FromBTCSwapState.EXPIRED];
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
readonly _pendingSwapStates = [
|
|
95
|
+
FromBTCSwapState.PR_CREATED,
|
|
96
|
+
FromBTCSwapState.QUOTE_SOFT_EXPIRED,
|
|
97
|
+
FromBTCSwapState.CLAIM_COMMITED,
|
|
98
|
+
FromBTCSwapState.BTC_TX_CONFIRMED,
|
|
99
|
+
FromBTCSwapState.EXPIRED
|
|
100
|
+
];
|
|
101
|
+
/**
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
readonly _claimableSwapStates = [FromBTCSwapState.BTC_TX_CONFIRMED];
|
|
105
|
+
/**
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
readonly _swapDeserializer = FromBTCSwap;
|
|
109
|
+
/**
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
readonly _synchronizer: (version?: string) => RelaySynchronizer<any, T["TX"], any> = (version?: string) => {
|
|
113
|
+
const _version = version ?? "v1";
|
|
114
|
+
const data = this.versionedSynchronizer[_version];
|
|
115
|
+
if(data==null) throw new Error(`Invalid contract version ${_version} requested`);
|
|
116
|
+
return data.synchronizer;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
readonly _btcRpc: BitcoinRpcWithAddressIndex<any>;
|
|
123
|
+
|
|
124
|
+
private readonly btcRelay: (version?: string) => BtcRelay<any, T["TX"], any> = (version?: string) => {
|
|
125
|
+
const _version = version ?? "v1";
|
|
126
|
+
const data = this.versionedBtcRelay[_version];
|
|
127
|
+
if(data==null) throw new Error(`Invalid contract version ${_version} requested`);
|
|
128
|
+
return data.btcRelay;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
private readonly versionedBtcRelay: {
|
|
132
|
+
[version: string]: {
|
|
133
|
+
btcRelay: BtcRelay<any, T["TX"], any>
|
|
134
|
+
}
|
|
135
|
+
}= {};
|
|
136
|
+
|
|
137
|
+
private readonly versionedSynchronizer: {
|
|
138
|
+
[version: string]: {
|
|
139
|
+
synchronizer: RelaySynchronizer<any, T["TX"], any>
|
|
140
|
+
}
|
|
141
|
+
}= {};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @param chainIdentifier
|
|
145
|
+
* @param unifiedStorage Storage interface for the current environment
|
|
146
|
+
* @param unifiedChainEvents On-chain event listener
|
|
147
|
+
* @param chain
|
|
148
|
+
* @param prices Pricing to use
|
|
149
|
+
* @param tokens
|
|
150
|
+
* @param versionedContracts
|
|
151
|
+
* @param versionedSynchronizer
|
|
152
|
+
* @param btcRpc Bitcoin RPC which also supports getting transactions by txoHash
|
|
153
|
+
* @param options
|
|
154
|
+
* @param events Instance to use for emitting events
|
|
155
|
+
*/
|
|
156
|
+
constructor(
|
|
157
|
+
chainIdentifier: string,
|
|
158
|
+
unifiedStorage: UnifiedSwapStorage<T>,
|
|
159
|
+
unifiedChainEvents: UnifiedSwapEventListener<T>,
|
|
160
|
+
chain: T["ChainInterface"],
|
|
161
|
+
prices: ISwapPrice,
|
|
162
|
+
tokens: WrapperCtorTokens,
|
|
163
|
+
versionedContracts: {
|
|
164
|
+
[version: string]: {
|
|
165
|
+
swapContract: T["Contract"],
|
|
166
|
+
swapDataConstructor: new (data: any) => T["Data"],
|
|
167
|
+
btcRelay: BtcRelay<any, T["TX"], any>
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
versionedSynchronizer: {
|
|
171
|
+
[version: string]: {
|
|
172
|
+
synchronizer: RelaySynchronizer<any, T["TX"], any>
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
btcRpc: BitcoinRpcWithAddressIndex<any>,
|
|
176
|
+
options?: AllOptional<FromBTCWrapperOptions>,
|
|
177
|
+
events?: EventEmitter<{swapState: [ISwap]}>
|
|
178
|
+
) {
|
|
179
|
+
super(
|
|
180
|
+
chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens,
|
|
181
|
+
{
|
|
182
|
+
...options,
|
|
183
|
+
bitcoinNetwork: options?.bitcoinNetwork ?? TEST_NETWORK,
|
|
184
|
+
safetyFactor: options?.safetyFactor ?? 2,
|
|
185
|
+
blocksTillTxConfirms: options?.blocksTillTxConfirms ?? 12,
|
|
186
|
+
maxConfirmations: options?.maxConfirmations ?? 6,
|
|
187
|
+
minSendWindow: options?.minSendWindow ?? 30*60, //Minimum time window for user to send in the on-chain funds for From BTC swap
|
|
188
|
+
bitcoinBlocktime: options?.bitcoinBlocktime ?? 10*60
|
|
189
|
+
},
|
|
190
|
+
versionedContracts,
|
|
191
|
+
events
|
|
192
|
+
);
|
|
193
|
+
this._btcRpc = btcRpc;
|
|
194
|
+
this.versionedBtcRelay = versionedContracts;
|
|
195
|
+
this.versionedSynchronizer = versionedSynchronizer;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @inheritDoc
|
|
200
|
+
* @internal
|
|
201
|
+
*/
|
|
202
|
+
protected processEventInitialize(swap: FromBTCSwap<T>, event: InitializeEvent<T["Data"]>): Promise<boolean> {
|
|
203
|
+
if(swap._state===FromBTCSwapState.PR_CREATED || swap._state===FromBTCSwapState.QUOTE_SOFT_EXPIRED) {
|
|
204
|
+
swap._state = FromBTCSwapState.CLAIM_COMMITED;
|
|
205
|
+
return Promise.resolve(true);
|
|
206
|
+
}
|
|
207
|
+
return Promise.resolve(false);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @inheritDoc
|
|
212
|
+
* @internal
|
|
213
|
+
*/
|
|
214
|
+
protected async processEventClaim(swap: FromBTCSwap<T>, event: ClaimEvent<T["Data"]>): Promise<boolean> {
|
|
215
|
+
if(swap._state!==FromBTCSwapState.FAILED && swap._state!==FromBTCSwapState.CLAIM_CLAIMED) {
|
|
216
|
+
await swap._setBitcoinTxId(Buffer.from(event.result, "hex").reverse().toString("hex")).catch(e => {
|
|
217
|
+
this.logger.warn("processEventClaim(): Error setting bitcoin txId: ", e);
|
|
218
|
+
});
|
|
219
|
+
swap._state = FromBTCSwapState.CLAIM_CLAIMED;
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @inheritDoc
|
|
227
|
+
* @internal
|
|
228
|
+
*/
|
|
229
|
+
protected processEventRefund(swap: FromBTCSwap<T>, event: RefundEvent<T["Data"]>): Promise<boolean> {
|
|
230
|
+
if(swap._state!==FromBTCSwapState.CLAIM_CLAIMED && swap._state!==FromBTCSwapState.FAILED) {
|
|
231
|
+
swap._state = FromBTCSwapState.FAILED;
|
|
232
|
+
return Promise.resolve(true);
|
|
233
|
+
}
|
|
234
|
+
return Promise.resolve(false);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Returns the swap expiry, leaving enough time for the user to send a transaction and for it to confirm
|
|
239
|
+
*
|
|
240
|
+
* @param data Swap data
|
|
241
|
+
* @param requiredConfirmations Confirmations required on the bitcoin side to settle the swap
|
|
242
|
+
*
|
|
243
|
+
* @internal
|
|
244
|
+
*/
|
|
245
|
+
_getOnchainSendTimeout(data: SwapData, requiredConfirmations: number): bigint {
|
|
246
|
+
const tsDelta = (this._options.blocksTillTxConfirms + requiredConfirmations) * this._options.bitcoinBlocktime * this._options.safetyFactor;
|
|
247
|
+
return data.getExpiry() - BigInt(tsDelta);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Pre-fetches claimer (watchtower) bounty data for the swap. Doesn't throw, instead returns null and aborts the
|
|
252
|
+
* provided abortController
|
|
253
|
+
*
|
|
254
|
+
* @param signer Smartchain signer address initiating the swap
|
|
255
|
+
* @param amountData
|
|
256
|
+
* @param options Options as passed to the swap creation function
|
|
257
|
+
* @param abortController
|
|
258
|
+
* @param contractVersion
|
|
259
|
+
*
|
|
260
|
+
* @private
|
|
261
|
+
*/
|
|
262
|
+
private async preFetchClaimerBounty(
|
|
263
|
+
signer: string,
|
|
264
|
+
amountData: AmountData,
|
|
265
|
+
options: {
|
|
266
|
+
feeSafetyFactorPPM: bigint,
|
|
267
|
+
blockSafetyFactor: bigint,
|
|
268
|
+
unsafeZeroWatchtowerFee: boolean
|
|
269
|
+
},
|
|
270
|
+
abortController: AbortController,
|
|
271
|
+
contractVersion: string
|
|
272
|
+
): Promise<{
|
|
273
|
+
feePerBlock: bigint,
|
|
274
|
+
safetyFactor: bigint,
|
|
275
|
+
startTimestamp: bigint,
|
|
276
|
+
addBlock: bigint,
|
|
277
|
+
addFee: bigint
|
|
278
|
+
} | undefined> {
|
|
279
|
+
const startTimestamp = BigInt(Math.floor(Date.now()/1000));
|
|
280
|
+
|
|
281
|
+
if(options.unsafeZeroWatchtowerFee) {
|
|
282
|
+
return {
|
|
283
|
+
feePerBlock: 0n,
|
|
284
|
+
safetyFactor: options.blockSafetyFactor,
|
|
285
|
+
startTimestamp: startTimestamp,
|
|
286
|
+
addBlock: 0n,
|
|
287
|
+
addFee: 0n
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const dummyAmount = BigInt(Math.floor(Math.random()* 0x1000000));
|
|
292
|
+
const dummySwapData = await this._contract(contractVersion).createSwapData(
|
|
293
|
+
ChainSwapType.CHAIN, signer, signer, amountData.token,
|
|
294
|
+
dummyAmount, this._contract(contractVersion).getHashForOnchain(randomBytes(20), dummyAmount, 3).toString("hex"),
|
|
295
|
+
this.getRandomSequence(), startTimestamp, false, true,
|
|
296
|
+
BigInt(Math.floor(Math.random() * 0x10000)), BigInt(Math.floor(Math.random() * 0x10000))
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
try {
|
|
300
|
+
const [feePerBlock, btcRelayData, currentBtcBlock, claimFeeRate] = await Promise.all([
|
|
301
|
+
this.btcRelay(contractVersion).getFeePerBlock(),
|
|
302
|
+
this.btcRelay(contractVersion).getTipData(),
|
|
303
|
+
this._btcRpc.getTipHeight(),
|
|
304
|
+
this._contract(contractVersion).getClaimFee(signer, dummySwapData)
|
|
305
|
+
]);
|
|
306
|
+
|
|
307
|
+
if(btcRelayData==null) throw new Error("Btc relay not initialized!");
|
|
308
|
+
|
|
309
|
+
const currentBtcRelayBlock = btcRelayData.blockheight;
|
|
310
|
+
const addBlock = Math.max(currentBtcBlock-currentBtcRelayBlock, 0);
|
|
311
|
+
return {
|
|
312
|
+
feePerBlock: feePerBlock * options.feeSafetyFactorPPM / 1_000_000n,
|
|
313
|
+
safetyFactor: options.blockSafetyFactor,
|
|
314
|
+
startTimestamp: startTimestamp,
|
|
315
|
+
addBlock: BigInt(addBlock),
|
|
316
|
+
addFee: claimFeeRate * options.feeSafetyFactorPPM / 1_000_000n
|
|
317
|
+
}
|
|
318
|
+
} catch (e) {
|
|
319
|
+
abortController.abort(e);
|
|
320
|
+
return undefined;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Returns calculated claimer bounty calculated from the claimer bounty data as fetched from preFetchClaimerBounty()
|
|
326
|
+
*
|
|
327
|
+
* @param data Parsed swap data returned from the intermediary
|
|
328
|
+
* @param options Options as passed to the swap creation function
|
|
329
|
+
* @param claimerBounty Claimer bounty data as fetched from {@link preFetchClaimerBounty} function
|
|
330
|
+
*
|
|
331
|
+
* @private
|
|
332
|
+
*/
|
|
333
|
+
private getClaimerBounty(
|
|
334
|
+
data: T["Data"],
|
|
335
|
+
options: {
|
|
336
|
+
blockSafetyFactor: bigint
|
|
337
|
+
},
|
|
338
|
+
claimerBounty: {
|
|
339
|
+
feePerBlock: bigint,
|
|
340
|
+
safetyFactor: bigint,
|
|
341
|
+
startTimestamp: bigint,
|
|
342
|
+
addBlock: bigint,
|
|
343
|
+
addFee: bigint
|
|
344
|
+
}
|
|
345
|
+
) : bigint {
|
|
346
|
+
const tsDelta = data.getExpiry() - claimerBounty.startTimestamp;
|
|
347
|
+
const blocksDelta = tsDelta / BigInt(this._options.bitcoinBlocktime) * options.blockSafetyFactor;
|
|
348
|
+
const totalBlock = blocksDelta + claimerBounty.addBlock;
|
|
349
|
+
return claimerBounty.addFee + (totalBlock * claimerBounty.feePerBlock);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Verifies response returned from intermediary
|
|
354
|
+
*
|
|
355
|
+
* @param signer
|
|
356
|
+
* @param resp Response as returned by the intermediary
|
|
357
|
+
* @param amountData
|
|
358
|
+
* @param lp Intermediary
|
|
359
|
+
* @param options Options as passed to the swap creation function
|
|
360
|
+
* @param data Parsed swap data returned by the intermediary
|
|
361
|
+
* @param sequence Required swap sequence
|
|
362
|
+
* @param claimerBounty Claimer bount data as returned from the preFetchClaimerBounty() pre-fetch promise
|
|
363
|
+
* @param depositToken
|
|
364
|
+
*
|
|
365
|
+
* @throws {IntermediaryError} in case the response is invalid
|
|
366
|
+
*
|
|
367
|
+
* @private
|
|
368
|
+
*/
|
|
369
|
+
private verifyReturnedData(
|
|
370
|
+
signer: string,
|
|
371
|
+
resp: FromBTCResponseType,
|
|
372
|
+
amountData: AmountData,
|
|
373
|
+
lp: Intermediary,
|
|
374
|
+
options: {
|
|
375
|
+
blockSafetyFactor: bigint
|
|
376
|
+
},
|
|
377
|
+
data: T["Data"],
|
|
378
|
+
sequence: bigint,
|
|
379
|
+
claimerBounty: {
|
|
380
|
+
feePerBlock: bigint,
|
|
381
|
+
safetyFactor: bigint,
|
|
382
|
+
startTimestamp: bigint,
|
|
383
|
+
addBlock: bigint,
|
|
384
|
+
addFee: bigint
|
|
385
|
+
},
|
|
386
|
+
depositToken: string
|
|
387
|
+
): void {
|
|
388
|
+
if(amountData.exactIn) {
|
|
389
|
+
if(resp.amount !== amountData.amount) throw new IntermediaryError("Invalid amount returned");
|
|
390
|
+
} else {
|
|
391
|
+
if(resp.total !== amountData.amount) throw new IntermediaryError("Invalid total returned");
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const requiredConfirmations = resp.confirmations;
|
|
395
|
+
if(requiredConfirmations>this._options.maxConfirmations) throw new IntermediaryError("Requires too many confirmations");
|
|
396
|
+
|
|
397
|
+
const totalClaimerBounty = this.getClaimerBounty(data, options, claimerBounty);
|
|
398
|
+
|
|
399
|
+
if(
|
|
400
|
+
data.getClaimerBounty() !== totalClaimerBounty ||
|
|
401
|
+
data.getType()!=ChainSwapType.CHAIN ||
|
|
402
|
+
data.getSequence() !== sequence ||
|
|
403
|
+
data.getAmount() !== resp.total ||
|
|
404
|
+
data.isPayIn() ||
|
|
405
|
+
!data.isToken(amountData.token) ||
|
|
406
|
+
!data.isOfferer(lp.getAddress(this.chainIdentifier)) ||
|
|
407
|
+
!data.isClaimer(signer) ||
|
|
408
|
+
!data.isDepositToken(depositToken) ||
|
|
409
|
+
data.hasSuccessAction()
|
|
410
|
+
) {
|
|
411
|
+
throw new IntermediaryError("Invalid data returned");
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
//Check that we have enough time to send the TX and for it to confirm
|
|
415
|
+
const expiry = this._getOnchainSendTimeout(data, requiredConfirmations);
|
|
416
|
+
const currentTimestamp = BigInt(Math.floor(Date.now()/1000));
|
|
417
|
+
if((expiry - currentTimestamp) < BigInt(this._options.minSendWindow)) {
|
|
418
|
+
throw new IntermediaryError("Send window too low");
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const version = lp.getContractVersion(this.chainIdentifier);
|
|
422
|
+
|
|
423
|
+
const lockingScript = toOutputScript(this._options.bitcoinNetwork, resp.btcAddress);
|
|
424
|
+
const desiredExtraData = this._contract(version).getExtraData(lockingScript, resp.amount, requiredConfirmations);
|
|
425
|
+
const desiredClaimHash = this._contract(version).getHashForOnchain(lockingScript, resp.amount, requiredConfirmations);
|
|
426
|
+
if(!desiredClaimHash.equals(Buffer.from(data.getClaimHash(), "hex"))) {
|
|
427
|
+
throw new IntermediaryError("Invalid claim hash returned!");
|
|
428
|
+
}
|
|
429
|
+
const extraData = data.getExtraData();
|
|
430
|
+
if(extraData==null || !desiredExtraData.equals(Buffer.from(extraData, "hex"))) {
|
|
431
|
+
throw new IntermediaryError("Invalid extra data returned!");
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Returns a newly created legacy Bitcoin -> Smart chain swap using the PrTLC based escrow swap protocol,
|
|
437
|
+
* with the passed amount.
|
|
438
|
+
*
|
|
439
|
+
* @param recipient Smart chain signer's address on the destination chain
|
|
440
|
+
* @param amountData Amount, token and exact input/output data for to swap
|
|
441
|
+
* @param lps An array of intermediaries (LPs) to get the quotes from
|
|
442
|
+
* @param options Optional additional quote options
|
|
443
|
+
* @param additionalParams Optional additional parameters sent to the LP when creating the swap
|
|
444
|
+
* @param abortSignal Abort signal
|
|
445
|
+
*/
|
|
446
|
+
create(
|
|
447
|
+
recipient: string,
|
|
448
|
+
amountData: AmountData,
|
|
449
|
+
lps: Intermediary[],
|
|
450
|
+
options?: FromBTCOptions,
|
|
451
|
+
additionalParams?: Record<string, any>,
|
|
452
|
+
abortSignal?: AbortSignal
|
|
453
|
+
): {
|
|
454
|
+
quote: Promise<FromBTCSwap<T>>,
|
|
455
|
+
intermediary: Intermediary
|
|
456
|
+
}[] {
|
|
457
|
+
let feeSafetyFactorPPM: bigint = 1_500_000n;
|
|
458
|
+
if(typeof(options?.feeSafetyFactor)==="bigint") {
|
|
459
|
+
feeSafetyFactorPPM = options.feeSafetyFactor * 1_000_000n;
|
|
460
|
+
} else if(typeof(options?.feeSafetyFactor)==="number") {
|
|
461
|
+
feeSafetyFactorPPM = BigInt(Math.floor(options.feeSafetyFactor * 1_000_000));
|
|
462
|
+
}
|
|
463
|
+
const lpVersions = Intermediary.getContractVersionsForLps(this.chainIdentifier, lps);
|
|
464
|
+
|
|
465
|
+
const _options = {
|
|
466
|
+
blockSafetyFactor: options?.blockSafetyFactor!=null ? BigInt(options.blockSafetyFactor) : 1n,
|
|
467
|
+
feeSafetyFactorPPM,
|
|
468
|
+
unsafeZeroWatchtowerFee: options?.unsafeZeroWatchtowerFee ?? false
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const sequence: bigint = this.getRandomSequence();
|
|
472
|
+
|
|
473
|
+
const _abortController = extendAbortController(abortSignal);
|
|
474
|
+
const pricePrefetchPromise: Promise<bigint | undefined> = this.preFetchPrice(amountData, _abortController.signal);
|
|
475
|
+
const usdPricePrefetchPromise: Promise<number | undefined> = this.preFetchUsdPrice(_abortController.signal);
|
|
476
|
+
const claimerBountyPrefetchPromise = mapArrayToObject(lpVersions, (contractVersion: string) => {
|
|
477
|
+
return this.preFetchClaimerBounty(recipient, amountData, _options, _abortController, contractVersion);
|
|
478
|
+
});
|
|
479
|
+
const nativeTokenAddress = this._chain.getNativeCurrencyAddress();
|
|
480
|
+
const feeRatePromise = this.preFetchFeeRate(recipient, amountData, undefined, _abortController, lpVersions);
|
|
481
|
+
|
|
482
|
+
const _signDataPromise = mapArrayToObject(lpVersions, (contractVersion: string) => {
|
|
483
|
+
return this._contract(contractVersion).preFetchBlockDataForSignatures == null ?
|
|
484
|
+
this.preFetchSignData(Promise.resolve(true), contractVersion) :
|
|
485
|
+
undefined;
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
return lps.map(lp => {
|
|
489
|
+
return {
|
|
490
|
+
intermediary: lp,
|
|
491
|
+
quote: (async () => {
|
|
492
|
+
if(lp.services[SwapType.FROM_BTC]==null) throw new Error("LP service for processing from btc swaps not found!");
|
|
493
|
+
const version = lp.getContractVersion(this.chainIdentifier);
|
|
494
|
+
|
|
495
|
+
const abortController = extendAbortController(_abortController.signal);
|
|
496
|
+
const liquidityPromise: Promise<bigint | undefined> = this.preFetchIntermediaryLiquidity(amountData, lp, abortController, version);
|
|
497
|
+
|
|
498
|
+
try {
|
|
499
|
+
const {signDataPromise, resp} = await tryWithRetries(async(retryCount: number) => {
|
|
500
|
+
const {signDataPrefetch, response} = IntermediaryAPI.initFromBTC(
|
|
501
|
+
this.chainIdentifier, lp.url, nativeTokenAddress,
|
|
502
|
+
{
|
|
503
|
+
claimer: recipient,
|
|
504
|
+
amount: amountData.amount,
|
|
505
|
+
token: amountData.token.toString(),
|
|
506
|
+
|
|
507
|
+
exactOut: !amountData.exactIn,
|
|
508
|
+
sequence,
|
|
509
|
+
|
|
510
|
+
claimerBounty: throwIfUndefined(claimerBountyPrefetchPromise[version]),
|
|
511
|
+
feeRate: throwIfUndefined(feeRatePromise[version]),
|
|
512
|
+
additionalParams
|
|
513
|
+
},
|
|
514
|
+
this._options.postRequestTimeout, abortController.signal, retryCount>0 ? false : undefined
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
let signDataPromise = _signDataPromise[version];
|
|
518
|
+
if(signDataPromise==null) {
|
|
519
|
+
signDataPromise = this.preFetchSignData(signDataPrefetch, version);
|
|
520
|
+
} else signDataPrefetch.catch(() => {});
|
|
521
|
+
|
|
522
|
+
return {
|
|
523
|
+
signDataPromise,
|
|
524
|
+
resp: await response
|
|
525
|
+
};
|
|
526
|
+
}, undefined, e => e instanceof RequestError, abortController.signal);
|
|
527
|
+
|
|
528
|
+
const data: T["Data"] = new (this._swapDataDeserializer(version))(resp.data);
|
|
529
|
+
data.setClaimer(recipient);
|
|
530
|
+
|
|
531
|
+
const swapFeeBtc = resp.swapFee * resp.amount / (data.getAmount() + resp.swapFee);
|
|
532
|
+
|
|
533
|
+
this.verifyReturnedData(recipient, resp, amountData, lp, _options, data, sequence, (await claimerBountyPrefetchPromise[version])!, nativeTokenAddress);
|
|
534
|
+
const [pricingInfo, signatureExpiry] = await Promise.all([
|
|
535
|
+
//Get intermediary's liquidity
|
|
536
|
+
this.verifyReturnedPrice(
|
|
537
|
+
lp.services[SwapType.FROM_BTC], false, resp.amount, resp.total,
|
|
538
|
+
amountData.token, {swapFeeBtc}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
539
|
+
),
|
|
540
|
+
this.verifyReturnedSignature(recipient, data, resp, feeRatePromise[version], signDataPromise, version, abortController.signal),
|
|
541
|
+
this.verifyIntermediaryLiquidity(data.getAmount(), throwIfUndefined(liquidityPromise)),
|
|
542
|
+
]);
|
|
543
|
+
|
|
544
|
+
const quote = new FromBTCSwap<T>(this, {
|
|
545
|
+
pricingInfo,
|
|
546
|
+
url: lp.url,
|
|
547
|
+
expiry: signatureExpiry,
|
|
548
|
+
swapFee: resp.swapFee,
|
|
549
|
+
swapFeeBtc,
|
|
550
|
+
feeRate: (await feeRatePromise[version])!,
|
|
551
|
+
signatureData: resp,
|
|
552
|
+
data,
|
|
553
|
+
address: resp.btcAddress,
|
|
554
|
+
amount: resp.amount,
|
|
555
|
+
exactIn: amountData.exactIn ?? true,
|
|
556
|
+
requiredConfirmations: resp.confirmations,
|
|
557
|
+
contractVersion: version
|
|
558
|
+
} as FromBTCSwapInit<T["Data"]>);
|
|
559
|
+
return quote;
|
|
560
|
+
} catch (e) {
|
|
561
|
+
abortController.abort(e);
|
|
562
|
+
throw e;
|
|
563
|
+
}
|
|
564
|
+
})()
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* @inheritDoc
|
|
571
|
+
*/
|
|
572
|
+
async recoverFromSwapDataAndState(
|
|
573
|
+
init: {data: T["Data"], getInitTxId: () => Promise<string>, getTxBlock: () => Promise<{blockTime: number, blockHeight: number}>},
|
|
574
|
+
state: SwapCommitState,
|
|
575
|
+
contractVersion: string,
|
|
576
|
+
lp?: Intermediary
|
|
577
|
+
): Promise<FromBTCSwap<T> | null> {
|
|
578
|
+
const data = init.data;
|
|
579
|
+
|
|
580
|
+
const swapInit: FromBTCSwapInit<T["Data"]> = {
|
|
581
|
+
pricingInfo: {
|
|
582
|
+
isValid: true,
|
|
583
|
+
satsBaseFee: 0n,
|
|
584
|
+
swapPriceUSatPerToken: 100_000_000_000_000n,
|
|
585
|
+
realPriceUSatPerToken: 100_000_000_000_000n,
|
|
586
|
+
differencePPM: 0n,
|
|
587
|
+
feePPM: 0n,
|
|
588
|
+
},
|
|
589
|
+
url: lp?.url,
|
|
590
|
+
expiry: 0,
|
|
591
|
+
swapFee: 0n,
|
|
592
|
+
swapFeeBtc: 0n,
|
|
593
|
+
feeRate: "",
|
|
594
|
+
signatureData: undefined,
|
|
595
|
+
data,
|
|
596
|
+
exactIn: false,
|
|
597
|
+
contractVersion
|
|
598
|
+
}
|
|
599
|
+
const swap = new FromBTCSwap(this, swapInit);
|
|
600
|
+
swap._commitTxId = await init.getInitTxId();
|
|
601
|
+
const blockData = await init.getTxBlock();
|
|
602
|
+
swap.createdAt = blockData.blockTime * 1000;
|
|
603
|
+
swap._setInitiated();
|
|
604
|
+
swap._state = FromBTCSwapState.CLAIM_COMMITED;
|
|
605
|
+
await swap._sync(false, false, state);
|
|
606
|
+
await swap._save();
|
|
607
|
+
return swap;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
}
|