@atomiqlabs/sdk 8.1.8 → 8.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bitcoin/coinselect2/utils.d.ts +6 -0
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +41 -5
- package/dist/bitcoin/wallet/BitcoinWallet.js +36 -1
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +52 -2
- package/dist/bitcoin/wallet/IBitcoinWallet.js +2 -1
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +42 -7
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +36 -1
- package/dist/enums/FeeType.d.ts +8 -1
- package/dist/enums/FeeType.js +8 -1
- package/dist/enums/SwapAmountType.d.ts +7 -0
- package/dist/enums/SwapAmountType.js +7 -0
- package/dist/enums/SwapDirection.d.ts +7 -0
- package/dist/enums/SwapDirection.js +7 -0
- package/dist/enums/SwapType.d.ts +62 -1
- package/dist/enums/SwapType.js +62 -1
- package/dist/errors/IntermediaryError.d.ts +4 -0
- package/dist/errors/IntermediaryError.js +1 -0
- package/dist/errors/RequestError.d.ts +15 -1
- package/dist/errors/RequestError.js +8 -0
- package/dist/errors/UserError.d.ts +1 -0
- package/dist/errors/UserError.js +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +7 -6
- package/dist/intermediaries/Intermediary.d.ts +61 -14
- package/dist/intermediaries/Intermediary.js +38 -11
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +62 -29
- package/dist/intermediaries/IntermediaryDiscovery.js +39 -24
- package/dist/prices/RedundantSwapPrice.d.ts +26 -5
- package/dist/prices/RedundantSwapPrice.js +22 -2
- package/dist/prices/SingleSwapPrice.d.ts +10 -7
- package/dist/prices/SingleSwapPrice.js +11 -8
- package/dist/prices/SwapPriceWithChain.d.ts +56 -19
- package/dist/prices/SwapPriceWithChain.js +62 -25
- package/dist/prices/abstract/IPriceProvider.d.ts +4 -4
- package/dist/prices/abstract/IPriceProvider.js +1 -1
- package/dist/prices/abstract/ISwapPrice.d.ts +95 -46
- package/dist/prices/abstract/ISwapPrice.js +104 -56
- package/dist/prices/providers/BinancePriceProvider.d.ts +8 -1
- package/dist/prices/providers/BinancePriceProvider.js +8 -1
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +7 -1
- package/dist/prices/providers/CoinGeckoPriceProvider.js +7 -1
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +7 -1
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +7 -1
- package/dist/prices/providers/CustomPriceProvider.d.ts +12 -1
- package/dist/prices/providers/CustomPriceProvider.js +12 -1
- package/dist/prices/providers/KrakenPriceProvider.d.ts +10 -1
- package/dist/prices/providers/KrakenPriceProvider.js +10 -1
- package/dist/prices/providers/OKXPriceProvider.d.ts +7 -1
- package/dist/prices/providers/OKXPriceProvider.js +7 -1
- package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +3 -0
- package/dist/prices/providers/abstract/ExchangePriceProvider.js +3 -0
- package/dist/storage/IUnifiedStorage.d.ts +19 -7
- package/dist/storage/UnifiedSwapStorage.d.ts +33 -3
- package/dist/storage/UnifiedSwapStorage.js +29 -1
- package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +31 -7
- package/dist/storage-browser/IndexedDBUnifiedStorage.js +29 -6
- package/dist/storage-browser/LocalStorageManager.d.ts +25 -1
- package/dist/storage-browser/LocalStorageManager.js +25 -1
- package/dist/swapper/Swapper.d.ts +380 -226
- package/dist/swapper/Swapper.js +383 -349
- package/dist/swapper/SwapperFactory.d.ts +66 -18
- package/dist/swapper/SwapperFactory.js +24 -3
- package/dist/swapper/SwapperUtils.d.ts +75 -28
- package/dist/swapper/SwapperUtils.js +107 -60
- package/dist/swapper/SwapperWithChain.d.ts +286 -91
- package/dist/swapper/SwapperWithChain.js +218 -64
- package/dist/swapper/SwapperWithSigner.d.ts +229 -80
- package/dist/swapper/SwapperWithSigner.js +190 -44
- package/dist/swaps/IAddressSwap.d.ts +12 -3
- package/dist/swaps/IAddressSwap.js +3 -2
- package/dist/swaps/IBTCWalletSwap.d.ts +26 -8
- package/dist/swaps/IBTCWalletSwap.js +3 -2
- package/dist/swaps/IClaimableSwap.d.ts +38 -6
- package/dist/swaps/IClaimableSwap.js +3 -2
- package/dist/swaps/IClaimableSwapWrapper.d.ts +11 -1
- package/dist/swaps/IRefundableSwap.d.ts +31 -5
- package/dist/swaps/IRefundableSwap.js +3 -2
- package/dist/swaps/ISwap.d.ts +162 -24
- package/dist/swaps/ISwap.js +92 -35
- package/dist/swaps/ISwapWithGasDrop.d.ts +8 -2
- package/dist/swaps/ISwapWithGasDrop.js +2 -1
- package/dist/swaps/ISwapWrapper.d.ts +161 -52
- package/dist/swaps/ISwapWrapper.js +131 -73
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +51 -6
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +22 -12
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +65 -12
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +38 -19
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +39 -9
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +30 -21
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +31 -15
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +33 -18
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +97 -28
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +91 -27
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +22 -9
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +24 -11
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +278 -60
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +519 -241
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +77 -26
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +132 -50
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +313 -52
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +544 -194
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +87 -26
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +147 -58
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +222 -55
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +462 -244
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +77 -23
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +116 -46
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +195 -58
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +324 -191
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +30 -5
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +44 -19
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +61 -20
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +75 -32
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +76 -50
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +106 -101
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +37 -14
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +66 -20
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +46 -17
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +82 -27
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +350 -88
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +482 -215
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +76 -24
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +247 -124
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +148 -20
- package/dist/swaps/trusted/ln/LnForGasSwap.js +175 -45
- package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +29 -10
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +30 -11
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +202 -49
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +232 -80
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +34 -12
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +33 -14
- package/dist/types/AmountData.d.ts +2 -1
- package/dist/types/CustomPriceFunction.d.ts +8 -2
- package/dist/types/PriceInfoType.d.ts +4 -4
- package/dist/types/PriceInfoType.js +3 -3
- package/dist/types/SwapExecutionAction.d.ts +85 -4
- package/dist/types/SwapWithSigner.d.ts +5 -2
- package/dist/types/SwapWithSigner.js +5 -2
- package/dist/types/Token.d.ts +11 -5
- package/dist/types/Token.js +6 -3
- package/dist/types/TokenAmount.d.ts +3 -0
- package/dist/types/TokenAmount.js +2 -0
- package/dist/types/fees/Fee.d.ts +3 -2
- package/dist/types/fees/FeeBreakdown.d.ts +3 -2
- package/dist/types/fees/PercentagePPM.d.ts +4 -2
- package/dist/types/fees/PercentagePPM.js +2 -1
- package/dist/types/lnurl/LNURLPay.d.ts +20 -12
- package/dist/types/lnurl/LNURLPay.js +8 -4
- package/dist/types/lnurl/LNURLWithdraw.d.ts +17 -10
- package/dist/types/lnurl/LNURLWithdraw.js +8 -4
- package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -0
- package/dist/types/wallets/LightningInvoiceCreateService.js +15 -0
- package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +3 -1
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +4 -2
- package/dist/utils/BitcoinUtils.d.ts +1 -0
- package/dist/utils/BitcoinUtils.js +5 -1
- package/dist/utils/SwapUtils.d.ts +58 -1
- package/dist/utils/SwapUtils.js +55 -1
- package/dist/utils/TokenUtils.d.ts +10 -2
- package/dist/utils/TokenUtils.js +12 -4
- package/package.json +3 -3
- package/src/bitcoin/coinselect2/utils.ts +6 -0
- package/src/bitcoin/wallet/BitcoinWallet.ts +41 -5
- package/src/bitcoin/wallet/IBitcoinWallet.ts +57 -2
- package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +42 -6
- package/src/enums/FeeType.ts +8 -1
- package/src/enums/SwapAmountType.ts +7 -0
- package/src/enums/SwapDirection.ts +7 -0
- package/src/enums/SwapType.ts +62 -2
- package/src/errors/IntermediaryError.ts +4 -0
- package/src/errors/RequestError.ts +15 -1
- package/src/errors/UserError.ts +1 -0
- package/src/index.ts +12 -5
- package/src/intermediaries/Intermediary.ts +61 -14
- package/src/intermediaries/IntermediaryDiscovery.ts +69 -34
- package/src/prices/RedundantSwapPrice.ts +26 -6
- package/src/prices/SingleSwapPrice.ts +11 -8
- package/src/prices/SwapPriceWithChain.ts +63 -26
- package/src/prices/abstract/IPriceProvider.ts +4 -4
- package/src/prices/abstract/ISwapPrice.ts +115 -66
- package/src/prices/providers/BinancePriceProvider.ts +8 -1
- package/src/prices/providers/CoinGeckoPriceProvider.ts +7 -1
- package/src/prices/providers/CoinPaprikaPriceProvider.ts +7 -1
- package/src/prices/providers/CustomPriceProvider.ts +12 -1
- package/src/prices/providers/KrakenPriceProvider.ts +10 -1
- package/src/prices/providers/OKXPriceProvider.ts +7 -1
- package/src/prices/providers/abstract/ExchangePriceProvider.ts +3 -0
- package/src/storage/IUnifiedStorage.ts +19 -7
- package/src/storage/UnifiedSwapStorage.ts +33 -3
- package/src/storage-browser/IndexedDBUnifiedStorage.ts +31 -8
- package/src/storage-browser/LocalStorageManager.ts +25 -1
- package/src/swapper/Swapper.ts +599 -390
- package/src/swapper/SwapperFactory.ts +73 -24
- package/src/swapper/SwapperUtils.ts +107 -60
- package/src/swapper/SwapperWithChain.ts +320 -81
- package/src/swapper/SwapperWithSigner.ts +263 -56
- package/src/swaps/IAddressSwap.ts +13 -3
- package/src/swaps/IBTCWalletSwap.ts +26 -10
- package/src/swaps/IClaimableSwap.ts +41 -6
- package/src/swaps/IClaimableSwapWrapper.ts +11 -2
- package/src/swaps/IRefundableSwap.ts +34 -5
- package/src/swaps/ISwap.ts +224 -85
- package/src/swaps/ISwapWithGasDrop.ts +8 -2
- package/src/swaps/ISwapWrapper.ts +216 -98
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +64 -18
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +83 -37
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +61 -30
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +37 -19
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +123 -50
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +24 -11
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +562 -258
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +156 -62
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +592 -227
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +177 -74
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +483 -245
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +141 -59
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +350 -195
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +48 -23
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +87 -40
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +110 -110
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +89 -34
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +101 -31
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +556 -259
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +292 -148
- package/src/swaps/trusted/ln/LnForGasSwap.ts +186 -47
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +34 -15
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +262 -88
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +41 -19
- package/src/types/AmountData.ts +2 -1
- package/src/types/CustomPriceFunction.ts +8 -2
- package/src/types/PriceInfoType.ts +4 -4
- package/src/types/SwapExecutionAction.ts +97 -5
- package/src/types/SwapWithSigner.ts +8 -4
- package/src/types/Token.ts +12 -5
- package/src/types/TokenAmount.ts +3 -0
- package/src/types/fees/Fee.ts +3 -2
- package/src/types/fees/FeeBreakdown.ts +3 -2
- package/src/types/fees/PercentagePPM.ts +4 -2
- package/src/types/lnurl/LNURLPay.ts +20 -12
- package/src/types/lnurl/LNURLWithdraw.ts +17 -10
- package/src/types/wallets/LightningInvoiceCreateService.ts +30 -0
- package/src/types/wallets/MinimalBitcoinWalletInterface.ts +3 -1
- package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +4 -2
- package/src/utils/BitcoinUtils.ts +5 -0
- package/src/utils/SwapUtils.ts +63 -1
- package/src/utils/TokenUtils.ts +12 -4
- package/dist/bitcoin/BitcoinRpcWithAddressIndex.d.ts +0 -68
- package/dist/bitcoin/BitcoinRpcWithAddressIndex.js +0 -2
- package/dist/bitcoin/LightningNetworkApi.d.ts +0 -12
- package/dist/bitcoin/LightningNetworkApi.js +0 -2
- package/dist/bitcoin/mempool/MempoolApi.d.ts +0 -350
- package/dist/bitcoin/mempool/MempoolApi.js +0 -311
- package/dist/bitcoin/mempool/MempoolBitcoinBlock.d.ts +0 -44
- package/dist/bitcoin/mempool/MempoolBitcoinBlock.js +0 -48
- package/dist/bitcoin/mempool/MempoolBitcoinRpc.d.ts +0 -119
- package/dist/bitcoin/mempool/MempoolBitcoinRpc.js +0 -361
- package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.d.ts +0 -22
- package/dist/bitcoin/mempool/synchronizer/MempoolBtcRelaySynchronizer.js +0 -105
- package/dist/errors/PaymentAuthError.d.ts +0 -11
- package/dist/errors/PaymentAuthError.js +0 -23
- package/src/errors/PaymentAuthError.ts +0 -26
|
@@ -19,9 +19,10 @@ const Logger_1 = require("../../../../utils/Logger");
|
|
|
19
19
|
const TimeoutUtils_1 = require("../../../../utils/TimeoutUtils");
|
|
20
20
|
const LNURLWithdraw_1 = require("../../../../types/lnurl/LNURLWithdraw");
|
|
21
21
|
const PriceInfoType_1 = require("../../../../types/PriceInfoType");
|
|
22
|
+
const sha2_1 = require("@noble/hashes/sha2");
|
|
22
23
|
/**
|
|
23
24
|
* State enum for FromBTCLNAuto swaps
|
|
24
|
-
* @category Swaps
|
|
25
|
+
* @category Swaps/Lightning → Smart chain
|
|
25
26
|
*/
|
|
26
27
|
var FromBTCLNAutoSwapState;
|
|
27
28
|
(function (FromBTCLNAutoSwapState) {
|
|
@@ -35,10 +36,10 @@ var FromBTCLNAutoSwapState;
|
|
|
35
36
|
FromBTCLNAutoSwapState[FromBTCLNAutoSwapState["CLAIM_CLAIMED"] = 3] = "CLAIM_CLAIMED";
|
|
36
37
|
})(FromBTCLNAutoSwapState = exports.FromBTCLNAutoSwapState || (exports.FromBTCLNAutoSwapState = {}));
|
|
37
38
|
function isFromBTCLNAutoSwapInit(obj) {
|
|
38
|
-
return typeof obj.pr === "string" &&
|
|
39
|
-
typeof obj.secret === "string" &&
|
|
40
|
-
typeof obj.btcAmountSwap === "bigint" &&
|
|
41
|
-
typeof obj.btcAmountGas === "bigint" &&
|
|
39
|
+
return (obj.pr == null || typeof obj.pr === "string") &&
|
|
40
|
+
(obj.secret == null || typeof obj.secret === "string") &&
|
|
41
|
+
(obj.btcAmountSwap == null || typeof obj.btcAmountSwap === "bigint") &&
|
|
42
|
+
(obj.btcAmountGas == null || typeof obj.btcAmountGas === "bigint") &&
|
|
42
43
|
typeof obj.gasSwapFeeBtc === "bigint" &&
|
|
43
44
|
typeof obj.gasSwapFee === "bigint" &&
|
|
44
45
|
(obj.gasPricingInfo == null || (0, PriceInfoType_1.isPriceInfoType)(obj.gasPricingInfo)) &&
|
|
@@ -48,21 +49,39 @@ function isFromBTCLNAutoSwapInit(obj) {
|
|
|
48
49
|
(0, IEscrowSwap_1.isIEscrowSwapInit)(obj);
|
|
49
50
|
}
|
|
50
51
|
exports.isFromBTCLNAutoSwapInit = isFromBTCLNAutoSwapInit;
|
|
52
|
+
/**
|
|
53
|
+
* New escrow based (HTLC) swaps for Bitcoin Lightning -> Smart chain swaps not requiring manual settlement on
|
|
54
|
+
* the destination by the user, and instead letting the LP initiate the escrow. Permissionless watchtower network
|
|
55
|
+
* handles the claiming of HTLC, with the swap secret broadcasted over Nostr. Also adds a possibility for the user
|
|
56
|
+
* to receive a native token on the destination chain as part of the swap (a "gas drop" feature).
|
|
57
|
+
*
|
|
58
|
+
* @category Swaps/Lightning → Smart chain
|
|
59
|
+
*/
|
|
51
60
|
class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Sets the LNURL data for the swap
|
|
63
|
+
*
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
_setLNURLData(lnurl, lnurlK1, lnurlCallback) {
|
|
67
|
+
this.lnurl = lnurl;
|
|
68
|
+
this.lnurlK1 = lnurlK1;
|
|
69
|
+
this.lnurlCallback = lnurlCallback;
|
|
54
70
|
}
|
|
55
71
|
constructor(wrapper, initOrObject) {
|
|
56
72
|
if (isFromBTCLNAutoSwapInit(initOrObject) && initOrObject.url != null)
|
|
57
73
|
initOrObject.url += "/frombtcln_auto";
|
|
58
74
|
super(wrapper, initOrObject);
|
|
59
|
-
this.inputToken = Token_1.BitcoinTokens.BTCLN;
|
|
60
75
|
this.TYPE = SwapType_1.SwapType.FROM_BTCLN_AUTO;
|
|
76
|
+
/**
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
this.inputToken = Token_1.BitcoinTokens.BTCLN;
|
|
61
80
|
this.lnurlFailSignal = new AbortController();
|
|
62
81
|
this.prPosted = false;
|
|
63
82
|
this.broadcastTickCounter = 0;
|
|
64
83
|
if (isFromBTCLNAutoSwapInit(initOrObject)) {
|
|
65
|
-
this.
|
|
84
|
+
this._state = FromBTCLNAutoSwapState.PR_CREATED;
|
|
66
85
|
this.pr = initOrObject.pr;
|
|
67
86
|
this.secret = initOrObject.secret;
|
|
68
87
|
this.initialSwapData = initOrObject.initialSwapData;
|
|
@@ -74,12 +93,13 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
74
93
|
this.lnurl = initOrObject.lnurl;
|
|
75
94
|
this.lnurlK1 = initOrObject.lnurlK1;
|
|
76
95
|
this.lnurlCallback = initOrObject.lnurlCallback;
|
|
96
|
+
this.usesClaimHashAsId = true;
|
|
77
97
|
}
|
|
78
98
|
else {
|
|
79
99
|
this.pr = initOrObject.pr;
|
|
80
100
|
this.secret = initOrObject.secret;
|
|
81
101
|
if (initOrObject.initialSwapData == null) {
|
|
82
|
-
this.initialSwapData = this.
|
|
102
|
+
this.initialSwapData = this._data;
|
|
83
103
|
}
|
|
84
104
|
else {
|
|
85
105
|
this.initialSwapData = base_1.SwapData.deserialize(initOrObject.initialSwapData);
|
|
@@ -89,225 +109,398 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
89
109
|
this.gasSwapFeeBtc = (0, Utils_1.toBigInt)(initOrObject.gasSwapFeeBtc);
|
|
90
110
|
this.gasSwapFee = (0, Utils_1.toBigInt)(initOrObject.gasSwapFee);
|
|
91
111
|
this.gasPricingInfo = (0, PriceInfoType_1.deserializePriceInfoType)(initOrObject.gasPricingInfo);
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
112
|
+
this._commitTxId = initOrObject.commitTxId;
|
|
113
|
+
this._claimTxId = initOrObject.claimTxId;
|
|
94
114
|
this.lnurl = initOrObject.lnurl;
|
|
95
115
|
this.lnurlK1 = initOrObject.lnurlK1;
|
|
96
116
|
this.lnurlCallback = initOrObject.lnurlCallback;
|
|
97
117
|
this.prPosted = initOrObject.prPosted;
|
|
118
|
+
this.usesClaimHashAsId = initOrObject.usesClaimHashAsId ?? false;
|
|
98
119
|
}
|
|
99
120
|
this.tryRecomputeSwapPrice();
|
|
100
121
|
this.logger = (0, Logger_1.getLogger)("FromBTCLNAuto(" + this.getIdentifierHashString() + "): ");
|
|
101
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* @inheritDoc
|
|
125
|
+
* @internal
|
|
126
|
+
*/
|
|
127
|
+
getSwapData() {
|
|
128
|
+
return this._data ?? this.initialSwapData;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* @inheritDoc
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
102
134
|
upgradeVersion() { }
|
|
103
135
|
/**
|
|
104
|
-
*
|
|
105
|
-
* @
|
|
136
|
+
* @inheritDoc
|
|
137
|
+
* @internal
|
|
106
138
|
*/
|
|
107
139
|
tryRecomputeSwapPrice() {
|
|
108
|
-
if (this.pricingInfo == null)
|
|
140
|
+
if (this.pricingInfo == null || this.btcAmountSwap == null)
|
|
109
141
|
return;
|
|
110
142
|
if (this.pricingInfo.swapPriceUSatPerToken == null) {
|
|
111
143
|
const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
112
|
-
this.pricingInfo = this.wrapper.
|
|
144
|
+
this.pricingInfo = this.wrapper._prices.recomputePriceInfoReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken());
|
|
113
145
|
this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
|
|
114
146
|
}
|
|
115
147
|
}
|
|
116
148
|
//////////////////////////////
|
|
117
149
|
//// Pricing
|
|
150
|
+
/**
|
|
151
|
+
* @inheritDoc
|
|
152
|
+
*/
|
|
118
153
|
async refreshPriceData() {
|
|
119
|
-
if (this.pricingInfo == null)
|
|
154
|
+
if (this.pricingInfo == null || this.btcAmountSwap == null)
|
|
120
155
|
return;
|
|
121
156
|
const usdPricePerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
122
|
-
this.pricingInfo = await this.wrapper.
|
|
157
|
+
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken());
|
|
123
158
|
this.pricingInfo.realPriceUsdPerBitcoin = usdPricePerBtc;
|
|
124
159
|
}
|
|
125
160
|
//////////////////////////////
|
|
126
161
|
//// Getters & utils
|
|
162
|
+
/**
|
|
163
|
+
* @inheritDoc
|
|
164
|
+
* @internal
|
|
165
|
+
*/
|
|
127
166
|
_getEscrowHash() {
|
|
128
167
|
//Use claim hash in case the data is not yet known
|
|
129
|
-
return this.
|
|
168
|
+
return this._data == null ? this.initialSwapData?.getClaimHash() : this._data?.getEscrowHash();
|
|
130
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* @inheritDoc
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
131
174
|
_getInitiator() {
|
|
132
175
|
return this.getSwapData().getClaimer();
|
|
133
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* @inheritDoc
|
|
179
|
+
*/
|
|
134
180
|
getId() {
|
|
135
181
|
return this.getIdentifierHashString();
|
|
136
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* @inheritDoc
|
|
185
|
+
*/
|
|
137
186
|
getOutputAddress() {
|
|
138
187
|
return this._getInitiator();
|
|
139
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* @inheritDoc
|
|
191
|
+
*/
|
|
140
192
|
getOutputTxId() {
|
|
141
|
-
return this.
|
|
193
|
+
return this._claimTxId ?? null;
|
|
142
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* @inheritDoc
|
|
197
|
+
*/
|
|
143
198
|
requiresAction() {
|
|
144
|
-
return this.
|
|
199
|
+
return this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED;
|
|
145
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* @inheritDoc
|
|
203
|
+
* @internal
|
|
204
|
+
*/
|
|
146
205
|
getIdentifierHashString() {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
206
|
+
const id = this.usesClaimHashAsId
|
|
207
|
+
? this.getClaimHash()
|
|
208
|
+
: this.getPaymentHash().toString("hex");
|
|
209
|
+
if (this._randomNonce == null)
|
|
210
|
+
return id;
|
|
211
|
+
return id + this._randomNonce;
|
|
151
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Returns the payment hash of the swap and lightning network invoice, or `null` if not known (i.e. if
|
|
215
|
+
* the swap was recovered from on-chain data, the payment hash might not be known)
|
|
216
|
+
*
|
|
217
|
+
* @internal
|
|
218
|
+
*/
|
|
152
219
|
getPaymentHash() {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
220
|
+
if (this.pr == null)
|
|
221
|
+
return null;
|
|
222
|
+
if (this.pr.toLowerCase().startsWith("ln")) {
|
|
223
|
+
const parsed = (0, bolt11_1.decode)(this.pr);
|
|
224
|
+
if (parsed.tagsObject.payment_hash == null)
|
|
225
|
+
throw new Error("Swap invoice has no payment hash field!");
|
|
226
|
+
return buffer_1.Buffer.from(parsed.tagsObject.payment_hash, "hex");
|
|
227
|
+
}
|
|
228
|
+
return buffer_1.Buffer.from(this.pr, "hex");
|
|
157
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* @inheritDoc
|
|
232
|
+
*/
|
|
158
233
|
getInputAddress() {
|
|
159
|
-
return this.lnurl ?? this.pr;
|
|
234
|
+
return this.lnurl ?? this.pr ?? null;
|
|
160
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* @inheritDoc
|
|
238
|
+
*/
|
|
161
239
|
getInputTxId() {
|
|
162
|
-
|
|
240
|
+
const paymentHash = this.getPaymentHash();
|
|
241
|
+
if (paymentHash == null)
|
|
242
|
+
return null;
|
|
243
|
+
return paymentHash.toString("hex");
|
|
163
244
|
}
|
|
164
245
|
/**
|
|
165
246
|
* Returns the lightning network BOLT11 invoice that needs to be paid as an input to the swap
|
|
166
247
|
*/
|
|
167
248
|
getAddress() {
|
|
168
|
-
return this.pr;
|
|
249
|
+
return this.pr ?? "";
|
|
169
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* @inheritDoc
|
|
253
|
+
*/
|
|
170
254
|
getHyperlink() {
|
|
171
|
-
return "lightning:" + this.pr.toUpperCase();
|
|
255
|
+
return this.pr == null ? "" : "lightning:" + this.pr.toUpperCase();
|
|
172
256
|
}
|
|
173
257
|
/**
|
|
174
258
|
* Returns the timeout time (in UNIX milliseconds) when the swap will definitelly be considered as expired
|
|
175
259
|
* if the LP doesn't make it expired sooner
|
|
176
260
|
*/
|
|
177
261
|
getDefinitiveExpiryTime() {
|
|
262
|
+
if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
|
|
263
|
+
return 0;
|
|
178
264
|
const decoded = (0, bolt11_1.decode)(this.pr);
|
|
179
265
|
if (decoded.tagsObject.min_final_cltv_expiry == null)
|
|
180
266
|
throw new Error("Swap invoice doesn't contain final ctlv delta field!");
|
|
181
267
|
if (decoded.timeExpireDate == null)
|
|
182
268
|
throw new Error("Swap invoice doesn't contain expiry date field!");
|
|
183
269
|
const finalCltvExpiryDelta = decoded.tagsObject.min_final_cltv_expiry ?? 144;
|
|
184
|
-
const finalCltvExpiryDelay = finalCltvExpiryDelta * this.wrapper.
|
|
270
|
+
const finalCltvExpiryDelay = finalCltvExpiryDelta * this.wrapper._options.bitcoinBlocktime * this.wrapper._options.safetyFactor;
|
|
185
271
|
return (decoded.timeExpireDate + finalCltvExpiryDelay) * 1000;
|
|
186
272
|
}
|
|
187
273
|
/**
|
|
188
274
|
* Returns timeout time (in UNIX milliseconds) when the swap htlc will expire
|
|
189
275
|
*/
|
|
190
276
|
getHtlcTimeoutTime() {
|
|
191
|
-
return this.
|
|
277
|
+
return this._data == null ? null : Number(this.wrapper._getHtlcTimeout(this._data)) * 1000;
|
|
192
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* @inheritDoc
|
|
281
|
+
*/
|
|
193
282
|
isFinished() {
|
|
194
|
-
return this.
|
|
283
|
+
return this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED || this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED || this._state === FromBTCLNAutoSwapState.FAILED;
|
|
195
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* @inheritDoc
|
|
287
|
+
*/
|
|
196
288
|
isClaimable() {
|
|
197
|
-
return this.
|
|
289
|
+
return this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED;
|
|
198
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* @inheritDoc
|
|
293
|
+
*/
|
|
199
294
|
isSuccessful() {
|
|
200
|
-
return this.
|
|
295
|
+
return this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED;
|
|
201
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* @inheritDoc
|
|
299
|
+
*/
|
|
202
300
|
isFailed() {
|
|
203
|
-
return this.
|
|
301
|
+
return this._state === FromBTCLNAutoSwapState.FAILED || this._state === FromBTCLNAutoSwapState.EXPIRED;
|
|
204
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* @inheritDoc
|
|
305
|
+
*/
|
|
205
306
|
isQuoteExpired() {
|
|
206
|
-
return this.
|
|
307
|
+
return this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
207
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* @inheritDoc
|
|
311
|
+
*/
|
|
208
312
|
isQuoteSoftExpired() {
|
|
209
|
-
return this.
|
|
313
|
+
return this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
210
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* @inheritDoc
|
|
317
|
+
*/
|
|
211
318
|
_verifyQuoteDefinitelyExpired() {
|
|
212
319
|
return Promise.resolve(this.getDefinitiveExpiryTime() < Date.now());
|
|
213
320
|
}
|
|
214
|
-
|
|
321
|
+
/**
|
|
322
|
+
* @inheritDoc
|
|
323
|
+
*/
|
|
324
|
+
_verifyQuoteValid() {
|
|
215
325
|
return Promise.resolve(this.getQuoteExpiry() > Date.now());
|
|
216
326
|
}
|
|
217
327
|
//////////////////////////////
|
|
218
328
|
//// Amounts & fees
|
|
329
|
+
/**
|
|
330
|
+
* Returns the satoshi amount of the lightning network invoice, or `null` if the lightning network
|
|
331
|
+
* invoice is not known (i.e. when the swap was recovered from on-chain data, the paid invoice
|
|
332
|
+
* cannot be recovered because it is purely off-chain)
|
|
333
|
+
*
|
|
334
|
+
* @internal
|
|
335
|
+
*/
|
|
219
336
|
getLightningInvoiceSats() {
|
|
337
|
+
if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
|
|
338
|
+
return null;
|
|
220
339
|
const parsed = (0, bolt11_1.decode)(this.pr);
|
|
221
340
|
if (parsed.millisatoshis == null)
|
|
222
341
|
throw new Error("Swap invoice doesn't contain msat amount field!");
|
|
223
342
|
return (BigInt(parsed.millisatoshis) + 999n) / 1000n;
|
|
224
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Returns the watchtower fee paid in BTC satoshis, or null if known (i.e. if the swap was recovered from
|
|
346
|
+
* on-chain data)
|
|
347
|
+
*
|
|
348
|
+
* @protected
|
|
349
|
+
*/
|
|
225
350
|
getWatchtowerFeeAmountBtc() {
|
|
351
|
+
if (this.btcAmountGas == null)
|
|
352
|
+
return null;
|
|
226
353
|
return (this.btcAmountGas - this.gasSwapFeeBtc) * this.getSwapData().getClaimerBounty() / this.getSwapData().getTotalDeposit();
|
|
227
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Returns the input amount for the actual swap (excluding the input amount used to cover the "gas drop"
|
|
357
|
+
* part of the swap), excluding fees
|
|
358
|
+
*
|
|
359
|
+
* @internal
|
|
360
|
+
*/
|
|
228
361
|
getInputSwapAmountWithoutFee() {
|
|
362
|
+
if (this.btcAmountSwap == null)
|
|
363
|
+
return null;
|
|
229
364
|
return this.btcAmountSwap - this.swapFeeBtc;
|
|
230
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* Returns the input amount purely for the "gas drop" part of the swap (this much BTC in sats will be
|
|
368
|
+
* swapped into the native gas token on the destination chain), excluding fees
|
|
369
|
+
*
|
|
370
|
+
* @internal
|
|
371
|
+
*/
|
|
231
372
|
getInputGasAmountWithoutFee() {
|
|
373
|
+
if (this.btcAmountGas == null)
|
|
374
|
+
return null;
|
|
232
375
|
return this.btcAmountGas - this.gasSwapFeeBtc;
|
|
233
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Get total btc amount in sats on the input, excluding the swap fee and watchtower fee
|
|
379
|
+
*
|
|
380
|
+
* @internal
|
|
381
|
+
*/
|
|
234
382
|
getInputAmountWithoutFee() {
|
|
383
|
+
if (this.btcAmountGas == null || this.btcAmountSwap)
|
|
384
|
+
return null;
|
|
235
385
|
return this.getInputSwapAmountWithoutFee() + this.getInputGasAmountWithoutFee() - this.getWatchtowerFeeAmountBtc();
|
|
236
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Returns the "would be" output amount if the swap charged no swap fee
|
|
389
|
+
*
|
|
390
|
+
* @internal
|
|
391
|
+
*/
|
|
237
392
|
getOutputAmountWithoutFee() {
|
|
238
393
|
return this.getSwapData().getAmount() + this.swapFee;
|
|
239
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* @inheritDoc
|
|
397
|
+
*/
|
|
240
398
|
getInputToken() {
|
|
241
399
|
return Token_1.BitcoinTokens.BTCLN;
|
|
242
400
|
}
|
|
401
|
+
/**
|
|
402
|
+
* @inheritDoc
|
|
403
|
+
*/
|
|
243
404
|
getInput() {
|
|
244
|
-
return (0, TokenAmount_1.toTokenAmount)(this.getLightningInvoiceSats(), this.inputToken, this.wrapper.
|
|
405
|
+
return (0, TokenAmount_1.toTokenAmount)(this.getLightningInvoiceSats(), this.inputToken, this.wrapper._prices, this.pricingInfo);
|
|
245
406
|
}
|
|
407
|
+
/**
|
|
408
|
+
* @inheritDoc
|
|
409
|
+
*/
|
|
246
410
|
getInputWithoutFee() {
|
|
247
|
-
return (0, TokenAmount_1.toTokenAmount)(this.getInputAmountWithoutFee(), this.inputToken, this.wrapper.
|
|
411
|
+
return (0, TokenAmount_1.toTokenAmount)(this.getInputAmountWithoutFee(), this.inputToken, this.wrapper._prices, this.pricingInfo);
|
|
248
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* @inheritDoc
|
|
415
|
+
*/
|
|
249
416
|
getOutputToken() {
|
|
250
|
-
return this.wrapper.
|
|
417
|
+
return this.wrapper._tokens[this.getSwapData().getToken()];
|
|
251
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* @inheritDoc
|
|
421
|
+
*/
|
|
252
422
|
getOutput() {
|
|
253
|
-
return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getAmount(), this.wrapper.
|
|
423
|
+
return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getAmount(), this.wrapper._tokens[this.getSwapData().getToken()], this.wrapper._prices, this.pricingInfo);
|
|
254
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* @inheritDoc
|
|
427
|
+
*/
|
|
255
428
|
getGasDropOutput() {
|
|
256
|
-
return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getSecurityDeposit() - this.getSwapData().getClaimerBounty(), this.wrapper.
|
|
429
|
+
return (0, TokenAmount_1.toTokenAmount)(this.getSwapData().getSecurityDeposit() - this.getSwapData().getClaimerBounty(), this.wrapper._tokens[this.getSwapData().getDepositToken()], this.wrapper._prices, this.gasPricingInfo);
|
|
257
430
|
}
|
|
431
|
+
/**
|
|
432
|
+
* Returns the swap fee charged by the intermediary (LP) on this swap
|
|
433
|
+
*
|
|
434
|
+
* @internal
|
|
435
|
+
*/
|
|
258
436
|
getSwapFee() {
|
|
259
437
|
if (this.pricingInfo == null)
|
|
260
438
|
throw new Error("No pricing info known, cannot estimate fee!");
|
|
261
|
-
const outputToken = this.wrapper.
|
|
439
|
+
const outputToken = this.wrapper._tokens[this.getSwapData().getToken()];
|
|
262
440
|
const gasSwapFeeInOutputToken = this.gasSwapFeeBtc
|
|
263
441
|
* (10n ** BigInt(outputToken.decimals))
|
|
264
442
|
* 1000000n
|
|
265
443
|
/ this.pricingInfo.swapPriceUSatPerToken;
|
|
266
444
|
const feeWithoutBaseFee = this.gasSwapFeeBtc + this.swapFeeBtc - this.pricingInfo.satsBaseFee;
|
|
267
|
-
const
|
|
268
|
-
const
|
|
445
|
+
const inputSats = this.getLightningInvoiceSats();
|
|
446
|
+
const swapFeePPM = inputSats != null
|
|
447
|
+
? feeWithoutBaseFee * 1000000n / (inputSats - this.swapFeeBtc - this.gasSwapFeeBtc)
|
|
448
|
+
: 0n;
|
|
449
|
+
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(this.swapFeeBtc + this.gasSwapFeeBtc, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
269
450
|
return {
|
|
270
451
|
amountInSrcToken,
|
|
271
|
-
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee + gasSwapFeeInOutputToken, outputToken, this.wrapper.
|
|
452
|
+
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee + gasSwapFeeInOutputToken, outputToken, this.wrapper._prices, this.pricingInfo),
|
|
272
453
|
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
273
454
|
pastUsdValue: amountInSrcToken.pastUsdValue,
|
|
274
455
|
usdValue: amountInSrcToken.usdValue,
|
|
275
456
|
composition: {
|
|
276
|
-
base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTCLN, this.wrapper.
|
|
457
|
+
base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo),
|
|
277
458
|
percentage: (0, PercentagePPM_1.ppmToPercentage)(swapFeePPM)
|
|
278
459
|
}
|
|
279
460
|
};
|
|
280
461
|
}
|
|
462
|
+
/**
|
|
463
|
+
* Returns the fee to be paid to watchtowers on the destination chain to automatically
|
|
464
|
+
* process and settle this swap without requiring any user interaction
|
|
465
|
+
*
|
|
466
|
+
* @internal
|
|
467
|
+
*/
|
|
281
468
|
getWatchtowerFee() {
|
|
282
469
|
if (this.pricingInfo == null)
|
|
283
470
|
throw new Error("No pricing info known, cannot estimate fee!");
|
|
284
471
|
const btcWatchtowerFee = this.getWatchtowerFeeAmountBtc();
|
|
285
|
-
const outputToken = this.wrapper.
|
|
286
|
-
const watchtowerFeeInOutputToken = btcWatchtowerFee
|
|
472
|
+
const outputToken = this.wrapper._tokens[this.getSwapData().getToken()];
|
|
473
|
+
const watchtowerFeeInOutputToken = btcWatchtowerFee == null ? 0n : btcWatchtowerFee
|
|
287
474
|
* (10n ** BigInt(outputToken.decimals))
|
|
288
475
|
* 1000000n
|
|
289
476
|
/ this.pricingInfo.swapPriceUSatPerToken;
|
|
290
|
-
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(btcWatchtowerFee, Token_1.BitcoinTokens.BTCLN, this.wrapper.
|
|
477
|
+
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(btcWatchtowerFee, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
291
478
|
return {
|
|
292
479
|
amountInSrcToken,
|
|
293
|
-
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(watchtowerFeeInOutputToken, outputToken, this.wrapper.
|
|
480
|
+
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(watchtowerFeeInOutputToken, outputToken, this.wrapper._prices, this.pricingInfo),
|
|
294
481
|
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
295
482
|
usdValue: amountInSrcToken.usdValue,
|
|
296
483
|
pastUsdValue: amountInSrcToken.pastUsdValue
|
|
297
484
|
};
|
|
298
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* @inheritDoc
|
|
488
|
+
*/
|
|
299
489
|
getFee() {
|
|
300
490
|
const swapFee = this.getSwapFee();
|
|
301
491
|
const watchtowerFee = this.getWatchtowerFee();
|
|
302
|
-
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(swapFee.amountInSrcToken.rawAmount + watchtowerFee.amountInSrcToken.rawAmount, Token_1.BitcoinTokens.BTCLN, this.wrapper.
|
|
492
|
+
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(swapFee.amountInSrcToken.rawAmount + watchtowerFee.amountInSrcToken.rawAmount, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
303
493
|
return {
|
|
304
494
|
amountInSrcToken,
|
|
305
|
-
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(swapFee.amountInDstToken.rawAmount + watchtowerFee.amountInDstToken.rawAmount, this.wrapper.
|
|
495
|
+
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(swapFee.amountInDstToken.rawAmount + watchtowerFee.amountInDstToken.rawAmount, this.wrapper._tokens[this.getSwapData().getToken()], this.wrapper._prices, this.pricingInfo),
|
|
306
496
|
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
307
497
|
usdValue: amountInSrcToken.usdValue,
|
|
308
498
|
pastUsdValue: amountInSrcToken.pastUsdValue
|
|
309
499
|
};
|
|
310
500
|
}
|
|
501
|
+
/**
|
|
502
|
+
* @inheritDoc
|
|
503
|
+
*/
|
|
311
504
|
getFeeBreakdown() {
|
|
312
505
|
return [
|
|
313
506
|
{
|
|
@@ -320,6 +513,11 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
320
513
|
}
|
|
321
514
|
];
|
|
322
515
|
}
|
|
516
|
+
isValidSecretPreimage(secret) {
|
|
517
|
+
const paymentHash = buffer_1.Buffer.from((0, sha2_1.sha256)(buffer_1.Buffer.from(secret, "hex")));
|
|
518
|
+
const claimHash = this.wrapper._contract.getHashForHtlc(paymentHash).toString("hex");
|
|
519
|
+
return this.getSwapData().getClaimHash() === claimHash;
|
|
520
|
+
}
|
|
323
521
|
//////////////////////////////
|
|
324
522
|
//// Execution
|
|
325
523
|
/**
|
|
@@ -329,22 +527,26 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
329
527
|
* link, wallet is not required and the LN invoice can be paid externally as well (just pass null or undefined here)
|
|
330
528
|
* @param callbacks Callbacks to track the progress of the swap
|
|
331
529
|
* @param options Optional options for the swap like feeRate, AbortSignal, and timeouts/intervals
|
|
530
|
+
* @param secret A swap secret to broadcast to watchtowers, generally only needed if the swap
|
|
531
|
+
* was recovered from on-chain data, or the pre-image was generated outside the SDK
|
|
332
532
|
*
|
|
333
533
|
* @returns {boolean} Whether a swap was settled automatically by swap watchtowers or requires manual claim by the
|
|
334
534
|
* user, in case `false` is returned the user should call `swap.claim()` to settle the swap on the destination manually
|
|
335
535
|
*/
|
|
336
|
-
async execute(walletOrLnurlWithdraw, callbacks, options) {
|
|
337
|
-
if (this.
|
|
536
|
+
async execute(walletOrLnurlWithdraw, callbacks, options, secret) {
|
|
537
|
+
if (this._state === FromBTCLNAutoSwapState.FAILED)
|
|
338
538
|
throw new Error("Swap failed!");
|
|
339
|
-
if (this.
|
|
539
|
+
if (this._state === FromBTCLNAutoSwapState.EXPIRED)
|
|
340
540
|
throw new Error("Swap HTLC expired!");
|
|
341
|
-
if (this.
|
|
541
|
+
if (this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
|
|
342
542
|
throw new Error("Swap quote expired!");
|
|
343
|
-
if (this.
|
|
543
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
|
|
344
544
|
throw new Error("Swap already settled!");
|
|
345
545
|
let abortSignal = options?.abortSignal;
|
|
346
|
-
if (this.
|
|
546
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED) {
|
|
347
547
|
if (walletOrLnurlWithdraw != null && this.lnurl == null) {
|
|
548
|
+
if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
|
|
549
|
+
throw new Error("Input lightning network invoice not available, the swap was probably recovered!");
|
|
348
550
|
if (typeof (walletOrLnurlWithdraw) === "string" || (0, LNURLWithdraw_1.isLNURLWithdraw)(walletOrLnurlWithdraw)) {
|
|
349
551
|
await this.settleWithLNURLWithdraw(walletOrLnurlWithdraw);
|
|
350
552
|
}
|
|
@@ -358,24 +560,29 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
358
560
|
}
|
|
359
561
|
}
|
|
360
562
|
}
|
|
361
|
-
if (this.
|
|
563
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
362
564
|
const paymentSuccess = await this.waitForPayment(callbacks?.onSourceTransactionReceived, options?.lightningTxCheckIntervalSeconds, abortSignal);
|
|
363
565
|
if (!paymentSuccess)
|
|
364
566
|
throw new Error("Failed to receive lightning network payment");
|
|
365
567
|
}
|
|
366
|
-
if (this.
|
|
568
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
|
|
367
569
|
return true;
|
|
368
|
-
if (this.
|
|
369
|
-
|
|
570
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
|
|
571
|
+
if (this.secret == null && secret == null)
|
|
572
|
+
throw new Error("Tried to wait till settlement, but no secret pre-image is known, please pass the secret pre-image as an argument!");
|
|
573
|
+
const success = await this.waitTillClaimed(options?.maxWaitTillAutomaticSettlementSeconds ?? 60, options?.abortSignal, secret);
|
|
370
574
|
if (success && callbacks?.onSwapSettled != null)
|
|
371
575
|
callbacks.onSwapSettled(this.getOutputTxId());
|
|
372
576
|
return success;
|
|
373
577
|
}
|
|
374
578
|
throw new Error("Invalid state reached!");
|
|
375
579
|
}
|
|
580
|
+
/**
|
|
581
|
+
* @inheritDoc
|
|
582
|
+
*/
|
|
376
583
|
async txsExecute() {
|
|
377
|
-
if (this.
|
|
378
|
-
if (!await this.
|
|
584
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED) {
|
|
585
|
+
if (!await this._verifyQuoteValid())
|
|
379
586
|
throw new Error("Quote already expired or close to expiry!");
|
|
380
587
|
return [
|
|
381
588
|
{
|
|
@@ -384,7 +591,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
384
591
|
chain: "LIGHTNING",
|
|
385
592
|
txs: [
|
|
386
593
|
{
|
|
387
|
-
|
|
594
|
+
type: "BOLT11_PAYMENT_REQUEST",
|
|
595
|
+
address: this.getAddress(),
|
|
388
596
|
hyperlink: this.getHyperlink()
|
|
389
597
|
}
|
|
390
598
|
]
|
|
@@ -396,25 +604,31 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
396
604
|
//////////////////////////////
|
|
397
605
|
//// Payment
|
|
398
606
|
/**
|
|
399
|
-
* Checks whether the LP received the LN payment
|
|
607
|
+
* Checks whether the LP received the LN payment
|
|
400
608
|
*
|
|
401
609
|
* @param save If the new swap state should be saved
|
|
610
|
+
*
|
|
611
|
+
* @internal
|
|
402
612
|
*/
|
|
403
613
|
async _checkIntermediaryPaymentReceived(save = true) {
|
|
404
|
-
if (this.
|
|
405
|
-
this.
|
|
406
|
-
this.
|
|
407
|
-
this.
|
|
614
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID ||
|
|
615
|
+
this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED ||
|
|
616
|
+
this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED ||
|
|
617
|
+
this._state === FromBTCLNAutoSwapState.FAILED ||
|
|
618
|
+
this._state === FromBTCLNAutoSwapState.EXPIRED)
|
|
408
619
|
return true;
|
|
409
|
-
if (this.
|
|
620
|
+
if (this._state === FromBTCLNAutoSwapState.QUOTE_EXPIRED)
|
|
410
621
|
return false;
|
|
411
622
|
if (this.url == null)
|
|
412
623
|
return false;
|
|
413
|
-
const
|
|
624
|
+
const paymentHash = this.getPaymentHash();
|
|
625
|
+
if (paymentHash == null)
|
|
626
|
+
throw new Error("Failed to check LP payment received, payment hash not known (probably recovered swap?)");
|
|
627
|
+
const resp = await IntermediaryAPI_1.IntermediaryAPI.getInvoiceStatus(this.url, paymentHash.toString("hex"));
|
|
414
628
|
switch (resp.code) {
|
|
415
629
|
case IntermediaryAPI_1.InvoiceStatusResponseCodes.PAID:
|
|
416
|
-
const data = new this.wrapper.
|
|
417
|
-
if (this.
|
|
630
|
+
const data = new this.wrapper._swapDataDeserializer(resp.data.data);
|
|
631
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
|
|
418
632
|
try {
|
|
419
633
|
await this._saveRealSwapData(data, save);
|
|
420
634
|
return true;
|
|
@@ -422,7 +636,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
422
636
|
catch (e) { }
|
|
423
637
|
return null;
|
|
424
638
|
case IntermediaryAPI_1.InvoiceStatusResponseCodes.EXPIRED:
|
|
425
|
-
this.
|
|
639
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
426
640
|
this.initiated = true;
|
|
427
641
|
if (save)
|
|
428
642
|
await this._saveAndEmit();
|
|
@@ -431,11 +645,20 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
431
645
|
return null;
|
|
432
646
|
}
|
|
433
647
|
}
|
|
648
|
+
/**
|
|
649
|
+
* Checks and overrides the swap data for this swap. This is used to set the swap data from
|
|
650
|
+
* on-chain events.
|
|
651
|
+
*
|
|
652
|
+
* @param data Swap data of the escrow swap
|
|
653
|
+
* @param save If the new data should be saved
|
|
654
|
+
*
|
|
655
|
+
* @internal
|
|
656
|
+
*/
|
|
434
657
|
async _saveRealSwapData(data, save) {
|
|
435
658
|
await this.checkIntermediaryReturnedData(data);
|
|
436
|
-
if (this.
|
|
437
|
-
this.
|
|
438
|
-
this.
|
|
659
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
|
|
660
|
+
this._state = FromBTCLNAutoSwapState.PR_PAID;
|
|
661
|
+
this._data = data;
|
|
439
662
|
this.initiated = true;
|
|
440
663
|
if (save)
|
|
441
664
|
await this._saveAndEmit();
|
|
@@ -447,9 +670,11 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
447
670
|
* Checks the data returned by the intermediary in the payment auth request
|
|
448
671
|
*
|
|
449
672
|
* @param data Parsed swap data as returned by the intermediary
|
|
450
|
-
*
|
|
673
|
+
*
|
|
451
674
|
* @throws {IntermediaryError} If the returned are not valid
|
|
452
675
|
* @throws {Error} If the swap is already committed on-chain
|
|
676
|
+
*
|
|
677
|
+
* @private
|
|
453
678
|
*/
|
|
454
679
|
async checkIntermediaryReturnedData(data) {
|
|
455
680
|
if (!data.isPayOut())
|
|
@@ -474,32 +699,40 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
474
699
|
throw new IntermediaryError_1.IntermediaryError("Invalid deposit token used!");
|
|
475
700
|
if (data.hasSuccessAction())
|
|
476
701
|
throw new IntermediaryError_1.IntermediaryError("Invalid has success action");
|
|
477
|
-
if (await this.wrapper.
|
|
702
|
+
if (await this.wrapper._contract.isExpired(this._getInitiator(), data))
|
|
478
703
|
throw new IntermediaryError_1.IntermediaryError("Not enough time to claim!");
|
|
479
|
-
if (this.wrapper.
|
|
704
|
+
if (this.wrapper._getHtlcTimeout(data) <= (Date.now() / 1000))
|
|
480
705
|
throw new IntermediaryError_1.IntermediaryError("HTLC expires too soon!");
|
|
481
706
|
}
|
|
482
707
|
/**
|
|
483
|
-
* Waits till
|
|
708
|
+
* Waits till a lightning network payment is received by the intermediary, and the intermediary
|
|
709
|
+
* initiates the swap HTLC on the smart chain side. After the HTLC is initiated you can wait
|
|
710
|
+
* for an automatic settlement by the watchtowers with the {@link waitTillClaimed} function,
|
|
711
|
+
* or settle manually using the {@link claim} or {@link txsClaim} functions.
|
|
712
|
+
*
|
|
713
|
+
* If this swap is using an LNURL-withdraw link as input, it automatically posts the
|
|
714
|
+
* generated invoice to the LNURL service to pay it.
|
|
484
715
|
*
|
|
485
716
|
* @param onPaymentReceived Callback as for when the LP reports having received the ln payment
|
|
486
|
-
* @param checkIntervalSeconds How often to poll the intermediary for answer (default 5 seconds)
|
|
487
717
|
* @param abortSignal Abort signal to stop waiting for payment
|
|
718
|
+
* @param checkIntervalSeconds How often to poll the intermediary for answer (default 5 seconds)
|
|
488
719
|
*/
|
|
489
720
|
async waitForPayment(onPaymentReceived, checkIntervalSeconds, abortSignal) {
|
|
490
721
|
checkIntervalSeconds ??= 5;
|
|
491
|
-
if (this.
|
|
722
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
492
723
|
await this.waitTillCommited(checkIntervalSeconds, abortSignal);
|
|
493
724
|
}
|
|
494
|
-
if (this.
|
|
725
|
+
if (this._state >= FromBTCLNAutoSwapState.CLAIM_COMMITED)
|
|
495
726
|
return true;
|
|
496
|
-
if (this.
|
|
727
|
+
if (this._state !== FromBTCLNAutoSwapState.PR_CREATED)
|
|
497
728
|
throw new Error("Must be in PR_CREATED state!");
|
|
498
729
|
const abortController = new AbortController();
|
|
499
730
|
if (abortSignal != null)
|
|
500
731
|
abortSignal.addEventListener("abort", () => abortController.abort(abortSignal.reason));
|
|
501
732
|
let save = false;
|
|
502
733
|
if (this.lnurl != null && this.lnurlK1 != null && this.lnurlCallback != null && !this.prPosted) {
|
|
734
|
+
if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
|
|
735
|
+
throw new Error("Input lightning network invoice not available, the swap was probably recovered!");
|
|
503
736
|
LNURL_1.LNURL.postInvoiceToLNURLWithdraw({ k1: this.lnurlK1, callback: this.lnurlCallback }, this.pr).catch(e => {
|
|
504
737
|
this.lnurlFailSignal.abort(e);
|
|
505
738
|
});
|
|
@@ -515,11 +748,14 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
515
748
|
let lnurlFailListener = () => abortController.abort(this.lnurlFailSignal.signal.reason);
|
|
516
749
|
this.lnurlFailSignal.signal.addEventListener("abort", lnurlFailListener);
|
|
517
750
|
this.lnurlFailSignal.signal.throwIfAborted();
|
|
518
|
-
|
|
519
|
-
|
|
751
|
+
const paymentHash = this.getPaymentHash();
|
|
752
|
+
if (paymentHash == null)
|
|
753
|
+
throw new Error("Swap payment hash not available, the swap was probably recovered!");
|
|
754
|
+
if (this.wrapper._messenger.warmup != null)
|
|
755
|
+
await this.wrapper._messenger.warmup().catch(e => {
|
|
520
756
|
this.logger.warn("waitForPayment(): Failed to warmup messenger: ", e);
|
|
521
757
|
});
|
|
522
|
-
if (this.
|
|
758
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED) {
|
|
523
759
|
const promises = [
|
|
524
760
|
this.waitTillState(FromBTCLNAutoSwapState.PR_PAID, "gte", abortController.signal).then(() => true)
|
|
525
761
|
];
|
|
@@ -527,17 +763,17 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
527
763
|
promises.push((async () => {
|
|
528
764
|
let resp = { code: IntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING, msg: "" };
|
|
529
765
|
while (!abortController.signal.aborted && resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING) {
|
|
530
|
-
resp = await IntermediaryAPI_1.IntermediaryAPI.getInvoiceStatus(this.url,
|
|
766
|
+
resp = await IntermediaryAPI_1.IntermediaryAPI.getInvoiceStatus(this.url, paymentHash.toString("hex"));
|
|
531
767
|
if (resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING)
|
|
532
768
|
await (0, TimeoutUtils_1.timeoutPromise)(checkIntervalSeconds * 1000, abortController.signal);
|
|
533
769
|
}
|
|
534
770
|
this.lnurlFailSignal.signal.removeEventListener("abort", lnurlFailListener);
|
|
535
771
|
abortController.signal.throwIfAborted();
|
|
536
772
|
if (resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.PAID) {
|
|
537
|
-
const swapData = new this.wrapper.
|
|
773
|
+
const swapData = new this.wrapper._swapDataDeserializer(resp.data.data);
|
|
538
774
|
return await this._saveRealSwapData(swapData, true);
|
|
539
775
|
}
|
|
540
|
-
if (this.
|
|
776
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
|
|
541
777
|
if (resp.code === IntermediaryAPI_1.InvoiceStatusResponseCodes.EXPIRED) {
|
|
542
778
|
await this._saveAndEmit(FromBTCLNAutoSwapState.QUOTE_EXPIRED);
|
|
543
779
|
}
|
|
@@ -551,17 +787,25 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
551
787
|
if (onPaymentReceived != null)
|
|
552
788
|
onPaymentReceived(this.getInputTxId());
|
|
553
789
|
}
|
|
554
|
-
if (this.
|
|
790
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
555
791
|
await this.waitTillCommited(checkIntervalSeconds, abortSignal);
|
|
556
792
|
}
|
|
557
|
-
return this.
|
|
793
|
+
return this._state >= FromBTCLNAutoSwapState.CLAIM_COMMITED;
|
|
558
794
|
}
|
|
559
795
|
//////////////////////////////
|
|
560
796
|
//// Commit
|
|
797
|
+
/**
|
|
798
|
+
* Waits till the intermediary (LP) initiates the swap HTLC escrow on the destination smart chain side
|
|
799
|
+
*
|
|
800
|
+
* @param checkIntervalSeconds How often to check via a polling watchdog
|
|
801
|
+
* @param abortSignal Abort signal
|
|
802
|
+
*
|
|
803
|
+
* @internal
|
|
804
|
+
*/
|
|
561
805
|
async waitTillCommited(checkIntervalSeconds, abortSignal) {
|
|
562
|
-
if (this.
|
|
806
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
|
|
563
807
|
return Promise.resolve();
|
|
564
|
-
if (this.
|
|
808
|
+
if (this._state !== FromBTCLNAutoSwapState.PR_PAID)
|
|
565
809
|
throw new Error("Invalid state");
|
|
566
810
|
const abortController = (0, Utils_1.extendAbortController)(abortSignal);
|
|
567
811
|
let result;
|
|
@@ -578,70 +822,97 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
578
822
|
}
|
|
579
823
|
if (result === false) {
|
|
580
824
|
this.logger.debug("waitTillCommited(): Resolved from watchdog - HTLC expired");
|
|
581
|
-
if (this.
|
|
825
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
582
826
|
await this._saveAndEmit(FromBTCLNAutoSwapState.EXPIRED);
|
|
583
827
|
}
|
|
584
828
|
return;
|
|
585
829
|
}
|
|
586
|
-
if (this.
|
|
830
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
587
831
|
await this._saveAndEmit(FromBTCLNAutoSwapState.CLAIM_COMMITED);
|
|
588
832
|
}
|
|
589
833
|
if (result === 0)
|
|
590
834
|
this.logger.debug("waitTillCommited(): Resolved from state changed");
|
|
591
835
|
if (result === true) {
|
|
592
836
|
this.logger.debug("waitTillCommited(): Resolved from watchdog - commited");
|
|
593
|
-
|
|
594
|
-
this.
|
|
595
|
-
|
|
837
|
+
if (this.secret != null)
|
|
838
|
+
await this._broadcastSecret().catch(e => {
|
|
839
|
+
this.logger.error("waitTillCommited(): Error broadcasting swap secret: ", e);
|
|
840
|
+
});
|
|
596
841
|
}
|
|
597
842
|
}
|
|
598
843
|
//////////////////////////////
|
|
599
844
|
//// Claim
|
|
600
845
|
/**
|
|
601
|
-
*
|
|
602
|
-
* (hash preimage)
|
|
846
|
+
* @inheritDoc
|
|
603
847
|
*
|
|
604
848
|
* @param _signer Optional signer address to use for claiming the swap, can also be different from the initializer
|
|
605
|
-
* @
|
|
849
|
+
* @param secret A swap secret to use for the claim transaction, generally only needed if the swap
|
|
850
|
+
* was recovered from on-chain data, or the pre-image was generated outside the SDK
|
|
851
|
+
*
|
|
852
|
+
* @throws {Error} If in invalid state (must be {@link FromBTCLNAutoSwapState.CLAIM_COMMITED})
|
|
606
853
|
*/
|
|
607
|
-
async txsClaim(_signer) {
|
|
608
|
-
if (this.
|
|
854
|
+
async txsClaim(_signer, secret) {
|
|
855
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
|
|
609
856
|
throw new Error("Must be in CLAIM_COMMITED state!");
|
|
610
|
-
if (this.
|
|
857
|
+
if (this._data == null)
|
|
611
858
|
throw new Error("Unknown data, wrong state?");
|
|
612
|
-
|
|
859
|
+
const useSecret = secret ?? this.secret;
|
|
860
|
+
if (useSecret == null)
|
|
861
|
+
throw new Error("Swap secret pre-image not known and not provided, please provide the swap secret pre-image as an argument");
|
|
862
|
+
if (!this.isValidSecretPreimage(useSecret))
|
|
863
|
+
throw new Error("Invalid swap secret pre-image provided!");
|
|
864
|
+
return await this.wrapper._contract.txsClaimWithSecret(_signer == null ?
|
|
613
865
|
this._getInitiator() :
|
|
614
|
-
((0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.
|
|
866
|
+
((0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer)), this._data, useSecret, true, true);
|
|
615
867
|
}
|
|
616
868
|
/**
|
|
617
|
-
*
|
|
869
|
+
* @inheritDoc
|
|
618
870
|
*
|
|
619
871
|
* @param _signer Signer to sign the transactions with, can also be different to the initializer
|
|
620
872
|
* @param abortSignal Abort signal to stop waiting for transaction confirmation
|
|
873
|
+
* @param onBeforeTxSent
|
|
874
|
+
* @param secret A swap secret to use for the claim transaction, generally only needed if the swap
|
|
875
|
+
* was recovered from on-chain data, or the pre-image was generated outside the SDK
|
|
621
876
|
*/
|
|
622
|
-
async claim(_signer, abortSignal) {
|
|
623
|
-
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper.
|
|
624
|
-
|
|
625
|
-
this.
|
|
626
|
-
|
|
877
|
+
async claim(_signer, abortSignal, onBeforeTxSent, secret) {
|
|
878
|
+
const signer = (0, base_1.isAbstractSigner)(_signer) ? _signer : await this.wrapper._chain.wrapSigner(_signer);
|
|
879
|
+
let txCount = 0;
|
|
880
|
+
const txs = await this.txsClaim(_signer, secret);
|
|
881
|
+
const result = await this.wrapper._chain.sendAndConfirm(signer, txs, true, abortSignal, undefined, (txId) => {
|
|
882
|
+
txCount++;
|
|
883
|
+
if (onBeforeTxSent != null && txCount === 1)
|
|
884
|
+
onBeforeTxSent(txId);
|
|
885
|
+
return Promise.resolve();
|
|
886
|
+
});
|
|
887
|
+
this._claimTxId = result[0];
|
|
888
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this._state === FromBTCLNAutoSwapState.EXPIRED || this._state === FromBTCLNAutoSwapState.FAILED) {
|
|
627
889
|
await this._saveAndEmit(FromBTCLNAutoSwapState.CLAIM_CLAIMED);
|
|
628
890
|
}
|
|
629
891
|
return result[0];
|
|
630
892
|
}
|
|
631
893
|
/**
|
|
632
|
-
* Waits till the swap is successfully claimed
|
|
894
|
+
* Waits till the swap is successfully settled (claimed), should be called after sending the claim (settlement)
|
|
895
|
+
* transactions manually to wait till the SDK processes the settlement and updates the swap state accordingly.
|
|
633
896
|
*
|
|
634
897
|
* @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled
|
|
635
898
|
* @param abortSignal AbortSignal
|
|
636
|
-
* @
|
|
899
|
+
* @param secret A swap secret to broadcast to watchtowers, generally only needed if the swap
|
|
900
|
+
* was recovered from on-chain data, or the pre-image was generated outside the SDK
|
|
901
|
+
*
|
|
902
|
+
* @throws {Error} If swap is in invalid state (must be {@link FromBTCLNAutoSwapState.CLAIM_COMMITED})
|
|
637
903
|
* @throws {Error} If the LP refunded sooner than we were able to claim
|
|
638
904
|
* @returns {boolean} whether the swap was claimed in time or not
|
|
639
905
|
*/
|
|
640
|
-
async waitTillClaimed(maxWaitTimeSeconds, abortSignal) {
|
|
641
|
-
if (this.
|
|
906
|
+
async waitTillClaimed(maxWaitTimeSeconds, abortSignal, secret) {
|
|
907
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
|
|
642
908
|
return Promise.resolve(true);
|
|
643
|
-
if (this.
|
|
909
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
|
|
644
910
|
throw new Error("Invalid state (not CLAIM_COMMITED)");
|
|
911
|
+
if (secret != null) {
|
|
912
|
+
if (!this.isValidSecretPreimage(secret))
|
|
913
|
+
throw new Error("Invalid swap secret pre-image provided!");
|
|
914
|
+
this.secret = secret;
|
|
915
|
+
}
|
|
645
916
|
const abortController = new AbortController();
|
|
646
917
|
if (abortSignal != null)
|
|
647
918
|
abortSignal.addEventListener("abort", () => abortController.abort(abortSignal.reason));
|
|
@@ -678,14 +949,14 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
678
949
|
}
|
|
679
950
|
this.logger.debug("waitTillClaimed(): Resolved from watchdog");
|
|
680
951
|
if (res?.type === base_1.SwapCommitStateType.PAID) {
|
|
681
|
-
if (this.
|
|
682
|
-
this.
|
|
952
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED) {
|
|
953
|
+
this._claimTxId = await res.getClaimTxId();
|
|
683
954
|
await this._saveAndEmit(FromBTCLNAutoSwapState.CLAIM_CLAIMED);
|
|
684
955
|
}
|
|
685
956
|
}
|
|
686
957
|
if (res?.type === base_1.SwapCommitStateType.NOT_COMMITED || res?.type === base_1.SwapCommitStateType.EXPIRED) {
|
|
687
|
-
if (this.
|
|
688
|
-
this.
|
|
958
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED &&
|
|
959
|
+
this._state !== FromBTCLNAutoSwapState.FAILED) {
|
|
689
960
|
await this._saveAndEmit(FromBTCLNAutoSwapState.FAILED);
|
|
690
961
|
}
|
|
691
962
|
throw new Error("Swap expired during claiming");
|
|
@@ -695,21 +966,29 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
695
966
|
//////////////////////////////
|
|
696
967
|
//// LNURL
|
|
697
968
|
/**
|
|
698
|
-
*
|
|
969
|
+
* Whether this swap uses an LNURL-withdraw link
|
|
699
970
|
*/
|
|
700
971
|
isLNURL() {
|
|
701
972
|
return this.lnurl != null;
|
|
702
973
|
}
|
|
703
974
|
/**
|
|
704
|
-
* Gets the used LNURL or null if this is not an LNURL-withdraw swap
|
|
975
|
+
* Gets the used LNURL or `null` if this is not an LNURL-withdraw swap
|
|
705
976
|
*/
|
|
706
977
|
getLNURL() {
|
|
707
978
|
return this.lnurl ?? null;
|
|
708
979
|
}
|
|
709
980
|
/**
|
|
710
|
-
* Pay the generated lightning network invoice with LNURL-withdraw
|
|
981
|
+
* Pay the generated lightning network invoice with an LNURL-withdraw link, this
|
|
982
|
+
* is useful when you want to display a lightning payment QR code and also want to
|
|
983
|
+
* allow payments using LNURL-withdraw NFC cards.
|
|
984
|
+
*
|
|
985
|
+
* Note that the swap needs to be created **without** an LNURL to begin with for this function
|
|
986
|
+
* to work. If this swap is already using an LNURL-withdraw link, this function throws.
|
|
711
987
|
*/
|
|
712
988
|
async settleWithLNURLWithdraw(lnurl) {
|
|
989
|
+
if (this._state !== FromBTCLNAutoSwapState.PR_CREATED &&
|
|
990
|
+
this._state !== FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
|
|
991
|
+
throw new Error("Must be in PR_CREATED state!");
|
|
713
992
|
if (this.lnurl != null)
|
|
714
993
|
throw new Error("Cannot settle LNURL-withdraw swap with different LNURL");
|
|
715
994
|
let lnurlParams;
|
|
@@ -722,6 +1001,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
722
1001
|
else {
|
|
723
1002
|
lnurlParams = lnurl.params;
|
|
724
1003
|
}
|
|
1004
|
+
if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
|
|
1005
|
+
throw new Error("Input lightning network invoice not available, the swap was probably recovered!");
|
|
725
1006
|
LNURL_1.LNURL.useLNURLWithdraw(lnurlParams, this.pr).catch(e => this.lnurlFailSignal.abort(e));
|
|
726
1007
|
this.lnurl = lnurlParams.url;
|
|
727
1008
|
this.lnurlCallback = lnurlParams.callback;
|
|
@@ -731,12 +1012,15 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
731
1012
|
}
|
|
732
1013
|
//////////////////////////////
|
|
733
1014
|
//// Storage
|
|
1015
|
+
/**
|
|
1016
|
+
* @inheritDoc
|
|
1017
|
+
*/
|
|
734
1018
|
serialize() {
|
|
735
1019
|
return {
|
|
736
1020
|
...super.serialize(),
|
|
737
|
-
data: this.
|
|
738
|
-
commitTxId: this.
|
|
739
|
-
claimTxId: this.
|
|
1021
|
+
data: this._data == null ? null : this._data.serialize(),
|
|
1022
|
+
commitTxId: this._commitTxId,
|
|
1023
|
+
claimTxId: this._claimTxId,
|
|
740
1024
|
btcAmountSwap: this.btcAmountSwap == null ? null : this.btcAmountSwap.toString(10),
|
|
741
1025
|
btcAmountGas: this.btcAmountGas == null ? null : this.btcAmountGas.toString(10),
|
|
742
1026
|
gasSwapFeeBtc: this.gasSwapFeeBtc == null ? null : this.gasSwapFeeBtc.toString(10),
|
|
@@ -748,7 +1032,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
748
1032
|
lnurlK1: this.lnurlK1,
|
|
749
1033
|
lnurlCallback: this.lnurlCallback,
|
|
750
1034
|
prPosted: this.prPosted,
|
|
751
|
-
initialSwapData: this.initialSwapData.serialize()
|
|
1035
|
+
initialSwapData: this.initialSwapData.serialize(),
|
|
1036
|
+
usesClaimHashAsId: this.usesClaimHashAsId
|
|
752
1037
|
};
|
|
753
1038
|
}
|
|
754
1039
|
//////////////////////////////
|
|
@@ -760,62 +1045,57 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
760
1045
|
* @private
|
|
761
1046
|
*/
|
|
762
1047
|
async syncStateFromChain(quoteDefinitelyExpired, commitStatus) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
commitStatus ??= await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
|
|
771
|
-
if (commitStatus?.type === base_1.SwapCommitStateType.PAID) {
|
|
772
|
-
if (this.claimTxId == null)
|
|
773
|
-
this.claimTxId = await commitStatus.getClaimTxId();
|
|
774
|
-
this.state = FromBTCLNAutoSwapState.CLAIM_CLAIMED;
|
|
775
|
-
return true;
|
|
1048
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID ||
|
|
1049
|
+
this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED ||
|
|
1050
|
+
this._state === FromBTCLNAutoSwapState.EXPIRED) {
|
|
1051
|
+
//Check for expiry before the getCommitStatus to prevent race conditions
|
|
1052
|
+
let quoteExpired = false;
|
|
1053
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
1054
|
+
quoteExpired = quoteDefinitelyExpired ?? await this._verifyQuoteDefinitelyExpired();
|
|
776
1055
|
}
|
|
777
|
-
if
|
|
778
|
-
|
|
1056
|
+
//Check if it's already successfully paid
|
|
1057
|
+
commitStatus ??= await this.wrapper._contract.getCommitStatus(this._getInitiator(), this._data);
|
|
1058
|
+
if (commitStatus != null && await this._forciblySetOnchainState(commitStatus))
|
|
779
1059
|
return true;
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
//Check if it's already committed
|
|
784
|
-
commitStatus ??= await this.wrapper.contract.getCommitStatus(this._getInitiator(), this.data);
|
|
785
|
-
switch (commitStatus?.type) {
|
|
786
|
-
case base_1.SwapCommitStateType.COMMITED:
|
|
787
|
-
this.state = FromBTCLNAutoSwapState.CLAIM_COMMITED;
|
|
788
|
-
return true;
|
|
789
|
-
case base_1.SwapCommitStateType.EXPIRED:
|
|
790
|
-
this.state = FromBTCLNAutoSwapState.EXPIRED;
|
|
791
|
-
return true;
|
|
792
|
-
case base_1.SwapCommitStateType.PAID:
|
|
793
|
-
if (this.claimTxId == null)
|
|
794
|
-
this.claimTxId = await commitStatus.getClaimTxId();
|
|
795
|
-
this.state = FromBTCLNAutoSwapState.CLAIM_CLAIMED;
|
|
1060
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
1061
|
+
if (quoteExpired) {
|
|
1062
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
796
1063
|
return true;
|
|
797
|
-
|
|
798
|
-
if (quoteExpired) {
|
|
799
|
-
this.state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
800
|
-
return true;
|
|
1064
|
+
}
|
|
801
1065
|
}
|
|
802
1066
|
}
|
|
803
1067
|
return false;
|
|
804
1068
|
}
|
|
805
|
-
|
|
806
|
-
|
|
1069
|
+
/**
|
|
1070
|
+
* @inheritDoc
|
|
1071
|
+
* @internal
|
|
1072
|
+
*/
|
|
1073
|
+
_shouldFetchOnchainState() {
|
|
1074
|
+
return this._state === FromBTCLNAutoSwapState.PR_PAID || this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this._state === FromBTCLNAutoSwapState.EXPIRED;
|
|
807
1075
|
}
|
|
1076
|
+
/**
|
|
1077
|
+
* @inheritDoc
|
|
1078
|
+
* @internal
|
|
1079
|
+
*/
|
|
808
1080
|
_shouldFetchExpiryStatus() {
|
|
809
|
-
return this.
|
|
1081
|
+
return this._state === FromBTCLNAutoSwapState.PR_PAID;
|
|
810
1082
|
}
|
|
1083
|
+
/**
|
|
1084
|
+
* @inheritDoc
|
|
1085
|
+
* @internal
|
|
1086
|
+
*/
|
|
811
1087
|
_shouldCheckIntermediary() {
|
|
812
|
-
return this.
|
|
1088
|
+
return this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
|
|
813
1089
|
}
|
|
1090
|
+
/**
|
|
1091
|
+
* @inheritDoc
|
|
1092
|
+
* @internal
|
|
1093
|
+
*/
|
|
814
1094
|
async _sync(save, quoteDefinitelyExpired, commitStatus, skipLpCheck) {
|
|
815
1095
|
let changed = false;
|
|
816
|
-
if (this.
|
|
817
|
-
if (this.
|
|
818
|
-
this.
|
|
1096
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
|
|
1097
|
+
if (this._state !== FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED && this.getQuoteExpiry() < Date.now()) {
|
|
1098
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
|
|
819
1099
|
changed ||= true;
|
|
820
1100
|
}
|
|
821
1101
|
if (!skipLpCheck)
|
|
@@ -827,39 +1107,98 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
827
1107
|
catch (e) {
|
|
828
1108
|
this.logger.error("_sync(): Failed to synchronize swap, error: ", e);
|
|
829
1109
|
}
|
|
830
|
-
if (this.
|
|
1110
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
|
|
831
1111
|
if (await this._verifyQuoteDefinitelyExpired()) {
|
|
832
|
-
this.
|
|
1112
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
833
1113
|
changed ||= true;
|
|
834
1114
|
}
|
|
835
1115
|
}
|
|
836
1116
|
}
|
|
837
1117
|
if (await this.syncStateFromChain(quoteDefinitelyExpired, commitStatus))
|
|
838
1118
|
changed = true;
|
|
1119
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
|
|
1120
|
+
const expired = await this.wrapper._contract.isExpired(this._getInitiator(), this._data);
|
|
1121
|
+
if (expired) {
|
|
1122
|
+
this._state = FromBTCLNAutoSwapState.EXPIRED;
|
|
1123
|
+
changed = true;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
839
1126
|
if (save && changed)
|
|
840
1127
|
await this._saveAndEmit();
|
|
841
|
-
if (this.
|
|
1128
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED && this.secret != null)
|
|
842
1129
|
await this._broadcastSecret().catch(e => {
|
|
843
1130
|
this.logger.error("_sync(): Error when broadcasting swap secret: ", e);
|
|
844
1131
|
});
|
|
845
1132
|
return changed;
|
|
846
1133
|
}
|
|
847
|
-
|
|
848
|
-
|
|
1134
|
+
/**
|
|
1135
|
+
* @inheritDoc
|
|
1136
|
+
* @internal
|
|
1137
|
+
*/
|
|
1138
|
+
async _forciblySetOnchainState(commitStatus) {
|
|
1139
|
+
switch (commitStatus?.type) {
|
|
1140
|
+
case base_1.SwapCommitStateType.PAID:
|
|
1141
|
+
if (this._claimTxId == null)
|
|
1142
|
+
this._claimTxId = await commitStatus.getClaimTxId();
|
|
1143
|
+
if (this.secret == null || this.pr == null)
|
|
1144
|
+
this._setSwapSecret(await commitStatus.getClaimResult());
|
|
1145
|
+
this._state = FromBTCLNAutoSwapState.CLAIM_CLAIMED;
|
|
1146
|
+
return true;
|
|
1147
|
+
case base_1.SwapCommitStateType.NOT_COMMITED:
|
|
1148
|
+
if (this._refundTxId == null && commitStatus.getRefundTxId != null)
|
|
1149
|
+
this._refundTxId = await commitStatus.getRefundTxId();
|
|
1150
|
+
if (this._refundTxId != null) {
|
|
1151
|
+
this._state = FromBTCLNAutoSwapState.FAILED;
|
|
1152
|
+
return true;
|
|
1153
|
+
}
|
|
1154
|
+
break;
|
|
1155
|
+
case base_1.SwapCommitStateType.EXPIRED:
|
|
1156
|
+
if (this._refundTxId == null && commitStatus.getRefundTxId != null)
|
|
1157
|
+
this._refundTxId = await commitStatus.getRefundTxId();
|
|
1158
|
+
this._state = this._refundTxId == null ? FromBTCLNAutoSwapState.QUOTE_EXPIRED : FromBTCLNAutoSwapState.FAILED;
|
|
1159
|
+
return true;
|
|
1160
|
+
case base_1.SwapCommitStateType.COMMITED:
|
|
1161
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED && this._state !== FromBTCLNAutoSwapState.EXPIRED) {
|
|
1162
|
+
this._state = FromBTCLNAutoSwapState.CLAIM_COMMITED;
|
|
1163
|
+
return true;
|
|
1164
|
+
}
|
|
1165
|
+
break;
|
|
1166
|
+
}
|
|
1167
|
+
return false;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Broadcasts the swap secret to the underlying data propagation layer (e.g. Nostr by default)
|
|
1171
|
+
*
|
|
1172
|
+
* @param noCheckExpiry Whether a swap expiration check should be skipped broadcasting
|
|
1173
|
+
* @param secret An optional secret pre-image for the swap to broadcast
|
|
1174
|
+
*
|
|
1175
|
+
* @internal
|
|
1176
|
+
*/
|
|
1177
|
+
async _broadcastSecret(noCheckExpiry, secret) {
|
|
1178
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
|
|
849
1179
|
throw new Error("Must be in CLAIM_COMMITED state to broadcast swap secret!");
|
|
850
|
-
if (this.
|
|
1180
|
+
if (this._data == null)
|
|
851
1181
|
throw new Error("Unknown data, wrong state?");
|
|
1182
|
+
const useSecret = secret ?? this.secret;
|
|
1183
|
+
if (useSecret == null)
|
|
1184
|
+
throw new Error("Swap secret pre-image not known and not provided, please provide the swap secret pre-image as an argument");
|
|
1185
|
+
if (!this.isValidSecretPreimage(useSecret))
|
|
1186
|
+
throw new Error("Invalid swap secret pre-image provided!");
|
|
852
1187
|
if (!noCheckExpiry) {
|
|
853
|
-
if (await this.wrapper.
|
|
1188
|
+
if (await this.wrapper._contract.isExpired(this._getInitiator(), this._data))
|
|
854
1189
|
throw new Error("On-chain HTLC already expired!");
|
|
855
1190
|
}
|
|
856
|
-
await this.wrapper.
|
|
1191
|
+
await this.wrapper._messenger.broadcast(new base_1.SwapClaimWitnessMessage(this._data, useSecret));
|
|
857
1192
|
}
|
|
1193
|
+
/**
|
|
1194
|
+
* @inheritDoc
|
|
1195
|
+
* @internal
|
|
1196
|
+
*/
|
|
858
1197
|
async _tick(save) {
|
|
859
|
-
switch (this.
|
|
1198
|
+
switch (this._state) {
|
|
860
1199
|
case FromBTCLNAutoSwapState.PR_CREATED:
|
|
861
1200
|
if (this.getQuoteExpiry() < Date.now()) {
|
|
862
|
-
this.
|
|
1201
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
|
|
863
1202
|
if (save)
|
|
864
1203
|
await this._saveAndEmit();
|
|
865
1204
|
return true;
|
|
@@ -867,7 +1206,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
867
1206
|
break;
|
|
868
1207
|
case FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED:
|
|
869
1208
|
if (this.getDefinitiveExpiryTime() < Date.now()) {
|
|
870
|
-
this.
|
|
1209
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
871
1210
|
if (save)
|
|
872
1211
|
await this._saveAndEmit();
|
|
873
1212
|
return true;
|
|
@@ -875,16 +1214,16 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
875
1214
|
break;
|
|
876
1215
|
case FromBTCLNAutoSwapState.PR_PAID:
|
|
877
1216
|
case FromBTCLNAutoSwapState.CLAIM_COMMITED:
|
|
878
|
-
const expired = await this.wrapper.
|
|
1217
|
+
const expired = await this.wrapper._contract.isExpired(this._getInitiator(), this._data);
|
|
879
1218
|
if (expired) {
|
|
880
|
-
this.
|
|
1219
|
+
this._state = FromBTCLNAutoSwapState.EXPIRED;
|
|
881
1220
|
if (save)
|
|
882
1221
|
await this._saveAndEmit();
|
|
883
1222
|
return true;
|
|
884
1223
|
}
|
|
885
|
-
if (this.
|
|
1224
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
|
|
886
1225
|
//Broadcast the secret over the provided messenger channel
|
|
887
|
-
if (this.broadcastTickCounter === 0)
|
|
1226
|
+
if (this.broadcastTickCounter === 0 && this.secret != null)
|
|
888
1227
|
await this._broadcastSecret(true).catch(e => {
|
|
889
1228
|
this.logger.warn("_tick(): Error when broadcasting swap secret: ", e);
|
|
890
1229
|
});
|
|
@@ -894,5 +1233,16 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
894
1233
|
}
|
|
895
1234
|
return false;
|
|
896
1235
|
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Forcibly sets the swap secret pre-image from on-chain data
|
|
1238
|
+
*
|
|
1239
|
+
* @internal
|
|
1240
|
+
*/
|
|
1241
|
+
_setSwapSecret(secret) {
|
|
1242
|
+
this.secret = secret;
|
|
1243
|
+
if (this.pr == null) {
|
|
1244
|
+
this.pr = buffer_1.Buffer.from((0, sha2_1.sha256)(buffer_1.Buffer.from(secret, "hex"))).toString("hex");
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
897
1247
|
}
|
|
898
1248
|
exports.FromBTCLNAutoSwap = FromBTCLNAutoSwap;
|