@atomiqlabs/sdk 8.1.7 → 8.3.1
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/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 +7 -0
- package/dist/enums/FeeType.js +7 -0
- 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 +4 -5
- package/dist/index.js +3 -4
- package/dist/intermediaries/Intermediary.d.ts +57 -10
- package/dist/intermediaries/Intermediary.js +37 -10
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +55 -22
- package/dist/intermediaries/IntermediaryDiscovery.js +35 -22
- package/dist/prices/RedundantSwapPrice.d.ts +24 -3
- package/dist/prices/RedundantSwapPrice.js +21 -1
- package/dist/prices/SingleSwapPrice.d.ts +9 -6
- package/dist/prices/SingleSwapPrice.js +10 -7
- package/dist/prices/SwapPriceWithChain.d.ts +54 -16
- package/dist/prices/SwapPriceWithChain.js +58 -20
- package/dist/prices/abstract/ISwapPrice.d.ts +94 -45
- package/dist/prices/abstract/ISwapPrice.js +103 -55
- package/dist/prices/providers/BinancePriceProvider.d.ts +7 -0
- package/dist/prices/providers/BinancePriceProvider.js +7 -0
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +6 -0
- package/dist/prices/providers/CoinGeckoPriceProvider.js +6 -0
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +6 -0
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +6 -0
- package/dist/prices/providers/CustomPriceProvider.d.ts +11 -0
- package/dist/prices/providers/CustomPriceProvider.js +11 -0
- package/dist/prices/providers/KrakenPriceProvider.d.ts +9 -0
- package/dist/prices/providers/KrakenPriceProvider.js +9 -0
- package/dist/prices/providers/OKXPriceProvider.d.ts +6 -0
- package/dist/prices/providers/OKXPriceProvider.js +6 -0
- 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 +303 -222
- package/dist/swapper/Swapper.js +376 -344
- package/dist/swapper/SwapperFactory.d.ts +41 -17
- package/dist/swapper/SwapperFactory.js +23 -2
- 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 +10 -1
- package/dist/swaps/IAddressSwap.js +2 -1
- package/dist/swaps/IBTCWalletSwap.d.ts +24 -6
- package/dist/swaps/IBTCWalletSwap.js +2 -1
- package/dist/swaps/IClaimableSwap.d.ts +36 -4
- package/dist/swaps/IClaimableSwap.js +2 -1
- package/dist/swaps/IClaimableSwapWrapper.d.ts +11 -1
- package/dist/swaps/IRefundableSwap.d.ts +29 -3
- package/dist/swaps/IRefundableSwap.js +2 -1
- package/dist/swaps/ISwap.d.ts +159 -21
- package/dist/swaps/ISwap.js +90 -33
- package/dist/swaps/ISwapWithGasDrop.d.ts +6 -0
- package/dist/swaps/ISwapWithGasDrop.js +1 -0
- package/dist/swaps/ISwapWrapper.d.ts +157 -48
- package/dist/swaps/ISwapWrapper.js +130 -72
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +49 -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 +94 -29
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +90 -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 +275 -58
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +516 -239
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +76 -25
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +131 -49
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +311 -51
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +542 -193
- 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 +209 -53
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +449 -242
- 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 +197 -56
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +326 -189
- 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 +60 -19
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +74 -31
- 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 +36 -13
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +65 -19
- 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 +328 -92
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +460 -219
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +76 -24
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +244 -124
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +146 -18
- package/dist/swaps/trusted/ln/LnForGasSwap.js +173 -43
- 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 +200 -47
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +230 -78
- 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 +7 -1
- package/dist/types/SwapExecutionAction.d.ts +74 -4
- package/dist/types/SwapWithSigner.d.ts +4 -1
- 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 +2 -1
- package/dist/types/fees/FeeBreakdown.d.ts +2 -1
- package/dist/types/fees/PercentagePPM.d.ts +2 -0
- package/dist/types/fees/PercentagePPM.js +1 -0
- package/dist/types/lnurl/LNURLPay.d.ts +14 -6
- package/dist/types/lnurl/LNURLPay.js +6 -2
- package/dist/types/lnurl/LNURLWithdraw.d.ts +12 -5
- package/dist/types/lnurl/LNURLWithdraw.js +6 -2
- package/dist/types/wallets/LightningInvoiceCreateService.d.ts +20 -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 +3 -1
- package/dist/utils/BitcoinUtils.d.ts +1 -0
- package/dist/utils/BitcoinUtils.js +5 -1
- package/dist/utils/SwapUtils.d.ts +56 -1
- package/dist/utils/SwapUtils.js +53 -1
- package/dist/utils/TokenUtils.d.ts +10 -2
- package/dist/utils/TokenUtils.js +12 -4
- package/package.json +3 -3
- 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 +7 -0
- 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 +6 -5
- package/src/intermediaries/Intermediary.ts +57 -10
- package/src/intermediaries/IntermediaryDiscovery.ts +60 -27
- package/src/prices/RedundantSwapPrice.ts +24 -4
- package/src/prices/SingleSwapPrice.ts +10 -7
- package/src/prices/SwapPriceWithChain.ts +59 -21
- package/src/prices/abstract/ISwapPrice.ts +114 -65
- package/src/prices/providers/BinancePriceProvider.ts +7 -0
- package/src/prices/providers/CoinGeckoPriceProvider.ts +6 -0
- package/src/prices/providers/CoinPaprikaPriceProvider.ts +6 -0
- package/src/prices/providers/CustomPriceProvider.ts +11 -0
- package/src/prices/providers/KrakenPriceProvider.ts +9 -0
- package/src/prices/providers/OKXPriceProvider.ts +6 -0
- 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 +513 -379
- package/src/swapper/SwapperFactory.ts +44 -21
- 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 +11 -1
- package/src/swaps/IBTCWalletSwap.ts +24 -8
- package/src/swaps/IClaimableSwap.ts +39 -4
- package/src/swaps/IClaimableSwapWrapper.ts +11 -2
- package/src/swaps/IRefundableSwap.ts +32 -3
- package/src/swaps/ISwap.ts +221 -82
- package/src/swaps/ISwapWithGasDrop.ts +6 -0
- package/src/swaps/ISwapWrapper.ts +212 -94
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +62 -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 +120 -51
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +24 -11
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +559 -256
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +155 -61
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +590 -226
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +177 -74
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +470 -243
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +141 -59
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +352 -193
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +48 -23
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +86 -39
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +110 -110
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +88 -33
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +101 -31
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +534 -263
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +289 -148
- package/src/swaps/trusted/ln/LnForGasSwap.ts +184 -45
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +34 -15
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +260 -86
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +41 -19
- package/src/types/AmountData.ts +2 -1
- package/src/types/CustomPriceFunction.ts +7 -1
- package/src/types/SwapExecutionAction.ts +84 -5
- package/src/types/SwapWithSigner.ts +7 -3
- package/src/types/Token.ts +12 -5
- package/src/types/TokenAmount.ts +3 -0
- package/src/types/fees/Fee.ts +2 -1
- package/src/types/fees/FeeBreakdown.ts +2 -1
- package/src/types/fees/PercentagePPM.ts +2 -0
- package/src/types/lnurl/LNURLPay.ts +14 -6
- package/src/types/lnurl/LNURLWithdraw.ts +12 -5
- package/src/types/wallets/LightningInvoiceCreateService.ts +26 -0
- package/src/types/wallets/MinimalBitcoinWalletInterface.ts +3 -1
- package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +3 -1
- package/src/utils/BitcoinUtils.ts +5 -0
- package/src/utils/SwapUtils.ts +61 -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,6 +19,7 @@ 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
25
|
* @category Swaps
|
|
@@ -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
|
|
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,96 @@ 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
|
-
*
|
|
894
|
+
* @inheritDoc
|
|
633
895
|
*
|
|
634
896
|
* @param maxWaitTimeSeconds Maximum time in seconds to wait for the swap to be settled
|
|
635
897
|
* @param abortSignal AbortSignal
|
|
636
|
-
* @
|
|
898
|
+
* @param secret A swap secret to broadcast to watchtowers, generally only needed if the swap
|
|
899
|
+
* was recovered from on-chain data, or the pre-image was generated outside the SDK
|
|
900
|
+
*
|
|
901
|
+
* @throws {Error} If swap is in invalid state (must be {@link FromBTCLNAutoSwapState.CLAIM_COMMITED})
|
|
637
902
|
* @throws {Error} If the LP refunded sooner than we were able to claim
|
|
638
903
|
* @returns {boolean} whether the swap was claimed in time or not
|
|
639
904
|
*/
|
|
640
|
-
async waitTillClaimed(maxWaitTimeSeconds, abortSignal) {
|
|
641
|
-
if (this.
|
|
905
|
+
async waitTillClaimed(maxWaitTimeSeconds, abortSignal, secret) {
|
|
906
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_CLAIMED)
|
|
642
907
|
return Promise.resolve(true);
|
|
643
|
-
if (this.
|
|
908
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
|
|
644
909
|
throw new Error("Invalid state (not CLAIM_COMMITED)");
|
|
910
|
+
if (secret != null) {
|
|
911
|
+
if (!this.isValidSecretPreimage(secret))
|
|
912
|
+
throw new Error("Invalid swap secret pre-image provided!");
|
|
913
|
+
this.secret = secret;
|
|
914
|
+
}
|
|
645
915
|
const abortController = new AbortController();
|
|
646
916
|
if (abortSignal != null)
|
|
647
917
|
abortSignal.addEventListener("abort", () => abortController.abort(abortSignal.reason));
|
|
@@ -678,14 +948,14 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
678
948
|
}
|
|
679
949
|
this.logger.debug("waitTillClaimed(): Resolved from watchdog");
|
|
680
950
|
if (res?.type === base_1.SwapCommitStateType.PAID) {
|
|
681
|
-
if (this.
|
|
682
|
-
this.
|
|
951
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED) {
|
|
952
|
+
this._claimTxId = await res.getClaimTxId();
|
|
683
953
|
await this._saveAndEmit(FromBTCLNAutoSwapState.CLAIM_CLAIMED);
|
|
684
954
|
}
|
|
685
955
|
}
|
|
686
956
|
if (res?.type === base_1.SwapCommitStateType.NOT_COMMITED || res?.type === base_1.SwapCommitStateType.EXPIRED) {
|
|
687
|
-
if (this.
|
|
688
|
-
this.
|
|
957
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_CLAIMED &&
|
|
958
|
+
this._state !== FromBTCLNAutoSwapState.FAILED) {
|
|
689
959
|
await this._saveAndEmit(FromBTCLNAutoSwapState.FAILED);
|
|
690
960
|
}
|
|
691
961
|
throw new Error("Swap expired during claiming");
|
|
@@ -695,21 +965,29 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
695
965
|
//////////////////////////////
|
|
696
966
|
//// LNURL
|
|
697
967
|
/**
|
|
698
|
-
*
|
|
968
|
+
* Whether this swap uses an LNURL-withdraw link
|
|
699
969
|
*/
|
|
700
970
|
isLNURL() {
|
|
701
971
|
return this.lnurl != null;
|
|
702
972
|
}
|
|
703
973
|
/**
|
|
704
|
-
* Gets the used LNURL or null if this is not an LNURL-withdraw swap
|
|
974
|
+
* Gets the used LNURL or `null` if this is not an LNURL-withdraw swap
|
|
705
975
|
*/
|
|
706
976
|
getLNURL() {
|
|
707
977
|
return this.lnurl ?? null;
|
|
708
978
|
}
|
|
709
979
|
/**
|
|
710
|
-
* Pay the generated lightning network invoice with LNURL-withdraw
|
|
980
|
+
* Pay the generated lightning network invoice with an LNURL-withdraw link, this
|
|
981
|
+
* is useful when you want to display a lightning payment QR code and also want to
|
|
982
|
+
* allow payments using LNURL-withdraw NFC cards.
|
|
983
|
+
*
|
|
984
|
+
* Note that the swap needs to be created **without** an LNURL to begin with for this function
|
|
985
|
+
* to work. If this swap is already using an LNURL-withdraw link, this function throws.
|
|
711
986
|
*/
|
|
712
987
|
async settleWithLNURLWithdraw(lnurl) {
|
|
988
|
+
if (this._state !== FromBTCLNAutoSwapState.PR_CREATED &&
|
|
989
|
+
this._state !== FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED)
|
|
990
|
+
throw new Error("Must be in PR_CREATED state!");
|
|
713
991
|
if (this.lnurl != null)
|
|
714
992
|
throw new Error("Cannot settle LNURL-withdraw swap with different LNURL");
|
|
715
993
|
let lnurlParams;
|
|
@@ -722,6 +1000,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
722
1000
|
else {
|
|
723
1001
|
lnurlParams = lnurl.params;
|
|
724
1002
|
}
|
|
1003
|
+
if (this.pr == null || !this.pr.toLowerCase().startsWith("ln"))
|
|
1004
|
+
throw new Error("Input lightning network invoice not available, the swap was probably recovered!");
|
|
725
1005
|
LNURL_1.LNURL.useLNURLWithdraw(lnurlParams, this.pr).catch(e => this.lnurlFailSignal.abort(e));
|
|
726
1006
|
this.lnurl = lnurlParams.url;
|
|
727
1007
|
this.lnurlCallback = lnurlParams.callback;
|
|
@@ -731,12 +1011,15 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
731
1011
|
}
|
|
732
1012
|
//////////////////////////////
|
|
733
1013
|
//// Storage
|
|
1014
|
+
/**
|
|
1015
|
+
* @inheritDoc
|
|
1016
|
+
*/
|
|
734
1017
|
serialize() {
|
|
735
1018
|
return {
|
|
736
1019
|
...super.serialize(),
|
|
737
|
-
data: this.
|
|
738
|
-
commitTxId: this.
|
|
739
|
-
claimTxId: this.
|
|
1020
|
+
data: this._data == null ? null : this._data.serialize(),
|
|
1021
|
+
commitTxId: this._commitTxId,
|
|
1022
|
+
claimTxId: this._claimTxId,
|
|
740
1023
|
btcAmountSwap: this.btcAmountSwap == null ? null : this.btcAmountSwap.toString(10),
|
|
741
1024
|
btcAmountGas: this.btcAmountGas == null ? null : this.btcAmountGas.toString(10),
|
|
742
1025
|
gasSwapFeeBtc: this.gasSwapFeeBtc == null ? null : this.gasSwapFeeBtc.toString(10),
|
|
@@ -748,7 +1031,8 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
748
1031
|
lnurlK1: this.lnurlK1,
|
|
749
1032
|
lnurlCallback: this.lnurlCallback,
|
|
750
1033
|
prPosted: this.prPosted,
|
|
751
|
-
initialSwapData: this.initialSwapData.serialize()
|
|
1034
|
+
initialSwapData: this.initialSwapData.serialize(),
|
|
1035
|
+
usesClaimHashAsId: this.usesClaimHashAsId
|
|
752
1036
|
};
|
|
753
1037
|
}
|
|
754
1038
|
//////////////////////////////
|
|
@@ -760,62 +1044,57 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
760
1044
|
* @private
|
|
761
1045
|
*/
|
|
762
1046
|
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;
|
|
1047
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID ||
|
|
1048
|
+
this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED ||
|
|
1049
|
+
this._state === FromBTCLNAutoSwapState.EXPIRED) {
|
|
1050
|
+
//Check for expiry before the getCommitStatus to prevent race conditions
|
|
1051
|
+
let quoteExpired = false;
|
|
1052
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
1053
|
+
quoteExpired = quoteDefinitelyExpired ?? await this._verifyQuoteDefinitelyExpired();
|
|
776
1054
|
}
|
|
777
|
-
if
|
|
778
|
-
|
|
1055
|
+
//Check if it's already successfully paid
|
|
1056
|
+
commitStatus ??= await this.wrapper._contract.getCommitStatus(this._getInitiator(), this._data);
|
|
1057
|
+
if (commitStatus != null && await this._forciblySetOnchainState(commitStatus))
|
|
779
1058
|
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;
|
|
1059
|
+
if (this._state === FromBTCLNAutoSwapState.PR_PAID) {
|
|
1060
|
+
if (quoteExpired) {
|
|
1061
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
796
1062
|
return true;
|
|
797
|
-
|
|
798
|
-
if (quoteExpired) {
|
|
799
|
-
this.state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
800
|
-
return true;
|
|
1063
|
+
}
|
|
801
1064
|
}
|
|
802
1065
|
}
|
|
803
1066
|
return false;
|
|
804
1067
|
}
|
|
805
|
-
|
|
806
|
-
|
|
1068
|
+
/**
|
|
1069
|
+
* @inheritDoc
|
|
1070
|
+
* @internal
|
|
1071
|
+
*/
|
|
1072
|
+
_shouldFetchOnchainState() {
|
|
1073
|
+
return this._state === FromBTCLNAutoSwapState.PR_PAID || this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED || this._state === FromBTCLNAutoSwapState.EXPIRED;
|
|
807
1074
|
}
|
|
1075
|
+
/**
|
|
1076
|
+
* @inheritDoc
|
|
1077
|
+
* @internal
|
|
1078
|
+
*/
|
|
808
1079
|
_shouldFetchExpiryStatus() {
|
|
809
|
-
return this.
|
|
1080
|
+
return this._state === FromBTCLNAutoSwapState.PR_PAID;
|
|
810
1081
|
}
|
|
1082
|
+
/**
|
|
1083
|
+
* @inheritDoc
|
|
1084
|
+
* @internal
|
|
1085
|
+
*/
|
|
811
1086
|
_shouldCheckIntermediary() {
|
|
812
|
-
return this.
|
|
1087
|
+
return this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
|
|
813
1088
|
}
|
|
1089
|
+
/**
|
|
1090
|
+
* @inheritDoc
|
|
1091
|
+
* @internal
|
|
1092
|
+
*/
|
|
814
1093
|
async _sync(save, quoteDefinitelyExpired, commitStatus, skipLpCheck) {
|
|
815
1094
|
let changed = false;
|
|
816
|
-
if (this.
|
|
817
|
-
if (this.
|
|
818
|
-
this.
|
|
1095
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
|
|
1096
|
+
if (this._state !== FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED && this.getQuoteExpiry() < Date.now()) {
|
|
1097
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
|
|
819
1098
|
changed ||= true;
|
|
820
1099
|
}
|
|
821
1100
|
if (!skipLpCheck)
|
|
@@ -827,39 +1106,98 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
827
1106
|
catch (e) {
|
|
828
1107
|
this.logger.error("_sync(): Failed to synchronize swap, error: ", e);
|
|
829
1108
|
}
|
|
830
|
-
if (this.
|
|
1109
|
+
if (this._state === FromBTCLNAutoSwapState.PR_CREATED || this._state === FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED) {
|
|
831
1110
|
if (await this._verifyQuoteDefinitelyExpired()) {
|
|
832
|
-
this.
|
|
1111
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
833
1112
|
changed ||= true;
|
|
834
1113
|
}
|
|
835
1114
|
}
|
|
836
1115
|
}
|
|
837
1116
|
if (await this.syncStateFromChain(quoteDefinitelyExpired, commitStatus))
|
|
838
1117
|
changed = true;
|
|
1118
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
|
|
1119
|
+
const expired = await this.wrapper._contract.isExpired(this._getInitiator(), this._data);
|
|
1120
|
+
if (expired) {
|
|
1121
|
+
this._state = FromBTCLNAutoSwapState.EXPIRED;
|
|
1122
|
+
changed = true;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
839
1125
|
if (save && changed)
|
|
840
1126
|
await this._saveAndEmit();
|
|
841
|
-
if (this.
|
|
1127
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED && this.secret != null)
|
|
842
1128
|
await this._broadcastSecret().catch(e => {
|
|
843
1129
|
this.logger.error("_sync(): Error when broadcasting swap secret: ", e);
|
|
844
1130
|
});
|
|
845
1131
|
return changed;
|
|
846
1132
|
}
|
|
847
|
-
|
|
848
|
-
|
|
1133
|
+
/**
|
|
1134
|
+
* @inheritDoc
|
|
1135
|
+
* @internal
|
|
1136
|
+
*/
|
|
1137
|
+
async _forciblySetOnchainState(commitStatus) {
|
|
1138
|
+
switch (commitStatus?.type) {
|
|
1139
|
+
case base_1.SwapCommitStateType.PAID:
|
|
1140
|
+
if (this._claimTxId == null)
|
|
1141
|
+
this._claimTxId = await commitStatus.getClaimTxId();
|
|
1142
|
+
if (this.secret == null || this.pr == null)
|
|
1143
|
+
this._setSwapSecret(await commitStatus.getClaimResult());
|
|
1144
|
+
this._state = FromBTCLNAutoSwapState.CLAIM_CLAIMED;
|
|
1145
|
+
return true;
|
|
1146
|
+
case base_1.SwapCommitStateType.NOT_COMMITED:
|
|
1147
|
+
if (this._refundTxId == null && commitStatus.getRefundTxId != null)
|
|
1148
|
+
this._refundTxId = await commitStatus.getRefundTxId();
|
|
1149
|
+
if (this._refundTxId != null) {
|
|
1150
|
+
this._state = FromBTCLNAutoSwapState.FAILED;
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1153
|
+
break;
|
|
1154
|
+
case base_1.SwapCommitStateType.EXPIRED:
|
|
1155
|
+
if (this._refundTxId == null && commitStatus.getRefundTxId != null)
|
|
1156
|
+
this._refundTxId = await commitStatus.getRefundTxId();
|
|
1157
|
+
this._state = this._refundTxId == null ? FromBTCLNAutoSwapState.QUOTE_EXPIRED : FromBTCLNAutoSwapState.FAILED;
|
|
1158
|
+
return true;
|
|
1159
|
+
case base_1.SwapCommitStateType.COMMITED:
|
|
1160
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED && this._state !== FromBTCLNAutoSwapState.EXPIRED) {
|
|
1161
|
+
this._state = FromBTCLNAutoSwapState.CLAIM_COMMITED;
|
|
1162
|
+
return true;
|
|
1163
|
+
}
|
|
1164
|
+
break;
|
|
1165
|
+
}
|
|
1166
|
+
return false;
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Broadcasts the swap secret to the underlying data propagation layer (e.g. Nostr by default)
|
|
1170
|
+
*
|
|
1171
|
+
* @param noCheckExpiry Whether a swap expiration check should be skipped broadcasting
|
|
1172
|
+
* @param secret An optional secret pre-image for the swap to broadcast
|
|
1173
|
+
*
|
|
1174
|
+
* @internal
|
|
1175
|
+
*/
|
|
1176
|
+
async _broadcastSecret(noCheckExpiry, secret) {
|
|
1177
|
+
if (this._state !== FromBTCLNAutoSwapState.CLAIM_COMMITED)
|
|
849
1178
|
throw new Error("Must be in CLAIM_COMMITED state to broadcast swap secret!");
|
|
850
|
-
if (this.
|
|
1179
|
+
if (this._data == null)
|
|
851
1180
|
throw new Error("Unknown data, wrong state?");
|
|
1181
|
+
const useSecret = secret ?? this.secret;
|
|
1182
|
+
if (useSecret == null)
|
|
1183
|
+
throw new Error("Swap secret pre-image not known and not provided, please provide the swap secret pre-image as an argument");
|
|
1184
|
+
if (!this.isValidSecretPreimage(useSecret))
|
|
1185
|
+
throw new Error("Invalid swap secret pre-image provided!");
|
|
852
1186
|
if (!noCheckExpiry) {
|
|
853
|
-
if (await this.wrapper.
|
|
1187
|
+
if (await this.wrapper._contract.isExpired(this._getInitiator(), this._data))
|
|
854
1188
|
throw new Error("On-chain HTLC already expired!");
|
|
855
1189
|
}
|
|
856
|
-
await this.wrapper.
|
|
1190
|
+
await this.wrapper._messenger.broadcast(new base_1.SwapClaimWitnessMessage(this._data, useSecret));
|
|
857
1191
|
}
|
|
1192
|
+
/**
|
|
1193
|
+
* @inheritDoc
|
|
1194
|
+
* @internal
|
|
1195
|
+
*/
|
|
858
1196
|
async _tick(save) {
|
|
859
|
-
switch (this.
|
|
1197
|
+
switch (this._state) {
|
|
860
1198
|
case FromBTCLNAutoSwapState.PR_CREATED:
|
|
861
1199
|
if (this.getQuoteExpiry() < Date.now()) {
|
|
862
|
-
this.
|
|
1200
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED;
|
|
863
1201
|
if (save)
|
|
864
1202
|
await this._saveAndEmit();
|
|
865
1203
|
return true;
|
|
@@ -867,7 +1205,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
867
1205
|
break;
|
|
868
1206
|
case FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED:
|
|
869
1207
|
if (this.getDefinitiveExpiryTime() < Date.now()) {
|
|
870
|
-
this.
|
|
1208
|
+
this._state = FromBTCLNAutoSwapState.QUOTE_EXPIRED;
|
|
871
1209
|
if (save)
|
|
872
1210
|
await this._saveAndEmit();
|
|
873
1211
|
return true;
|
|
@@ -875,16 +1213,16 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
875
1213
|
break;
|
|
876
1214
|
case FromBTCLNAutoSwapState.PR_PAID:
|
|
877
1215
|
case FromBTCLNAutoSwapState.CLAIM_COMMITED:
|
|
878
|
-
const expired = await this.wrapper.
|
|
1216
|
+
const expired = await this.wrapper._contract.isExpired(this._getInitiator(), this._data);
|
|
879
1217
|
if (expired) {
|
|
880
|
-
this.
|
|
1218
|
+
this._state = FromBTCLNAutoSwapState.EXPIRED;
|
|
881
1219
|
if (save)
|
|
882
1220
|
await this._saveAndEmit();
|
|
883
1221
|
return true;
|
|
884
1222
|
}
|
|
885
|
-
if (this.
|
|
1223
|
+
if (this._state === FromBTCLNAutoSwapState.CLAIM_COMMITED) {
|
|
886
1224
|
//Broadcast the secret over the provided messenger channel
|
|
887
|
-
if (this.broadcastTickCounter === 0)
|
|
1225
|
+
if (this.broadcastTickCounter === 0 && this.secret != null)
|
|
888
1226
|
await this._broadcastSecret(true).catch(e => {
|
|
889
1227
|
this.logger.warn("_tick(): Error when broadcasting swap secret: ", e);
|
|
890
1228
|
});
|
|
@@ -894,5 +1232,16 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
894
1232
|
}
|
|
895
1233
|
return false;
|
|
896
1234
|
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Forcibly sets the swap secret pre-image from on-chain data
|
|
1237
|
+
*
|
|
1238
|
+
* @internal
|
|
1239
|
+
*/
|
|
1240
|
+
_setSwapSecret(secret) {
|
|
1241
|
+
this.secret = secret;
|
|
1242
|
+
if (this.pr == null) {
|
|
1243
|
+
this.pr = buffer_1.Buffer.from((0, sha2_1.sha256)(buffer_1.Buffer.from(secret, "hex"))).toString("hex");
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
897
1246
|
}
|
|
898
1247
|
exports.FromBTCLNAutoSwap = FromBTCLNAutoSwap;
|