@atomiqlabs/sdk 8.6.6 → 8.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SmartChainAssets.d.ts +181 -181
- package/dist/SmartChainAssets.js +181 -181
- package/dist/bitcoin/coinselect2/accumulative.d.ts +6 -6
- package/dist/bitcoin/coinselect2/accumulative.js +52 -51
- package/dist/bitcoin/coinselect2/blackjack.d.ts +6 -6
- package/dist/bitcoin/coinselect2/blackjack.js +38 -37
- package/dist/bitcoin/coinselect2/index.d.ts +19 -17
- package/dist/bitcoin/coinselect2/index.js +69 -69
- package/dist/bitcoin/coinselect2/utils.d.ts +77 -75
- package/dist/bitcoin/coinselect2/utils.js +123 -123
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +130 -128
- package/dist/bitcoin/wallet/BitcoinWallet.js +322 -322
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +78 -78
- package/dist/bitcoin/wallet/IBitcoinWallet.js +21 -20
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +101 -99
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +176 -176
- package/dist/enums/FeeType.d.ts +15 -15
- package/dist/enums/FeeType.js +19 -19
- package/dist/enums/SwapAmountType.d.ts +15 -15
- package/dist/enums/SwapAmountType.js +19 -19
- package/dist/enums/SwapDirection.d.ts +15 -15
- package/dist/enums/SwapDirection.js +19 -19
- package/dist/enums/SwapSide.d.ts +15 -15
- package/dist/enums/SwapSide.js +19 -19
- package/dist/enums/SwapType.d.ts +75 -75
- package/dist/enums/SwapType.js +79 -79
- package/dist/errors/IntermediaryError.d.ts +13 -13
- package/dist/errors/IntermediaryError.js +27 -27
- package/dist/errors/RequestError.d.ts +32 -32
- package/dist/errors/RequestError.js +54 -54
- package/dist/errors/UserError.d.ts +8 -8
- package/dist/errors/UserError.js +16 -16
- package/dist/events/UnifiedSwapEventListener.d.ts +23 -23
- package/dist/events/UnifiedSwapEventListener.js +130 -130
- package/dist/http/HttpUtils.d.ts +27 -27
- package/dist/http/HttpUtils.js +91 -90
- package/dist/http/paramcoders/IParamReader.d.ts +8 -8
- package/dist/http/paramcoders/IParamReader.js +2 -2
- package/dist/http/paramcoders/ParamDecoder.d.ts +44 -42
- package/dist/http/paramcoders/ParamDecoder.js +137 -137
- package/dist/http/paramcoders/ParamEncoder.d.ts +20 -18
- package/dist/http/paramcoders/ParamEncoder.js +36 -36
- package/dist/http/paramcoders/SchemaVerifier.d.ts +26 -26
- package/dist/http/paramcoders/SchemaVerifier.js +145 -145
- package/dist/http/paramcoders/client/ResponseParamDecoder.d.ts +11 -11
- package/dist/http/paramcoders/client/ResponseParamDecoder.js +57 -57
- package/dist/http/paramcoders/client/StreamParamEncoder.d.ts +13 -11
- package/dist/http/paramcoders/client/StreamParamEncoder.js +26 -26
- package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +16 -16
- package/dist/http/paramcoders/client/StreamingFetchPromise.js +174 -173
- package/dist/index.d.ts +85 -85
- package/dist/index.js +158 -158
- package/dist/intermediaries/Intermediary.d.ts +157 -157
- package/dist/intermediaries/Intermediary.js +142 -142
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +199 -198
- package/dist/intermediaries/IntermediaryDiscovery.js +406 -406
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +439 -437
- package/dist/intermediaries/apis/IntermediaryAPI.js +603 -603
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.d.ts +155 -155
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.js +137 -137
- package/dist/lnurl/LNURL.d.ts +102 -102
- package/dist/lnurl/LNURL.js +321 -321
- package/dist/prices/RedundantSwapPrice.d.ts +110 -110
- package/dist/prices/RedundantSwapPrice.js +222 -222
- package/dist/prices/SingleSwapPrice.d.ts +34 -34
- package/dist/prices/SingleSwapPrice.js +44 -44
- package/dist/prices/SwapPriceWithChain.d.ts +107 -107
- package/dist/prices/SwapPriceWithChain.js +128 -128
- package/dist/prices/abstract/ICachedSwapPrice.d.ts +28 -28
- package/dist/prices/abstract/ICachedSwapPrice.js +62 -62
- package/dist/prices/abstract/IPriceProvider.d.ts +81 -81
- package/dist/prices/abstract/IPriceProvider.js +74 -74
- package/dist/prices/abstract/ISwapPrice.d.ts +168 -168
- package/dist/prices/abstract/ISwapPrice.js +279 -279
- package/dist/prices/providers/BinancePriceProvider.d.ts +23 -23
- package/dist/prices/providers/BinancePriceProvider.js +30 -30
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +23 -23
- package/dist/prices/providers/CoinGeckoPriceProvider.js +29 -29
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +25 -25
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +29 -29
- package/dist/prices/providers/CustomPriceProvider.d.ts +24 -24
- package/dist/prices/providers/CustomPriceProvider.js +35 -35
- package/dist/prices/providers/KrakenPriceProvider.d.ts +38 -38
- package/dist/prices/providers/KrakenPriceProvider.js +45 -45
- package/dist/prices/providers/OKXPriceProvider.d.ts +34 -34
- package/dist/prices/providers/OKXPriceProvider.js +29 -29
- package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +17 -17
- package/dist/prices/providers/abstract/ExchangePriceProvider.js +21 -21
- package/dist/prices/providers/abstract/HttpPriceProvider.d.ts +7 -7
- package/dist/prices/providers/abstract/HttpPriceProvider.js +12 -12
- package/dist/storage/IUnifiedStorage.d.ts +85 -85
- package/dist/storage/IUnifiedStorage.js +2 -2
- package/dist/storage/UnifiedSwapStorage.d.ts +114 -114
- package/dist/storage/UnifiedSwapStorage.js +116 -116
- package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +63 -63
- package/dist/storage-browser/IndexedDBUnifiedStorage.js +298 -298
- package/dist/storage-browser/LocalStorageManager.d.ts +49 -49
- package/dist/storage-browser/LocalStorageManager.js +93 -93
- package/dist/swapper/Swapper.d.ts +687 -686
- package/dist/swapper/Swapper.js +1603 -1603
- package/dist/swapper/SwapperFactory.d.ts +135 -135
- package/dist/swapper/SwapperFactory.js +162 -162
- package/dist/swapper/SwapperUtils.d.ts +200 -200
- package/dist/swapper/SwapperUtils.js +467 -467
- package/dist/swapper/SwapperWithChain.d.ts +404 -404
- package/dist/swapper/SwapperWithChain.js +469 -469
- package/dist/swapper/SwapperWithSigner.d.ts +322 -322
- package/dist/swapper/SwapperWithSigner.js +318 -318
- package/dist/swaps/IAddressSwap.d.ts +22 -22
- package/dist/swaps/IAddressSwap.js +14 -13
- package/dist/swaps/IBTCWalletSwap.d.ts +73 -73
- package/dist/swaps/IBTCWalletSwap.js +18 -17
- package/dist/swaps/IClaimableSwap.d.ts +49 -49
- package/dist/swaps/IClaimableSwap.js +15 -14
- package/dist/swaps/IClaimableSwapWrapper.d.ts +15 -15
- package/dist/swaps/IClaimableSwapWrapper.js +2 -2
- package/dist/swaps/IRefundableSwap.d.ts +43 -43
- package/dist/swaps/IRefundableSwap.js +14 -13
- package/dist/swaps/ISwap.d.ts +387 -386
- package/dist/swaps/ISwap.js +346 -346
- package/dist/swaps/ISwapWithGasDrop.d.ts +21 -21
- package/dist/swaps/ISwapWithGasDrop.js +12 -11
- package/dist/swaps/ISwapWrapper.d.ts +285 -283
- package/dist/swaps/ISwapWrapper.js +353 -353
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +98 -98
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +126 -126
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +135 -133
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +169 -169
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +115 -114
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +134 -134
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +101 -98
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +130 -130
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +162 -162
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +190 -190
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +58 -58
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +78 -78
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +531 -529
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +1285 -1285
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +184 -181
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +418 -418
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +583 -581
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +1371 -1371
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +228 -225
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +506 -506
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +458 -458
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +1126 -1126
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +191 -190
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +378 -378
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +403 -403
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +924 -924
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +62 -62
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +112 -112
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +127 -125
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +256 -256
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +242 -241
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +520 -520
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +73 -73
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +155 -155
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +128 -127
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +278 -278
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +630 -630
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1443 -1443
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +214 -213
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +756 -756
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +261 -261
- package/dist/swaps/trusted/ln/LnForGasSwap.js +511 -511
- package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +40 -40
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +82 -82
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +342 -342
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +715 -715
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +69 -68
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +92 -92
- package/dist/types/AmountData.d.ts +10 -10
- package/dist/types/AmountData.js +2 -2
- package/dist/types/CustomPriceFunction.d.ts +11 -11
- package/dist/types/CustomPriceFunction.js +2 -2
- package/dist/types/PriceInfoType.d.ts +28 -28
- package/dist/types/PriceInfoType.js +57 -56
- package/dist/types/SwapExecutionAction.d.ts +88 -88
- package/dist/types/SwapExecutionAction.js +2 -2
- package/dist/types/SwapStateInfo.d.ts +5 -5
- package/dist/types/SwapStateInfo.js +2 -2
- package/dist/types/SwapWithSigner.d.ts +17 -17
- package/dist/types/SwapWithSigner.js +43 -42
- package/dist/types/Token.d.ts +99 -99
- package/dist/types/Token.js +76 -76
- package/dist/types/TokenAmount.d.ts +69 -69
- package/dist/types/TokenAmount.js +60 -59
- package/dist/types/fees/Fee.d.ts +50 -50
- package/dist/types/fees/Fee.js +2 -2
- package/dist/types/fees/FeeBreakdown.d.ts +11 -11
- package/dist/types/fees/FeeBreakdown.js +2 -2
- package/dist/types/fees/PercentagePPM.d.ts +17 -17
- package/dist/types/fees/PercentagePPM.js +18 -17
- package/dist/types/lnurl/LNURLPay.d.ts +61 -61
- package/dist/types/lnurl/LNURLPay.js +31 -30
- package/dist/types/lnurl/LNURLWithdraw.d.ts +48 -48
- package/dist/types/lnurl/LNURLWithdraw.js +27 -26
- package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -24
- package/dist/types/wallets/LightningInvoiceCreateService.js +15 -14
- package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +23 -23
- package/dist/types/wallets/MinimalBitcoinWalletInterface.js +2 -2
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +9 -9
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.js +2 -2
- package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -1
- package/dist/utils/AutomaticClockDriftCorrection.js +70 -69
- package/dist/utils/BitcoinUtils.d.ts +14 -12
- package/dist/utils/BitcoinUtils.js +102 -101
- package/dist/utils/BitcoinWalletUtils.d.ts +7 -7
- package/dist/utils/BitcoinWalletUtils.js +14 -13
- package/dist/utils/Logger.d.ts +7 -7
- package/dist/utils/Logger.js +12 -11
- package/dist/utils/RetryUtils.d.ts +22 -22
- package/dist/utils/RetryUtils.js +67 -66
- package/dist/utils/SwapUtils.d.ts +88 -88
- package/dist/utils/SwapUtils.js +72 -72
- package/dist/utils/TimeoutUtils.d.ts +17 -17
- package/dist/utils/TimeoutUtils.js +55 -54
- package/dist/utils/TokenUtils.d.ts +19 -19
- package/dist/utils/TokenUtils.js +37 -36
- package/dist/utils/TypeUtils.d.ts +7 -7
- package/dist/utils/TypeUtils.js +2 -2
- package/dist/utils/Utils.d.ts +58 -56
- package/dist/utils/Utils.js +194 -193
- package/package.json +1 -1
|
@@ -1,511 +1,511 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LnForGasSwap = exports.LnForGasSwapState = void 0;
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
[LnForGasSwapState.
|
|
46
|
-
[LnForGasSwapState.
|
|
47
|
-
[LnForGasSwapState.
|
|
48
|
-
[LnForGasSwapState.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
typeof (obj.
|
|
54
|
-
typeof (obj.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Trusted swap for Bitcoin Lightning -> Smart chains, to be used for minor amounts to get gas tokens on
|
|
60
|
-
* the destination chain, which is only needed for Solana, which still uses legacy swaps
|
|
61
|
-
*
|
|
62
|
-
* @category Swaps/Trusted Gas Swaps
|
|
63
|
-
*/
|
|
64
|
-
class LnForGasSwap extends ISwap_1.ISwap {
|
|
65
|
-
constructor(wrapper, initOrObj) {
|
|
66
|
-
if (isLnForGasSwapInit(initOrObj) && initOrObj.url != null)
|
|
67
|
-
initOrObj.url += "/lnforgas";
|
|
68
|
-
super(wrapper, initOrObj);
|
|
69
|
-
this.TYPE = SwapType_1.SwapType.TRUSTED_FROM_BTCLN;
|
|
70
|
-
/**
|
|
71
|
-
* @internal
|
|
72
|
-
*/
|
|
73
|
-
this.swapStateDescription = LnForGasSwapStateDescription;
|
|
74
|
-
/**
|
|
75
|
-
* @internal
|
|
76
|
-
*/
|
|
77
|
-
this.swapStateName = (state) => LnForGasSwapState[state];
|
|
78
|
-
/**
|
|
79
|
-
* @internal
|
|
80
|
-
*/
|
|
81
|
-
this.currentVersion = 2;
|
|
82
|
-
if (isLnForGasSwapInit(initOrObj)) {
|
|
83
|
-
this.pr = initOrObj.pr;
|
|
84
|
-
this.outputAmount = initOrObj.outputAmount;
|
|
85
|
-
this.recipient = initOrObj.recipient;
|
|
86
|
-
this.token = initOrObj.token;
|
|
87
|
-
this._state = LnForGasSwapState.PR_CREATED;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
this.pr = initOrObj.pr;
|
|
91
|
-
this.outputAmount = (0, Utils_1.toBigInt)(initOrObj.outputAmount);
|
|
92
|
-
this.recipient = initOrObj.recipient;
|
|
93
|
-
this.token = initOrObj.token;
|
|
94
|
-
this.scTxId = initOrObj.scTxId;
|
|
95
|
-
}
|
|
96
|
-
this.tryRecomputeSwapPrice();
|
|
97
|
-
if (this.pr != null) {
|
|
98
|
-
const decoded = (0, bolt11_1.decode)(this.pr);
|
|
99
|
-
if (decoded.timeExpireDate != null)
|
|
100
|
-
this.expiry = decoded.timeExpireDate * 1000;
|
|
101
|
-
}
|
|
102
|
-
this.logger = (0, Logger_1.getLogger)("LnForGas(" + this.getId() + "): ");
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* @inheritDoc
|
|
106
|
-
* @internal
|
|
107
|
-
*/
|
|
108
|
-
upgradeVersion() {
|
|
109
|
-
if (this.version == 1) {
|
|
110
|
-
if (this._state === 1)
|
|
111
|
-
this._state = LnForGasSwapState.FINISHED;
|
|
112
|
-
this.version = 2;
|
|
113
|
-
}
|
|
114
|
-
if (this.version == null) {
|
|
115
|
-
//Noop
|
|
116
|
-
this.version = 1;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* @inheritDoc
|
|
121
|
-
* @internal
|
|
122
|
-
*/
|
|
123
|
-
tryRecomputeSwapPrice() {
|
|
124
|
-
if (this.swapFeeBtc == null && this.swapFee != null) {
|
|
125
|
-
this.swapFeeBtc = this.swapFee * this.getInput().rawAmount / this.getOutAmountWithoutFee();
|
|
126
|
-
}
|
|
127
|
-
super.tryRecomputeSwapPrice();
|
|
128
|
-
}
|
|
129
|
-
//////////////////////////////
|
|
130
|
-
//// Getters & utils
|
|
131
|
-
/**
|
|
132
|
-
* @inheritDoc
|
|
133
|
-
* @internal
|
|
134
|
-
*/
|
|
135
|
-
_getEscrowHash() {
|
|
136
|
-
return this.getId();
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* @inheritDoc
|
|
140
|
-
*/
|
|
141
|
-
getOutputAddress() {
|
|
142
|
-
return this.recipient;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* @inheritDoc
|
|
146
|
-
*/
|
|
147
|
-
getInputAddress() {
|
|
148
|
-
return this.pr;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* @inheritDoc
|
|
152
|
-
*/
|
|
153
|
-
getInputTxId() {
|
|
154
|
-
return this.getId();
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* @inheritDoc
|
|
158
|
-
*/
|
|
159
|
-
getOutputTxId() {
|
|
160
|
-
return this.scTxId ?? null;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* @inheritDoc
|
|
164
|
-
*/
|
|
165
|
-
getId() {
|
|
166
|
-
if (this.pr == null)
|
|
167
|
-
throw new Error("No payment request assigned to this swap!");
|
|
168
|
-
const decodedPR = (0, bolt11_1.decode)(this.pr);
|
|
169
|
-
if (decodedPR.tagsObject.payment_hash == null)
|
|
170
|
-
throw new Error("Lightning invoice has no payment hash!");
|
|
171
|
-
return decodedPR.tagsObject.payment_hash;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Returns the lightning network BOLT11 invoice that needs to be paid as an input to the swap
|
|
175
|
-
*/
|
|
176
|
-
getAddress() {
|
|
177
|
-
return this.pr;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Returns a string that can be displayed as QR code representation of the lightning invoice (with lightning: prefix)
|
|
181
|
-
*/
|
|
182
|
-
getHyperlink() {
|
|
183
|
-
return "lightning:" + this.pr.toUpperCase();
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* @inheritDoc
|
|
187
|
-
*/
|
|
188
|
-
requiresAction() {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* @inheritDoc
|
|
193
|
-
*/
|
|
194
|
-
isFinished() {
|
|
195
|
-
return this._state === LnForGasSwapState.FINISHED || this._state === LnForGasSwapState.FAILED || this._state === LnForGasSwapState.EXPIRED;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* @inheritDoc
|
|
199
|
-
*/
|
|
200
|
-
isQuoteExpired() {
|
|
201
|
-
return this._state === LnForGasSwapState.EXPIRED;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* @inheritDoc
|
|
205
|
-
*/
|
|
206
|
-
isQuoteSoftExpired() {
|
|
207
|
-
return this.expiry < Date.now();
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* @inheritDoc
|
|
211
|
-
*/
|
|
212
|
-
isFailed() {
|
|
213
|
-
return this._state === LnForGasSwapState.FAILED;
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* @inheritDoc
|
|
217
|
-
*/
|
|
218
|
-
isSuccessful() {
|
|
219
|
-
return this._state === LnForGasSwapState.FINISHED;
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* @inheritDoc
|
|
223
|
-
*/
|
|
224
|
-
isInProgress() {
|
|
225
|
-
return (this._state === LnForGasSwapState.PR_CREATED && this.initiated) || this._state === LnForGasSwapState.PR_PAID;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* @inheritDoc
|
|
229
|
-
* @internal
|
|
230
|
-
*/
|
|
231
|
-
_verifyQuoteDefinitelyExpired() {
|
|
232
|
-
return Promise.resolve(this.expiry < Date.now());
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* @inheritDoc
|
|
236
|
-
* @internal
|
|
237
|
-
*/
|
|
238
|
-
_verifyQuoteValid() {
|
|
239
|
-
return Promise.resolve(this.expiry > Date.now());
|
|
240
|
-
}
|
|
241
|
-
//////////////////////////////
|
|
242
|
-
//// Amounts & fees
|
|
243
|
-
/**
|
|
244
|
-
* Returns an output amount in base units without a swap fee included, hence this value
|
|
245
|
-
* is larger than the actual output amount
|
|
246
|
-
*
|
|
247
|
-
* @internal
|
|
248
|
-
*/
|
|
249
|
-
getOutAmountWithoutFee() {
|
|
250
|
-
return this.outputAmount + (this.swapFee ?? 0n);
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* @inheritDoc
|
|
254
|
-
*/
|
|
255
|
-
getOutputToken() {
|
|
256
|
-
return this.wrapper._tokens[this.wrapper._chain.getNativeCurrencyAddress()];
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* @inheritDoc
|
|
260
|
-
*/
|
|
261
|
-
getOutput() {
|
|
262
|
-
return (0, TokenAmount_1.toTokenAmount)(this.outputAmount, this.wrapper._tokens[this.wrapper._chain.getNativeCurrencyAddress()], this.wrapper._prices, this.pricingInfo);
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* @inheritDoc
|
|
266
|
-
*/
|
|
267
|
-
getInputToken() {
|
|
268
|
-
return Token_1.BitcoinTokens.BTCLN;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* @inheritDoc
|
|
272
|
-
*/
|
|
273
|
-
getInput() {
|
|
274
|
-
const parsed = (0, bolt11_1.decode)(this.pr);
|
|
275
|
-
const msats = parsed.millisatoshis;
|
|
276
|
-
if (msats == null)
|
|
277
|
-
throw new Error("Swap lightning invoice has no msat amount field!");
|
|
278
|
-
const amount = (BigInt(msats) + 999n) / 1000n;
|
|
279
|
-
return (0, TokenAmount_1.toTokenAmount)(amount, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* @inheritDoc
|
|
283
|
-
*/
|
|
284
|
-
getInputWithoutFee() {
|
|
285
|
-
const parsed = (0, bolt11_1.decode)(this.pr);
|
|
286
|
-
const msats = parsed.millisatoshis;
|
|
287
|
-
if (msats == null)
|
|
288
|
-
throw new Error("Swap lightning invoice has no msat amount field!");
|
|
289
|
-
const amount = (BigInt(msats) + 999n) / 1000n;
|
|
290
|
-
return (0, TokenAmount_1.toTokenAmount)(amount - (this.swapFeeBtc ?? 0n), Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Returns the swap fee charged by the intermediary (LP) on this swap
|
|
294
|
-
*
|
|
295
|
-
* @internal
|
|
296
|
-
*/
|
|
297
|
-
getSwapFee() {
|
|
298
|
-
if (this.pricingInfo == null)
|
|
299
|
-
throw new Error("No pricing info known, cannot estimate swap fee!");
|
|
300
|
-
const feeWithoutBaseFee = this.swapFeeBtc == null ? 0n : this.swapFeeBtc - this.pricingInfo.satsBaseFee;
|
|
301
|
-
const swapFeePPM = feeWithoutBaseFee * 1000000n / this.getInputWithoutFee().rawAmount;
|
|
302
|
-
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(this.swapFeeBtc ?? 0n, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
303
|
-
return {
|
|
304
|
-
amountInSrcToken,
|
|
305
|
-
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee ?? 0n, this.wrapper._tokens[this.wrapper._chain.getNativeCurrencyAddress()], this.wrapper._prices, this.pricingInfo),
|
|
306
|
-
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
307
|
-
usdValue: amountInSrcToken.usdValue,
|
|
308
|
-
pastUsdValue: amountInSrcToken.pastUsdValue,
|
|
309
|
-
composition: {
|
|
310
|
-
base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo),
|
|
311
|
-
percentage: (0, PercentagePPM_1.ppmToPercentage)(swapFeePPM)
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* @inheritDoc
|
|
317
|
-
*/
|
|
318
|
-
getFee() {
|
|
319
|
-
return this.getSwapFee();
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* @inheritDoc
|
|
323
|
-
*/
|
|
324
|
-
getFeeBreakdown() {
|
|
325
|
-
return [{
|
|
326
|
-
type: FeeType_1.FeeType.SWAP,
|
|
327
|
-
fee: this.getSwapFee()
|
|
328
|
-
}];
|
|
329
|
-
}
|
|
330
|
-
//////////////////////////////
|
|
331
|
-
//// Payment
|
|
332
|
-
/**
|
|
333
|
-
* @inheritDoc
|
|
334
|
-
*/
|
|
335
|
-
async txsExecute() {
|
|
336
|
-
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
337
|
-
if (!await this._verifyQuoteValid())
|
|
338
|
-
throw new Error("Quote already expired or close to expiry!");
|
|
339
|
-
return [
|
|
340
|
-
{
|
|
341
|
-
name: "Payment",
|
|
342
|
-
description: "Initiates the swap by paying up the lightning network invoice",
|
|
343
|
-
chain: "LIGHTNING",
|
|
344
|
-
txs: [
|
|
345
|
-
{
|
|
346
|
-
type: "BOLT11_PAYMENT_REQUEST",
|
|
347
|
-
address: this.pr,
|
|
348
|
-
hyperlink: this.getHyperlink()
|
|
349
|
-
}
|
|
350
|
-
]
|
|
351
|
-
}
|
|
352
|
-
];
|
|
353
|
-
}
|
|
354
|
-
throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED");
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* @remark Not supported
|
|
358
|
-
*/
|
|
359
|
-
async execute() {
|
|
360
|
-
throw new Error("Not supported");
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* @inheritDoc
|
|
364
|
-
*/
|
|
365
|
-
async getCurrentActions() {
|
|
366
|
-
try {
|
|
367
|
-
return await this.txsExecute();
|
|
368
|
-
}
|
|
369
|
-
catch (e) {
|
|
370
|
-
return [];
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Queries the intermediary (LP) node for the state of the swap
|
|
375
|
-
*
|
|
376
|
-
* @param save Whether the save the result or not
|
|
377
|
-
*
|
|
378
|
-
* @returns Whether the swap was successful as `boolean` or `null` if the swap is still pending
|
|
379
|
-
* @internal
|
|
380
|
-
*/
|
|
381
|
-
async checkInvoicePaid(save = true) {
|
|
382
|
-
if (this._state === LnForGasSwapState.FAILED || this._state === LnForGasSwapState.EXPIRED)
|
|
383
|
-
return false;
|
|
384
|
-
if (this._state === LnForGasSwapState.FINISHED)
|
|
385
|
-
return true;
|
|
386
|
-
if (this.url == null)
|
|
387
|
-
return false;
|
|
388
|
-
const decodedPR = (0, bolt11_1.decode)(this.pr);
|
|
389
|
-
const paymentHash = decodedPR.tagsObject.payment_hash;
|
|
390
|
-
if (paymentHash == null)
|
|
391
|
-
throw new Error("Invalid swap invoice, payment hash not found!");
|
|
392
|
-
const response = await TrustedIntermediaryAPI_1.TrustedIntermediaryAPI.getInvoiceStatus(this.url, paymentHash, this.wrapper._options.getRequestTimeout);
|
|
393
|
-
this.logger.debug("checkInvoicePaid(): LP response: ", response);
|
|
394
|
-
switch (response.code) {
|
|
395
|
-
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.PAID:
|
|
396
|
-
this.scTxId = response.data.txId;
|
|
397
|
-
const txStatus = await this.wrapper._chain.getTxIdStatus(this.scTxId);
|
|
398
|
-
if (txStatus === "success") {
|
|
399
|
-
this._state = LnForGasSwapState.FINISHED;
|
|
400
|
-
if (save)
|
|
401
|
-
await this._saveAndEmit();
|
|
402
|
-
return true;
|
|
403
|
-
}
|
|
404
|
-
return null;
|
|
405
|
-
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.EXPIRED:
|
|
406
|
-
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
407
|
-
this._state = LnForGasSwapState.EXPIRED;
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
this._state = LnForGasSwapState.FAILED;
|
|
411
|
-
}
|
|
412
|
-
if (save)
|
|
413
|
-
await this._saveAndEmit();
|
|
414
|
-
return false;
|
|
415
|
-
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.TX_SENT:
|
|
416
|
-
this.scTxId = response.data.txId;
|
|
417
|
-
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
418
|
-
this._state = LnForGasSwapState.PR_PAID;
|
|
419
|
-
if (save)
|
|
420
|
-
await this._saveAndEmit();
|
|
421
|
-
}
|
|
422
|
-
return null;
|
|
423
|
-
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING:
|
|
424
|
-
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
425
|
-
this._state = LnForGasSwapState.PR_PAID;
|
|
426
|
-
if (save)
|
|
427
|
-
await this._saveAndEmit();
|
|
428
|
-
}
|
|
429
|
-
return null;
|
|
430
|
-
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.AWAIT_PAYMENT:
|
|
431
|
-
return null;
|
|
432
|
-
default:
|
|
433
|
-
this._state = LnForGasSwapState.FAILED;
|
|
434
|
-
if (save)
|
|
435
|
-
await this._saveAndEmit();
|
|
436
|
-
return false;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* A blocking promise resolving when payment was received by the intermediary and client can continue,
|
|
441
|
-
* rejecting in case of failure. The swap must be in {@link LnForGasSwapState.PR_CREATED} state!
|
|
442
|
-
*
|
|
443
|
-
* @param checkIntervalSeconds How often to poll the intermediary for answer (default 5 seconds)
|
|
444
|
-
* @param abortSignal Abort signal
|
|
445
|
-
* @throws {Error} When in invalid state (not PR_CREATED)
|
|
446
|
-
*/
|
|
447
|
-
async waitForPayment(checkIntervalSeconds, abortSignal) {
|
|
448
|
-
if (this._state !== LnForGasSwapState.PR_CREATED)
|
|
449
|
-
throw new Error("Must be in PR_CREATED state!");
|
|
450
|
-
if (!this.initiated) {
|
|
451
|
-
this.initiated = true;
|
|
452
|
-
await this._saveAndEmit();
|
|
453
|
-
}
|
|
454
|
-
while (!abortSignal?.aborted && (this._state === LnForGasSwapState.PR_CREATED || this._state === LnForGasSwapState.PR_PAID)) {
|
|
455
|
-
await this.checkInvoicePaid(true);
|
|
456
|
-
if (this._state === LnForGasSwapState.PR_CREATED || this._state === LnForGasSwapState.PR_PAID)
|
|
457
|
-
await (0, TimeoutUtils_1.timeoutPromise)((checkIntervalSeconds ?? 5) * 1000, abortSignal);
|
|
458
|
-
}
|
|
459
|
-
if (this.isFailed())
|
|
460
|
-
throw new Error("Swap failed");
|
|
461
|
-
return !this.isQuoteExpired();
|
|
462
|
-
}
|
|
463
|
-
//////////////////////////////
|
|
464
|
-
//// Storage
|
|
465
|
-
/**
|
|
466
|
-
* @inheritDoc
|
|
467
|
-
*/
|
|
468
|
-
serialize() {
|
|
469
|
-
return {
|
|
470
|
-
...super.serialize(),
|
|
471
|
-
pr: this.pr,
|
|
472
|
-
outputAmount: this.outputAmount == null ? null : this.outputAmount.toString(10),
|
|
473
|
-
recipient: this.recipient,
|
|
474
|
-
token: this.token,
|
|
475
|
-
scTxId: this.scTxId
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* @inheritDoc
|
|
480
|
-
* @internal
|
|
481
|
-
*/
|
|
482
|
-
_getInitiator() {
|
|
483
|
-
return this.recipient;
|
|
484
|
-
}
|
|
485
|
-
//////////////////////////////
|
|
486
|
-
//// Swap ticks & sync
|
|
487
|
-
/**
|
|
488
|
-
* @inheritDoc
|
|
489
|
-
* @internal
|
|
490
|
-
*/
|
|
491
|
-
async _sync(save) {
|
|
492
|
-
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
493
|
-
//Check if it's maybe already paid
|
|
494
|
-
const res = await this.checkInvoicePaid(false);
|
|
495
|
-
if (res !== null) {
|
|
496
|
-
if (save)
|
|
497
|
-
await this._saveAndEmit();
|
|
498
|
-
return true;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
return false;
|
|
502
|
-
}
|
|
503
|
-
/**
|
|
504
|
-
* @inheritDoc
|
|
505
|
-
* @internal
|
|
506
|
-
*/
|
|
507
|
-
_tick(save) {
|
|
508
|
-
return Promise.resolve(false);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
exports.LnForGasSwap = LnForGasSwap;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LnForGasSwap = exports.isLnForGasSwapInit = exports.LnForGasSwapState = void 0;
|
|
4
|
+
const bolt11_1 = require("@atomiqlabs/bolt11");
|
|
5
|
+
const SwapType_1 = require("../../../enums/SwapType");
|
|
6
|
+
const Utils_1 = require("../../../utils/Utils");
|
|
7
|
+
const ISwap_1 = require("../../ISwap");
|
|
8
|
+
const TrustedIntermediaryAPI_1 = require("../../../intermediaries/apis/TrustedIntermediaryAPI");
|
|
9
|
+
const FeeType_1 = require("../../../enums/FeeType");
|
|
10
|
+
const PercentagePPM_1 = require("../../../types/fees/PercentagePPM");
|
|
11
|
+
const TokenAmount_1 = require("../../../types/TokenAmount");
|
|
12
|
+
const Token_1 = require("../../../types/Token");
|
|
13
|
+
const Logger_1 = require("../../../utils/Logger");
|
|
14
|
+
const TimeoutUtils_1 = require("../../../utils/TimeoutUtils");
|
|
15
|
+
/**
|
|
16
|
+
* State enum for trusted Lightning gas swaps
|
|
17
|
+
*
|
|
18
|
+
* @category Swaps/Trusted Gas Swaps
|
|
19
|
+
*/
|
|
20
|
+
var LnForGasSwapState;
|
|
21
|
+
(function (LnForGasSwapState) {
|
|
22
|
+
/**
|
|
23
|
+
* The swap quote expired without user sending in the lightning network payment
|
|
24
|
+
*/
|
|
25
|
+
LnForGasSwapState[LnForGasSwapState["EXPIRED"] = -2] = "EXPIRED";
|
|
26
|
+
/**
|
|
27
|
+
* The swap has failed after the intermediary already received a lightning network payment on the source
|
|
28
|
+
*/
|
|
29
|
+
LnForGasSwapState[LnForGasSwapState["FAILED"] = -1] = "FAILED";
|
|
30
|
+
/**
|
|
31
|
+
* Swap was created, pay the provided lightning network invoice
|
|
32
|
+
*/
|
|
33
|
+
LnForGasSwapState[LnForGasSwapState["PR_CREATED"] = 0] = "PR_CREATED";
|
|
34
|
+
/**
|
|
35
|
+
* User paid the lightning network invoice on the source
|
|
36
|
+
*/
|
|
37
|
+
LnForGasSwapState[LnForGasSwapState["PR_PAID"] = 1] = "PR_PAID";
|
|
38
|
+
/**
|
|
39
|
+
* The swap is finished after the intermediary sent funds on the destination chain
|
|
40
|
+
*/
|
|
41
|
+
LnForGasSwapState[LnForGasSwapState["FINISHED"] = 2] = "FINISHED";
|
|
42
|
+
})(LnForGasSwapState = exports.LnForGasSwapState || (exports.LnForGasSwapState = {}));
|
|
43
|
+
const LnForGasSwapStateDescription = {
|
|
44
|
+
[LnForGasSwapState.EXPIRED]: "The swap quote expired without user sending in the lightning network payment",
|
|
45
|
+
[LnForGasSwapState.FAILED]: "The swap has failed after the intermediary already received a lightning network payment on the source",
|
|
46
|
+
[LnForGasSwapState.PR_CREATED]: "Swap was created, pay the provided lightning network invoice",
|
|
47
|
+
[LnForGasSwapState.PR_PAID]: "User paid the lightning network invoice on the source",
|
|
48
|
+
[LnForGasSwapState.FINISHED]: "The swap is finished after the intermediary sent funds on the destination chain"
|
|
49
|
+
};
|
|
50
|
+
function isLnForGasSwapInit(obj) {
|
|
51
|
+
return typeof (obj.pr) === "string" &&
|
|
52
|
+
typeof (obj.outputAmount) === "bigint" &&
|
|
53
|
+
typeof (obj.recipient) === "string" &&
|
|
54
|
+
typeof (obj.token) === "string" &&
|
|
55
|
+
(0, ISwap_1.isISwapInit)(obj);
|
|
56
|
+
}
|
|
57
|
+
exports.isLnForGasSwapInit = isLnForGasSwapInit;
|
|
58
|
+
/**
|
|
59
|
+
* Trusted swap for Bitcoin Lightning -> Smart chains, to be used for minor amounts to get gas tokens on
|
|
60
|
+
* the destination chain, which is only needed for Solana, which still uses legacy swaps
|
|
61
|
+
*
|
|
62
|
+
* @category Swaps/Trusted Gas Swaps
|
|
63
|
+
*/
|
|
64
|
+
class LnForGasSwap extends ISwap_1.ISwap {
|
|
65
|
+
constructor(wrapper, initOrObj) {
|
|
66
|
+
if (isLnForGasSwapInit(initOrObj) && initOrObj.url != null)
|
|
67
|
+
initOrObj.url += "/lnforgas";
|
|
68
|
+
super(wrapper, initOrObj);
|
|
69
|
+
this.TYPE = SwapType_1.SwapType.TRUSTED_FROM_BTCLN;
|
|
70
|
+
/**
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
this.swapStateDescription = LnForGasSwapStateDescription;
|
|
74
|
+
/**
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
this.swapStateName = (state) => LnForGasSwapState[state];
|
|
78
|
+
/**
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
this.currentVersion = 2;
|
|
82
|
+
if (isLnForGasSwapInit(initOrObj)) {
|
|
83
|
+
this.pr = initOrObj.pr;
|
|
84
|
+
this.outputAmount = initOrObj.outputAmount;
|
|
85
|
+
this.recipient = initOrObj.recipient;
|
|
86
|
+
this.token = initOrObj.token;
|
|
87
|
+
this._state = LnForGasSwapState.PR_CREATED;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this.pr = initOrObj.pr;
|
|
91
|
+
this.outputAmount = (0, Utils_1.toBigInt)(initOrObj.outputAmount);
|
|
92
|
+
this.recipient = initOrObj.recipient;
|
|
93
|
+
this.token = initOrObj.token;
|
|
94
|
+
this.scTxId = initOrObj.scTxId;
|
|
95
|
+
}
|
|
96
|
+
this.tryRecomputeSwapPrice();
|
|
97
|
+
if (this.pr != null) {
|
|
98
|
+
const decoded = (0, bolt11_1.decode)(this.pr);
|
|
99
|
+
if (decoded.timeExpireDate != null)
|
|
100
|
+
this.expiry = decoded.timeExpireDate * 1000;
|
|
101
|
+
}
|
|
102
|
+
this.logger = (0, Logger_1.getLogger)("LnForGas(" + this.getId() + "): ");
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* @inheritDoc
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
upgradeVersion() {
|
|
109
|
+
if (this.version == 1) {
|
|
110
|
+
if (this._state === 1)
|
|
111
|
+
this._state = LnForGasSwapState.FINISHED;
|
|
112
|
+
this.version = 2;
|
|
113
|
+
}
|
|
114
|
+
if (this.version == null) {
|
|
115
|
+
//Noop
|
|
116
|
+
this.version = 1;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* @inheritDoc
|
|
121
|
+
* @internal
|
|
122
|
+
*/
|
|
123
|
+
tryRecomputeSwapPrice() {
|
|
124
|
+
if (this.swapFeeBtc == null && this.swapFee != null) {
|
|
125
|
+
this.swapFeeBtc = this.swapFee * this.getInput().rawAmount / this.getOutAmountWithoutFee();
|
|
126
|
+
}
|
|
127
|
+
super.tryRecomputeSwapPrice();
|
|
128
|
+
}
|
|
129
|
+
//////////////////////////////
|
|
130
|
+
//// Getters & utils
|
|
131
|
+
/**
|
|
132
|
+
* @inheritDoc
|
|
133
|
+
* @internal
|
|
134
|
+
*/
|
|
135
|
+
_getEscrowHash() {
|
|
136
|
+
return this.getId();
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* @inheritDoc
|
|
140
|
+
*/
|
|
141
|
+
getOutputAddress() {
|
|
142
|
+
return this.recipient;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* @inheritDoc
|
|
146
|
+
*/
|
|
147
|
+
getInputAddress() {
|
|
148
|
+
return this.pr;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* @inheritDoc
|
|
152
|
+
*/
|
|
153
|
+
getInputTxId() {
|
|
154
|
+
return this.getId();
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @inheritDoc
|
|
158
|
+
*/
|
|
159
|
+
getOutputTxId() {
|
|
160
|
+
return this.scTxId ?? null;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* @inheritDoc
|
|
164
|
+
*/
|
|
165
|
+
getId() {
|
|
166
|
+
if (this.pr == null)
|
|
167
|
+
throw new Error("No payment request assigned to this swap!");
|
|
168
|
+
const decodedPR = (0, bolt11_1.decode)(this.pr);
|
|
169
|
+
if (decodedPR.tagsObject.payment_hash == null)
|
|
170
|
+
throw new Error("Lightning invoice has no payment hash!");
|
|
171
|
+
return decodedPR.tagsObject.payment_hash;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Returns the lightning network BOLT11 invoice that needs to be paid as an input to the swap
|
|
175
|
+
*/
|
|
176
|
+
getAddress() {
|
|
177
|
+
return this.pr;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Returns a string that can be displayed as QR code representation of the lightning invoice (with lightning: prefix)
|
|
181
|
+
*/
|
|
182
|
+
getHyperlink() {
|
|
183
|
+
return "lightning:" + this.pr.toUpperCase();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* @inheritDoc
|
|
187
|
+
*/
|
|
188
|
+
requiresAction() {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* @inheritDoc
|
|
193
|
+
*/
|
|
194
|
+
isFinished() {
|
|
195
|
+
return this._state === LnForGasSwapState.FINISHED || this._state === LnForGasSwapState.FAILED || this._state === LnForGasSwapState.EXPIRED;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* @inheritDoc
|
|
199
|
+
*/
|
|
200
|
+
isQuoteExpired() {
|
|
201
|
+
return this._state === LnForGasSwapState.EXPIRED;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* @inheritDoc
|
|
205
|
+
*/
|
|
206
|
+
isQuoteSoftExpired() {
|
|
207
|
+
return this.expiry < Date.now();
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* @inheritDoc
|
|
211
|
+
*/
|
|
212
|
+
isFailed() {
|
|
213
|
+
return this._state === LnForGasSwapState.FAILED;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* @inheritDoc
|
|
217
|
+
*/
|
|
218
|
+
isSuccessful() {
|
|
219
|
+
return this._state === LnForGasSwapState.FINISHED;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* @inheritDoc
|
|
223
|
+
*/
|
|
224
|
+
isInProgress() {
|
|
225
|
+
return (this._state === LnForGasSwapState.PR_CREATED && this.initiated) || this._state === LnForGasSwapState.PR_PAID;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* @inheritDoc
|
|
229
|
+
* @internal
|
|
230
|
+
*/
|
|
231
|
+
_verifyQuoteDefinitelyExpired() {
|
|
232
|
+
return Promise.resolve(this.expiry < Date.now());
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* @inheritDoc
|
|
236
|
+
* @internal
|
|
237
|
+
*/
|
|
238
|
+
_verifyQuoteValid() {
|
|
239
|
+
return Promise.resolve(this.expiry > Date.now());
|
|
240
|
+
}
|
|
241
|
+
//////////////////////////////
|
|
242
|
+
//// Amounts & fees
|
|
243
|
+
/**
|
|
244
|
+
* Returns an output amount in base units without a swap fee included, hence this value
|
|
245
|
+
* is larger than the actual output amount
|
|
246
|
+
*
|
|
247
|
+
* @internal
|
|
248
|
+
*/
|
|
249
|
+
getOutAmountWithoutFee() {
|
|
250
|
+
return this.outputAmount + (this.swapFee ?? 0n);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* @inheritDoc
|
|
254
|
+
*/
|
|
255
|
+
getOutputToken() {
|
|
256
|
+
return this.wrapper._tokens[this.wrapper._chain.getNativeCurrencyAddress()];
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* @inheritDoc
|
|
260
|
+
*/
|
|
261
|
+
getOutput() {
|
|
262
|
+
return (0, TokenAmount_1.toTokenAmount)(this.outputAmount, this.wrapper._tokens[this.wrapper._chain.getNativeCurrencyAddress()], this.wrapper._prices, this.pricingInfo);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* @inheritDoc
|
|
266
|
+
*/
|
|
267
|
+
getInputToken() {
|
|
268
|
+
return Token_1.BitcoinTokens.BTCLN;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* @inheritDoc
|
|
272
|
+
*/
|
|
273
|
+
getInput() {
|
|
274
|
+
const parsed = (0, bolt11_1.decode)(this.pr);
|
|
275
|
+
const msats = parsed.millisatoshis;
|
|
276
|
+
if (msats == null)
|
|
277
|
+
throw new Error("Swap lightning invoice has no msat amount field!");
|
|
278
|
+
const amount = (BigInt(msats) + 999n) / 1000n;
|
|
279
|
+
return (0, TokenAmount_1.toTokenAmount)(amount, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* @inheritDoc
|
|
283
|
+
*/
|
|
284
|
+
getInputWithoutFee() {
|
|
285
|
+
const parsed = (0, bolt11_1.decode)(this.pr);
|
|
286
|
+
const msats = parsed.millisatoshis;
|
|
287
|
+
if (msats == null)
|
|
288
|
+
throw new Error("Swap lightning invoice has no msat amount field!");
|
|
289
|
+
const amount = (BigInt(msats) + 999n) / 1000n;
|
|
290
|
+
return (0, TokenAmount_1.toTokenAmount)(amount - (this.swapFeeBtc ?? 0n), Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Returns the swap fee charged by the intermediary (LP) on this swap
|
|
294
|
+
*
|
|
295
|
+
* @internal
|
|
296
|
+
*/
|
|
297
|
+
getSwapFee() {
|
|
298
|
+
if (this.pricingInfo == null)
|
|
299
|
+
throw new Error("No pricing info known, cannot estimate swap fee!");
|
|
300
|
+
const feeWithoutBaseFee = this.swapFeeBtc == null ? 0n : this.swapFeeBtc - this.pricingInfo.satsBaseFee;
|
|
301
|
+
const swapFeePPM = feeWithoutBaseFee * 1000000n / this.getInputWithoutFee().rawAmount;
|
|
302
|
+
const amountInSrcToken = (0, TokenAmount_1.toTokenAmount)(this.swapFeeBtc ?? 0n, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo);
|
|
303
|
+
return {
|
|
304
|
+
amountInSrcToken,
|
|
305
|
+
amountInDstToken: (0, TokenAmount_1.toTokenAmount)(this.swapFee ?? 0n, this.wrapper._tokens[this.wrapper._chain.getNativeCurrencyAddress()], this.wrapper._prices, this.pricingInfo),
|
|
306
|
+
currentUsdValue: amountInSrcToken.currentUsdValue,
|
|
307
|
+
usdValue: amountInSrcToken.usdValue,
|
|
308
|
+
pastUsdValue: amountInSrcToken.pastUsdValue,
|
|
309
|
+
composition: {
|
|
310
|
+
base: (0, TokenAmount_1.toTokenAmount)(this.pricingInfo.satsBaseFee, Token_1.BitcoinTokens.BTCLN, this.wrapper._prices, this.pricingInfo),
|
|
311
|
+
percentage: (0, PercentagePPM_1.ppmToPercentage)(swapFeePPM)
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* @inheritDoc
|
|
317
|
+
*/
|
|
318
|
+
getFee() {
|
|
319
|
+
return this.getSwapFee();
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* @inheritDoc
|
|
323
|
+
*/
|
|
324
|
+
getFeeBreakdown() {
|
|
325
|
+
return [{
|
|
326
|
+
type: FeeType_1.FeeType.SWAP,
|
|
327
|
+
fee: this.getSwapFee()
|
|
328
|
+
}];
|
|
329
|
+
}
|
|
330
|
+
//////////////////////////////
|
|
331
|
+
//// Payment
|
|
332
|
+
/**
|
|
333
|
+
* @inheritDoc
|
|
334
|
+
*/
|
|
335
|
+
async txsExecute() {
|
|
336
|
+
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
337
|
+
if (!await this._verifyQuoteValid())
|
|
338
|
+
throw new Error("Quote already expired or close to expiry!");
|
|
339
|
+
return [
|
|
340
|
+
{
|
|
341
|
+
name: "Payment",
|
|
342
|
+
description: "Initiates the swap by paying up the lightning network invoice",
|
|
343
|
+
chain: "LIGHTNING",
|
|
344
|
+
txs: [
|
|
345
|
+
{
|
|
346
|
+
type: "BOLT11_PAYMENT_REQUEST",
|
|
347
|
+
address: this.pr,
|
|
348
|
+
hyperlink: this.getHyperlink()
|
|
349
|
+
}
|
|
350
|
+
]
|
|
351
|
+
}
|
|
352
|
+
];
|
|
353
|
+
}
|
|
354
|
+
throw new Error("Invalid swap state to obtain execution txns, required PR_CREATED");
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* @remark Not supported
|
|
358
|
+
*/
|
|
359
|
+
async execute() {
|
|
360
|
+
throw new Error("Not supported");
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* @inheritDoc
|
|
364
|
+
*/
|
|
365
|
+
async getCurrentActions() {
|
|
366
|
+
try {
|
|
367
|
+
return await this.txsExecute();
|
|
368
|
+
}
|
|
369
|
+
catch (e) {
|
|
370
|
+
return [];
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Queries the intermediary (LP) node for the state of the swap
|
|
375
|
+
*
|
|
376
|
+
* @param save Whether the save the result or not
|
|
377
|
+
*
|
|
378
|
+
* @returns Whether the swap was successful as `boolean` or `null` if the swap is still pending
|
|
379
|
+
* @internal
|
|
380
|
+
*/
|
|
381
|
+
async checkInvoicePaid(save = true) {
|
|
382
|
+
if (this._state === LnForGasSwapState.FAILED || this._state === LnForGasSwapState.EXPIRED)
|
|
383
|
+
return false;
|
|
384
|
+
if (this._state === LnForGasSwapState.FINISHED)
|
|
385
|
+
return true;
|
|
386
|
+
if (this.url == null)
|
|
387
|
+
return false;
|
|
388
|
+
const decodedPR = (0, bolt11_1.decode)(this.pr);
|
|
389
|
+
const paymentHash = decodedPR.tagsObject.payment_hash;
|
|
390
|
+
if (paymentHash == null)
|
|
391
|
+
throw new Error("Invalid swap invoice, payment hash not found!");
|
|
392
|
+
const response = await TrustedIntermediaryAPI_1.TrustedIntermediaryAPI.getInvoiceStatus(this.url, paymentHash, this.wrapper._options.getRequestTimeout);
|
|
393
|
+
this.logger.debug("checkInvoicePaid(): LP response: ", response);
|
|
394
|
+
switch (response.code) {
|
|
395
|
+
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.PAID:
|
|
396
|
+
this.scTxId = response.data.txId;
|
|
397
|
+
const txStatus = await this.wrapper._chain.getTxIdStatus(this.scTxId);
|
|
398
|
+
if (txStatus === "success") {
|
|
399
|
+
this._state = LnForGasSwapState.FINISHED;
|
|
400
|
+
if (save)
|
|
401
|
+
await this._saveAndEmit();
|
|
402
|
+
return true;
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.EXPIRED:
|
|
406
|
+
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
407
|
+
this._state = LnForGasSwapState.EXPIRED;
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
this._state = LnForGasSwapState.FAILED;
|
|
411
|
+
}
|
|
412
|
+
if (save)
|
|
413
|
+
await this._saveAndEmit();
|
|
414
|
+
return false;
|
|
415
|
+
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.TX_SENT:
|
|
416
|
+
this.scTxId = response.data.txId;
|
|
417
|
+
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
418
|
+
this._state = LnForGasSwapState.PR_PAID;
|
|
419
|
+
if (save)
|
|
420
|
+
await this._saveAndEmit();
|
|
421
|
+
}
|
|
422
|
+
return null;
|
|
423
|
+
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.PENDING:
|
|
424
|
+
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
425
|
+
this._state = LnForGasSwapState.PR_PAID;
|
|
426
|
+
if (save)
|
|
427
|
+
await this._saveAndEmit();
|
|
428
|
+
}
|
|
429
|
+
return null;
|
|
430
|
+
case TrustedIntermediaryAPI_1.InvoiceStatusResponseCodes.AWAIT_PAYMENT:
|
|
431
|
+
return null;
|
|
432
|
+
default:
|
|
433
|
+
this._state = LnForGasSwapState.FAILED;
|
|
434
|
+
if (save)
|
|
435
|
+
await this._saveAndEmit();
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* A blocking promise resolving when payment was received by the intermediary and client can continue,
|
|
441
|
+
* rejecting in case of failure. The swap must be in {@link LnForGasSwapState.PR_CREATED} state!
|
|
442
|
+
*
|
|
443
|
+
* @param checkIntervalSeconds How often to poll the intermediary for answer (default 5 seconds)
|
|
444
|
+
* @param abortSignal Abort signal
|
|
445
|
+
* @throws {Error} When in invalid state (not PR_CREATED)
|
|
446
|
+
*/
|
|
447
|
+
async waitForPayment(checkIntervalSeconds, abortSignal) {
|
|
448
|
+
if (this._state !== LnForGasSwapState.PR_CREATED)
|
|
449
|
+
throw new Error("Must be in PR_CREATED state!");
|
|
450
|
+
if (!this.initiated) {
|
|
451
|
+
this.initiated = true;
|
|
452
|
+
await this._saveAndEmit();
|
|
453
|
+
}
|
|
454
|
+
while (!abortSignal?.aborted && (this._state === LnForGasSwapState.PR_CREATED || this._state === LnForGasSwapState.PR_PAID)) {
|
|
455
|
+
await this.checkInvoicePaid(true);
|
|
456
|
+
if (this._state === LnForGasSwapState.PR_CREATED || this._state === LnForGasSwapState.PR_PAID)
|
|
457
|
+
await (0, TimeoutUtils_1.timeoutPromise)((checkIntervalSeconds ?? 5) * 1000, abortSignal);
|
|
458
|
+
}
|
|
459
|
+
if (this.isFailed())
|
|
460
|
+
throw new Error("Swap failed");
|
|
461
|
+
return !this.isQuoteExpired();
|
|
462
|
+
}
|
|
463
|
+
//////////////////////////////
|
|
464
|
+
//// Storage
|
|
465
|
+
/**
|
|
466
|
+
* @inheritDoc
|
|
467
|
+
*/
|
|
468
|
+
serialize() {
|
|
469
|
+
return {
|
|
470
|
+
...super.serialize(),
|
|
471
|
+
pr: this.pr,
|
|
472
|
+
outputAmount: this.outputAmount == null ? null : this.outputAmount.toString(10),
|
|
473
|
+
recipient: this.recipient,
|
|
474
|
+
token: this.token,
|
|
475
|
+
scTxId: this.scTxId
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* @inheritDoc
|
|
480
|
+
* @internal
|
|
481
|
+
*/
|
|
482
|
+
_getInitiator() {
|
|
483
|
+
return this.recipient;
|
|
484
|
+
}
|
|
485
|
+
//////////////////////////////
|
|
486
|
+
//// Swap ticks & sync
|
|
487
|
+
/**
|
|
488
|
+
* @inheritDoc
|
|
489
|
+
* @internal
|
|
490
|
+
*/
|
|
491
|
+
async _sync(save) {
|
|
492
|
+
if (this._state === LnForGasSwapState.PR_CREATED) {
|
|
493
|
+
//Check if it's maybe already paid
|
|
494
|
+
const res = await this.checkInvoicePaid(false);
|
|
495
|
+
if (res !== null) {
|
|
496
|
+
if (save)
|
|
497
|
+
await this._saveAndEmit();
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* @inheritDoc
|
|
505
|
+
* @internal
|
|
506
|
+
*/
|
|
507
|
+
_tick(save) {
|
|
508
|
+
return Promise.resolve(false);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
exports.LnForGasSwap = LnForGasSwap;
|