@atomiqlabs/lp-lib 10.3.11 → 11.0.0
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/index.d.ts +2 -1
- package/dist/index.js +2 -4
- package/dist/plugins/IPlugin.d.ts +3 -2
- package/dist/plugins/PluginManager.d.ts +3 -2
- package/dist/plugins/PluginManager.js +2 -2
- package/dist/swaps/FromBtcBaseSwap.d.ts +5 -1
- package/dist/swaps/FromBtcBaseSwap.js +20 -0
- package/dist/swaps/FromBtcBaseSwapHandler.d.ts +1 -0
- package/dist/swaps/FromBtcBaseSwapHandler.js +1 -1
- package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +8 -6
- package/dist/swaps/FromBtcLnBaseSwapHandler.js +7 -5
- package/dist/swaps/SwapHandler.d.ts +1 -4
- package/dist/swaps/SwapHandler.js +1 -2
- package/dist/swaps/SwapHandlerSwap.d.ts +4 -0
- package/dist/swaps/SwapHandlerSwap.js +9 -1
- package/dist/swaps/ToBtcBaseSwap.d.ts +3 -1
- package/dist/swaps/ToBtcBaseSwap.js +8 -2
- package/dist/swaps/ToBtcBaseSwapHandler.d.ts +1 -0
- package/dist/swaps/ToBtcBaseSwapHandler.js +1 -1
- package/dist/swaps/frombtc_abstract/FromBtcAbs.d.ts +3 -5
- package/dist/swaps/frombtc_abstract/FromBtcAbs.js +18 -25
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.d.ts +1 -4
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.js +3 -16
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.d.ts +6 -9
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.js +238 -137
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.d.ts +9 -6
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.js +15 -10
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.d.ts +2 -2
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.js +42 -62
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +1 -6
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.js +2 -14
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.d.ts +3 -5
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.js +64 -80
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +1 -2
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.js +5 -8
- package/dist/swaps/tobtc_abstract/ToBtcAbs.d.ts +5 -125
- package/dist/swaps/tobtc_abstract/ToBtcAbs.js +41 -334
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.d.ts +1 -4
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.js +2 -11
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.d.ts +5 -55
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.js +152 -398
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +1 -6
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.js +2 -15
- package/dist/utils/Utils.d.ts +0 -10
- package/dist/utils/Utils.js +1 -34
- package/dist/wallets/IBitcoinWallet.d.ts +62 -0
- package/dist/wallets/IBitcoinWallet.js +2 -0
- package/dist/wallets/ILightningWallet.d.ts +118 -0
- package/dist/wallets/ILightningWallet.js +37 -0
- package/package.json +4 -9
- package/src/index.ts +3 -5
- package/src/plugins/IPlugin.ts +4 -2
- package/src/plugins/PluginManager.ts +6 -3
- package/src/swaps/FromBtcBaseSwap.ts +24 -1
- package/src/swaps/FromBtcBaseSwapHandler.ts +6 -2
- package/src/swaps/FromBtcLnBaseSwapHandler.ts +22 -6
- package/src/swaps/SwapHandler.ts +1 -8
- package/src/swaps/SwapHandlerSwap.ts +14 -1
- package/src/swaps/ToBtcBaseSwap.ts +12 -3
- package/src/swaps/ToBtcBaseSwapHandler.ts +6 -2
- package/src/swaps/frombtc_abstract/FromBtcAbs.ts +24 -28
- package/src/swaps/frombtc_abstract/FromBtcSwapAbs.ts +3 -18
- package/src/swaps/frombtc_trusted/FromBtcTrusted.ts +260 -159
- package/src/swaps/frombtc_trusted/FromBtcTrustedSwap.ts +22 -15
- package/src/swaps/frombtcln_abstract/FromBtcLnAbs.ts +69 -79
- package/src/swaps/frombtcln_abstract/FromBtcLnSwapAbs.ts +3 -20
- package/src/swaps/frombtcln_trusted/FromBtcLnTrusted.ts +80 -97
- package/src/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.ts +6 -9
- package/src/swaps/tobtc_abstract/ToBtcAbs.ts +52 -410
- package/src/swaps/tobtc_abstract/ToBtcSwapAbs.ts +3 -18
- package/src/swaps/tobtcln_abstract/ToBtcLnAbs.ts +157 -434
- package/src/swaps/tobtcln_abstract/ToBtcLnSwapAbs.ts +3 -20
- package/src/utils/Utils.ts +0 -31
- package/src/wallets/IBitcoinWallet.ts +66 -0
- package/src/wallets/ILightningWallet.ts +179 -0
- package/dist/fees/OneDollarFeeEstimator.d.ts +0 -16
- package/dist/fees/OneDollarFeeEstimator.js +0 -71
- package/dist/utils/coinselect2/accumulative.d.ts +0 -6
- package/dist/utils/coinselect2/accumulative.js +0 -44
- package/dist/utils/coinselect2/blackjack.d.ts +0 -6
- package/dist/utils/coinselect2/blackjack.js +0 -41
- package/dist/utils/coinselect2/index.d.ts +0 -16
- package/dist/utils/coinselect2/index.js +0 -40
- package/dist/utils/coinselect2/utils.d.ts +0 -64
- package/dist/utils/coinselect2/utils.js +0 -121
- package/src/fees/OneDollarFeeEstimator.ts +0 -95
- package/src/utils/coinselect2/accumulative.js +0 -32
- package/src/utils/coinselect2/accumulative.ts +0 -58
- package/src/utils/coinselect2/blackjack.js +0 -29
- package/src/utils/coinselect2/blackjack.ts +0 -54
- package/src/utils/coinselect2/index.js +0 -16
- package/src/utils/coinselect2/index.ts +0 -50
- package/src/utils/coinselect2/utils.js +0 -110
- package/src/utils/coinselect2/utils.ts +0 -183
|
@@ -11,8 +11,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.ToBtcLnAbs = void 0;
|
|
13
13
|
const BN = require("bn.js");
|
|
14
|
-
const bolt11 = require("@atomiqlabs/bolt11");
|
|
15
|
-
const lncli = require("ln-service");
|
|
16
14
|
const ToBtcLnSwapAbs_1 = require("./ToBtcLnSwapAbs");
|
|
17
15
|
const SwapHandler_1 = require("../SwapHandler");
|
|
18
16
|
const base_1 = require("@atomiqlabs/base");
|
|
@@ -22,52 +20,18 @@ const crypto_1 = require("crypto");
|
|
|
22
20
|
const ServerParamDecoder_1 = require("../../utils/paramcoders/server/ServerParamDecoder");
|
|
23
21
|
const SchemaVerifier_1 = require("../../utils/paramcoders/SchemaVerifier");
|
|
24
22
|
const ToBtcBaseSwapHandler_1 = require("../ToBtcBaseSwapHandler");
|
|
25
|
-
const
|
|
26
|
-
"038f8f113c580048d847d6949371726653e02b928196bad310e3eda39ff61723f6"
|
|
27
|
-
]);
|
|
28
|
-
function routesMatch(routesA, routesB) {
|
|
29
|
-
if (routesA === routesB)
|
|
30
|
-
return true;
|
|
31
|
-
if (routesA == null || routesB == null) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
if (routesA.length !== routesB.length)
|
|
35
|
-
return false;
|
|
36
|
-
for (let i = 0; i < routesA.length; i++) {
|
|
37
|
-
if (routesA[i] === routesB[i])
|
|
38
|
-
continue;
|
|
39
|
-
if (routesA[i] == null || routesB[i] == null) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
if (routesA[i].length !== routesB[i].length)
|
|
43
|
-
return false;
|
|
44
|
-
for (let e = 0; e < routesA[i].length; e++) {
|
|
45
|
-
if (routesA[i][e] === routesB[i][e])
|
|
46
|
-
continue;
|
|
47
|
-
if (routesA[i][e] == null || routesB[i][e] == null) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
if (routesA[i][e].public_key !== routesB[i][e].public_key ||
|
|
51
|
-
routesA[i][e].base_fee_mtokens !== routesB[i][e].base_fee_mtokens ||
|
|
52
|
-
routesA[i][e].channel !== routesB[i][e].channel ||
|
|
53
|
-
routesA[i][e].cltv_delta !== routesB[i][e].cltv_delta ||
|
|
54
|
-
routesA[i][e].fee_rate !== routesB[i][e].fee_rate) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
23
|
+
const ILightningWallet_1 = require("../../wallets/ILightningWallet");
|
|
61
24
|
/**
|
|
62
25
|
* Swap handler handling to BTCLN swaps using submarine swaps
|
|
63
26
|
*/
|
|
64
27
|
class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
65
|
-
constructor(storageDirectory, path, chainData,
|
|
66
|
-
super(storageDirectory, path, chainData,
|
|
28
|
+
constructor(storageDirectory, path, chainData, lightning, swapPricing, config) {
|
|
29
|
+
super(storageDirectory, path, chainData, swapPricing);
|
|
67
30
|
this.LIGHTNING_LIQUIDITY_CACHE_TIMEOUT = 5 * 1000;
|
|
68
31
|
this.activeSubscriptions = new Set();
|
|
69
32
|
this.type = SwapHandler_1.SwapHandlerType.TO_BTCLN;
|
|
70
33
|
this.exactInAuths = {};
|
|
34
|
+
this.lightning = lightning;
|
|
71
35
|
const anyConfig = config;
|
|
72
36
|
anyConfig.minTsSendCltv = config.gracePeriod.add(config.bitcoinBlocktime.mul(config.minSendCltv).mul(config.safetyFactor));
|
|
73
37
|
this.config = anyConfig;
|
|
@@ -75,27 +39,6 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
75
39
|
this.config.minLnBaseFee = this.config.minLnBaseFee || new BN(5);
|
|
76
40
|
this.config.exactInExpiry = this.config.exactInExpiry || 10 * 1000;
|
|
77
41
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Fetches the payment info, returns null if payment not found
|
|
80
|
-
*
|
|
81
|
-
* @param paymentHash
|
|
82
|
-
* @private
|
|
83
|
-
*/
|
|
84
|
-
getPayment(paymentHash) {
|
|
85
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
-
try {
|
|
87
|
-
return yield lncli.getPayment({
|
|
88
|
-
id: paymentHash,
|
|
89
|
-
lnd: this.LND
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
if (Array.isArray(e) && e[0] === 404 && e[1] === "SentPaymentNotFound")
|
|
94
|
-
return null;
|
|
95
|
-
throw e;
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
42
|
/**
|
|
100
43
|
* Cleans up exactIn authorization that are already past their expiry
|
|
101
44
|
*
|
|
@@ -112,19 +55,18 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
112
55
|
}
|
|
113
56
|
processPastSwap(swap) {
|
|
114
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
-
|
|
116
|
-
const timestamp = new BN(Math.floor(Date.now() / 1000)).sub(new BN(this.config.maxSkew));
|
|
58
|
+
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
117
59
|
if (swap.state === ToBtcLnSwapAbs_1.ToBtcLnSwapState.SAVED) {
|
|
118
60
|
//Cancel the swaps where signature is expired
|
|
119
|
-
const isSignatureExpired = swap.
|
|
61
|
+
const isSignatureExpired = yield swapContract.isInitAuthorizationExpired(swap.data, swap);
|
|
120
62
|
if (isSignatureExpired) {
|
|
121
63
|
this.swapLogger.info(swap, "processPastSwap(state=SAVED): signature expired, cancel uncommited swap, invoice: " + swap.pr);
|
|
122
64
|
yield this.removeSwapData(swap, ToBtcLnSwapAbs_1.ToBtcLnSwapState.CANCELED);
|
|
123
65
|
return;
|
|
124
66
|
}
|
|
125
67
|
//Cancel the swaps where lightning invoice is expired
|
|
126
|
-
const decodedPR =
|
|
127
|
-
const isInvoiceExpired = decodedPR.
|
|
68
|
+
const decodedPR = yield this.lightning.parsePaymentRequest(swap.pr);
|
|
69
|
+
const isInvoiceExpired = decodedPR.expiryEpochMillis < Date.now();
|
|
128
70
|
if (isInvoiceExpired) {
|
|
129
71
|
this.swapLogger.info(swap, "processPastSwap(state=SAVED): invoice expired, cancel uncommited swap, invoice: " + swap.pr);
|
|
130
72
|
yield this.removeSwapData(swap, ToBtcLnSwapAbs_1.ToBtcLnSwapState.CANCELED);
|
|
@@ -138,8 +80,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
138
80
|
if (swap.state === ToBtcLnSwapAbs_1.ToBtcLnSwapState.NON_PAYABLE) {
|
|
139
81
|
//Remove expired swaps (as these can already be unilaterally refunded by the client), so we don't need
|
|
140
82
|
// to be able to cooperatively refund them
|
|
141
|
-
|
|
142
|
-
if (isSwapExpired) {
|
|
83
|
+
if (swapContract.isExpired(signer.getAddress(), swap.data)) {
|
|
143
84
|
this.swapLogger.info(swap, "processPastSwap(state=NON_PAYABLE): swap expired, removing swap data, invoice: " + swap.pr);
|
|
144
85
|
yield this.removeSwapData(swap);
|
|
145
86
|
}
|
|
@@ -209,48 +150,46 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
209
150
|
*/
|
|
210
151
|
processPaymentResult(swap, lnPaymentStatus) {
|
|
211
152
|
return __awaiter(this, void 0, void 0, function* () {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
153
|
+
switch (lnPaymentStatus.status) {
|
|
154
|
+
case "pending":
|
|
155
|
+
return;
|
|
156
|
+
case "failed":
|
|
157
|
+
this.swapLogger.info(swap, "processPaymentResult(): invoice payment failed, cancelling swap, invoice: " + swap.pr);
|
|
158
|
+
yield swap.setState(ToBtcLnSwapAbs_1.ToBtcLnSwapState.NON_PAYABLE);
|
|
159
|
+
yield this.storageManager.saveData(swap.data.getHash(), swap.data.getSequence(), swap);
|
|
160
|
+
return;
|
|
161
|
+
case "confirmed":
|
|
162
|
+
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
163
|
+
swap.secret = lnPaymentStatus.secret;
|
|
164
|
+
swap.setRealNetworkFee(lnPaymentStatus.feeMtokens.div(new BN(1000)));
|
|
165
|
+
this.swapLogger.info(swap, "processPaymentResult(): invoice paid, secret: " + swap.secret + " realRoutingFee: " + swap.realNetworkFee.toString(10) + " invoice: " + swap.pr);
|
|
166
|
+
yield swap.setState(ToBtcLnSwapAbs_1.ToBtcLnSwapState.PAID);
|
|
167
|
+
yield this.storageManager.saveData(swap.data.getHash(), swap.data.getSequence(), swap);
|
|
168
|
+
//Check if escrow state exists
|
|
169
|
+
const isCommited = yield swapContract.isCommited(swap.data);
|
|
170
|
+
if (!isCommited) {
|
|
171
|
+
const status = yield swapContract.getCommitStatus(signer.getAddress(), swap.data);
|
|
172
|
+
if (status === base_1.SwapCommitStatus.PAID) {
|
|
173
|
+
//This is alright, we got the money
|
|
174
|
+
yield this.removeSwapData(swap, ToBtcLnSwapAbs_1.ToBtcLnSwapState.CLAIMED);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
else if (status === base_1.SwapCommitStatus.EXPIRED) {
|
|
178
|
+
//This means the user was able to refund before we were able to claim, no good
|
|
179
|
+
yield this.removeSwapData(swap, ToBtcLnSwapAbs_1.ToBtcLnSwapState.REFUNDED);
|
|
180
|
+
}
|
|
181
|
+
this.swapLogger.warn(swap, "processPaymentResult(): tried to claim but escrow doesn't exist anymore," +
|
|
182
|
+
" status: " + status +
|
|
183
|
+
" invoice: " + swap.pr);
|
|
236
184
|
return;
|
|
237
185
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
this.swapLogger.warn(swap, "processPaymentResult(): tried to claim but escrow doesn't exist anymore," +
|
|
243
|
-
" status: " + status +
|
|
244
|
-
" invoice: " + swap.pr);
|
|
186
|
+
const success = yield this.tryClaimSwap(swap);
|
|
187
|
+
if (success)
|
|
188
|
+
this.swapLogger.info(swap, "processPaymentResult(): swap claimed successfully, invoice: " + swap.pr);
|
|
245
189
|
return;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (success)
|
|
249
|
-
this.swapLogger.info(swap, "processPaymentResult(): swap claimed successfully, invoice: " + swap.pr);
|
|
250
|
-
return;
|
|
190
|
+
default:
|
|
191
|
+
throw new Error("Invalid lnPaymentStatus");
|
|
251
192
|
}
|
|
252
|
-
//This should never happen
|
|
253
|
-
throw new Error("Invalid lnPaymentStatus");
|
|
254
193
|
});
|
|
255
194
|
}
|
|
256
195
|
/**
|
|
@@ -262,29 +201,18 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
262
201
|
const paymentHash = invoiceData.data.getHash();
|
|
263
202
|
if (this.activeSubscriptions.has(paymentHash))
|
|
264
203
|
return false;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
this.swapLogger.info(invoiceData, "subscribeToPayment(): result callback, outcome: " + outcome + " invoice: " + invoiceData.pr);
|
|
269
|
-
this.processPaymentResult(invoiceData, lnPaymentStatus).catch(e => this.swapLogger.error(invoiceData, "subscribeToPayment(): process payment result", e));
|
|
270
|
-
subscription.removeAllListeners();
|
|
204
|
+
this.lightning.waitForPayment(paymentHash).then(result => {
|
|
205
|
+
this.swapLogger.info(invoiceData, "subscribeToPayment(): result callback, outcome: " + result.status + " invoice: " + invoiceData.pr);
|
|
206
|
+
this.processPaymentResult(invoiceData, result).catch(e => this.swapLogger.error(invoiceData, "subscribeToPayment(): process payment result", e));
|
|
271
207
|
this.activeSubscriptions.delete(paymentHash);
|
|
272
|
-
};
|
|
273
|
-
subscription.on('confirmed', (payment) => onResult({
|
|
274
|
-
is_confirmed: true,
|
|
275
|
-
payment
|
|
276
|
-
}));
|
|
277
|
-
subscription.on('failed', (data) => onResult({
|
|
278
|
-
is_failed: true,
|
|
279
|
-
error: data
|
|
280
|
-
}));
|
|
208
|
+
});
|
|
281
209
|
this.swapLogger.info(invoiceData, "subscribeToPayment(): subscribe to payment outcome, invoice: " + invoiceData.pr);
|
|
282
210
|
this.activeSubscriptions.add(paymentHash);
|
|
283
211
|
return true;
|
|
284
212
|
}
|
|
285
213
|
sendLightningPayment(swap) {
|
|
286
214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
287
|
-
const decodedPR =
|
|
215
|
+
const decodedPR = yield this.lightning.parsePaymentRequest(swap.pr);
|
|
288
216
|
const expiryTimestamp = swap.data.getExpiry();
|
|
289
217
|
const currentTimestamp = new BN(Math.floor(Date.now() / 1000));
|
|
290
218
|
//Run checks
|
|
@@ -294,7 +222,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
294
222
|
code: 90005,
|
|
295
223
|
msg: "Not enough time to reliably pay the invoice"
|
|
296
224
|
};
|
|
297
|
-
const isInvoiceExpired = decodedPR.
|
|
225
|
+
const isInvoiceExpired = decodedPR.expiryEpochMillis < Date.now();
|
|
298
226
|
if (isInvoiceExpired)
|
|
299
227
|
throw {
|
|
300
228
|
code: 90006,
|
|
@@ -304,21 +232,19 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
304
232
|
const maxFee = swap.quotedNetworkFee;
|
|
305
233
|
const maxUsableCLTVdelta = expiryTimestamp.sub(currentTimestamp).sub(this.config.gracePeriod).div(this.config.bitcoinBlocktime.mul(this.config.safetyFactor));
|
|
306
234
|
yield swap.setState(ToBtcLnSwapAbs_1.ToBtcLnSwapState.COMMITED);
|
|
307
|
-
yield this.storageManager.saveData(decodedPR.
|
|
235
|
+
yield this.storageManager.saveData(decodedPR.id, swap.data.getSequence(), swap);
|
|
308
236
|
//Initiate payment
|
|
309
|
-
const { current_block_height } = yield lncli.getHeight({ lnd: this.LND });
|
|
310
|
-
const obj = {
|
|
311
|
-
request: swap.pr,
|
|
312
|
-
max_fee: maxFee.toString(10),
|
|
313
|
-
max_timeout_height: new BN(current_block_height).add(maxUsableCLTVdelta).toString(10),
|
|
314
|
-
lnd: this.LND
|
|
315
|
-
};
|
|
316
237
|
this.swapLogger.info(swap, "sendLightningPayment(): paying lightning network invoice," +
|
|
317
238
|
" cltvDelta: " + maxUsableCLTVdelta.toString(10) +
|
|
318
239
|
" maxFee: " + maxFee.toString(10) +
|
|
319
240
|
" invoice: " + swap.pr);
|
|
241
|
+
const blockHeight = yield this.lightning.getBlockheight();
|
|
320
242
|
try {
|
|
321
|
-
yield
|
|
243
|
+
yield this.lightning.pay({
|
|
244
|
+
request: swap.pr,
|
|
245
|
+
maxFeeMtokens: maxFee.mul(new BN(1000)),
|
|
246
|
+
maxTimeoutHeight: blockHeight + maxUsableCLTVdelta.toNumber()
|
|
247
|
+
});
|
|
322
248
|
}
|
|
323
249
|
catch (e) {
|
|
324
250
|
throw {
|
|
@@ -341,7 +267,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
341
267
|
processInitialized(swap) {
|
|
342
268
|
return __awaiter(this, void 0, void 0, function* () {
|
|
343
269
|
//Check if payment was already made
|
|
344
|
-
let lnPaymentStatus = yield this.getPayment(swap.getHash());
|
|
270
|
+
let lnPaymentStatus = yield this.lightning.getPayment(swap.getHash());
|
|
345
271
|
if (swap.metadata != null)
|
|
346
272
|
swap.metadata.times.payPaymentChecked = Date.now();
|
|
347
273
|
const paymentExists = lnPaymentStatus != null;
|
|
@@ -364,7 +290,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
364
290
|
this.subscribeToPayment(swap);
|
|
365
291
|
return;
|
|
366
292
|
}
|
|
367
|
-
if (lnPaymentStatus.
|
|
293
|
+
if (lnPaymentStatus.status === "pending") {
|
|
368
294
|
this.subscribeToPayment(swap);
|
|
369
295
|
return;
|
|
370
296
|
}
|
|
@@ -453,38 +379,40 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
453
379
|
* @throws {DefinedRuntimeError} will throw an error if the pr is invalid, without amount or expired
|
|
454
380
|
*/
|
|
455
381
|
checkPaymentRequest(pr) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
code: 20021,
|
|
463
|
-
msg: "Invalid request body (pr - cannot be parsed)"
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
if (parsedPR.millisatoshis == null)
|
|
467
|
-
throw {
|
|
468
|
-
code: 20022,
|
|
469
|
-
msg: "Invalid request body (pr - needs to have amount)"
|
|
470
|
-
};
|
|
471
|
-
let halfConfidence = false;
|
|
472
|
-
if (parsedPR.timeExpireDate < ((Date.now() / 1000) + (this.config.authorizationTimeout + (2 * 60)))) {
|
|
473
|
-
if (!this.config.allowShortExpiry) {
|
|
382
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
383
|
+
let parsedPR;
|
|
384
|
+
try {
|
|
385
|
+
parsedPR = yield this.lightning.parsePaymentRequest(pr);
|
|
386
|
+
}
|
|
387
|
+
catch (e) {
|
|
474
388
|
throw {
|
|
475
|
-
code:
|
|
476
|
-
msg: "Invalid request body (pr -
|
|
389
|
+
code: 20021,
|
|
390
|
+
msg: "Invalid request body (pr - cannot be parsed)"
|
|
477
391
|
};
|
|
478
392
|
}
|
|
479
|
-
|
|
393
|
+
if (parsedPR.mtokens == null)
|
|
480
394
|
throw {
|
|
481
|
-
code:
|
|
482
|
-
msg: "Invalid request body (pr -
|
|
395
|
+
code: 20022,
|
|
396
|
+
msg: "Invalid request body (pr - needs to have amount)"
|
|
483
397
|
};
|
|
398
|
+
let halfConfidence = false;
|
|
399
|
+
if (parsedPR.expiryEpochMillis < Date.now() + ((this.config.authorizationTimeout + (2 * 60)) * 1000)) {
|
|
400
|
+
if (!this.config.allowShortExpiry) {
|
|
401
|
+
throw {
|
|
402
|
+
code: 20020,
|
|
403
|
+
msg: "Invalid request body (pr - expired)"
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
else if (parsedPR.expiryEpochMillis < Date.now()) {
|
|
407
|
+
throw {
|
|
408
|
+
code: 20020,
|
|
409
|
+
msg: "Invalid request body (pr - expired)"
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
halfConfidence = true;
|
|
484
413
|
}
|
|
485
|
-
halfConfidence
|
|
486
|
-
}
|
|
487
|
-
return { parsedPR, halfConfidence };
|
|
414
|
+
return { parsedPR, halfConfidence };
|
|
415
|
+
});
|
|
488
416
|
}
|
|
489
417
|
/**
|
|
490
418
|
* Checks if the request specified too short of an expiry
|
|
@@ -511,7 +439,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
511
439
|
*/
|
|
512
440
|
checkPriorPayment(paymentHash, abortSignal) {
|
|
513
441
|
return __awaiter(this, void 0, void 0, function* () {
|
|
514
|
-
const payment = yield this.getPayment(paymentHash);
|
|
442
|
+
const payment = yield this.lightning.getPayment(paymentHash);
|
|
515
443
|
if (payment != null)
|
|
516
444
|
throw {
|
|
517
445
|
code: 20010,
|
|
@@ -530,15 +458,14 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
530
458
|
*/
|
|
531
459
|
checkLiquidity(amount, abortSignal, useCached = false) {
|
|
532
460
|
return __awaiter(this, void 0, void 0, function* () {
|
|
533
|
-
const amountBDMtokens = amount.mul(new BN(1000));
|
|
534
461
|
if (!useCached || this.lightningLiquidityCache == null || this.lightningLiquidityCache.timestamp < Date.now() - this.LIGHTNING_LIQUIDITY_CACHE_TIMEOUT) {
|
|
535
|
-
const channelBalances = yield
|
|
462
|
+
const channelBalances = yield this.lightning.getLightningBalance();
|
|
536
463
|
this.lightningLiquidityCache = {
|
|
537
|
-
|
|
464
|
+
liquidity: channelBalances.localBalance,
|
|
538
465
|
timestamp: Date.now()
|
|
539
466
|
};
|
|
540
467
|
}
|
|
541
|
-
if (
|
|
468
|
+
if (amount.gt(this.lightningLiquidityCache.liquidity)) {
|
|
542
469
|
throw {
|
|
543
470
|
code: 20002,
|
|
544
471
|
msg: "Not enough liquidity"
|
|
@@ -547,157 +474,6 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
547
474
|
abortSignal.throwIfAborted();
|
|
548
475
|
});
|
|
549
476
|
}
|
|
550
|
-
/**
|
|
551
|
-
* Computes the route paying to the specified bolt11 invoice, estimating the fee, uses bLIP-39 blinded paths
|
|
552
|
-
*
|
|
553
|
-
* @param amountSats
|
|
554
|
-
* @param maxFee
|
|
555
|
-
* @param parsedRequest
|
|
556
|
-
* @param maxTimeoutBlockheight
|
|
557
|
-
* @param metadata
|
|
558
|
-
* @param maxUsableCLTV
|
|
559
|
-
* @private
|
|
560
|
-
*/
|
|
561
|
-
getRoutesInvoiceBLIP39(amountSats, maxFee, parsedRequest, maxTimeoutBlockheight, metadata, maxUsableCLTV) {
|
|
562
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
563
|
-
metadata.routeReq = [];
|
|
564
|
-
const routeReqs = parsedRequest.blindedPaths.map((blindedPath) => __awaiter(this, void 0, void 0, function* () {
|
|
565
|
-
if (new BN(blindedPath.cltv_expiry_delta + 10).gt(maxUsableCLTV))
|
|
566
|
-
return null;
|
|
567
|
-
const originalMsatAmount = amountSats.mul(new BN(1000));
|
|
568
|
-
const blindedFeeTotalMsat = new BN(blindedPath.fee_base_msat)
|
|
569
|
-
.add(originalMsatAmount.mul(new BN(blindedPath.fee_proportional_millionths)).div(new BN(1000000)));
|
|
570
|
-
const routeReq = {
|
|
571
|
-
destination: blindedPath.introduction_node,
|
|
572
|
-
cltv_delta: Math.max(blindedPath.cltv_expiry_delta, parsedRequest.cltv_delta),
|
|
573
|
-
mtokens: originalMsatAmount.add(blindedFeeTotalMsat).toString(10),
|
|
574
|
-
max_fee_mtokens: maxFee.mul(new BN(1000)).sub(blindedFeeTotalMsat).toString(10),
|
|
575
|
-
max_timeout_height: maxTimeoutBlockheight.toString(10),
|
|
576
|
-
// total_mtokens: amountSats.mul(new BN(1000)).toString(10),
|
|
577
|
-
routes: parsedRequest.routes,
|
|
578
|
-
is_ignoring_past_failures: true,
|
|
579
|
-
lnd: null
|
|
580
|
-
};
|
|
581
|
-
metadata.routeReq.push(Object.assign({}, routeReq));
|
|
582
|
-
routeReq.lnd = this.LND;
|
|
583
|
-
let resp;
|
|
584
|
-
try {
|
|
585
|
-
resp = yield lncli.getRouteToDestination(routeReq);
|
|
586
|
-
}
|
|
587
|
-
catch (e) {
|
|
588
|
-
(0, Utils_1.handleLndError)(e);
|
|
589
|
-
}
|
|
590
|
-
if (resp == null || resp.route == null)
|
|
591
|
-
return null;
|
|
592
|
-
const adjustedFeeMsats = new BN(resp.route.fee_mtokens).add(blindedFeeTotalMsat);
|
|
593
|
-
resp.route.fee_mtokens = adjustedFeeMsats.toString(10);
|
|
594
|
-
resp.route.fee = adjustedFeeMsats.div(new BN(1000)).toNumber();
|
|
595
|
-
resp.route.safe_fee = adjustedFeeMsats.add(new BN(999)).div(new BN(1000)).toNumber();
|
|
596
|
-
const totalAdjustedMsats = new BN(routeReq.mtokens).add(blindedFeeTotalMsat);
|
|
597
|
-
resp.route.mtokens = totalAdjustedMsats.toString(10);
|
|
598
|
-
resp.route.tokens = totalAdjustedMsats.div(new BN(1000)).toNumber();
|
|
599
|
-
resp.route.safe_tokens = totalAdjustedMsats.add(new BN(999)).div(new BN(1000)).toNumber();
|
|
600
|
-
return resp.route;
|
|
601
|
-
}));
|
|
602
|
-
const responses = yield Promise.all(routeReqs);
|
|
603
|
-
metadata.routeResponsesBLIP39 = responses.map(resp => { return Object.assign({}, resp); });
|
|
604
|
-
return responses.reduce((prev, current) => {
|
|
605
|
-
if (prev == null)
|
|
606
|
-
return current;
|
|
607
|
-
if (current == null)
|
|
608
|
-
return prev;
|
|
609
|
-
current.fee_mtokens = BN.max(new BN(prev.fee_mtokens), new BN(current.fee_mtokens)).toString(10);
|
|
610
|
-
current.fee = Math.max(prev.fee, current.fee);
|
|
611
|
-
current.safe_fee = Math.max(prev.safe_fee, current.safe_fee);
|
|
612
|
-
current.mtokens = BN.max(new BN(prev.mtokens), new BN(current.mtokens)).toString(10);
|
|
613
|
-
current.tokens = Math.max(prev.tokens, current.tokens);
|
|
614
|
-
current.safe_tokens = Math.max(prev.safe_tokens, current.safe_tokens);
|
|
615
|
-
current.timeout = Math.max(prev.timeout, current.timeout);
|
|
616
|
-
return current;
|
|
617
|
-
});
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* Computes the route paying to the specified bolt11 invoice, estimating the fee
|
|
622
|
-
*
|
|
623
|
-
* @param amountSats
|
|
624
|
-
* @param maxFee
|
|
625
|
-
* @param parsedRequest
|
|
626
|
-
* @param maxTimeoutBlockheight
|
|
627
|
-
* @param metadata
|
|
628
|
-
* @param maxUsableCLTV
|
|
629
|
-
* @private
|
|
630
|
-
*/
|
|
631
|
-
getRoutesInvoice(amountSats, maxFee, parsedRequest, maxTimeoutBlockheight, metadata, maxUsableCLTV) {
|
|
632
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
633
|
-
if (parsedRequest.blindedPaths != null && parsedRequest.blindedPaths.length > 0)
|
|
634
|
-
return yield this.getRoutesInvoiceBLIP39(amountSats, maxFee, parsedRequest, maxTimeoutBlockheight, metadata, maxUsableCLTV);
|
|
635
|
-
const routesReq = {
|
|
636
|
-
destination: parsedRequest.destination,
|
|
637
|
-
cltv_delta: parsedRequest.cltv_delta,
|
|
638
|
-
mtokens: amountSats.mul(new BN(1000)).toString(10),
|
|
639
|
-
max_fee_mtokens: maxFee.mul(new BN(1000)).toString(10),
|
|
640
|
-
payment: parsedRequest.payment,
|
|
641
|
-
max_timeout_height: maxTimeoutBlockheight.toString(10),
|
|
642
|
-
total_mtokens: amountSats.mul(new BN(1000)).toString(10),
|
|
643
|
-
routes: parsedRequest.routes,
|
|
644
|
-
is_ignoring_past_failures: true
|
|
645
|
-
};
|
|
646
|
-
metadata.routeReq = Object.assign({}, routesReq);
|
|
647
|
-
routesReq.lnd = this.LND;
|
|
648
|
-
let obj;
|
|
649
|
-
try {
|
|
650
|
-
obj = yield lncli.getRouteToDestination(routesReq);
|
|
651
|
-
}
|
|
652
|
-
catch (e) {
|
|
653
|
-
(0, Utils_1.handleLndError)(e);
|
|
654
|
-
}
|
|
655
|
-
return (obj === null || obj === void 0 ? void 0 : obj.route) == null ? null : obj.route;
|
|
656
|
-
});
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Sends a probe payment to the specified bolt11 invoice to check if it is reachable
|
|
660
|
-
*
|
|
661
|
-
* @param amountSats
|
|
662
|
-
* @param maxFee
|
|
663
|
-
* @param parsedRequest
|
|
664
|
-
* @param maxTimeoutBlockheight
|
|
665
|
-
* @param metadata
|
|
666
|
-
* @private
|
|
667
|
-
*/
|
|
668
|
-
probeInvoice(amountSats, maxFee, parsedRequest, maxTimeoutBlockheight, metadata) {
|
|
669
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
670
|
-
const probeReq = {
|
|
671
|
-
destination: parsedRequest.destination,
|
|
672
|
-
cltv_delta: parsedRequest.cltv_delta,
|
|
673
|
-
mtokens: amountSats.mul(new BN(1000)).toString(10),
|
|
674
|
-
max_fee_mtokens: maxFee.mul(new BN(1000)).toString(10),
|
|
675
|
-
max_timeout_height: maxTimeoutBlockheight.toString(10),
|
|
676
|
-
payment: parsedRequest.payment,
|
|
677
|
-
total_mtokens: amountSats.mul(new BN(1000)).toString(10),
|
|
678
|
-
routes: parsedRequest.routes
|
|
679
|
-
};
|
|
680
|
-
metadata.probeRequest = Object.assign({}, probeReq);
|
|
681
|
-
probeReq.lnd = this.LND;
|
|
682
|
-
let is_snowflake = false;
|
|
683
|
-
if (parsedRequest.routes != null) {
|
|
684
|
-
for (let route of parsedRequest.routes) {
|
|
685
|
-
if (SNOWFLAKE_LIST.has(route[0].public_key) || SNOWFLAKE_LIST.has(route[1].public_key)) {
|
|
686
|
-
is_snowflake = true;
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
let obj;
|
|
691
|
-
if (!is_snowflake)
|
|
692
|
-
try {
|
|
693
|
-
obj = yield lncli.probeForRoute(probeReq);
|
|
694
|
-
}
|
|
695
|
-
catch (e) {
|
|
696
|
-
(0, Utils_1.handleLndError)(e);
|
|
697
|
-
}
|
|
698
|
-
return (obj === null || obj === void 0 ? void 0 : obj.route) == null ? null : obj.route;
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
477
|
/**
|
|
702
478
|
* Estimates the routing fee & confidence by either probing or routing (if probing fails), the fee is also adjusted
|
|
703
479
|
* according to routing fee multiplier, and subject to minimums set in config
|
|
@@ -714,29 +490,27 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
714
490
|
checkAndGetNetworkFee(amountBD, maxFee, expiryTimestamp, currentTimestamp, pr, metadata, abortSignal) {
|
|
715
491
|
return __awaiter(this, void 0, void 0, function* () {
|
|
716
492
|
const maxUsableCLTV = expiryTimestamp.sub(currentTimestamp).sub(this.config.gracePeriod).div(this.config.bitcoinBlocktime.mul(this.config.safetyFactor));
|
|
717
|
-
const
|
|
493
|
+
const blockHeight = yield this.lightning.getBlockheight();
|
|
718
494
|
abortSignal.throwIfAborted();
|
|
719
495
|
metadata.times.blockheightFetched = Date.now();
|
|
720
|
-
const maxTimeoutBlockheight = new BN(
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
abortSignal.throwIfAborted();
|
|
732
|
-
}
|
|
496
|
+
const maxTimeoutBlockheight = new BN(blockHeight).add(maxUsableCLTV);
|
|
497
|
+
const req = {
|
|
498
|
+
request: pr,
|
|
499
|
+
amountMtokens: amountBD.mul(new BN(1000)),
|
|
500
|
+
maxFeeMtokens: maxFee.mul(new BN(1000)),
|
|
501
|
+
maxTimeoutHeight: maxTimeoutBlockheight.toNumber()
|
|
502
|
+
};
|
|
503
|
+
let probeOrRouteResp = yield this.lightning.probe(req);
|
|
504
|
+
metadata.times.probeResult = Date.now();
|
|
505
|
+
metadata.probeResponse = Object.assign({}, probeOrRouteResp);
|
|
506
|
+
abortSignal.throwIfAborted();
|
|
733
507
|
if (probeOrRouteResp == null) {
|
|
734
508
|
if (!this.config.allowProbeFailedSwaps)
|
|
735
509
|
throw {
|
|
736
510
|
code: 20002,
|
|
737
511
|
msg: "Cannot route the payment!"
|
|
738
512
|
};
|
|
739
|
-
const routeResp = yield this.
|
|
513
|
+
const routeResp = yield this.lightning.route(req);
|
|
740
514
|
metadata.times.routingResult = Date.now();
|
|
741
515
|
metadata.routeResponse = Object.assign({}, routeResp);
|
|
742
516
|
abortSignal.throwIfAborted();
|
|
@@ -746,20 +520,19 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
746
520
|
msg: "Cannot route the payment!"
|
|
747
521
|
};
|
|
748
522
|
this.logger.info("checkAndGetNetworkFee(): routing result," +
|
|
749
|
-
" destination: " +
|
|
523
|
+
" destination: " + routeResp.destination +
|
|
750
524
|
" confidence: " + routeResp.confidence +
|
|
751
|
-
"
|
|
525
|
+
" fee mtokens: " + routeResp.feeMtokens.toString(10));
|
|
752
526
|
probeOrRouteResp = routeResp;
|
|
753
|
-
if (parsedRequest.blindedPaths == null)
|
|
754
|
-
probeOrRouteResp.confidence = 0;
|
|
755
527
|
}
|
|
756
528
|
else {
|
|
757
529
|
this.logger.info("checkAndGetNetworkFee(): route probed," +
|
|
758
|
-
" destination: " +
|
|
530
|
+
" destination: " + probeOrRouteResp.destination +
|
|
759
531
|
" confidence: " + probeOrRouteResp.confidence +
|
|
760
|
-
"
|
|
532
|
+
" fee mtokens: " + probeOrRouteResp.feeMtokens.toString(10));
|
|
761
533
|
}
|
|
762
|
-
|
|
534
|
+
const safeFeeTokens = probeOrRouteResp.feeMtokens.add(new BN(999)).div(new BN(1000));
|
|
535
|
+
let actualRoutingFee = safeFeeTokens.mul(this.config.routingFeeMultiplier);
|
|
763
536
|
const minRoutingFee = amountBD.mul(this.config.minLnRoutingFeePPM).div(new BN(1000000)).add(this.config.minLnBaseFee);
|
|
764
537
|
if (actualRoutingFee.lt(minRoutingFee)) {
|
|
765
538
|
actualRoutingFee = minRoutingFee;
|
|
@@ -772,8 +545,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
772
545
|
}
|
|
773
546
|
return {
|
|
774
547
|
networkFee: actualRoutingFee,
|
|
775
|
-
confidence: probeOrRouteResp.confidence
|
|
776
|
-
routes: parsedRequest.routes
|
|
548
|
+
confidence: probeOrRouteResp.confidence
|
|
777
549
|
};
|
|
778
550
|
});
|
|
779
551
|
}
|
|
@@ -810,18 +582,16 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
810
582
|
*/
|
|
811
583
|
checkPaymentRequestMatchesInitial(pr, parsedAuth) {
|
|
812
584
|
return __awaiter(this, void 0, void 0, function* () {
|
|
813
|
-
const parsedRequest = yield
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
parsedRequest.cltv_delta !== parsedAuth.cltvDelta ||
|
|
818
|
-
!new BN(parsedRequest.mtokens).eq(parsedAuth.amount.mul(new BN(1000)))) {
|
|
585
|
+
const parsedRequest = yield this.lightning.parsePaymentRequest(pr);
|
|
586
|
+
if (parsedRequest.destination !== parsedAuth.initialInvoice.destination ||
|
|
587
|
+
parsedRequest.cltvDelta !== parsedAuth.initialInvoice.cltvDelta ||
|
|
588
|
+
!parsedRequest.mtokens.eq(parsedAuth.amount.mul(new BN(1000)))) {
|
|
819
589
|
throw {
|
|
820
590
|
code: 20102,
|
|
821
591
|
msg: "Provided PR doesn't match initial!"
|
|
822
592
|
};
|
|
823
593
|
}
|
|
824
|
-
if (!routesMatch(parsedRequest.routes, parsedAuth.routes)) {
|
|
594
|
+
if (!(0, ILightningWallet_1.routesMatch)(parsedRequest.routes, parsedAuth.initialInvoice.routes)) {
|
|
825
595
|
throw {
|
|
826
596
|
code: 20102,
|
|
827
597
|
msg: "Provided PR doesn't match initial (routes)!"
|
|
@@ -852,27 +622,27 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
852
622
|
const abortSignal = responseStream.getAbortSignal();
|
|
853
623
|
//Check request params
|
|
854
624
|
const parsedAuth = this.checkExactInAuthorization(parsedBody.reqId);
|
|
855
|
-
const { parsedPR, halfConfidence } = this.checkPaymentRequest(parsedBody.pr);
|
|
625
|
+
const { parsedPR, halfConfidence } = yield this.checkPaymentRequest(parsedBody.pr);
|
|
856
626
|
yield this.checkPaymentRequestMatchesInitial(parsedBody.pr, parsedAuth);
|
|
857
627
|
const metadata = parsedAuth.metadata;
|
|
858
628
|
const sequence = new BN((0, crypto_1.randomBytes)(8));
|
|
859
629
|
const { swapContract, signer } = this.getChain(parsedAuth.chainIdentifier);
|
|
860
630
|
//Create swap data
|
|
861
|
-
const payObject = yield swapContract.createSwapData(base_1.ChainSwapType.HTLC, parsedAuth.offerer, signer.getAddress(), parsedAuth.token, parsedAuth.total, parsedPR.
|
|
631
|
+
const payObject = yield swapContract.createSwapData(base_1.ChainSwapType.HTLC, parsedAuth.offerer, signer.getAddress(), parsedAuth.token, parsedAuth.total, parsedPR.id, sequence, parsedAuth.swapExpiry, new BN(0), 0, true, false, new BN(0), new BN(0));
|
|
862
632
|
metadata.times.swapCreated = Date.now();
|
|
863
633
|
//Sign swap data
|
|
864
634
|
const prefetchedSignData = parsedAuth.preFetchSignData;
|
|
865
635
|
const sigData = yield this.getToBtcSignatureData(parsedAuth.chainIdentifier, payObject, req, abortSignal, prefetchedSignData);
|
|
866
636
|
metadata.times.swapSigned = Date.now();
|
|
867
637
|
//Create swap
|
|
868
|
-
const createdSwap = new ToBtcLnSwapAbs_1.ToBtcLnSwapAbs(parsedAuth.chainIdentifier, parsedBody.pr, parsedAuth.swapFee, parsedAuth.swapFeeInToken, parsedAuth.quotedNetworkFee, parsedAuth.quotedNetworkFeeInToken
|
|
638
|
+
const createdSwap = new ToBtcLnSwapAbs_1.ToBtcLnSwapAbs(parsedAuth.chainIdentifier, parsedBody.pr, parsedPR.mtokens, parsedAuth.swapFee, parsedAuth.swapFeeInToken, parsedAuth.quotedNetworkFee, parsedAuth.quotedNetworkFeeInToken);
|
|
869
639
|
createdSwap.data = payObject;
|
|
870
640
|
createdSwap.metadata = metadata;
|
|
871
641
|
yield PluginManager_1.PluginManager.swapCreate(createdSwap);
|
|
872
|
-
yield this.storageManager.saveData(parsedPR.
|
|
642
|
+
yield this.storageManager.saveData(parsedPR.id, sequence, createdSwap);
|
|
873
643
|
this.swapLogger.info(createdSwap, "REST: /payInvoiceExactIn: created exact in swap," +
|
|
874
644
|
" reqId: " + parsedBody.reqId +
|
|
875
|
-
"
|
|
645
|
+
" mtokens: " + parsedPR.mtokens.toString(10) +
|
|
876
646
|
" invoice: " + createdSwap.pr);
|
|
877
647
|
yield responseStream.writeParamsAndEnd({
|
|
878
648
|
code: 20000,
|
|
@@ -945,10 +715,10 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
945
715
|
this.checkMaxFee(parsedBody.maxFee);
|
|
946
716
|
this.checkExpiry(parsedBody.expiryTimestamp, currentTimestamp);
|
|
947
717
|
yield this.checkVaultInitialized(chainIdentifier, parsedBody.token);
|
|
948
|
-
const { parsedPR, halfConfidence } = this.checkPaymentRequest(parsedBody.pr);
|
|
718
|
+
const { parsedPR, halfConfidence } = yield this.checkPaymentRequest(parsedBody.pr);
|
|
949
719
|
const requestedAmount = {
|
|
950
720
|
input: !!parsedBody.exactIn,
|
|
951
|
-
amount: !!parsedBody.exactIn ? parsedBody.amount :
|
|
721
|
+
amount: !!parsedBody.exactIn ? parsedBody.amount : parsedPR.mtokens.add(new BN(999)).div(new BN(1000))
|
|
952
722
|
};
|
|
953
723
|
const fees = yield this.preCheckAmounts(request, requestedAmount, useToken);
|
|
954
724
|
metadata.times.requestChecked = Date.now();
|
|
@@ -957,7 +727,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
957
727
|
//Pre-fetch
|
|
958
728
|
const { pricePrefetchPromise, signDataPrefetchPromise } = this.getToBtcPrefetches(chainIdentifier, useToken, responseStream, abortController);
|
|
959
729
|
//Check if prior payment has been made
|
|
960
|
-
yield this.checkPriorPayment(parsedPR.
|
|
730
|
+
yield this.checkPriorPayment(parsedPR.id, abortController.signal);
|
|
961
731
|
metadata.times.priorPaymentChecked = Date.now();
|
|
962
732
|
//Check amounts
|
|
963
733
|
const { amountBD, networkFeeData, totalInToken, swapFee, swapFeeInToken, networkFeeInToken } = yield this.checkToBtcAmount(request, requestedAmount, fees, useToken, (amountBD) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -978,9 +748,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
978
748
|
reqId,
|
|
979
749
|
expiry: Date.now() + this.config.exactInExpiry,
|
|
980
750
|
amount: amountBD,
|
|
981
|
-
|
|
982
|
-
cltvDelta: parsedPR.tagsObject.min_final_cltv_expiry,
|
|
983
|
-
routes: networkFeeData.routes,
|
|
751
|
+
initialInvoice: parsedPR,
|
|
984
752
|
quotedNetworkFeeInToken: networkFeeInToken,
|
|
985
753
|
swapFeeInToken,
|
|
986
754
|
total: totalInToken,
|
|
@@ -996,7 +764,7 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
996
764
|
this.logger.info("REST: /payInvoice: created exact in swap," +
|
|
997
765
|
" reqId: " + reqId +
|
|
998
766
|
" amount: " + amountBD.toString(10) +
|
|
999
|
-
" destination: " + parsedPR.
|
|
767
|
+
" destination: " + parsedPR.destination);
|
|
1000
768
|
yield responseStream.writeParamsAndEnd({
|
|
1001
769
|
code: 20000,
|
|
1002
770
|
msg: "Success",
|
|
@@ -1009,18 +777,22 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
1009
777
|
}
|
|
1010
778
|
const sequence = new BN((0, crypto_1.randomBytes)(8));
|
|
1011
779
|
//Create swap data
|
|
1012
|
-
const payObject = yield swapContract.createSwapData(base_1.ChainSwapType.HTLC, parsedBody.offerer, signer.getAddress(), useToken, totalInToken, parsedPR.
|
|
780
|
+
const payObject = yield swapContract.createSwapData(base_1.ChainSwapType.HTLC, parsedBody.offerer, signer.getAddress(), useToken, totalInToken, parsedPR.id, sequence, parsedBody.expiryTimestamp, new BN(0), 0, true, false, new BN(0), new BN(0));
|
|
1013
781
|
abortController.signal.throwIfAborted();
|
|
1014
782
|
metadata.times.swapCreated = Date.now();
|
|
1015
783
|
//Sign swap data
|
|
1016
784
|
const sigData = yield this.getToBtcSignatureData(chainIdentifier, payObject, req, abortController.signal, signDataPrefetchPromise);
|
|
1017
785
|
metadata.times.swapSigned = Date.now();
|
|
1018
786
|
//Create swap
|
|
1019
|
-
const createdSwap = new ToBtcLnSwapAbs_1.ToBtcLnSwapAbs(chainIdentifier, parsedBody.pr, swapFee, swapFeeInToken, networkFeeData.networkFee, networkFeeInToken
|
|
787
|
+
const createdSwap = new ToBtcLnSwapAbs_1.ToBtcLnSwapAbs(chainIdentifier, parsedBody.pr, parsedPR.mtokens, swapFee, swapFeeInToken, networkFeeData.networkFee, networkFeeInToken);
|
|
1020
788
|
createdSwap.data = payObject;
|
|
1021
789
|
createdSwap.metadata = metadata;
|
|
790
|
+
createdSwap.prefix = sigData.prefix;
|
|
791
|
+
createdSwap.timeout = sigData.timeout;
|
|
792
|
+
createdSwap.signature = sigData.signature;
|
|
793
|
+
createdSwap.feeRate = sigData.feeRate;
|
|
1022
794
|
yield PluginManager_1.PluginManager.swapCreate(createdSwap);
|
|
1023
|
-
yield this.storageManager.saveData(parsedPR.
|
|
795
|
+
yield this.storageManager.saveData(parsedPR.id, sequence, createdSwap);
|
|
1024
796
|
this.swapLogger.info(createdSwap, "REST: /payInvoice: created swap," +
|
|
1025
797
|
" amount: " + amountBD.toString(10) +
|
|
1026
798
|
" invoice: " + createdSwap.pr);
|
|
@@ -1062,14 +834,13 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
1062
834
|
const data = yield this.storageManager.getData(parsedBody.paymentHash, parsedBody.sequence);
|
|
1063
835
|
const isSwapFound = data != null;
|
|
1064
836
|
if (isSwapFound) {
|
|
1065
|
-
const
|
|
1066
|
-
if (isExpired)
|
|
837
|
+
const { signer, swapContract } = this.getChain(data.chainIdentifier);
|
|
838
|
+
if (swapContract.isExpired(signer.getAddress(), data.data))
|
|
1067
839
|
throw {
|
|
1068
840
|
_httpStatus: 200,
|
|
1069
841
|
code: 20010,
|
|
1070
842
|
msg: "Payment expired"
|
|
1071
843
|
};
|
|
1072
|
-
const { signer, swapContract } = this.getChain(data.chainIdentifier);
|
|
1073
844
|
if (data.state === ToBtcLnSwapAbs_1.ToBtcLnSwapState.NON_PAYABLE) {
|
|
1074
845
|
const refundSigData = yield swapContract.getRefundSignature(signer, data.data, this.config.authorizationTimeout);
|
|
1075
846
|
//Double check the state after promise result
|
|
@@ -1092,61 +863,37 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
1092
863
|
return;
|
|
1093
864
|
}
|
|
1094
865
|
}
|
|
1095
|
-
const payment = yield this.getPayment(parsedBody.paymentHash);
|
|
866
|
+
const payment = yield this.lightning.getPayment(parsedBody.paymentHash);
|
|
1096
867
|
if (payment == null)
|
|
1097
868
|
throw {
|
|
1098
869
|
_httpStatus: 200,
|
|
1099
870
|
code: 20007,
|
|
1100
871
|
msg: "Payment not found"
|
|
1101
872
|
};
|
|
1102
|
-
if (payment.
|
|
873
|
+
if (payment.status === "pending")
|
|
1103
874
|
throw {
|
|
1104
875
|
_httpStatus: 200,
|
|
1105
876
|
code: 20008,
|
|
1106
877
|
msg: "Payment in-flight"
|
|
1107
878
|
};
|
|
1108
|
-
if (payment.
|
|
879
|
+
if (payment.status === "confirmed")
|
|
1109
880
|
throw {
|
|
1110
881
|
_httpStatus: 200,
|
|
1111
882
|
code: 20006,
|
|
1112
883
|
msg: "Already paid",
|
|
1113
884
|
data: {
|
|
1114
|
-
secret: payment.
|
|
885
|
+
secret: payment.secret
|
|
1115
886
|
}
|
|
1116
887
|
};
|
|
1117
|
-
if (payment.
|
|
888
|
+
if (payment.status === "failed")
|
|
1118
889
|
throw {
|
|
1119
890
|
_httpStatus: 200,
|
|
1120
891
|
code: 20010,
|
|
1121
|
-
msg: "Payment expired"
|
|
892
|
+
msg: "Payment expired",
|
|
893
|
+
data: {
|
|
894
|
+
reason: payment.failedReason
|
|
895
|
+
}
|
|
1122
896
|
};
|
|
1123
|
-
// NOTE: Fixed by not removing swap data until the HTLC is either expired, claimed or refunded.
|
|
1124
|
-
// //TODO_old: Fix this by providing chain identifier as part of the invoice description, or maybe just do it the proper
|
|
1125
|
-
// // way and just keep storing the data until the HTLC expiry
|
|
1126
|
-
// if(payment.is_failed) {
|
|
1127
|
-
// //TODO_old: This might not be the best idea with EVM chains
|
|
1128
|
-
// const commitedData = await this.swapContract.getCommitedData(parsedBody.paymentHash);
|
|
1129
|
-
//
|
|
1130
|
-
// if(commitedData==null) throw {
|
|
1131
|
-
// code: 20005,
|
|
1132
|
-
// msg: "Not committed"
|
|
1133
|
-
// };
|
|
1134
|
-
//
|
|
1135
|
-
// const refundSigData = await this.swapContract.getRefundSignature(commitedData, this.config.authorizationTimeout);
|
|
1136
|
-
//
|
|
1137
|
-
// this.swapLogger.info(commitedData, "REST: /getRefundAuthorization: returning refund authorization, because invoice payment failed");
|
|
1138
|
-
//
|
|
1139
|
-
// res.status(200).json({
|
|
1140
|
-
// code: 20000,
|
|
1141
|
-
// msg: "Success",
|
|
1142
|
-
// data: {
|
|
1143
|
-
// address: this.swapContract.getAddress(),
|
|
1144
|
-
// prefix: refundSigData.prefix,
|
|
1145
|
-
// timeout: refundSigData.timeout,
|
|
1146
|
-
// signature: refundSigData.signature
|
|
1147
|
-
// }
|
|
1148
|
-
// });
|
|
1149
|
-
// }
|
|
1150
897
|
}));
|
|
1151
898
|
restServer.post(this.path + '/getRefundAuthorization', getRefundAuthorization);
|
|
1152
899
|
restServer.get(this.path + '/getRefundAuthorization', getRefundAuthorization);
|
|
@@ -1155,6 +902,13 @@ class ToBtcLnAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
1155
902
|
init() {
|
|
1156
903
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1157
904
|
yield this.storageManager.loadData(ToBtcLnSwapAbs_1.ToBtcLnSwapAbs);
|
|
905
|
+
//Check if all swaps contain a valid amount
|
|
906
|
+
for (let swap of yield this.storageManager.query([])) {
|
|
907
|
+
if (swap.amount == null) {
|
|
908
|
+
const parsedPR = yield this.lightning.parsePaymentRequest(swap.pr);
|
|
909
|
+
swap.amount = parsedPR.mtokens.add(new BN(999)).div(new BN(1000));
|
|
910
|
+
}
|
|
911
|
+
}
|
|
1158
912
|
this.subscribeToEvents();
|
|
1159
913
|
yield PluginManager_1.PluginManager.serviceInitialize(this);
|
|
1160
914
|
});
|