@atomiqlabs/lp-lib 14.0.0-dev.13 → 14.0.0-dev.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/dist/fees/IBtcFeeEstimator.d.ts +3 -3
- package/dist/fees/IBtcFeeEstimator.js +2 -2
- package/dist/index.d.ts +42 -42
- package/dist/index.js +58 -58
- package/dist/info/InfoHandler.d.ts +17 -17
- package/dist/info/InfoHandler.js +61 -61
- package/dist/plugins/IPlugin.d.ts +143 -143
- package/dist/plugins/IPlugin.js +34 -34
- package/dist/plugins/PluginManager.d.ts +112 -112
- package/dist/plugins/PluginManager.js +259 -259
- package/dist/prices/BinanceSwapPrice.d.ts +26 -26
- package/dist/prices/BinanceSwapPrice.js +92 -92
- package/dist/prices/CoinGeckoSwapPrice.d.ts +30 -30
- package/dist/prices/CoinGeckoSwapPrice.js +64 -64
- package/dist/prices/ISwapPrice.d.ts +43 -43
- package/dist/prices/ISwapPrice.js +55 -55
- package/dist/prices/OKXSwapPrice.d.ts +26 -26
- package/dist/prices/OKXSwapPrice.js +92 -92
- package/dist/storage/IIntermediaryStorage.d.ts +18 -18
- package/dist/storage/IIntermediaryStorage.js +2 -2
- package/dist/storagemanager/IntermediaryStorageManager.d.ts +19 -19
- package/dist/storagemanager/IntermediaryStorageManager.js +111 -111
- package/dist/storagemanager/StorageManager.d.ts +13 -13
- package/dist/storagemanager/StorageManager.js +64 -64
- package/dist/swaps/SwapHandler.d.ts +153 -153
- package/dist/swaps/SwapHandler.js +160 -160
- package/dist/swaps/SwapHandlerSwap.d.ts +79 -79
- package/dist/swaps/SwapHandlerSwap.js +78 -78
- package/dist/swaps/assertions/AmountAssertions.d.ts +28 -28
- package/dist/swaps/assertions/AmountAssertions.js +72 -72
- package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +76 -76
- package/dist/swaps/assertions/FromBtcAmountAssertions.js +180 -172
- package/dist/swaps/assertions/LightningAssertions.d.ts +44 -44
- package/dist/swaps/assertions/LightningAssertions.js +86 -86
- package/dist/swaps/assertions/ToBtcAmountAssertions.d.ts +53 -53
- package/dist/swaps/assertions/ToBtcAmountAssertions.js +150 -150
- package/dist/swaps/escrow/EscrowHandler.d.ts +51 -51
- package/dist/swaps/escrow/EscrowHandler.js +158 -158
- package/dist/swaps/escrow/EscrowHandlerSwap.d.ts +35 -35
- package/dist/swaps/escrow/EscrowHandlerSwap.js +69 -69
- package/dist/swaps/escrow/FromBtcBaseSwap.d.ts +14 -14
- package/dist/swaps/escrow/FromBtcBaseSwap.js +32 -32
- package/dist/swaps/escrow/FromBtcBaseSwapHandler.d.ts +102 -102
- package/dist/swaps/escrow/FromBtcBaseSwapHandler.js +210 -210
- package/dist/swaps/escrow/ToBtcBaseSwap.d.ts +36 -36
- package/dist/swaps/escrow/ToBtcBaseSwap.js +67 -67
- package/dist/swaps/escrow/ToBtcBaseSwapHandler.d.ts +53 -53
- package/dist/swaps/escrow/ToBtcBaseSwapHandler.js +81 -81
- package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.d.ts +83 -83
- package/dist/swaps/escrow/frombtc_abstract/FromBtcAbs.js +318 -318
- package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.d.ts +21 -21
- package/dist/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.js +50 -50
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.d.ts +107 -107
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.js +675 -675
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +33 -33
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.js +91 -91
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.d.ts +104 -104
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.js +659 -659
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.d.ts +55 -55
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.js +120 -120
- package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.d.ts +171 -171
- package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +706 -706
- package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.d.ts +26 -26
- package/dist/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.js +62 -62
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.d.ts +177 -177
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.js +861 -861
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +23 -23
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.js +56 -56
- package/dist/swaps/spv_vault_swap/SpvVault.d.ts +41 -41
- package/dist/swaps/spv_vault_swap/SpvVault.js +111 -111
- package/dist/swaps/spv_vault_swap/SpvVaultSwap.d.ts +67 -67
- package/dist/swaps/spv_vault_swap/SpvVaultSwap.js +158 -158
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.d.ts +68 -68
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +491 -491
- package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +52 -52
- package/dist/swaps/spv_vault_swap/SpvVaults.js +364 -364
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.d.ts +51 -51
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +650 -650
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.d.ts +52 -52
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.js +118 -118
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.d.ts +76 -76
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.js +494 -494
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +34 -34
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.js +81 -81
- package/dist/utils/Utils.d.ts +29 -29
- package/dist/utils/Utils.js +89 -89
- package/dist/utils/paramcoders/IParamReader.d.ts +5 -5
- package/dist/utils/paramcoders/IParamReader.js +2 -2
- package/dist/utils/paramcoders/IParamWriter.d.ts +4 -4
- package/dist/utils/paramcoders/IParamWriter.js +2 -2
- package/dist/utils/paramcoders/LegacyParamEncoder.d.ts +10 -10
- package/dist/utils/paramcoders/LegacyParamEncoder.js +22 -22
- package/dist/utils/paramcoders/ParamDecoder.d.ts +25 -25
- package/dist/utils/paramcoders/ParamDecoder.js +222 -222
- package/dist/utils/paramcoders/ParamEncoder.d.ts +9 -9
- package/dist/utils/paramcoders/ParamEncoder.js +22 -22
- package/dist/utils/paramcoders/SchemaVerifier.d.ts +21 -21
- package/dist/utils/paramcoders/SchemaVerifier.js +84 -84
- package/dist/utils/paramcoders/server/ServerParamDecoder.d.ts +8 -8
- package/dist/utils/paramcoders/server/ServerParamDecoder.js +107 -107
- package/dist/utils/paramcoders/server/ServerParamEncoder.d.ts +11 -11
- package/dist/utils/paramcoders/server/ServerParamEncoder.js +65 -65
- package/dist/wallets/IBitcoinWallet.d.ts +67 -67
- package/dist/wallets/IBitcoinWallet.js +2 -2
- package/dist/wallets/ILightningWallet.d.ts +117 -117
- package/dist/wallets/ILightningWallet.js +37 -37
- package/dist/wallets/ISpvVaultSigner.d.ts +7 -7
- package/dist/wallets/ISpvVaultSigner.js +2 -2
- package/package.json +36 -36
- package/src/fees/IBtcFeeEstimator.ts +6 -6
- package/src/index.ts +53 -53
- package/src/info/InfoHandler.ts +106 -106
- package/src/plugins/IPlugin.ts +168 -168
- package/src/plugins/PluginManager.ts +336 -336
- package/src/prices/BinanceSwapPrice.ts +113 -113
- package/src/prices/CoinGeckoSwapPrice.ts +87 -87
- package/src/prices/ISwapPrice.ts +88 -88
- package/src/prices/OKXSwapPrice.ts +113 -113
- package/src/storage/IIntermediaryStorage.ts +19 -19
- package/src/storagemanager/IntermediaryStorageManager.ts +118 -118
- package/src/storagemanager/StorageManager.ts +78 -78
- package/src/swaps/SwapHandler.ts +277 -277
- package/src/swaps/SwapHandlerSwap.ts +141 -141
- package/src/swaps/assertions/AmountAssertions.ts +76 -76
- package/src/swaps/assertions/FromBtcAmountAssertions.ts +246 -238
- package/src/swaps/assertions/LightningAssertions.ts +103 -103
- package/src/swaps/assertions/ToBtcAmountAssertions.ts +203 -203
- package/src/swaps/escrow/EscrowHandler.ts +179 -179
- package/src/swaps/escrow/EscrowHandlerSwap.ts +86 -86
- package/src/swaps/escrow/FromBtcBaseSwap.ts +38 -38
- package/src/swaps/escrow/FromBtcBaseSwapHandler.ts +286 -286
- package/src/swaps/escrow/ToBtcBaseSwap.ts +85 -85
- package/src/swaps/escrow/ToBtcBaseSwapHandler.ts +129 -129
- package/src/swaps/escrow/frombtc_abstract/FromBtcAbs.ts +452 -452
- package/src/swaps/escrow/frombtc_abstract/FromBtcSwapAbs.ts +61 -61
- package/src/swaps/escrow/frombtcln_abstract/FromBtcLnAbs.ts +856 -856
- package/src/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.ts +141 -141
- package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.ts +822 -822
- package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.ts +196 -196
- package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +879 -879
- package/src/swaps/escrow/tobtc_abstract/ToBtcSwapAbs.ts +102 -102
- package/src/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.ts +1110 -1110
- package/src/swaps/escrow/tobtcln_abstract/ToBtcLnSwapAbs.ts +77 -77
- package/src/swaps/spv_vault_swap/SpvVault.ts +143 -143
- package/src/swaps/spv_vault_swap/SpvVaultSwap.ts +225 -225
- package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +627 -627
- package/src/swaps/spv_vault_swap/SpvVaults.ts +435 -435
- package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +747 -747
- package/src/swaps/trusted/frombtc_trusted/FromBtcTrustedSwap.ts +185 -185
- package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.ts +590 -590
- package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrustedSwap.ts +121 -121
- package/src/utils/Utils.ts +104 -104
- package/src/utils/paramcoders/IParamReader.ts +7 -7
- package/src/utils/paramcoders/IParamWriter.ts +8 -8
- package/src/utils/paramcoders/LegacyParamEncoder.ts +27 -27
- package/src/utils/paramcoders/ParamDecoder.ts +218 -218
- package/src/utils/paramcoders/ParamEncoder.ts +29 -29
- package/src/utils/paramcoders/SchemaVerifier.ts +96 -96
- package/src/utils/paramcoders/server/ServerParamDecoder.ts +118 -118
- package/src/utils/paramcoders/server/ServerParamEncoder.ts +75 -75
- package/src/wallets/IBitcoinWallet.ts +68 -68
- package/src/wallets/ILightningWallet.ts +178 -178
- package/src/wallets/ISpvVaultSigner.ts +10 -10
|
@@ -1,494 +1,494 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FromBtcLnTrusted = void 0;
|
|
4
|
-
const crypto_1 = require("crypto");
|
|
5
|
-
const FromBtcLnTrustedSwap_1 = require("./FromBtcLnTrustedSwap");
|
|
6
|
-
const SwapHandler_1 = require("../../SwapHandler");
|
|
7
|
-
const Utils_1 = require("../../../utils/Utils");
|
|
8
|
-
const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
|
|
9
|
-
const PluginManager_1 = require("../../../plugins/PluginManager");
|
|
10
|
-
const FromBtcAmountAssertions_1 = require("../../assertions/FromBtcAmountAssertions");
|
|
11
|
-
const LightningAssertions_1 = require("../../assertions/LightningAssertions");
|
|
12
|
-
/**
|
|
13
|
-
* Swap handler handling from BTCLN swaps using submarine swaps
|
|
14
|
-
*/
|
|
15
|
-
class FromBtcLnTrusted extends SwapHandler_1.SwapHandler {
|
|
16
|
-
constructor(storageDirectory, path, chains, lightning, swapPricing, config) {
|
|
17
|
-
super(storageDirectory, path, chains, swapPricing);
|
|
18
|
-
this.type = SwapHandler_1.SwapHandlerType.FROM_BTCLN_TRUSTED;
|
|
19
|
-
this.activeSubscriptions = new Map();
|
|
20
|
-
this.processedTxIds = new Map();
|
|
21
|
-
this.lightning = lightning;
|
|
22
|
-
this.LightningAssertions = new LightningAssertions_1.LightningAssertions(this.logger, lightning);
|
|
23
|
-
this.AmountAssertions = new FromBtcAmountAssertions_1.FromBtcAmountAssertions(config, swapPricing);
|
|
24
|
-
this.config = config;
|
|
25
|
-
this.config.invoiceTimeoutSeconds = this.config.invoiceTimeoutSeconds || 90;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Unsubscribe from the pending lightning network invoice
|
|
29
|
-
*
|
|
30
|
-
* @param paymentHash
|
|
31
|
-
* @private
|
|
32
|
-
*/
|
|
33
|
-
unsubscribeInvoice(paymentHash) {
|
|
34
|
-
const controller = this.activeSubscriptions.get(paymentHash);
|
|
35
|
-
if (controller == null)
|
|
36
|
-
return false;
|
|
37
|
-
controller.abort("Unsubscribed");
|
|
38
|
-
this.activeSubscriptions.delete(paymentHash);
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Subscribe to a pending lightning network invoice
|
|
43
|
-
*
|
|
44
|
-
* @param invoiceData
|
|
45
|
-
*/
|
|
46
|
-
subscribeToInvoice(invoiceData) {
|
|
47
|
-
const hash = invoiceData.getIdentifierHash();
|
|
48
|
-
//Already subscribed
|
|
49
|
-
if (this.activeSubscriptions.has(hash))
|
|
50
|
-
return;
|
|
51
|
-
const abortController = new AbortController();
|
|
52
|
-
this.lightning.waitForInvoice(hash, abortController.signal).then(invoice => {
|
|
53
|
-
this.swapLogger.debug(invoiceData, "subscribeToInvoice(): invoice_updated: ", invoice);
|
|
54
|
-
if (invoice.status !== "held")
|
|
55
|
-
return;
|
|
56
|
-
this.htlcReceived(invoiceData, invoice).catch(e => this.swapLogger.error(invoiceData, "subscribeToInvoice(): Error calling htlcReceived(): ", e));
|
|
57
|
-
this.activeSubscriptions.delete(hash);
|
|
58
|
-
});
|
|
59
|
-
this.swapLogger.debug(invoiceData, "subscribeToInvoice(): Subscribed to invoice payment");
|
|
60
|
-
this.activeSubscriptions.set(hash, abortController);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @param swap
|
|
65
|
-
* @protected
|
|
66
|
-
* @returns {Promise<boolean>} Whether the invoice should be cancelled
|
|
67
|
-
*/
|
|
68
|
-
async processPastSwap(swap) {
|
|
69
|
-
if (swap.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED)
|
|
70
|
-
return true;
|
|
71
|
-
if (swap.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED)
|
|
72
|
-
return true;
|
|
73
|
-
const parsedPR = await this.lightning.parsePaymentRequest(swap.pr);
|
|
74
|
-
const invoice = await this.lightning.getInvoice(parsedPR.id);
|
|
75
|
-
switch (invoice.status) {
|
|
76
|
-
case "held":
|
|
77
|
-
try {
|
|
78
|
-
await this.htlcReceived(swap, invoice);
|
|
79
|
-
//Result is either FromBtcLnTrustedSwapState.RECEIVED or FromBtcLnTrustedSwapState.CANCELED
|
|
80
|
-
}
|
|
81
|
-
catch (e) {
|
|
82
|
-
this.swapLogger.error(swap, "processPastSwap(): Error calling htlcReceived(): ", e);
|
|
83
|
-
}
|
|
84
|
-
return false;
|
|
85
|
-
case "confirmed":
|
|
86
|
-
return false;
|
|
87
|
-
default:
|
|
88
|
-
const isInvoiceExpired = parsedPR.expiryEpochMillis < Date.now();
|
|
89
|
-
if (isInvoiceExpired) {
|
|
90
|
-
await swap.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED);
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
this.subscribeToInvoice(swap);
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
async cancelInvoices(swaps) {
|
|
98
|
-
for (let swap of swaps) {
|
|
99
|
-
//Cancel invoices
|
|
100
|
-
try {
|
|
101
|
-
const paymentHash = swap.getIdentifierHash();
|
|
102
|
-
await this.lightning.cancelHodlInvoice(paymentHash);
|
|
103
|
-
this.unsubscribeInvoice(paymentHash);
|
|
104
|
-
this.swapLogger.info(swap, "cancelInvoices(): invoice cancelled!");
|
|
105
|
-
await this.removeSwapData(swap);
|
|
106
|
-
}
|
|
107
|
-
catch (e) {
|
|
108
|
-
this.swapLogger.error(swap, "cancelInvoices(): cannot cancel hodl invoice id", e);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Checks past swaps, refunds and deletes ones that are already expired.
|
|
114
|
-
*/
|
|
115
|
-
async processPastSwaps() {
|
|
116
|
-
const cancelInvoices = [];
|
|
117
|
-
const queriedData = await this.storageManager.query([
|
|
118
|
-
{
|
|
119
|
-
key: "state",
|
|
120
|
-
value: [
|
|
121
|
-
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CREATED,
|
|
122
|
-
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED,
|
|
123
|
-
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT,
|
|
124
|
-
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED,
|
|
125
|
-
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED,
|
|
126
|
-
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED,
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
]);
|
|
130
|
-
for (let { obj: swap } of queriedData) {
|
|
131
|
-
if (await this.processPastSwap(swap))
|
|
132
|
-
cancelInvoices.push(swap);
|
|
133
|
-
}
|
|
134
|
-
await this.cancelInvoices(cancelInvoices);
|
|
135
|
-
}
|
|
136
|
-
async cancelSwapAndInvoice(swap) {
|
|
137
|
-
if (swap.state !== FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED)
|
|
138
|
-
return;
|
|
139
|
-
await swap.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED);
|
|
140
|
-
const paymentHash = swap.getIdentifierHash();
|
|
141
|
-
await this.lightning.cancelHodlInvoice(paymentHash);
|
|
142
|
-
this.unsubscribeInvoice(paymentHash);
|
|
143
|
-
await this.removeSwapData(swap);
|
|
144
|
-
this.swapLogger.info(swap, "cancelSwapAndInvoice(): swap removed & invoice cancelled, invoice: ", swap.pr);
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Saves the state of received HTLC of the lightning payment
|
|
148
|
-
*
|
|
149
|
-
* @param invoiceData
|
|
150
|
-
* @param invoice
|
|
151
|
-
*/
|
|
152
|
-
async htlcReceived(invoiceData, invoice) {
|
|
153
|
-
const { signer, chainInterface } = this.getChain(invoiceData.chainIdentifier);
|
|
154
|
-
//Important to prevent race condition and issuing 2 signed init messages at the same time
|
|
155
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CREATED) {
|
|
156
|
-
if (invoiceData.metadata != null)
|
|
157
|
-
invoiceData.metadata.times.htlcReceived = Date.now();
|
|
158
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED);
|
|
159
|
-
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
160
|
-
}
|
|
161
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED) {
|
|
162
|
-
const balance = chainInterface.getBalance(signer.getAddress(), invoiceData.token);
|
|
163
|
-
try {
|
|
164
|
-
await this.checkBalance(invoiceData.output, balance, null);
|
|
165
|
-
if (invoiceData.metadata != null)
|
|
166
|
-
invoiceData.metadata.times.htlcBalanceChecked = Date.now();
|
|
167
|
-
}
|
|
168
|
-
catch (e) {
|
|
169
|
-
await this.cancelSwapAndInvoice(invoiceData);
|
|
170
|
-
throw e;
|
|
171
|
-
}
|
|
172
|
-
if (invoiceData.state !== FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED)
|
|
173
|
-
return;
|
|
174
|
-
const txns = await chainInterface.txsTransfer(signer.getAddress(), invoiceData.token, invoiceData.output, invoiceData.dstAddress);
|
|
175
|
-
let unlock = invoiceData.lock(Infinity);
|
|
176
|
-
if (unlock == null)
|
|
177
|
-
return;
|
|
178
|
-
const result = await chainInterface.sendAndConfirm(signer, txns, true, null, false, async (txId, rawTx) => {
|
|
179
|
-
invoiceData.txIds = { init: txId };
|
|
180
|
-
invoiceData.scRawTx = rawTx;
|
|
181
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED) {
|
|
182
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT);
|
|
183
|
-
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
184
|
-
}
|
|
185
|
-
}).catch(e => this.swapLogger.error(invoiceData, "htlcReceived(): Error sending transfer txns", e));
|
|
186
|
-
if (result == null) {
|
|
187
|
-
//Cancel invoice
|
|
188
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED);
|
|
189
|
-
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
190
|
-
await this.lightning.cancelHodlInvoice(invoice.id);
|
|
191
|
-
this.unsubscribeInvoice(invoice.id);
|
|
192
|
-
await this.removeSwapData(invoice.id, null);
|
|
193
|
-
this.swapLogger.info(invoiceData, "htlcReceived(): transaction sending failed, refunding lightning: ", invoiceData.pr);
|
|
194
|
-
throw {
|
|
195
|
-
code: 20002,
|
|
196
|
-
msg: "Transaction sending failed"
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
//Successfully paid
|
|
201
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED);
|
|
202
|
-
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
203
|
-
}
|
|
204
|
-
unlock();
|
|
205
|
-
unlock = null;
|
|
206
|
-
}
|
|
207
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT) {
|
|
208
|
-
if (invoiceData.isLocked())
|
|
209
|
-
return;
|
|
210
|
-
const txStatus = await chainInterface.getTxStatus(invoiceData.scRawTx);
|
|
211
|
-
if (txStatus === "not_found") {
|
|
212
|
-
//Retry
|
|
213
|
-
invoiceData.txIds = { init: null };
|
|
214
|
-
invoiceData.scRawTx = null;
|
|
215
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED);
|
|
216
|
-
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
217
|
-
}
|
|
218
|
-
if (txStatus === "reverted") {
|
|
219
|
-
//Cancel invoice
|
|
220
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED);
|
|
221
|
-
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
222
|
-
await this.lightning.cancelHodlInvoice(invoice.id);
|
|
223
|
-
this.unsubscribeInvoice(invoice.id);
|
|
224
|
-
await this.removeSwapData(invoice.id, null);
|
|
225
|
-
this.swapLogger.info(invoiceData, "htlcReceived(): transaction reverted, refunding lightning: ", invoiceData.pr);
|
|
226
|
-
throw {
|
|
227
|
-
code: 20002,
|
|
228
|
-
msg: "Transaction reverted"
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
if (txStatus === "success") {
|
|
232
|
-
//Successfully paid
|
|
233
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED);
|
|
234
|
-
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED) {
|
|
238
|
-
await this.lightning.settleHodlInvoice(invoiceData.secret);
|
|
239
|
-
if (invoiceData.metadata != null)
|
|
240
|
-
invoiceData.metadata.times.htlcSettled = Date.now();
|
|
241
|
-
const paymentHash = invoiceData.getIdentifierHash();
|
|
242
|
-
this.processedTxIds.set(paymentHash, invoiceData.txIds.init);
|
|
243
|
-
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SETTLED);
|
|
244
|
-
this.unsubscribeInvoice(paymentHash);
|
|
245
|
-
this.swapLogger.info(invoiceData, "htlcReceived(): invoice settled, invoice: " + invoiceData.pr + " scTxId: " + invoiceData.txIds.init);
|
|
246
|
-
await this.removeSwapData(invoiceData);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
*
|
|
251
|
-
* Checks if the lightning invoice is in HELD state (htlcs received but yet unclaimed)
|
|
252
|
-
*
|
|
253
|
-
* @param paymentHash
|
|
254
|
-
* @throws {DefinedRuntimeError} Will throw if the lightning invoice is not found, or if it isn't in the HELD state
|
|
255
|
-
* @returns the fetched lightning invoice
|
|
256
|
-
*/
|
|
257
|
-
async checkInvoiceStatus(paymentHash) {
|
|
258
|
-
const invoice = await this.lightning.getInvoice(paymentHash);
|
|
259
|
-
const isInvoiceFound = invoice != null;
|
|
260
|
-
if (!isInvoiceFound)
|
|
261
|
-
throw {
|
|
262
|
-
_httpStatus: 200,
|
|
263
|
-
code: 10001,
|
|
264
|
-
msg: "Invoice expired/canceled"
|
|
265
|
-
};
|
|
266
|
-
const arr = invoice.description.split("-");
|
|
267
|
-
let chainIdentifier;
|
|
268
|
-
let address;
|
|
269
|
-
if (arr.length > 2 && arr[1] === "GAS") {
|
|
270
|
-
chainIdentifier = arr[0];
|
|
271
|
-
address = arr[2];
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
chainIdentifier = this.chains.default;
|
|
275
|
-
address = invoice.description;
|
|
276
|
-
}
|
|
277
|
-
const { chainInterface } = this.getChain(chainIdentifier);
|
|
278
|
-
if (!chainInterface.isValidAddress(address))
|
|
279
|
-
throw {
|
|
280
|
-
_httpStatus: 200,
|
|
281
|
-
code: 10001,
|
|
282
|
-
msg: "Invoice expired/canceled"
|
|
283
|
-
};
|
|
284
|
-
switch (invoice.status) {
|
|
285
|
-
case "held":
|
|
286
|
-
return invoice;
|
|
287
|
-
case "canceled":
|
|
288
|
-
throw {
|
|
289
|
-
_httpStatus: 200,
|
|
290
|
-
code: 10001,
|
|
291
|
-
msg: "Invoice expired/canceled"
|
|
292
|
-
};
|
|
293
|
-
case "confirmed":
|
|
294
|
-
throw {
|
|
295
|
-
_httpStatus: 200,
|
|
296
|
-
code: 10000,
|
|
297
|
-
msg: "Invoice already paid",
|
|
298
|
-
data: {
|
|
299
|
-
txId: this.processedTxIds.get(paymentHash)
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
case "unpaid":
|
|
303
|
-
throw {
|
|
304
|
-
_httpStatus: 200,
|
|
305
|
-
code: 10010,
|
|
306
|
-
msg: "Invoice yet unpaid"
|
|
307
|
-
};
|
|
308
|
-
default:
|
|
309
|
-
throw new Error("Lightning invoice invalid state!");
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
startRestServer(restServer) {
|
|
313
|
-
const createInvoice = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
314
|
-
var _a;
|
|
315
|
-
const metadata = { request: {}, times: {} };
|
|
316
|
-
const chainIdentifier = req.query.chain ?? this.chains.default;
|
|
317
|
-
const { signer, chainInterface } = this.getChain(chainIdentifier);
|
|
318
|
-
metadata.times.requestReceived = Date.now();
|
|
319
|
-
/**
|
|
320
|
-
* address: string solana address of the recipient
|
|
321
|
-
* amount: string amount (in lamports/smart chain base units) of the invoice
|
|
322
|
-
*/
|
|
323
|
-
(_a = req.query).token ?? (_a.token = chainInterface.getNativeCurrencyAddress());
|
|
324
|
-
const parsedBody = (0, SchemaVerifier_1.verifySchema)(req.query, {
|
|
325
|
-
address: (val) => val != null &&
|
|
326
|
-
typeof (val) === "string" &&
|
|
327
|
-
chainInterface.isValidAddress(val) ? val : null,
|
|
328
|
-
token: (val) => val != null &&
|
|
329
|
-
typeof (val) === "string" &&
|
|
330
|
-
this.isTokenSupported(chainIdentifier, val) ? val : null,
|
|
331
|
-
amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
|
|
332
|
-
exactIn: (val) => val === "true" ? true :
|
|
333
|
-
(val === "false" || val === undefined) ? false : null
|
|
334
|
-
});
|
|
335
|
-
if (parsedBody == null)
|
|
336
|
-
throw {
|
|
337
|
-
code: 20100,
|
|
338
|
-
msg: "Invalid request body"
|
|
339
|
-
};
|
|
340
|
-
metadata.request = parsedBody;
|
|
341
|
-
const requestedAmount = { input: parsedBody.exactIn, amount: parsedBody.amount, token: parsedBody.token };
|
|
342
|
-
const request = {
|
|
343
|
-
chainIdentifier,
|
|
344
|
-
raw: req,
|
|
345
|
-
parsed: parsedBody,
|
|
346
|
-
metadata
|
|
347
|
-
};
|
|
348
|
-
const useToken = parsedBody.token;
|
|
349
|
-
//Check request params
|
|
350
|
-
const fees = await this.AmountAssertions.preCheckFromBtcAmounts(this.type, request, requestedAmount);
|
|
351
|
-
metadata.times.requestChecked = Date.now();
|
|
352
|
-
//Create abortController for parallel prefetches
|
|
353
|
-
const responseStream = res.responseStream;
|
|
354
|
-
const abortController = (0, Utils_1.getAbortController)(responseStream);
|
|
355
|
-
//Pre-fetch data
|
|
356
|
-
const pricePrefetchPromise = this.swapPricing.preFetchPrice(useToken, chainIdentifier).catch(e => {
|
|
357
|
-
this.logger.error("pricePrefetchPromise(): pricePrefetch error: ", e);
|
|
358
|
-
abortController.abort(e);
|
|
359
|
-
return null;
|
|
360
|
-
});
|
|
361
|
-
const balancePrefetch = chainInterface.getBalance(signer.getAddress(), useToken).catch(e => {
|
|
362
|
-
this.logger.error("getBalancePrefetch(): balancePrefetch error: ", e);
|
|
363
|
-
abortController.abort(e);
|
|
364
|
-
return null;
|
|
365
|
-
});
|
|
366
|
-
const channelsPrefetch = this.LightningAssertions.getChannelsPrefetch(abortController);
|
|
367
|
-
//Check valid amount specified (min/max)
|
|
368
|
-
const { amountBD, swapFee, swapFeeInToken, totalInToken } = await this.AmountAssertions.checkFromBtcAmount(this.type, request, { ...requestedAmount, pricePrefetch: pricePrefetchPromise }, fees, abortController.signal);
|
|
369
|
-
metadata.times.priceCalculated = Date.now();
|
|
370
|
-
//Check if we have enough funds to honor the request
|
|
371
|
-
await this.checkBalance(totalInToken, balancePrefetch, abortController.signal);
|
|
372
|
-
await this.LightningAssertions.checkInboundLiquidity(amountBD, channelsPrefetch, abortController.signal);
|
|
373
|
-
metadata.times.balanceChecked = Date.now();
|
|
374
|
-
const secret = (0, crypto_1.randomBytes)(32);
|
|
375
|
-
const hash = (0, crypto_1.createHash)("sha256").update(secret).digest();
|
|
376
|
-
const hodlInvoiceObj = {
|
|
377
|
-
description: chainIdentifier + "-GAS-" + parsedBody.address,
|
|
378
|
-
cltvDelta: Number(this.config.minCltv) + 5,
|
|
379
|
-
expiresAt: Date.now() + (this.config.invoiceTimeoutSeconds * 1000),
|
|
380
|
-
id: hash.toString("hex"),
|
|
381
|
-
mtokens: amountBD * 1000n
|
|
382
|
-
};
|
|
383
|
-
metadata.invoiceRequest = hodlInvoiceObj;
|
|
384
|
-
const hodlInvoice = await this.lightning.createHodlInvoice(hodlInvoiceObj);
|
|
385
|
-
abortController.signal.throwIfAborted();
|
|
386
|
-
metadata.times.invoiceCreated = Date.now();
|
|
387
|
-
metadata.invoiceResponse = { ...hodlInvoice };
|
|
388
|
-
const createdSwap = new FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwap(chainIdentifier, hodlInvoice.request, hodlInvoice.mtokens, swapFee, swapFeeInToken, totalInToken, secret.toString("hex"), parsedBody.address, useToken);
|
|
389
|
-
metadata.times.swapCreated = Date.now();
|
|
390
|
-
createdSwap.metadata = metadata;
|
|
391
|
-
await PluginManager_1.PluginManager.swapCreate(createdSwap);
|
|
392
|
-
await this.storageManager.saveData(hash.toString("hex"), null, createdSwap);
|
|
393
|
-
this.subscribeToInvoice(createdSwap);
|
|
394
|
-
this.swapLogger.info(createdSwap, "REST: /createInvoice: Created swap invoice: " + hodlInvoice.request + " amount: " + amountBD.toString(10));
|
|
395
|
-
res.status(200).json({
|
|
396
|
-
msg: "Success",
|
|
397
|
-
code: 10000,
|
|
398
|
-
data: {
|
|
399
|
-
pr: hodlInvoice.request,
|
|
400
|
-
amountSats: amountBD.toString(10),
|
|
401
|
-
swapFeeSats: swapFee.toString(10),
|
|
402
|
-
swapFee: swapFeeInToken.toString(10),
|
|
403
|
-
total: totalInToken.toString(10),
|
|
404
|
-
intermediaryKey: signer.getAddress()
|
|
405
|
-
}
|
|
406
|
-
});
|
|
407
|
-
});
|
|
408
|
-
restServer.get(this.path + "/createInvoice", createInvoice);
|
|
409
|
-
const getInvoiceStatus = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
410
|
-
/**
|
|
411
|
-
* paymentHash: string payment hash of the invoice
|
|
412
|
-
*/
|
|
413
|
-
const parsedBody = (0, SchemaVerifier_1.verifySchema)({ ...req.body, ...req.query }, {
|
|
414
|
-
paymentHash: (val) => val != null &&
|
|
415
|
-
typeof (val) === "string" &&
|
|
416
|
-
val.length === 64 &&
|
|
417
|
-
Utils_1.HEX_REGEX.test(val) ? val : null,
|
|
418
|
-
});
|
|
419
|
-
await this.checkInvoiceStatus(parsedBody.paymentHash);
|
|
420
|
-
const invoiceData = await this.storageManager.getData(parsedBody.paymentHash, null);
|
|
421
|
-
if (invoiceData == null)
|
|
422
|
-
throw {
|
|
423
|
-
_httpStatus: 200,
|
|
424
|
-
code: 10001,
|
|
425
|
-
msg: "Invoice expired/canceled"
|
|
426
|
-
};
|
|
427
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED ||
|
|
428
|
-
invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED)
|
|
429
|
-
throw {
|
|
430
|
-
_httpStatus: 200,
|
|
431
|
-
code: 10001,
|
|
432
|
-
msg: "Invoice expired/canceled"
|
|
433
|
-
};
|
|
434
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CREATED)
|
|
435
|
-
throw {
|
|
436
|
-
_httpStatus: 200,
|
|
437
|
-
code: 10010,
|
|
438
|
-
msg: "Invoice yet unpaid"
|
|
439
|
-
};
|
|
440
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED)
|
|
441
|
-
throw {
|
|
442
|
-
_httpStatus: 200,
|
|
443
|
-
code: 10011,
|
|
444
|
-
msg: "Invoice received, payment processing"
|
|
445
|
-
};
|
|
446
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT)
|
|
447
|
-
throw {
|
|
448
|
-
_httpStatus: 200,
|
|
449
|
-
code: 10012,
|
|
450
|
-
msg: "Tx sent",
|
|
451
|
-
data: {
|
|
452
|
-
txId: invoiceData.txIds.init
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED)
|
|
456
|
-
throw {
|
|
457
|
-
_httpStatus: 200,
|
|
458
|
-
code: 10000,
|
|
459
|
-
msg: "Success, tx confirmed",
|
|
460
|
-
data: {
|
|
461
|
-
txId: invoiceData.txIds.init
|
|
462
|
-
}
|
|
463
|
-
};
|
|
464
|
-
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SETTLED)
|
|
465
|
-
throw {
|
|
466
|
-
_httpStatus: 200,
|
|
467
|
-
code: 10000,
|
|
468
|
-
msg: "Success, tx confirmed - invoice settled",
|
|
469
|
-
data: {
|
|
470
|
-
txId: invoiceData.txIds.init
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
});
|
|
474
|
-
restServer.get(this.path + "/getInvoiceStatus", getInvoiceStatus);
|
|
475
|
-
this.logger.info("started at path: ", this.path);
|
|
476
|
-
}
|
|
477
|
-
async init() {
|
|
478
|
-
await this.storageManager.loadData(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwap);
|
|
479
|
-
//Check if all swaps contain a valid amount
|
|
480
|
-
for (let { obj: swap } of await this.storageManager.query([])) {
|
|
481
|
-
if (swap.amount == null) {
|
|
482
|
-
const parsedPR = await this.lightning.parsePaymentRequest(swap.pr);
|
|
483
|
-
swap.amount = (parsedPR.mtokens + 999n) / 1000n;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
await PluginManager_1.PluginManager.serviceInitialize(this);
|
|
487
|
-
}
|
|
488
|
-
getInfoData() {
|
|
489
|
-
return {
|
|
490
|
-
minCltv: Number(this.config.minCltv)
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
exports.FromBtcLnTrusted = FromBtcLnTrusted;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FromBtcLnTrusted = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const FromBtcLnTrustedSwap_1 = require("./FromBtcLnTrustedSwap");
|
|
6
|
+
const SwapHandler_1 = require("../../SwapHandler");
|
|
7
|
+
const Utils_1 = require("../../../utils/Utils");
|
|
8
|
+
const SchemaVerifier_1 = require("../../../utils/paramcoders/SchemaVerifier");
|
|
9
|
+
const PluginManager_1 = require("../../../plugins/PluginManager");
|
|
10
|
+
const FromBtcAmountAssertions_1 = require("../../assertions/FromBtcAmountAssertions");
|
|
11
|
+
const LightningAssertions_1 = require("../../assertions/LightningAssertions");
|
|
12
|
+
/**
|
|
13
|
+
* Swap handler handling from BTCLN swaps using submarine swaps
|
|
14
|
+
*/
|
|
15
|
+
class FromBtcLnTrusted extends SwapHandler_1.SwapHandler {
|
|
16
|
+
constructor(storageDirectory, path, chains, lightning, swapPricing, config) {
|
|
17
|
+
super(storageDirectory, path, chains, swapPricing);
|
|
18
|
+
this.type = SwapHandler_1.SwapHandlerType.FROM_BTCLN_TRUSTED;
|
|
19
|
+
this.activeSubscriptions = new Map();
|
|
20
|
+
this.processedTxIds = new Map();
|
|
21
|
+
this.lightning = lightning;
|
|
22
|
+
this.LightningAssertions = new LightningAssertions_1.LightningAssertions(this.logger, lightning);
|
|
23
|
+
this.AmountAssertions = new FromBtcAmountAssertions_1.FromBtcAmountAssertions(config, swapPricing);
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.config.invoiceTimeoutSeconds = this.config.invoiceTimeoutSeconds || 90;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Unsubscribe from the pending lightning network invoice
|
|
29
|
+
*
|
|
30
|
+
* @param paymentHash
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
unsubscribeInvoice(paymentHash) {
|
|
34
|
+
const controller = this.activeSubscriptions.get(paymentHash);
|
|
35
|
+
if (controller == null)
|
|
36
|
+
return false;
|
|
37
|
+
controller.abort("Unsubscribed");
|
|
38
|
+
this.activeSubscriptions.delete(paymentHash);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Subscribe to a pending lightning network invoice
|
|
43
|
+
*
|
|
44
|
+
* @param invoiceData
|
|
45
|
+
*/
|
|
46
|
+
subscribeToInvoice(invoiceData) {
|
|
47
|
+
const hash = invoiceData.getIdentifierHash();
|
|
48
|
+
//Already subscribed
|
|
49
|
+
if (this.activeSubscriptions.has(hash))
|
|
50
|
+
return;
|
|
51
|
+
const abortController = new AbortController();
|
|
52
|
+
this.lightning.waitForInvoice(hash, abortController.signal).then(invoice => {
|
|
53
|
+
this.swapLogger.debug(invoiceData, "subscribeToInvoice(): invoice_updated: ", invoice);
|
|
54
|
+
if (invoice.status !== "held")
|
|
55
|
+
return;
|
|
56
|
+
this.htlcReceived(invoiceData, invoice).catch(e => this.swapLogger.error(invoiceData, "subscribeToInvoice(): Error calling htlcReceived(): ", e));
|
|
57
|
+
this.activeSubscriptions.delete(hash);
|
|
58
|
+
});
|
|
59
|
+
this.swapLogger.debug(invoiceData, "subscribeToInvoice(): Subscribed to invoice payment");
|
|
60
|
+
this.activeSubscriptions.set(hash, abortController);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param swap
|
|
65
|
+
* @protected
|
|
66
|
+
* @returns {Promise<boolean>} Whether the invoice should be cancelled
|
|
67
|
+
*/
|
|
68
|
+
async processPastSwap(swap) {
|
|
69
|
+
if (swap.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED)
|
|
70
|
+
return true;
|
|
71
|
+
if (swap.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED)
|
|
72
|
+
return true;
|
|
73
|
+
const parsedPR = await this.lightning.parsePaymentRequest(swap.pr);
|
|
74
|
+
const invoice = await this.lightning.getInvoice(parsedPR.id);
|
|
75
|
+
switch (invoice.status) {
|
|
76
|
+
case "held":
|
|
77
|
+
try {
|
|
78
|
+
await this.htlcReceived(swap, invoice);
|
|
79
|
+
//Result is either FromBtcLnTrustedSwapState.RECEIVED or FromBtcLnTrustedSwapState.CANCELED
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
this.swapLogger.error(swap, "processPastSwap(): Error calling htlcReceived(): ", e);
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
case "confirmed":
|
|
86
|
+
return false;
|
|
87
|
+
default:
|
|
88
|
+
const isInvoiceExpired = parsedPR.expiryEpochMillis < Date.now();
|
|
89
|
+
if (isInvoiceExpired) {
|
|
90
|
+
await swap.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
this.subscribeToInvoice(swap);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async cancelInvoices(swaps) {
|
|
98
|
+
for (let swap of swaps) {
|
|
99
|
+
//Cancel invoices
|
|
100
|
+
try {
|
|
101
|
+
const paymentHash = swap.getIdentifierHash();
|
|
102
|
+
await this.lightning.cancelHodlInvoice(paymentHash);
|
|
103
|
+
this.unsubscribeInvoice(paymentHash);
|
|
104
|
+
this.swapLogger.info(swap, "cancelInvoices(): invoice cancelled!");
|
|
105
|
+
await this.removeSwapData(swap);
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
this.swapLogger.error(swap, "cancelInvoices(): cannot cancel hodl invoice id", e);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Checks past swaps, refunds and deletes ones that are already expired.
|
|
114
|
+
*/
|
|
115
|
+
async processPastSwaps() {
|
|
116
|
+
const cancelInvoices = [];
|
|
117
|
+
const queriedData = await this.storageManager.query([
|
|
118
|
+
{
|
|
119
|
+
key: "state",
|
|
120
|
+
value: [
|
|
121
|
+
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CREATED,
|
|
122
|
+
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED,
|
|
123
|
+
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT,
|
|
124
|
+
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED,
|
|
125
|
+
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED,
|
|
126
|
+
FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED,
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
]);
|
|
130
|
+
for (let { obj: swap } of queriedData) {
|
|
131
|
+
if (await this.processPastSwap(swap))
|
|
132
|
+
cancelInvoices.push(swap);
|
|
133
|
+
}
|
|
134
|
+
await this.cancelInvoices(cancelInvoices);
|
|
135
|
+
}
|
|
136
|
+
async cancelSwapAndInvoice(swap) {
|
|
137
|
+
if (swap.state !== FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED)
|
|
138
|
+
return;
|
|
139
|
+
await swap.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED);
|
|
140
|
+
const paymentHash = swap.getIdentifierHash();
|
|
141
|
+
await this.lightning.cancelHodlInvoice(paymentHash);
|
|
142
|
+
this.unsubscribeInvoice(paymentHash);
|
|
143
|
+
await this.removeSwapData(swap);
|
|
144
|
+
this.swapLogger.info(swap, "cancelSwapAndInvoice(): swap removed & invoice cancelled, invoice: ", swap.pr);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Saves the state of received HTLC of the lightning payment
|
|
148
|
+
*
|
|
149
|
+
* @param invoiceData
|
|
150
|
+
* @param invoice
|
|
151
|
+
*/
|
|
152
|
+
async htlcReceived(invoiceData, invoice) {
|
|
153
|
+
const { signer, chainInterface } = this.getChain(invoiceData.chainIdentifier);
|
|
154
|
+
//Important to prevent race condition and issuing 2 signed init messages at the same time
|
|
155
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CREATED) {
|
|
156
|
+
if (invoiceData.metadata != null)
|
|
157
|
+
invoiceData.metadata.times.htlcReceived = Date.now();
|
|
158
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED);
|
|
159
|
+
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
160
|
+
}
|
|
161
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED) {
|
|
162
|
+
const balance = chainInterface.getBalance(signer.getAddress(), invoiceData.token);
|
|
163
|
+
try {
|
|
164
|
+
await this.checkBalance(invoiceData.output, balance, null);
|
|
165
|
+
if (invoiceData.metadata != null)
|
|
166
|
+
invoiceData.metadata.times.htlcBalanceChecked = Date.now();
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
await this.cancelSwapAndInvoice(invoiceData);
|
|
170
|
+
throw e;
|
|
171
|
+
}
|
|
172
|
+
if (invoiceData.state !== FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED)
|
|
173
|
+
return;
|
|
174
|
+
const txns = await chainInterface.txsTransfer(signer.getAddress(), invoiceData.token, invoiceData.output, invoiceData.dstAddress);
|
|
175
|
+
let unlock = invoiceData.lock(Infinity);
|
|
176
|
+
if (unlock == null)
|
|
177
|
+
return;
|
|
178
|
+
const result = await chainInterface.sendAndConfirm(signer, txns, true, null, false, async (txId, rawTx) => {
|
|
179
|
+
invoiceData.txIds = { init: txId };
|
|
180
|
+
invoiceData.scRawTx = rawTx;
|
|
181
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED) {
|
|
182
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT);
|
|
183
|
+
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
184
|
+
}
|
|
185
|
+
}).catch(e => this.swapLogger.error(invoiceData, "htlcReceived(): Error sending transfer txns", e));
|
|
186
|
+
if (result == null) {
|
|
187
|
+
//Cancel invoice
|
|
188
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED);
|
|
189
|
+
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
190
|
+
await this.lightning.cancelHodlInvoice(invoice.id);
|
|
191
|
+
this.unsubscribeInvoice(invoice.id);
|
|
192
|
+
await this.removeSwapData(invoice.id, null);
|
|
193
|
+
this.swapLogger.info(invoiceData, "htlcReceived(): transaction sending failed, refunding lightning: ", invoiceData.pr);
|
|
194
|
+
throw {
|
|
195
|
+
code: 20002,
|
|
196
|
+
msg: "Transaction sending failed"
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
//Successfully paid
|
|
201
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED);
|
|
202
|
+
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
203
|
+
}
|
|
204
|
+
unlock();
|
|
205
|
+
unlock = null;
|
|
206
|
+
}
|
|
207
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT) {
|
|
208
|
+
if (invoiceData.isLocked())
|
|
209
|
+
return;
|
|
210
|
+
const txStatus = await chainInterface.getTxStatus(invoiceData.scRawTx);
|
|
211
|
+
if (txStatus === "not_found") {
|
|
212
|
+
//Retry
|
|
213
|
+
invoiceData.txIds = { init: null };
|
|
214
|
+
invoiceData.scRawTx = null;
|
|
215
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED);
|
|
216
|
+
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
217
|
+
}
|
|
218
|
+
if (txStatus === "reverted") {
|
|
219
|
+
//Cancel invoice
|
|
220
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED);
|
|
221
|
+
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
222
|
+
await this.lightning.cancelHodlInvoice(invoice.id);
|
|
223
|
+
this.unsubscribeInvoice(invoice.id);
|
|
224
|
+
await this.removeSwapData(invoice.id, null);
|
|
225
|
+
this.swapLogger.info(invoiceData, "htlcReceived(): transaction reverted, refunding lightning: ", invoiceData.pr);
|
|
226
|
+
throw {
|
|
227
|
+
code: 20002,
|
|
228
|
+
msg: "Transaction reverted"
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
if (txStatus === "success") {
|
|
232
|
+
//Successfully paid
|
|
233
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED);
|
|
234
|
+
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED) {
|
|
238
|
+
await this.lightning.settleHodlInvoice(invoiceData.secret);
|
|
239
|
+
if (invoiceData.metadata != null)
|
|
240
|
+
invoiceData.metadata.times.htlcSettled = Date.now();
|
|
241
|
+
const paymentHash = invoiceData.getIdentifierHash();
|
|
242
|
+
this.processedTxIds.set(paymentHash, invoiceData.txIds.init);
|
|
243
|
+
await invoiceData.setState(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SETTLED);
|
|
244
|
+
this.unsubscribeInvoice(paymentHash);
|
|
245
|
+
this.swapLogger.info(invoiceData, "htlcReceived(): invoice settled, invoice: " + invoiceData.pr + " scTxId: " + invoiceData.txIds.init);
|
|
246
|
+
await this.removeSwapData(invoiceData);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
*
|
|
251
|
+
* Checks if the lightning invoice is in HELD state (htlcs received but yet unclaimed)
|
|
252
|
+
*
|
|
253
|
+
* @param paymentHash
|
|
254
|
+
* @throws {DefinedRuntimeError} Will throw if the lightning invoice is not found, or if it isn't in the HELD state
|
|
255
|
+
* @returns the fetched lightning invoice
|
|
256
|
+
*/
|
|
257
|
+
async checkInvoiceStatus(paymentHash) {
|
|
258
|
+
const invoice = await this.lightning.getInvoice(paymentHash);
|
|
259
|
+
const isInvoiceFound = invoice != null;
|
|
260
|
+
if (!isInvoiceFound)
|
|
261
|
+
throw {
|
|
262
|
+
_httpStatus: 200,
|
|
263
|
+
code: 10001,
|
|
264
|
+
msg: "Invoice expired/canceled"
|
|
265
|
+
};
|
|
266
|
+
const arr = invoice.description.split("-");
|
|
267
|
+
let chainIdentifier;
|
|
268
|
+
let address;
|
|
269
|
+
if (arr.length > 2 && arr[1] === "GAS") {
|
|
270
|
+
chainIdentifier = arr[0];
|
|
271
|
+
address = arr[2];
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
chainIdentifier = this.chains.default;
|
|
275
|
+
address = invoice.description;
|
|
276
|
+
}
|
|
277
|
+
const { chainInterface } = this.getChain(chainIdentifier);
|
|
278
|
+
if (!chainInterface.isValidAddress(address))
|
|
279
|
+
throw {
|
|
280
|
+
_httpStatus: 200,
|
|
281
|
+
code: 10001,
|
|
282
|
+
msg: "Invoice expired/canceled"
|
|
283
|
+
};
|
|
284
|
+
switch (invoice.status) {
|
|
285
|
+
case "held":
|
|
286
|
+
return invoice;
|
|
287
|
+
case "canceled":
|
|
288
|
+
throw {
|
|
289
|
+
_httpStatus: 200,
|
|
290
|
+
code: 10001,
|
|
291
|
+
msg: "Invoice expired/canceled"
|
|
292
|
+
};
|
|
293
|
+
case "confirmed":
|
|
294
|
+
throw {
|
|
295
|
+
_httpStatus: 200,
|
|
296
|
+
code: 10000,
|
|
297
|
+
msg: "Invoice already paid",
|
|
298
|
+
data: {
|
|
299
|
+
txId: this.processedTxIds.get(paymentHash)
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
case "unpaid":
|
|
303
|
+
throw {
|
|
304
|
+
_httpStatus: 200,
|
|
305
|
+
code: 10010,
|
|
306
|
+
msg: "Invoice yet unpaid"
|
|
307
|
+
};
|
|
308
|
+
default:
|
|
309
|
+
throw new Error("Lightning invoice invalid state!");
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
startRestServer(restServer) {
|
|
313
|
+
const createInvoice = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
314
|
+
var _a;
|
|
315
|
+
const metadata = { request: {}, times: {} };
|
|
316
|
+
const chainIdentifier = req.query.chain ?? this.chains.default;
|
|
317
|
+
const { signer, chainInterface } = this.getChain(chainIdentifier);
|
|
318
|
+
metadata.times.requestReceived = Date.now();
|
|
319
|
+
/**
|
|
320
|
+
* address: string solana address of the recipient
|
|
321
|
+
* amount: string amount (in lamports/smart chain base units) of the invoice
|
|
322
|
+
*/
|
|
323
|
+
(_a = req.query).token ?? (_a.token = chainInterface.getNativeCurrencyAddress());
|
|
324
|
+
const parsedBody = (0, SchemaVerifier_1.verifySchema)(req.query, {
|
|
325
|
+
address: (val) => val != null &&
|
|
326
|
+
typeof (val) === "string" &&
|
|
327
|
+
chainInterface.isValidAddress(val) ? val : null,
|
|
328
|
+
token: (val) => val != null &&
|
|
329
|
+
typeof (val) === "string" &&
|
|
330
|
+
this.isTokenSupported(chainIdentifier, val) ? val : null,
|
|
331
|
+
amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
|
|
332
|
+
exactIn: (val) => val === "true" ? true :
|
|
333
|
+
(val === "false" || val === undefined) ? false : null
|
|
334
|
+
});
|
|
335
|
+
if (parsedBody == null)
|
|
336
|
+
throw {
|
|
337
|
+
code: 20100,
|
|
338
|
+
msg: "Invalid request body"
|
|
339
|
+
};
|
|
340
|
+
metadata.request = parsedBody;
|
|
341
|
+
const requestedAmount = { input: parsedBody.exactIn, amount: parsedBody.amount, token: parsedBody.token };
|
|
342
|
+
const request = {
|
|
343
|
+
chainIdentifier,
|
|
344
|
+
raw: req,
|
|
345
|
+
parsed: parsedBody,
|
|
346
|
+
metadata
|
|
347
|
+
};
|
|
348
|
+
const useToken = parsedBody.token;
|
|
349
|
+
//Check request params
|
|
350
|
+
const fees = await this.AmountAssertions.preCheckFromBtcAmounts(this.type, request, requestedAmount);
|
|
351
|
+
metadata.times.requestChecked = Date.now();
|
|
352
|
+
//Create abortController for parallel prefetches
|
|
353
|
+
const responseStream = res.responseStream;
|
|
354
|
+
const abortController = (0, Utils_1.getAbortController)(responseStream);
|
|
355
|
+
//Pre-fetch data
|
|
356
|
+
const pricePrefetchPromise = this.swapPricing.preFetchPrice(useToken, chainIdentifier).catch(e => {
|
|
357
|
+
this.logger.error("pricePrefetchPromise(): pricePrefetch error: ", e);
|
|
358
|
+
abortController.abort(e);
|
|
359
|
+
return null;
|
|
360
|
+
});
|
|
361
|
+
const balancePrefetch = chainInterface.getBalance(signer.getAddress(), useToken).catch(e => {
|
|
362
|
+
this.logger.error("getBalancePrefetch(): balancePrefetch error: ", e);
|
|
363
|
+
abortController.abort(e);
|
|
364
|
+
return null;
|
|
365
|
+
});
|
|
366
|
+
const channelsPrefetch = this.LightningAssertions.getChannelsPrefetch(abortController);
|
|
367
|
+
//Check valid amount specified (min/max)
|
|
368
|
+
const { amountBD, swapFee, swapFeeInToken, totalInToken } = await this.AmountAssertions.checkFromBtcAmount(this.type, request, { ...requestedAmount, pricePrefetch: pricePrefetchPromise }, fees, abortController.signal);
|
|
369
|
+
metadata.times.priceCalculated = Date.now();
|
|
370
|
+
//Check if we have enough funds to honor the request
|
|
371
|
+
await this.checkBalance(totalInToken, balancePrefetch, abortController.signal);
|
|
372
|
+
await this.LightningAssertions.checkInboundLiquidity(amountBD, channelsPrefetch, abortController.signal);
|
|
373
|
+
metadata.times.balanceChecked = Date.now();
|
|
374
|
+
const secret = (0, crypto_1.randomBytes)(32);
|
|
375
|
+
const hash = (0, crypto_1.createHash)("sha256").update(secret).digest();
|
|
376
|
+
const hodlInvoiceObj = {
|
|
377
|
+
description: chainIdentifier + "-GAS-" + parsedBody.address,
|
|
378
|
+
cltvDelta: Number(this.config.minCltv) + 5,
|
|
379
|
+
expiresAt: Date.now() + (this.config.invoiceTimeoutSeconds * 1000),
|
|
380
|
+
id: hash.toString("hex"),
|
|
381
|
+
mtokens: amountBD * 1000n
|
|
382
|
+
};
|
|
383
|
+
metadata.invoiceRequest = hodlInvoiceObj;
|
|
384
|
+
const hodlInvoice = await this.lightning.createHodlInvoice(hodlInvoiceObj);
|
|
385
|
+
abortController.signal.throwIfAborted();
|
|
386
|
+
metadata.times.invoiceCreated = Date.now();
|
|
387
|
+
metadata.invoiceResponse = { ...hodlInvoice };
|
|
388
|
+
const createdSwap = new FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwap(chainIdentifier, hodlInvoice.request, hodlInvoice.mtokens, swapFee, swapFeeInToken, totalInToken, secret.toString("hex"), parsedBody.address, useToken);
|
|
389
|
+
metadata.times.swapCreated = Date.now();
|
|
390
|
+
createdSwap.metadata = metadata;
|
|
391
|
+
await PluginManager_1.PluginManager.swapCreate(createdSwap);
|
|
392
|
+
await this.storageManager.saveData(hash.toString("hex"), null, createdSwap);
|
|
393
|
+
this.subscribeToInvoice(createdSwap);
|
|
394
|
+
this.swapLogger.info(createdSwap, "REST: /createInvoice: Created swap invoice: " + hodlInvoice.request + " amount: " + amountBD.toString(10));
|
|
395
|
+
res.status(200).json({
|
|
396
|
+
msg: "Success",
|
|
397
|
+
code: 10000,
|
|
398
|
+
data: {
|
|
399
|
+
pr: hodlInvoice.request,
|
|
400
|
+
amountSats: amountBD.toString(10),
|
|
401
|
+
swapFeeSats: swapFee.toString(10),
|
|
402
|
+
swapFee: swapFeeInToken.toString(10),
|
|
403
|
+
total: totalInToken.toString(10),
|
|
404
|
+
intermediaryKey: signer.getAddress()
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
restServer.get(this.path + "/createInvoice", createInvoice);
|
|
409
|
+
const getInvoiceStatus = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
410
|
+
/**
|
|
411
|
+
* paymentHash: string payment hash of the invoice
|
|
412
|
+
*/
|
|
413
|
+
const parsedBody = (0, SchemaVerifier_1.verifySchema)({ ...req.body, ...req.query }, {
|
|
414
|
+
paymentHash: (val) => val != null &&
|
|
415
|
+
typeof (val) === "string" &&
|
|
416
|
+
val.length === 64 &&
|
|
417
|
+
Utils_1.HEX_REGEX.test(val) ? val : null,
|
|
418
|
+
});
|
|
419
|
+
await this.checkInvoiceStatus(parsedBody.paymentHash);
|
|
420
|
+
const invoiceData = await this.storageManager.getData(parsedBody.paymentHash, null);
|
|
421
|
+
if (invoiceData == null)
|
|
422
|
+
throw {
|
|
423
|
+
_httpStatus: 200,
|
|
424
|
+
code: 10001,
|
|
425
|
+
msg: "Invoice expired/canceled"
|
|
426
|
+
};
|
|
427
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CANCELED ||
|
|
428
|
+
invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.REFUNDED)
|
|
429
|
+
throw {
|
|
430
|
+
_httpStatus: 200,
|
|
431
|
+
code: 10001,
|
|
432
|
+
msg: "Invoice expired/canceled"
|
|
433
|
+
};
|
|
434
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CREATED)
|
|
435
|
+
throw {
|
|
436
|
+
_httpStatus: 200,
|
|
437
|
+
code: 10010,
|
|
438
|
+
msg: "Invoice yet unpaid"
|
|
439
|
+
};
|
|
440
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.RECEIVED)
|
|
441
|
+
throw {
|
|
442
|
+
_httpStatus: 200,
|
|
443
|
+
code: 10011,
|
|
444
|
+
msg: "Invoice received, payment processing"
|
|
445
|
+
};
|
|
446
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SENT)
|
|
447
|
+
throw {
|
|
448
|
+
_httpStatus: 200,
|
|
449
|
+
code: 10012,
|
|
450
|
+
msg: "Tx sent",
|
|
451
|
+
data: {
|
|
452
|
+
txId: invoiceData.txIds.init
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.CONFIRMED)
|
|
456
|
+
throw {
|
|
457
|
+
_httpStatus: 200,
|
|
458
|
+
code: 10000,
|
|
459
|
+
msg: "Success, tx confirmed",
|
|
460
|
+
data: {
|
|
461
|
+
txId: invoiceData.txIds.init
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
if (invoiceData.state === FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwapState.SETTLED)
|
|
465
|
+
throw {
|
|
466
|
+
_httpStatus: 200,
|
|
467
|
+
code: 10000,
|
|
468
|
+
msg: "Success, tx confirmed - invoice settled",
|
|
469
|
+
data: {
|
|
470
|
+
txId: invoiceData.txIds.init
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
});
|
|
474
|
+
restServer.get(this.path + "/getInvoiceStatus", getInvoiceStatus);
|
|
475
|
+
this.logger.info("started at path: ", this.path);
|
|
476
|
+
}
|
|
477
|
+
async init() {
|
|
478
|
+
await this.storageManager.loadData(FromBtcLnTrustedSwap_1.FromBtcLnTrustedSwap);
|
|
479
|
+
//Check if all swaps contain a valid amount
|
|
480
|
+
for (let { obj: swap } of await this.storageManager.query([])) {
|
|
481
|
+
if (swap.amount == null) {
|
|
482
|
+
const parsedPR = await this.lightning.parsePaymentRequest(swap.pr);
|
|
483
|
+
swap.amount = (parsedPR.mtokens + 999n) / 1000n;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
await PluginManager_1.PluginManager.serviceInitialize(this);
|
|
487
|
+
}
|
|
488
|
+
getInfoData() {
|
|
489
|
+
return {
|
|
490
|
+
minCltv: Number(this.config.minCltv)
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
exports.FromBtcLnTrusted = FromBtcLnTrusted;
|