@atomiqlabs/lp-lib 11.0.5 → 12.0.0-beta.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/info/InfoHandler.js +3 -12
- package/dist/plugins/IPlugin.d.ts +34 -35
- package/dist/plugins/IPlugin.js +7 -8
- package/dist/plugins/PluginManager.d.ts +29 -30
- package/dist/plugins/PluginManager.js +160 -188
- package/dist/prices/BinanceSwapPrice.d.ts +1 -2
- package/dist/prices/BinanceSwapPrice.js +56 -70
- package/dist/prices/CoinGeckoSwapPrice.d.ts +2 -3
- package/dist/prices/CoinGeckoSwapPrice.js +30 -42
- package/dist/prices/OKXSwapPrice.d.ts +1 -2
- package/dist/prices/OKXSwapPrice.js +56 -70
- package/dist/storage/IIntermediaryStorage.d.ts +8 -5
- package/dist/storagemanager/IntermediaryStorageManager.d.ts +8 -5
- package/dist/storagemanager/IntermediaryStorageManager.js +52 -61
- package/dist/storagemanager/StorageManager.js +42 -59
- package/dist/swaps/FromBtcBaseSwap.d.ts +7 -8
- package/dist/swaps/FromBtcBaseSwap.js +2 -3
- package/dist/swaps/FromBtcBaseSwapHandler.d.ts +44 -31
- package/dist/swaps/FromBtcBaseSwapHandler.js +217 -196
- package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +1 -2
- package/dist/swaps/FromBtcLnBaseSwapHandler.js +13 -24
- package/dist/swaps/ISwapPrice.d.ts +4 -5
- package/dist/swaps/ISwapPrice.js +8 -30
- package/dist/swaps/SwapHandler.d.ts +26 -15
- package/dist/swaps/SwapHandler.js +107 -66
- package/dist/swaps/SwapHandlerSwap.d.ts +22 -11
- package/dist/swaps/SwapHandlerSwap.js +32 -8
- package/dist/swaps/ToBtcBaseSwap.d.ts +16 -17
- package/dist/swaps/ToBtcBaseSwap.js +4 -4
- package/dist/swaps/ToBtcBaseSwapHandler.d.ts +17 -17
- package/dist/swaps/ToBtcBaseSwapHandler.js +140 -155
- package/dist/swaps/frombtc_abstract/FromBtcAbs.d.ts +8 -15
- package/dist/swaps/frombtc_abstract/FromBtcAbs.js +131 -196
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.d.ts +3 -5
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.js +4 -4
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.d.ts +10 -8
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.js +330 -362
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.d.ts +10 -10
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.js +7 -4
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.d.ts +8 -8
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.js +330 -400
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +10 -4
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.js +36 -6
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.d.ts +8 -7
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.js +251 -273
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +5 -5
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.js +7 -5
- package/dist/swaps/tobtc_abstract/ToBtcAbs.d.ts +13 -12
- package/dist/swaps/tobtc_abstract/ToBtcAbs.js +261 -323
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.d.ts +4 -4
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.js +7 -6
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.d.ts +22 -21
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.js +398 -453
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +3 -2
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.js +10 -6
- package/dist/utils/Utils.d.ts +2 -3
- package/dist/utils/Utils.js +4 -14
- package/dist/utils/paramcoders/LegacyParamEncoder.js +3 -14
- package/dist/utils/paramcoders/ParamDecoder.js +53 -65
- package/dist/utils/paramcoders/SchemaVerifier.d.ts +4 -5
- package/dist/utils/paramcoders/SchemaVerifier.js +8 -9
- package/dist/utils/paramcoders/server/ServerParamDecoder.js +1 -1
- package/dist/utils/paramcoders/server/ServerParamEncoder.js +3 -14
- package/dist/wallets/IBitcoinWallet.d.ts +4 -5
- package/dist/wallets/ILightningWallet.d.ts +20 -21
- package/dist/wallets/ILightningWallet.js +1 -1
- package/package.json +4 -6
- package/src/plugins/IPlugin.ts +28 -29
- package/src/plugins/PluginManager.ts +21 -22
- package/src/prices/BinanceSwapPrice.ts +3 -4
- package/src/prices/CoinGeckoSwapPrice.ts +4 -5
- package/src/prices/OKXSwapPrice.ts +3 -4
- package/src/storage/IIntermediaryStorage.ts +4 -5
- package/src/storagemanager/IntermediaryStorageManager.ts +17 -9
- package/src/swaps/FromBtcBaseSwap.ts +9 -10
- package/src/swaps/FromBtcBaseSwapHandler.ts +133 -91
- package/src/swaps/FromBtcLnBaseSwapHandler.ts +2 -3
- package/src/swaps/ISwapPrice.ts +10 -20
- package/src/swaps/SwapHandler.ts +101 -35
- package/src/swaps/SwapHandlerSwap.ts +42 -17
- package/src/swaps/ToBtcBaseSwap.ts +20 -18
- package/src/swaps/ToBtcBaseSwapHandler.ts +33 -33
- package/src/swaps/frombtc_abstract/FromBtcAbs.ts +64 -97
- package/src/swaps/frombtc_abstract/FromBtcSwapAbs.ts +7 -8
- package/src/swaps/frombtc_trusted/FromBtcTrusted.ts +56 -55
- package/src/swaps/frombtc_trusted/FromBtcTrustedSwap.ts +28 -21
- package/src/swaps/frombtcln_abstract/FromBtcLnAbs.ts +81 -116
- package/src/swaps/frombtcln_abstract/FromBtcLnSwapAbs.ts +73 -9
- package/src/swaps/frombtcln_trusted/FromBtcLnTrusted.ts +39 -36
- package/src/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.ts +26 -12
- package/src/swaps/tobtc_abstract/ToBtcAbs.ts +82 -98
- package/src/swaps/tobtc_abstract/ToBtcSwapAbs.ts +25 -20
- package/src/swaps/tobtcln_abstract/ToBtcLnAbs.ts +106 -118
- package/src/swaps/tobtcln_abstract/ToBtcLnSwapAbs.ts +17 -9
- package/src/utils/Utils.ts +3 -4
- package/src/utils/paramcoders/ParamDecoder.ts +5 -5
- package/src/utils/paramcoders/SchemaVerifier.ts +10 -11
- package/src/utils/paramcoders/server/ServerParamDecoder.ts +1 -1
- package/src/wallets/IBitcoinWallet.ts +4 -5
- package/src/wallets/ILightningWallet.ts +21 -22
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.FromBtcLnAbs = void 0;
|
|
13
|
-
const BN = require("bn.js");
|
|
14
4
|
const crypto_1 = require("crypto");
|
|
15
5
|
const FromBtcLnSwapAbs_1 = require("./FromBtcLnSwapAbs");
|
|
16
6
|
const SwapHandler_1 = require("../SwapHandler");
|
|
@@ -27,240 +17,193 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
27
17
|
constructor(storageDirectory, path, chains, lightning, swapPricing, config) {
|
|
28
18
|
super(storageDirectory, path, chains, lightning, swapPricing);
|
|
29
19
|
this.type = SwapHandler_1.SwapHandlerType.FROM_BTCLN;
|
|
20
|
+
this.swapType = base_1.ChainSwapType.HTLC;
|
|
30
21
|
this.config = config;
|
|
31
22
|
this.config.invoiceTimeoutSeconds = this.config.invoiceTimeoutSeconds || 90;
|
|
32
23
|
}
|
|
33
|
-
processPastSwap(swap) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (!isInvoiceExpired)
|
|
45
|
-
return null;
|
|
46
|
-
this.swapLogger.info(swap, "processPastSwap(state=CREATED): swap LN invoice expired, cancelling, invoice: " + swap.pr);
|
|
47
|
-
yield swap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED);
|
|
48
|
-
return "CANCEL";
|
|
49
|
-
}
|
|
50
|
-
//Adjust the state of the swap and expiry
|
|
51
|
-
try {
|
|
52
|
-
yield this.htlcReceived(swap, invoice);
|
|
53
|
-
//Result is either FromBtcLnSwapState.RECEIVED or FromBtcLnSwapState.CANCELED
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
this.swapLogger.error(swap, "processPastSwap(state=CREATED): htlcReceived error", e);
|
|
57
|
-
}
|
|
58
|
-
// @ts-ignore Previous call (htlcReceived) mutates the state of the swap, so this is valid
|
|
59
|
-
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED) {
|
|
60
|
-
this.swapLogger.info(swap, "processPastSwap(state=CREATED): invoice CANCELED after htlcReceived(), cancelling, invoice: " + swap.pr);
|
|
61
|
-
return "CANCEL";
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED) {
|
|
66
|
-
const isAuthorizationExpired = yield swapContract.isInitAuthorizationExpired(swap.data, swap);
|
|
67
|
-
if (isAuthorizationExpired) {
|
|
68
|
-
const isCommited = yield swapContract.isCommited(swap.data);
|
|
69
|
-
if (!isCommited) {
|
|
70
|
-
this.swapLogger.info(swap, "processPastSwap(state=RECEIVED): swap not committed before authorization expiry, cancelling the LN invoice, invoice: " + swap.pr);
|
|
71
|
-
yield swap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED);
|
|
72
|
-
return "CANCEL";
|
|
73
|
-
}
|
|
74
|
-
this.swapLogger.info(swap, "processPastSwap(state=RECEIVED): swap committed (detected from processPastSwap), invoice: " + swap.pr);
|
|
75
|
-
yield swap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED);
|
|
76
|
-
yield this.storageManager.saveData(swap.data.getHash(), null, swap);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED || swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED) {
|
|
80
|
-
if (!swapContract.isExpired(signer.getAddress(), swap.data))
|
|
24
|
+
async processPastSwap(swap) {
|
|
25
|
+
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
26
|
+
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED) {
|
|
27
|
+
//Check if already paid
|
|
28
|
+
const parsedPR = await this.lightning.parsePaymentRequest(swap.pr);
|
|
29
|
+
const invoice = await this.lightning.getInvoice(parsedPR.id);
|
|
30
|
+
const isBeingPaid = invoice.status === "held";
|
|
31
|
+
if (!isBeingPaid) {
|
|
32
|
+
//Not paid
|
|
33
|
+
const isInvoiceExpired = parsedPR.expiryEpochMillis < Date.now();
|
|
34
|
+
if (!isInvoiceExpired)
|
|
81
35
|
return null;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
this.swapLogger.info(swap, "processPastSwap(state=COMMITED): swap timed out, refunding to self, invoice: " + swap.pr);
|
|
85
|
-
return "REFUND";
|
|
86
|
-
}
|
|
87
|
-
this.swapLogger.info(swap, "processPastSwap(state=RECEIVED): swap timed out, cancelling the LN invoice, invoice: " + swap.pr);
|
|
36
|
+
this.swapLogger.info(swap, "processPastSwap(state=CREATED): swap LN invoice expired, cancelling, invoice: " + swap.pr);
|
|
37
|
+
await swap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED);
|
|
88
38
|
return "CANCEL";
|
|
89
39
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
refundSwaps(refundSwaps) {
|
|
97
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
-
for (let refundSwap of refundSwaps) {
|
|
99
|
-
const { swapContract, signer } = this.getChain(refundSwap.chainIdentifier);
|
|
100
|
-
const unlock = refundSwap.lock(swapContract.refundTimeout);
|
|
101
|
-
if (unlock == null)
|
|
102
|
-
continue;
|
|
103
|
-
this.swapLogger.debug(refundSwap, "refundSwaps(): initiate refund of swap");
|
|
104
|
-
yield swapContract.refund(signer, refundSwap.data, true, false, { waitForConfirmation: true });
|
|
105
|
-
this.swapLogger.info(refundSwap, "refundsSwaps(): swap refunded, invoice: " + refundSwap.pr);
|
|
106
|
-
yield refundSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.REFUNDED);
|
|
107
|
-
unlock();
|
|
40
|
+
//Adjust the state of the swap and expiry
|
|
41
|
+
try {
|
|
42
|
+
await this.htlcReceived(swap, invoice);
|
|
43
|
+
//Result is either FromBtcLnSwapState.RECEIVED or FromBtcLnSwapState.CANCELED
|
|
108
44
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
cancelInvoices(swaps) {
|
|
112
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
-
for (let swap of swaps) {
|
|
114
|
-
//Refund
|
|
115
|
-
const paymentHash = swap.data.getHash();
|
|
116
|
-
try {
|
|
117
|
-
yield this.lightning.cancelHodlInvoice(paymentHash);
|
|
118
|
-
this.swapLogger.info(swap, "cancelInvoices(): invoice cancelled!");
|
|
119
|
-
yield this.removeSwapData(swap);
|
|
120
|
-
}
|
|
121
|
-
catch (e) {
|
|
122
|
-
this.swapLogger.error(swap, "cancelInvoices(): cannot cancel hodl invoice id", e);
|
|
123
|
-
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
this.swapLogger.error(swap, "processPastSwap(state=CREATED): htlcReceived error", e);
|
|
124
47
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
for (let swap of swaps) {
|
|
130
|
-
try {
|
|
131
|
-
yield this.lightning.settleHodlInvoice(swap.secret);
|
|
132
|
-
if (swap.metadata != null)
|
|
133
|
-
swap.metadata.times.htlcSettled = Date.now();
|
|
134
|
-
yield this.removeSwapData(swap, FromBtcLnSwapAbs_1.FromBtcLnSwapState.SETTLED);
|
|
135
|
-
this.swapLogger.info(swap, "settleInvoices(): invoice settled, secret: " + swap.secret);
|
|
136
|
-
}
|
|
137
|
-
catch (e) {
|
|
138
|
-
this.swapLogger.error(swap, "settleInvoices(): cannot settle invoice", e);
|
|
139
|
-
}
|
|
48
|
+
// @ts-ignore Previous call (htlcReceived) mutates the state of the swap, so this is valid
|
|
49
|
+
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED) {
|
|
50
|
+
this.swapLogger.info(swap, "processPastSwap(state=CREATED): invoice CANCELED after htlcReceived(), cancelling, invoice: " + swap.pr);
|
|
51
|
+
return "CANCEL";
|
|
140
52
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const queriedData = yield this.storageManager.query([
|
|
152
|
-
{
|
|
153
|
-
key: "state",
|
|
154
|
-
value: [
|
|
155
|
-
FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED,
|
|
156
|
-
FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED,
|
|
157
|
-
FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED,
|
|
158
|
-
FromBtcLnSwapAbs_1.FromBtcLnSwapState.CLAIMED,
|
|
159
|
-
FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED,
|
|
160
|
-
]
|
|
161
|
-
}
|
|
162
|
-
]);
|
|
163
|
-
for (let swap of queriedData) {
|
|
164
|
-
switch (yield this.processPastSwap(swap)) {
|
|
165
|
-
case "CANCEL":
|
|
166
|
-
cancelInvoices.push(swap);
|
|
167
|
-
break;
|
|
168
|
-
case "SETTLE":
|
|
169
|
-
settleInvoices.push(swap);
|
|
170
|
-
break;
|
|
171
|
-
case "REFUND":
|
|
172
|
-
refundSwaps.push(swap);
|
|
173
|
-
break;
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED) {
|
|
56
|
+
const isAuthorizationExpired = await swapContract.isInitAuthorizationExpired(swap.data, swap);
|
|
57
|
+
if (isAuthorizationExpired) {
|
|
58
|
+
const isCommited = await swapContract.isCommited(swap.data);
|
|
59
|
+
if (!isCommited) {
|
|
60
|
+
this.swapLogger.info(swap, "processPastSwap(state=RECEIVED): swap not committed before authorization expiry, cancelling the LN invoice, invoice: " + swap.pr);
|
|
61
|
+
await swap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED);
|
|
62
|
+
return "CANCEL";
|
|
174
63
|
}
|
|
64
|
+
this.swapLogger.info(swap, "processPastSwap(state=RECEIVED): swap committed (detected from processPastSwap), invoice: " + swap.pr);
|
|
65
|
+
await swap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED);
|
|
66
|
+
await this.saveSwapData(swap);
|
|
175
67
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
//Only process HTLC requests
|
|
185
|
-
if (event.swapType !== base_1.ChainSwapType.HTLC)
|
|
186
|
-
return;
|
|
187
|
-
const swapData = yield event.swapData();
|
|
188
|
-
const { swapContract, signer } = this.getChain(chainIdentifier);
|
|
189
|
-
if (!swapData.isOfferer(signer.getAddress()))
|
|
190
|
-
return;
|
|
191
|
-
if (swapData.isPayIn())
|
|
192
|
-
return;
|
|
193
|
-
const paymentHash = event.paymentHash;
|
|
194
|
-
const savedSwap = yield this.storageManager.getData(paymentHash, null);
|
|
195
|
-
if (savedSwap == null || savedSwap.chainIdentifier !== chainIdentifier)
|
|
196
|
-
return;
|
|
197
|
-
this.swapLogger.info(savedSwap, "SC: InitializeEvent: HTLC initialized by the client, invoice: " + savedSwap.pr);
|
|
198
|
-
savedSwap.txIds.init = (_a = event.meta) === null || _a === void 0 ? void 0 : _a.txId;
|
|
199
|
-
if (savedSwap.metadata != null)
|
|
200
|
-
savedSwap.metadata.times.initTxReceived = Date.now();
|
|
201
|
-
if (savedSwap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED) {
|
|
202
|
-
yield savedSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED);
|
|
203
|
-
savedSwap.data = swapData;
|
|
204
|
-
yield this.storageManager.saveData(paymentHash, null, savedSwap);
|
|
68
|
+
}
|
|
69
|
+
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED || swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED) {
|
|
70
|
+
if (!await swapContract.isExpired(signer.getAddress(), swap.data))
|
|
71
|
+
return null;
|
|
72
|
+
const isCommited = await swapContract.isCommited(swap.data);
|
|
73
|
+
if (isCommited) {
|
|
74
|
+
this.swapLogger.info(swap, "processPastSwap(state=COMMITED): swap timed out, refunding to self, invoice: " + swap.pr);
|
|
75
|
+
return "REFUND";
|
|
205
76
|
}
|
|
206
|
-
|
|
77
|
+
this.swapLogger.info(swap, "processPastSwap(state=RECEIVED): swap timed out, cancelling the LN invoice, invoice: " + swap.pr);
|
|
78
|
+
return "CANCEL";
|
|
79
|
+
}
|
|
80
|
+
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CLAIMED)
|
|
81
|
+
return "SETTLE";
|
|
82
|
+
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED)
|
|
83
|
+
return "CANCEL";
|
|
207
84
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
85
|
+
async refundSwaps(refundSwaps) {
|
|
86
|
+
for (let refundSwap of refundSwaps) {
|
|
87
|
+
const { swapContract, signer } = this.getChain(refundSwap.chainIdentifier);
|
|
88
|
+
const unlock = refundSwap.lock(swapContract.refundTimeout);
|
|
89
|
+
if (unlock == null)
|
|
90
|
+
continue;
|
|
91
|
+
this.swapLogger.debug(refundSwap, "refundSwaps(): initiate refund of swap");
|
|
92
|
+
await swapContract.refund(signer, refundSwap.data, true, false, { waitForConfirmation: true });
|
|
93
|
+
this.swapLogger.info(refundSwap, "refundsSwaps(): swap refunded, invoice: " + refundSwap.pr);
|
|
94
|
+
await refundSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.REFUNDED);
|
|
95
|
+
unlock();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async cancelInvoices(swaps) {
|
|
99
|
+
for (let swap of swaps) {
|
|
100
|
+
//Refund
|
|
101
|
+
const paymentHash = swap.lnPaymentHash;
|
|
224
102
|
try {
|
|
225
|
-
|
|
226
|
-
this.swapLogger.info(
|
|
227
|
-
|
|
228
|
-
if (savedSwap.metadata != null)
|
|
229
|
-
savedSwap.metadata.times.htlcSettled = Date.now();
|
|
230
|
-
yield this.removeSwapData(savedSwap, FromBtcLnSwapAbs_1.FromBtcLnSwapState.SETTLED);
|
|
103
|
+
await this.lightning.cancelHodlInvoice(paymentHash);
|
|
104
|
+
this.swapLogger.info(swap, "cancelInvoices(): invoice cancelled!");
|
|
105
|
+
await this.removeSwapData(swap);
|
|
231
106
|
}
|
|
232
107
|
catch (e) {
|
|
233
|
-
this.swapLogger.error(
|
|
234
|
-
savedSwap.secret = secretHex;
|
|
235
|
-
yield savedSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CLAIMED);
|
|
236
|
-
yield this.storageManager.saveData(paymentHashHex, null, savedSwap);
|
|
108
|
+
this.swapLogger.error(swap, "cancelInvoices(): cannot cancel hodl invoice id", e);
|
|
237
109
|
}
|
|
238
|
-
}
|
|
110
|
+
}
|
|
239
111
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
243
|
-
//Refund
|
|
244
|
-
//Try to get the hash from the refundMap
|
|
245
|
-
if (event.paymentHash == null)
|
|
246
|
-
return;
|
|
247
|
-
const savedSwap = yield this.storageManager.getData(event.paymentHash, null);
|
|
248
|
-
if (savedSwap == null || savedSwap.chainIdentifier !== chainIdentifier)
|
|
249
|
-
return;
|
|
250
|
-
savedSwap.txIds.refund = (_a = event.meta) === null || _a === void 0 ? void 0 : _a.txId;
|
|
251
|
-
this.swapLogger.info(savedSwap, "SC: RefundEvent: swap refunded to us, invoice: " + savedSwap.pr);
|
|
112
|
+
async settleInvoices(swaps) {
|
|
113
|
+
for (let swap of swaps) {
|
|
252
114
|
try {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
115
|
+
await this.lightning.settleHodlInvoice(swap.secret);
|
|
116
|
+
if (swap.metadata != null)
|
|
117
|
+
swap.metadata.times.htlcSettled = Date.now();
|
|
118
|
+
await this.removeSwapData(swap, FromBtcLnSwapAbs_1.FromBtcLnSwapState.SETTLED);
|
|
119
|
+
this.swapLogger.info(swap, "settleInvoices(): invoice settled, secret: " + swap.secret);
|
|
256
120
|
}
|
|
257
121
|
catch (e) {
|
|
258
|
-
this.swapLogger.error(
|
|
259
|
-
yield savedSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED);
|
|
260
|
-
// await PluginManager.swapStateChange(savedSwap);
|
|
261
|
-
yield this.storageManager.saveData(event.paymentHash, null, savedSwap);
|
|
122
|
+
this.swapLogger.error(swap, "settleInvoices(): cannot settle invoice", e);
|
|
262
123
|
}
|
|
263
|
-
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Checks past swaps, refunds and deletes ones that are already expired.
|
|
128
|
+
*/
|
|
129
|
+
async processPastSwaps() {
|
|
130
|
+
const settleInvoices = [];
|
|
131
|
+
const cancelInvoices = [];
|
|
132
|
+
const refundSwaps = [];
|
|
133
|
+
const queriedData = await this.storageManager.query([
|
|
134
|
+
{
|
|
135
|
+
key: "state",
|
|
136
|
+
value: [
|
|
137
|
+
FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED,
|
|
138
|
+
FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED,
|
|
139
|
+
FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED,
|
|
140
|
+
FromBtcLnSwapAbs_1.FromBtcLnSwapState.CLAIMED,
|
|
141
|
+
FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED,
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
]);
|
|
145
|
+
for (let { obj: swap } of queriedData) {
|
|
146
|
+
switch (await this.processPastSwap(swap)) {
|
|
147
|
+
case "CANCEL":
|
|
148
|
+
cancelInvoices.push(swap);
|
|
149
|
+
break;
|
|
150
|
+
case "SETTLE":
|
|
151
|
+
settleInvoices.push(swap);
|
|
152
|
+
break;
|
|
153
|
+
case "REFUND":
|
|
154
|
+
refundSwaps.push(swap);
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
await this.refundSwaps(refundSwaps);
|
|
159
|
+
await this.cancelInvoices(cancelInvoices);
|
|
160
|
+
await this.settleInvoices(settleInvoices);
|
|
161
|
+
}
|
|
162
|
+
async processInitializeEvent(chainIdentifier, savedSwap, event) {
|
|
163
|
+
this.swapLogger.info(savedSwap, "SC: InitializeEvent: HTLC initialized by the client, invoice: " + savedSwap.pr);
|
|
164
|
+
if (savedSwap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED) {
|
|
165
|
+
await savedSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.COMMITED);
|
|
166
|
+
await this.saveSwapData(savedSwap);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async processClaimEvent(chainIdentifier, savedSwap, event) {
|
|
170
|
+
//Claim
|
|
171
|
+
//This is the important part, we need to catch the claim TX, else we may lose money
|
|
172
|
+
const secret = Buffer.from(event.result, "hex");
|
|
173
|
+
const paymentHash = (0, crypto_1.createHash)("sha256").update(secret).digest();
|
|
174
|
+
const secretHex = secret.toString("hex");
|
|
175
|
+
const paymentHashHex = paymentHash.toString("hex");
|
|
176
|
+
if (savedSwap.lnPaymentHash !== paymentHashHex)
|
|
177
|
+
return;
|
|
178
|
+
this.swapLogger.info(savedSwap, "SC: ClaimEvent: swap HTLC successfully claimed by the client, invoice: " + savedSwap.pr);
|
|
179
|
+
try {
|
|
180
|
+
await this.lightning.settleHodlInvoice(secretHex);
|
|
181
|
+
this.swapLogger.info(savedSwap, "SC: ClaimEvent: invoice settled, secret: " + secretHex);
|
|
182
|
+
savedSwap.secret = secretHex;
|
|
183
|
+
if (savedSwap.metadata != null)
|
|
184
|
+
savedSwap.metadata.times.htlcSettled = Date.now();
|
|
185
|
+
await this.removeSwapData(savedSwap, FromBtcLnSwapAbs_1.FromBtcLnSwapState.SETTLED);
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
this.swapLogger.error(savedSwap, "SC: ClaimEvent: cannot settle invoice", e);
|
|
189
|
+
savedSwap.secret = secretHex;
|
|
190
|
+
await savedSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CLAIMED);
|
|
191
|
+
await this.saveSwapData(savedSwap);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async processRefundEvent(chainIdentifier, savedSwap, event) {
|
|
195
|
+
this.swapLogger.info(savedSwap, "SC: RefundEvent: swap refunded to us, invoice: " + savedSwap.pr);
|
|
196
|
+
try {
|
|
197
|
+
await this.lightning.cancelHodlInvoice(savedSwap.lnPaymentHash);
|
|
198
|
+
this.swapLogger.info(savedSwap, "SC: RefundEvent: invoice cancelled");
|
|
199
|
+
await this.removeSwapData(savedSwap, FromBtcLnSwapAbs_1.FromBtcLnSwapState.REFUNDED);
|
|
200
|
+
}
|
|
201
|
+
catch (e) {
|
|
202
|
+
this.swapLogger.error(savedSwap, "SC: RefundEvent: cannot cancel invoice", e);
|
|
203
|
+
await savedSwap.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED);
|
|
204
|
+
// await PluginManager.swapStateChange(savedSwap);
|
|
205
|
+
await this.saveSwapData(savedSwap);
|
|
206
|
+
}
|
|
264
207
|
}
|
|
265
208
|
/**
|
|
266
209
|
* Called when lightning HTLC is received, also signs an init transaction on the smart chain side, expiry of the
|
|
@@ -269,60 +212,58 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
269
212
|
* @param invoiceData
|
|
270
213
|
* @param invoice
|
|
271
214
|
*/
|
|
272
|
-
htlcReceived(invoiceData, invoice) {
|
|
273
|
-
|
|
274
|
-
|
|
215
|
+
async htlcReceived(invoiceData, invoice) {
|
|
216
|
+
this.swapLogger.debug(invoiceData, "htlcReceived(): invoice: ", invoice);
|
|
217
|
+
if (invoiceData.metadata != null)
|
|
218
|
+
invoiceData.metadata.times.htlcReceived = Date.now();
|
|
219
|
+
const useToken = invoiceData.token;
|
|
220
|
+
const escrowAmount = invoiceData.totalTokens;
|
|
221
|
+
//Create abort controller for parallel fetches
|
|
222
|
+
const abortController = new AbortController();
|
|
223
|
+
//Pre-fetch data
|
|
224
|
+
const balancePrefetch = this.getBalancePrefetch(invoiceData.chainIdentifier, useToken, abortController);
|
|
225
|
+
const blockheightPrefetch = this.getBlockheightPrefetch(abortController);
|
|
226
|
+
const signDataPrefetchPromise = this.getSignDataPrefetch(invoiceData.chainIdentifier, abortController);
|
|
227
|
+
let expiryTimeout;
|
|
228
|
+
try {
|
|
229
|
+
//Check if we have enough liquidity to proceed
|
|
230
|
+
await this.checkBalance(escrowAmount, balancePrefetch, abortController.signal);
|
|
275
231
|
if (invoiceData.metadata != null)
|
|
276
|
-
invoiceData.metadata.times.
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
//Create abort controller for parallel fetches
|
|
280
|
-
const abortController = new AbortController();
|
|
281
|
-
//Pre-fetch data
|
|
282
|
-
const balancePrefetch = this.getBalancePrefetch(invoiceData.chainIdentifier, useToken, abortController);
|
|
283
|
-
const blockheightPrefetch = this.getBlockheightPrefetch(abortController);
|
|
284
|
-
const signDataPrefetchPromise = this.getSignDataPrefetch(invoiceData.chainIdentifier, abortController);
|
|
285
|
-
let expiryTimeout;
|
|
286
|
-
try {
|
|
287
|
-
//Check if we have enough liquidity to proceed
|
|
288
|
-
yield this.checkBalance(sendAmount, balancePrefetch, abortController.signal);
|
|
289
|
-
if (invoiceData.metadata != null)
|
|
290
|
-
invoiceData.metadata.times.htlcBalanceChecked = Date.now();
|
|
291
|
-
//Check if HTLC expiry is long enough
|
|
292
|
-
expiryTimeout = yield this.checkHtlcExpiry(invoice, blockheightPrefetch, abortController.signal);
|
|
293
|
-
if (invoiceData.metadata != null)
|
|
294
|
-
invoiceData.metadata.times.htlcTimeoutCalculated = Date.now();
|
|
295
|
-
}
|
|
296
|
-
catch (e) {
|
|
297
|
-
if (!abortController.signal.aborted) {
|
|
298
|
-
if (invoiceData.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED)
|
|
299
|
-
yield this.cancelSwapAndInvoice(invoiceData);
|
|
300
|
-
}
|
|
301
|
-
throw e;
|
|
302
|
-
}
|
|
303
|
-
const { swapContract, signer } = this.getChain(invoiceData.chainIdentifier);
|
|
304
|
-
//Create real swap data
|
|
305
|
-
const payInvoiceObject = yield swapContract.createSwapData(base_1.ChainSwapType.HTLC, signer.getAddress(), invoiceData.data.getClaimer(), useToken, sendAmount, invoice.id, new BN(0), new BN(Math.floor(Date.now() / 1000)).add(expiryTimeout), new BN(0), 0, false, true, invoiceData.data.getSecurityDeposit(), new BN(0));
|
|
306
|
-
abortController.signal.throwIfAborted();
|
|
307
|
-
if (invoiceData.metadata != null)
|
|
308
|
-
invoiceData.metadata.times.htlcSwapCreated = Date.now();
|
|
309
|
-
//Sign swap data
|
|
310
|
-
const sigData = yield swapContract.getInitSignature(signer, payInvoiceObject, this.config.authorizationTimeout, signDataPrefetchPromise == null ? null : yield signDataPrefetchPromise, invoiceData.feeRate);
|
|
311
|
-
//No need to check abortController anymore since all pending promises are resolved by now
|
|
232
|
+
invoiceData.metadata.times.htlcBalanceChecked = Date.now();
|
|
233
|
+
//Check if HTLC expiry is long enough
|
|
234
|
+
expiryTimeout = await this.checkHtlcExpiry(invoice, blockheightPrefetch, abortController.signal);
|
|
312
235
|
if (invoiceData.metadata != null)
|
|
313
|
-
invoiceData.metadata.times.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
invoiceData.
|
|
318
|
-
|
|
319
|
-
invoiceData.signature = sigData.signature;
|
|
320
|
-
//Setting the state variable is done outside the promise, so is done synchronously
|
|
321
|
-
yield invoiceData.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED);
|
|
322
|
-
yield this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
323
|
-
return;
|
|
236
|
+
invoiceData.metadata.times.htlcTimeoutCalculated = Date.now();
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
if (!abortController.signal.aborted) {
|
|
240
|
+
if (invoiceData.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED)
|
|
241
|
+
await this.cancelSwapAndInvoice(invoiceData);
|
|
324
242
|
}
|
|
325
|
-
|
|
243
|
+
throw e;
|
|
244
|
+
}
|
|
245
|
+
const { swapContract, signer } = this.getChain(invoiceData.chainIdentifier);
|
|
246
|
+
//Create real swap data
|
|
247
|
+
const payInvoiceObject = await swapContract.createSwapData(base_1.ChainSwapType.HTLC, signer.getAddress(), invoiceData.claimer, useToken, escrowAmount, invoiceData.claimHash, 0n, BigInt(Math.floor(Date.now() / 1000)) + expiryTimeout, false, true, invoiceData.securityDeposit, 0n, invoiceData.depositToken);
|
|
248
|
+
abortController.signal.throwIfAborted();
|
|
249
|
+
if (invoiceData.metadata != null)
|
|
250
|
+
invoiceData.metadata.times.htlcSwapCreated = Date.now();
|
|
251
|
+
//Sign swap data
|
|
252
|
+
const sigData = await swapContract.getInitSignature(signer, payInvoiceObject, this.getInitAuthorizationTimeout(invoiceData.chainIdentifier), signDataPrefetchPromise == null ? null : await signDataPrefetchPromise, invoiceData.feeRate);
|
|
253
|
+
//No need to check abortController anymore since all pending promises are resolved by now
|
|
254
|
+
if (invoiceData.metadata != null)
|
|
255
|
+
invoiceData.metadata.times.htlcSwapSigned = Date.now();
|
|
256
|
+
//Important to prevent race condition and issuing 2 signed init messages at the same time
|
|
257
|
+
if (invoiceData.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED) {
|
|
258
|
+
invoiceData.data = payInvoiceObject;
|
|
259
|
+
invoiceData.prefix = sigData.prefix;
|
|
260
|
+
invoiceData.timeout = sigData.timeout;
|
|
261
|
+
invoiceData.signature = sigData.signature;
|
|
262
|
+
//Setting the state variable is done outside the promise, so is done synchronously
|
|
263
|
+
await invoiceData.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED);
|
|
264
|
+
await this.saveSwapData(invoiceData);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
326
267
|
}
|
|
327
268
|
/**
|
|
328
269
|
* Checks invoice description hash
|
|
@@ -387,46 +328,42 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
387
328
|
* @throws {DefinedRuntimeError} Will throw if HTLC expires too soon and therefore cannot be processed
|
|
388
329
|
* @returns expiry timeout in seconds
|
|
389
330
|
*/
|
|
390
|
-
checkHtlcExpiry(invoice, blockheightPrefetch, signal) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
return this.config.minCltv.mul(this.config.bitcoinBlocktime.div(this.config.safetyFactor)).sub(this.config.gracePeriod);
|
|
408
|
-
});
|
|
331
|
+
async checkHtlcExpiry(invoice, blockheightPrefetch, signal) {
|
|
332
|
+
const timeout = this.getInvoicePaymentsTimeout(invoice);
|
|
333
|
+
const current_block_height = await blockheightPrefetch;
|
|
334
|
+
signal.throwIfAborted();
|
|
335
|
+
const blockDelta = BigInt(timeout - current_block_height);
|
|
336
|
+
const htlcExpiresTooSoon = blockDelta < this.config.minCltv;
|
|
337
|
+
if (htlcExpiresTooSoon) {
|
|
338
|
+
throw {
|
|
339
|
+
code: 20002,
|
|
340
|
+
msg: "Not enough time to reliably process the swap",
|
|
341
|
+
data: {
|
|
342
|
+
requiredDelta: this.config.minCltv.toString(10),
|
|
343
|
+
actualDelta: blockDelta.toString(10)
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
return (this.config.minCltv * this.config.bitcoinBlocktime / this.config.safetyFactor) - this.config.gracePeriod;
|
|
409
348
|
}
|
|
410
349
|
/**
|
|
411
350
|
* Cancels the swap (CANCELED state) & also cancels the LN invoice (including all pending HTLCs)
|
|
412
351
|
*
|
|
413
352
|
* @param invoiceData
|
|
414
353
|
*/
|
|
415
|
-
cancelSwapAndInvoice(invoiceData) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
yield this.removeSwapData(invoiceData);
|
|
423
|
-
this.swapLogger.info(invoiceData, "cancelSwapAndInvoice(): swap removed & invoice cancelled, invoice: ", invoiceData.pr);
|
|
424
|
-
});
|
|
354
|
+
async cancelSwapAndInvoice(invoiceData) {
|
|
355
|
+
if (invoiceData.state !== FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED)
|
|
356
|
+
return;
|
|
357
|
+
await invoiceData.setState(FromBtcLnSwapAbs_1.FromBtcLnSwapState.CANCELED);
|
|
358
|
+
await this.lightning.cancelHodlInvoice(invoiceData.lnPaymentHash);
|
|
359
|
+
await this.removeSwapData(invoiceData);
|
|
360
|
+
this.swapLogger.info(invoiceData, "cancelSwapAndInvoice(): swap removed & invoice cancelled, invoice: ", invoiceData.pr);
|
|
425
361
|
}
|
|
426
362
|
;
|
|
427
363
|
getDummySwapData(chainIdentifier, useToken, address, paymentHash) {
|
|
428
364
|
const { swapContract, signer } = this.getChain(chainIdentifier);
|
|
429
|
-
|
|
365
|
+
const dummyAmount = BigInt(Math.floor(Math.random() * 0x1000000));
|
|
366
|
+
return swapContract.createSwapData(base_1.ChainSwapType.HTLC, signer.getAddress(), address, useToken, dummyAmount, swapContract.getHashForHtlc(Buffer.from(paymentHash, "hex")).toString("hex"), base_1.BigIntBufferUtils.fromBuffer((0, crypto_1.randomBytes)(8)), BigInt(Math.floor(Date.now() / 1000)), false, true, BigInt(Math.floor(Math.random() * 0x10000)), 0n);
|
|
430
367
|
}
|
|
431
368
|
/**
|
|
432
369
|
*
|
|
@@ -436,64 +373,63 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
436
373
|
* @throws {DefinedRuntimeError} Will throw if the lightning invoice is not found, or if it isn't in the HELD state
|
|
437
374
|
* @returns the fetched lightning invoice
|
|
438
375
|
*/
|
|
439
|
-
checkInvoiceStatus(paymentHash) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
376
|
+
async checkInvoiceStatus(paymentHash) {
|
|
377
|
+
const invoice = await this.lightning.getInvoice(paymentHash);
|
|
378
|
+
if (invoice == null)
|
|
379
|
+
throw {
|
|
380
|
+
_httpStatus: 200,
|
|
381
|
+
code: 10001,
|
|
382
|
+
msg: "Invoice expired/canceled"
|
|
383
|
+
};
|
|
384
|
+
const arr = invoice.description.split("-");
|
|
385
|
+
let chainIdentifier;
|
|
386
|
+
let address;
|
|
387
|
+
if (arr.length > 1) {
|
|
388
|
+
chainIdentifier = arr[0];
|
|
389
|
+
address = arr[1];
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
chainIdentifier = this.chains.default;
|
|
393
|
+
address = invoice.description;
|
|
394
|
+
}
|
|
395
|
+
const { swapContract } = this.getChain(chainIdentifier);
|
|
396
|
+
if (!swapContract.isValidAddress(address))
|
|
397
|
+
throw {
|
|
398
|
+
_httpStatus: 200,
|
|
399
|
+
code: 10001,
|
|
400
|
+
msg: "Invoice expired/canceled"
|
|
401
|
+
};
|
|
402
|
+
switch (invoice.status) {
|
|
403
|
+
case "canceled":
|
|
443
404
|
throw {
|
|
444
405
|
_httpStatus: 200,
|
|
445
406
|
code: 10001,
|
|
446
407
|
msg: "Invoice expired/canceled"
|
|
447
408
|
};
|
|
448
|
-
|
|
449
|
-
let chainIdentifier;
|
|
450
|
-
let address;
|
|
451
|
-
if (arr.length > 1) {
|
|
452
|
-
chainIdentifier = arr[0];
|
|
453
|
-
address = arr[1];
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
chainIdentifier = this.chains.default;
|
|
457
|
-
address = invoice.description;
|
|
458
|
-
}
|
|
459
|
-
const { swapContract } = this.getChain(chainIdentifier);
|
|
460
|
-
if (!swapContract.isValidAddress(address))
|
|
409
|
+
case "confirmed":
|
|
461
410
|
throw {
|
|
462
411
|
_httpStatus: 200,
|
|
463
|
-
code:
|
|
464
|
-
msg: "Invoice
|
|
412
|
+
code: 10002,
|
|
413
|
+
msg: "Invoice already paid"
|
|
465
414
|
};
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
_httpStatus: 200,
|
|
476
|
-
code: 10002,
|
|
477
|
-
msg: "Invoice already paid"
|
|
478
|
-
};
|
|
479
|
-
case "unpaid":
|
|
480
|
-
throw {
|
|
481
|
-
_httpStatus: 200,
|
|
482
|
-
code: 10003,
|
|
483
|
-
msg: "Invoice yet unpaid"
|
|
484
|
-
};
|
|
485
|
-
default:
|
|
486
|
-
return invoice;
|
|
487
|
-
}
|
|
488
|
-
});
|
|
415
|
+
case "unpaid":
|
|
416
|
+
throw {
|
|
417
|
+
_httpStatus: 200,
|
|
418
|
+
code: 10003,
|
|
419
|
+
msg: "Invoice yet unpaid"
|
|
420
|
+
};
|
|
421
|
+
default:
|
|
422
|
+
return invoice;
|
|
423
|
+
}
|
|
489
424
|
}
|
|
490
425
|
startRestServer(restServer) {
|
|
491
426
|
restServer.use(this.path + "/createInvoice", (0, ServerParamDecoder_1.serverParamDecoder)(10 * 1000));
|
|
492
|
-
restServer.post(this.path + "/createInvoice", (0, Utils_1.expressHandlerWrapper)((req, res) =>
|
|
493
|
-
var _a;
|
|
427
|
+
restServer.post(this.path + "/createInvoice", (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
494
428
|
const metadata = { request: {}, times: {} };
|
|
495
|
-
const chainIdentifier =
|
|
429
|
+
const chainIdentifier = req.query.chain ?? this.chains.default;
|
|
496
430
|
const { swapContract, signer } = this.getChain(chainIdentifier);
|
|
431
|
+
const depositToken = req.query.depositToken ?? swapContract.getNativeCurrencyAddress();
|
|
432
|
+
this.checkAllowedDepositToken(chainIdentifier, depositToken);
|
|
497
433
|
metadata.times.requestReceived = Date.now();
|
|
498
434
|
/**
|
|
499
435
|
* address: string solana address of the recipient
|
|
@@ -506,7 +442,7 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
506
442
|
*Sent later:
|
|
507
443
|
* feeRate: string Fee rate to use for the init signature
|
|
508
444
|
*/
|
|
509
|
-
const parsedBody =
|
|
445
|
+
const parsedBody = await req.paramReader.getParams({
|
|
510
446
|
address: (val) => val != null &&
|
|
511
447
|
typeof (val) === "string" &&
|
|
512
448
|
swapContract.isValidAddress(val) ? val : null,
|
|
@@ -514,7 +450,7 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
514
450
|
typeof (val) === "string" &&
|
|
515
451
|
val.length === 64 &&
|
|
516
452
|
Utils_1.HEX_REGEX.test(val) ? val : null,
|
|
517
|
-
amount: SchemaVerifier_1.FieldTypeEnum.
|
|
453
|
+
amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
|
|
518
454
|
token: (val) => val != null &&
|
|
519
455
|
typeof (val) === "string" &&
|
|
520
456
|
this.isTokenSupported(chainIdentifier, val) ? val : null,
|
|
@@ -537,61 +473,58 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
537
473
|
const useToken = parsedBody.token;
|
|
538
474
|
//Check request params
|
|
539
475
|
this.checkDescriptionHash(parsedBody.descriptionHash);
|
|
540
|
-
const fees =
|
|
476
|
+
const fees = await this.preCheckAmounts(request, requestedAmount, useToken);
|
|
541
477
|
metadata.times.requestChecked = Date.now();
|
|
542
478
|
//Create abortController for parallel prefetches
|
|
543
479
|
const responseStream = res.responseStream;
|
|
544
480
|
const abortController = this.getAbortController(responseStream);
|
|
545
481
|
//Pre-fetch data
|
|
546
|
-
const { pricePrefetchPromise,
|
|
482
|
+
const { pricePrefetchPromise, gasTokenPricePrefetchPromise, depositTokenPricePrefetchPromise } = this.getFromBtcPricePrefetches(chainIdentifier, useToken, depositToken, abortController);
|
|
547
483
|
const balancePrefetch = this.getBalancePrefetch(chainIdentifier, useToken, abortController);
|
|
548
484
|
const channelsPrefetch = this.getChannelsPrefetch(abortController);
|
|
549
|
-
const dummySwapData =
|
|
485
|
+
const dummySwapData = await this.getDummySwapData(chainIdentifier, useToken, parsedBody.address, parsedBody.paymentHash);
|
|
550
486
|
abortController.signal.throwIfAborted();
|
|
551
|
-
const baseSDPromise = this.getBaseSecurityDepositPrefetch(chainIdentifier, dummySwapData, abortController);
|
|
487
|
+
const baseSDPromise = this.getBaseSecurityDepositPrefetch(chainIdentifier, dummySwapData, depositToken, gasTokenPricePrefetchPromise, depositTokenPricePrefetchPromise, abortController);
|
|
552
488
|
//Asynchronously send the node's public key to the client
|
|
553
489
|
this.sendPublicKeyAsync(responseStream);
|
|
554
490
|
//Check valid amount specified (min/max)
|
|
555
|
-
const { amountBD, swapFee, swapFeeInToken, totalInToken } =
|
|
491
|
+
const { amountBD, swapFee, swapFeeInToken, totalInToken } = await this.checkFromBtcAmount(request, requestedAmount, fees, useToken, abortController.signal, pricePrefetchPromise);
|
|
556
492
|
metadata.times.priceCalculated = Date.now();
|
|
557
493
|
//Check if we have enough funds to honor the request
|
|
558
|
-
|
|
559
|
-
|
|
494
|
+
await this.checkBalance(totalInToken, balancePrefetch, abortController.signal);
|
|
495
|
+
await this.checkInboundLiquidity(amountBD, channelsPrefetch, abortController.signal);
|
|
560
496
|
metadata.times.balanceChecked = Date.now();
|
|
561
497
|
//Create swap
|
|
562
498
|
const hodlInvoiceObj = {
|
|
563
499
|
description: chainIdentifier + "-" + parsedBody.address,
|
|
564
|
-
cltvDelta: this.config.minCltv
|
|
500
|
+
cltvDelta: Number(this.config.minCltv) + 5,
|
|
565
501
|
expiresAt: Date.now() + (this.config.invoiceTimeoutSeconds * 1000),
|
|
566
502
|
id: parsedBody.paymentHash,
|
|
567
|
-
mtokens: amountBD
|
|
503
|
+
mtokens: amountBD * 1000n,
|
|
568
504
|
descriptionHash: parsedBody.descriptionHash
|
|
569
505
|
};
|
|
570
506
|
metadata.invoiceRequest = hodlInvoiceObj;
|
|
571
|
-
const hodlInvoice =
|
|
507
|
+
const hodlInvoice = await this.lightning.createHodlInvoice(hodlInvoiceObj);
|
|
572
508
|
abortController.signal.throwIfAborted();
|
|
573
509
|
metadata.times.invoiceCreated = Date.now();
|
|
574
|
-
metadata.invoiceResponse =
|
|
575
|
-
const createdSwap = new FromBtcLnSwapAbs_1.FromBtcLnSwapAbs(chainIdentifier, hodlInvoice.request, hodlInvoice.mtokens, swapFee, swapFeeInToken);
|
|
510
|
+
metadata.invoiceResponse = { ...hodlInvoice };
|
|
576
511
|
//Pre-compute the security deposit
|
|
577
|
-
const expiryTimeout = this.config.minCltv
|
|
578
|
-
const totalSecurityDeposit =
|
|
512
|
+
const expiryTimeout = (this.config.minCltv * this.config.bitcoinBlocktime / this.config.safetyFactor) - this.config.gracePeriod;
|
|
513
|
+
const totalSecurityDeposit = await this.getSecurityDeposit(chainIdentifier, amountBD, swapFee, expiryTimeout, baseSDPromise, depositToken, depositTokenPricePrefetchPromise, abortController.signal, metadata);
|
|
579
514
|
metadata.times.securityDepositCalculated = Date.now();
|
|
580
|
-
|
|
581
|
-
createdSwap.data = yield swapContract.createSwapData(base_1.ChainSwapType.HTLC, signer.getAddress(), parsedBody.address, useToken, totalInToken, parsedBody.paymentHash, new BN(0), null, null, 0, false, true, totalSecurityDeposit, new BN(0));
|
|
582
|
-
abortController.signal.throwIfAborted();
|
|
515
|
+
const createdSwap = new FromBtcLnSwapAbs_1.FromBtcLnSwapAbs(chainIdentifier, hodlInvoice.request, parsedBody.paymentHash, hodlInvoice.mtokens, swapFee, swapFeeInToken, parsedBody.address, useToken, totalInToken, swapContract.getHashForHtlc(Buffer.from(parsedBody.paymentHash, "hex")).toString("hex"), totalSecurityDeposit, depositToken);
|
|
583
516
|
metadata.times.swapCreated = Date.now();
|
|
584
517
|
createdSwap.metadata = metadata;
|
|
585
518
|
//Save the desired fee rate for the signature
|
|
586
|
-
const feeRateObj =
|
|
519
|
+
const feeRateObj = await req.paramReader.getParams({
|
|
587
520
|
feeRate: SchemaVerifier_1.FieldTypeEnum.String
|
|
588
|
-
}).catch(
|
|
521
|
+
}).catch(() => null);
|
|
589
522
|
abortController.signal.throwIfAborted();
|
|
590
|
-
createdSwap.feeRate =
|
|
591
|
-
|
|
592
|
-
|
|
523
|
+
createdSwap.feeRate = feeRateObj?.feeRate != null && typeof (feeRateObj.feeRate) === "string" ? feeRateObj.feeRate : null;
|
|
524
|
+
await PluginManager_1.PluginManager.swapCreate(createdSwap);
|
|
525
|
+
await this.saveSwapData(createdSwap);
|
|
593
526
|
this.swapLogger.info(createdSwap, "REST: /createInvoice: Created swap invoice: " + hodlInvoice.request + " amount: " + amountBD.toString(10));
|
|
594
|
-
|
|
527
|
+
await responseStream.writeParamsAndEnd({
|
|
595
528
|
code: 20000,
|
|
596
529
|
msg: "Success",
|
|
597
530
|
data: {
|
|
@@ -602,37 +535,37 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
602
535
|
securityDeposit: totalSecurityDeposit.toString(10)
|
|
603
536
|
}
|
|
604
537
|
});
|
|
605
|
-
}))
|
|
606
|
-
const getInvoiceStatus = (0, Utils_1.expressHandlerWrapper)((req, res) =>
|
|
538
|
+
}));
|
|
539
|
+
const getInvoiceStatus = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
607
540
|
/**
|
|
608
541
|
* paymentHash: string payment hash of the invoice
|
|
609
542
|
*/
|
|
610
|
-
const parsedBody = (0, SchemaVerifier_1.verifySchema)(
|
|
543
|
+
const parsedBody = (0, SchemaVerifier_1.verifySchema)({ ...req.body, ...req.query }, {
|
|
611
544
|
paymentHash: (val) => val != null &&
|
|
612
545
|
typeof (val) === "string" &&
|
|
613
546
|
val.length === 64 &&
|
|
614
547
|
Utils_1.HEX_REGEX.test(val) ? val : null,
|
|
615
548
|
});
|
|
616
|
-
|
|
549
|
+
await this.checkInvoiceStatus(parsedBody.paymentHash);
|
|
617
550
|
res.status(200).json({
|
|
618
551
|
code: 10000,
|
|
619
552
|
msg: "Success"
|
|
620
553
|
});
|
|
621
|
-
})
|
|
554
|
+
});
|
|
622
555
|
restServer.post(this.path + "/getInvoiceStatus", getInvoiceStatus);
|
|
623
556
|
restServer.get(this.path + "/getInvoiceStatus", getInvoiceStatus);
|
|
624
|
-
const getInvoicePaymentAuth = (0, Utils_1.expressHandlerWrapper)((req, res) =>
|
|
557
|
+
const getInvoicePaymentAuth = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
625
558
|
/**
|
|
626
559
|
* paymentHash: string payment hash of the invoice
|
|
627
560
|
*/
|
|
628
|
-
const parsedBody = (0, SchemaVerifier_1.verifySchema)(
|
|
561
|
+
const parsedBody = (0, SchemaVerifier_1.verifySchema)({ ...req.body, ...req.query }, {
|
|
629
562
|
paymentHash: (val) => val != null &&
|
|
630
563
|
typeof (val) === "string" &&
|
|
631
564
|
val.length === 64 &&
|
|
632
565
|
Utils_1.HEX_REGEX.test(val) ? val : null,
|
|
633
566
|
});
|
|
634
|
-
const invoice =
|
|
635
|
-
const swap =
|
|
567
|
+
const invoice = await this.checkInvoiceStatus(parsedBody.paymentHash);
|
|
568
|
+
const swap = await this.storageManager.getData(parsedBody.paymentHash, null);
|
|
636
569
|
if (swap == null)
|
|
637
570
|
throw {
|
|
638
571
|
_httpStatus: 200,
|
|
@@ -641,7 +574,7 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
641
574
|
};
|
|
642
575
|
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
643
576
|
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.RECEIVED) {
|
|
644
|
-
if (
|
|
577
|
+
if (await swapContract.isInitAuthorizationExpired(swap.data, swap))
|
|
645
578
|
throw {
|
|
646
579
|
_httpStatus: 200,
|
|
647
580
|
code: 10001,
|
|
@@ -650,7 +583,7 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
650
583
|
}
|
|
651
584
|
if (swap.state === FromBtcLnSwapAbs_1.FromBtcLnSwapState.CREATED) {
|
|
652
585
|
try {
|
|
653
|
-
|
|
586
|
+
await this.htlcReceived(swap, invoice);
|
|
654
587
|
}
|
|
655
588
|
catch (e) {
|
|
656
589
|
if ((0, Utils_1.isDefinedRuntimeError)(e))
|
|
@@ -676,35 +609,32 @@ class FromBtcLnAbs extends FromBtcLnBaseSwapHandler_1.FromBtcLnBaseSwapHandler {
|
|
|
676
609
|
msg: "Success",
|
|
677
610
|
data: {
|
|
678
611
|
address: signer.getAddress(),
|
|
679
|
-
data: swap.serialize()
|
|
680
|
-
nonce: swap.nonce,
|
|
612
|
+
data: swap.data.serialize(),
|
|
681
613
|
prefix: swap.prefix,
|
|
682
614
|
timeout: swap.timeout,
|
|
683
615
|
signature: swap.signature
|
|
684
616
|
}
|
|
685
617
|
});
|
|
686
|
-
})
|
|
618
|
+
});
|
|
687
619
|
restServer.post(this.path + "/getInvoicePaymentAuth", getInvoicePaymentAuth);
|
|
688
620
|
restServer.get(this.path + "/getInvoicePaymentAuth", getInvoicePaymentAuth);
|
|
689
621
|
this.logger.info("started at path: ", this.path);
|
|
690
622
|
}
|
|
691
|
-
init() {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
swap.amount = parsedPR.mtokens.add(new BN(999)).div(new BN(1000));
|
|
699
|
-
}
|
|
623
|
+
async init() {
|
|
624
|
+
await this.loadData(FromBtcLnSwapAbs_1.FromBtcLnSwapAbs);
|
|
625
|
+
//Check if all swaps contain a valid amount
|
|
626
|
+
for (let { obj: swap } of await this.storageManager.query([])) {
|
|
627
|
+
if (swap.amount == null) {
|
|
628
|
+
const parsedPR = await this.lightning.parsePaymentRequest(swap.pr);
|
|
629
|
+
swap.amount = (parsedPR.mtokens + 999n) / 1000n;
|
|
700
630
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
631
|
+
}
|
|
632
|
+
this.subscribeToEvents();
|
|
633
|
+
await PluginManager_1.PluginManager.serviceInitialize(this);
|
|
704
634
|
}
|
|
705
635
|
getInfoData() {
|
|
706
636
|
return {
|
|
707
|
-
minCltv: this.config.minCltv
|
|
637
|
+
minCltv: Number(this.config.minCltv)
|
|
708
638
|
};
|
|
709
639
|
}
|
|
710
640
|
}
|