@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,349 +1,326 @@
|
|
|
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.FromBtcTrusted = void 0;
|
|
13
4
|
const FromBtcBaseSwapHandler_1 = require("../FromBtcBaseSwapHandler");
|
|
14
5
|
const FromBtcTrustedSwap_1 = require("./FromBtcTrustedSwap");
|
|
15
6
|
const SwapHandler_1 = require("../SwapHandler");
|
|
16
|
-
const BN = require("bn.js");
|
|
17
7
|
const PluginManager_1 = require("../../plugins/PluginManager");
|
|
18
8
|
const Utils_1 = require("../../utils/Utils");
|
|
19
9
|
const SchemaVerifier_1 = require("../../utils/paramcoders/SchemaVerifier");
|
|
20
|
-
const ServerParamDecoder_1 = require("../../utils/paramcoders/server/ServerParamDecoder");
|
|
21
10
|
class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
22
11
|
constructor(storageDirectory, path, chains, bitcoin, swapPricing, bitcoinRpc, config) {
|
|
23
12
|
var _a;
|
|
24
|
-
var _b;
|
|
25
13
|
super(storageDirectory, path, chains, swapPricing);
|
|
26
14
|
this.type = SwapHandler_1.SwapHandlerType.FROM_BTC_TRUSTED;
|
|
15
|
+
this.swapType = null;
|
|
27
16
|
this.subscriptions = new Map();
|
|
28
17
|
this.doubleSpendWatchdogSwaps = new Set();
|
|
29
18
|
this.refundedSwaps = new Map();
|
|
30
19
|
this.doubleSpentSwaps = new Map();
|
|
31
20
|
this.processedTxIds = new Map();
|
|
32
21
|
this.config = config;
|
|
33
|
-
(_a =
|
|
22
|
+
(_a = this.config).recommendFeeMultiplier ?? (_a.recommendFeeMultiplier = 1.25);
|
|
34
23
|
this.bitcoin = bitcoin;
|
|
35
24
|
this.bitcoinRpc = bitcoinRpc;
|
|
36
|
-
for (let chainId in chains.chains) {
|
|
37
|
-
this.allowedTokens[chainId] = new Set([chains.chains[chainId].swapContract.getNativeCurrencyAddress()]);
|
|
38
|
-
}
|
|
39
25
|
}
|
|
40
26
|
getAllAncestors(tx) {
|
|
41
27
|
return Promise.all(tx.ins.map(input => this.bitcoinRpc.getTransaction(input.txid).then(tx => {
|
|
42
28
|
return { tx, vout: input.vout };
|
|
43
29
|
})));
|
|
44
30
|
}
|
|
45
|
-
refundSwap(swap) {
|
|
46
|
-
|
|
47
|
-
if (swap.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
51
|
-
}
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
let unlock = swap.lock(30 * 1000);
|
|
55
|
-
if (unlock == null)
|
|
56
|
-
return;
|
|
57
|
-
const feeRate = yield this.bitcoin.getFeeRate();
|
|
58
|
-
const ourOutput = swap.btcTx.outs[swap.vout];
|
|
59
|
-
const resp = yield this.bitcoin.drainAll(swap.refundAddress, [{
|
|
60
|
-
type: this.bitcoin.getAddressType(),
|
|
61
|
-
confirmations: swap.btcTx.confirmations,
|
|
62
|
-
outputScript: Buffer.from(ourOutput.scriptPubKey.hex, "hex"),
|
|
63
|
-
value: ourOutput.value,
|
|
64
|
-
txId: swap.btcTx.txid,
|
|
65
|
-
vout: swap.vout
|
|
66
|
-
}], feeRate);
|
|
67
|
-
if (resp == null) {
|
|
68
|
-
this.swapLogger.error(swap, "refundSwap(): cannot refund swap because of dust limit, txId: " + swap.txId);
|
|
69
|
-
unlock();
|
|
70
|
-
return;
|
|
31
|
+
async refundSwap(swap) {
|
|
32
|
+
if (swap.refundAddress == null) {
|
|
33
|
+
if (swap.state !== FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDABLE) {
|
|
34
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDABLE);
|
|
35
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
71
36
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
let unlock = swap.lock(30 * 1000);
|
|
40
|
+
if (unlock == null)
|
|
41
|
+
return;
|
|
42
|
+
const feeRate = await this.bitcoin.getFeeRate();
|
|
43
|
+
const ourOutput = swap.btcTx.outs[swap.vout];
|
|
44
|
+
const resp = await this.bitcoin.drainAll(swap.refundAddress, [{
|
|
45
|
+
type: this.bitcoin.getAddressType(),
|
|
46
|
+
confirmations: swap.btcTx.confirmations,
|
|
47
|
+
outputScript: Buffer.from(ourOutput.scriptPubKey.hex, "hex"),
|
|
48
|
+
value: ourOutput.value,
|
|
49
|
+
txId: swap.btcTx.txid,
|
|
50
|
+
vout: swap.vout
|
|
51
|
+
}], feeRate);
|
|
52
|
+
if (resp == null) {
|
|
53
|
+
this.swapLogger.error(swap, "refundSwap(): cannot refund swap because of dust limit, txId: " + swap.txId);
|
|
82
54
|
unlock();
|
|
83
|
-
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (swap.metadata != null)
|
|
58
|
+
swap.metadata.times.refundSignPSBT = Date.now();
|
|
59
|
+
this.swapLogger.debug(swap, "refundSwap(): signed raw transaction: " + resp.raw);
|
|
60
|
+
const refundTxId = resp.txId;
|
|
61
|
+
swap.refundTxId = refundTxId;
|
|
62
|
+
//Send the refund TX
|
|
63
|
+
await this.bitcoin.sendRawTransaction(resp.raw);
|
|
64
|
+
this.swapLogger.debug(swap, "refundSwap(): sent refund transaction: " + refundTxId);
|
|
65
|
+
this.refundedSwaps.set(swap.getIdentifierHash(), refundTxId);
|
|
66
|
+
await this.removeSwapData(swap, FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDED);
|
|
67
|
+
unlock();
|
|
68
|
+
}
|
|
69
|
+
async burn(swap) {
|
|
70
|
+
const ourOutput = swap.btcTx.outs[swap.vout];
|
|
71
|
+
//Check if we can even increase the feeRate by burning
|
|
72
|
+
const txSize = 110;
|
|
73
|
+
const burnTxFeeRate = Math.floor(ourOutput.value / txSize);
|
|
74
|
+
const initialTxFeeRate = Math.ceil(swap.txFee / swap.txSize);
|
|
75
|
+
if (burnTxFeeRate < initialTxFeeRate) {
|
|
76
|
+
this.swapLogger.warn(swap, "burn(): cannot send burn transaction, pays too little fee, " +
|
|
77
|
+
"initialTxId: " + swap.txId + " initialTxFeeRate: " + initialTxFeeRate + " burnTxFeeRate: " + burnTxFeeRate);
|
|
78
|
+
this.doubleSpentSwaps.set(swap.getIdentifierHash(), null);
|
|
79
|
+
await this.removeSwapData(swap, FromBtcTrustedSwap_1.FromBtcTrustedSwapState.DOUBLE_SPENT);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
//Construct PSBT
|
|
83
|
+
const resp = await this.bitcoin.burnAll([{
|
|
84
|
+
type: this.bitcoin.getAddressType(),
|
|
85
|
+
confirmations: swap.btcTx.confirmations,
|
|
86
|
+
outputScript: Buffer.from(ourOutput.scriptPubKey.hex, "hex"),
|
|
87
|
+
value: ourOutput.value,
|
|
88
|
+
txId: swap.btcTx.txid,
|
|
89
|
+
vout: swap.vout
|
|
90
|
+
}]);
|
|
91
|
+
if (swap.metadata != null)
|
|
92
|
+
swap.metadata.times.burnSignPSBT = Date.now();
|
|
93
|
+
this.swapLogger.debug(swap, "burn(): signed raw transaction: " + resp.raw);
|
|
94
|
+
const burnTxId = resp.txId;
|
|
95
|
+
swap.burnTxId = burnTxId;
|
|
96
|
+
//Send the original TX + our burn TX as a package
|
|
97
|
+
const sendTxns = [swap.btcTx.raw, resp.raw];
|
|
98
|
+
//TODO: We should handle this in a better way
|
|
99
|
+
try {
|
|
100
|
+
await this.bitcoinRpc.sendRawPackage(sendTxns);
|
|
101
|
+
this.swapLogger.debug(swap, "burn(): sent burn transaction: " + burnTxId);
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
this.swapLogger.error(swap, "burn(): error sending burn package: ", e);
|
|
105
|
+
}
|
|
106
|
+
this.doubleSpentSwaps.set(swap.getIdentifierHash(), burnTxId);
|
|
107
|
+
await this.removeSwapData(swap, FromBtcTrustedSwap_1.FromBtcTrustedSwapState.DOUBLE_SPENT);
|
|
84
108
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
async processPastSwap(swap, tx, vout) {
|
|
110
|
+
const foundVout = tx.outs[vout];
|
|
111
|
+
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
112
|
+
const outputScript = this.bitcoin.toOutputScript(swap.btcAddress).toString("hex");
|
|
113
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CREATED) {
|
|
114
|
+
this.subscriptions.set(outputScript, swap);
|
|
115
|
+
if (foundVout == null) {
|
|
116
|
+
//Check expiry
|
|
117
|
+
if (swap.expiresAt < Date.now()) {
|
|
118
|
+
this.subscriptions.delete(outputScript);
|
|
119
|
+
await this.bitcoin.addUnusedAddress(swap.btcAddress);
|
|
120
|
+
await this.removeSwapData(swap, FromBtcTrustedSwap_1.FromBtcTrustedSwapState.EXPIRED);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
97
123
|
return;
|
|
98
124
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
outputScript: Buffer.from(ourOutput.scriptPubKey.hex, "hex"),
|
|
104
|
-
value: ourOutput.value,
|
|
105
|
-
txId: swap.btcTx.txid,
|
|
106
|
-
vout: swap.vout
|
|
107
|
-
}]);
|
|
108
|
-
if (swap.metadata != null)
|
|
109
|
-
swap.metadata.times.burnSignPSBT = Date.now();
|
|
110
|
-
this.swapLogger.debug(swap, "burn(): signed raw transaction: " + resp.raw);
|
|
111
|
-
const burnTxId = resp.txId;
|
|
112
|
-
swap.burnTxId = burnTxId;
|
|
113
|
-
//Send the original TX + our burn TX as a package
|
|
114
|
-
const sendTxns = [swap.btcTx.raw, resp.raw];
|
|
115
|
-
//TODO: We should handle this in a better way
|
|
116
|
-
try {
|
|
117
|
-
yield this.bitcoinRpc.sendRawPackage(sendTxns);
|
|
118
|
-
this.swapLogger.debug(swap, "burn(): sent burn transaction: " + burnTxId);
|
|
119
|
-
}
|
|
120
|
-
catch (e) {
|
|
121
|
-
this.swapLogger.error(swap, "burn(): error sending burn package: ", e);
|
|
125
|
+
const sentSats = BigInt(foundVout.value);
|
|
126
|
+
if (sentSats === swap.amount) {
|
|
127
|
+
swap.adjustedInput = swap.amount;
|
|
128
|
+
swap.adjustedOutput = swap.outputTokens;
|
|
122
129
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
processPastSwap(swap, tx, vout) {
|
|
128
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
-
const foundVout = tx.outs[vout];
|
|
130
|
-
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
131
|
-
const outputScript = this.bitcoin.toOutputScript(swap.btcAddress).toString("hex");
|
|
132
|
-
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CREATED) {
|
|
133
|
-
this.subscriptions.set(outputScript, swap);
|
|
134
|
-
if (foundVout == null) {
|
|
135
|
-
//Check expiry
|
|
136
|
-
if (swap.expiresAt < Date.now()) {
|
|
137
|
-
this.subscriptions.delete(outputScript);
|
|
138
|
-
yield this.bitcoin.addUnusedAddress(swap.btcAddress);
|
|
139
|
-
yield this.removeSwapData(swap, FromBtcTrustedSwap_1.FromBtcTrustedSwapState.EXPIRED);
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
130
|
+
else {
|
|
131
|
+
//If lower than minimum then ignore
|
|
132
|
+
if (sentSats < this.config.min)
|
|
142
133
|
return;
|
|
143
|
-
|
|
144
|
-
const sentSats = new BN(foundVout.value);
|
|
145
|
-
if (sentSats.eq(swap.amount)) {
|
|
146
|
-
swap.adjustedInput = swap.amount;
|
|
147
|
-
swap.adjustedOutput = swap.outputTokens;
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
//If lower than minimum then ignore
|
|
151
|
-
if (sentSats.lt(this.config.min))
|
|
152
|
-
return;
|
|
153
|
-
if (sentSats.gt(this.config.max)) {
|
|
154
|
-
swap.adjustedInput = sentSats;
|
|
155
|
-
swap.btcTx = tx;
|
|
156
|
-
swap.txId = tx.txid;
|
|
157
|
-
swap.vout = vout;
|
|
158
|
-
this.subscriptions.delete(outputScript);
|
|
159
|
-
yield this.refundSwap(swap);
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
//Adjust the amount
|
|
134
|
+
if (sentSats > this.config.max) {
|
|
163
135
|
swap.adjustedInput = sentSats;
|
|
164
|
-
swap.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
this.subscriptions.delete(outputScript);
|
|
170
|
-
yield swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED);
|
|
171
|
-
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
172
|
-
}
|
|
173
|
-
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED) {
|
|
174
|
-
//Check if transaction still exists
|
|
175
|
-
if (tx == null || foundVout == null || tx.txid !== swap.txId) {
|
|
176
|
-
yield swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CREATED);
|
|
177
|
-
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
136
|
+
swap.btcTx = tx;
|
|
137
|
+
swap.txId = tx.txid;
|
|
138
|
+
swap.vout = vout;
|
|
139
|
+
this.subscriptions.delete(outputScript);
|
|
140
|
+
await this.refundSwap(swap);
|
|
178
141
|
return;
|
|
179
142
|
}
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
143
|
+
//Adjust the amount
|
|
144
|
+
swap.adjustedInput = sentSats;
|
|
145
|
+
swap.adjustedOutput = swap.outputTokens * sentSats / swap.amount;
|
|
146
|
+
}
|
|
147
|
+
swap.btcTx = tx;
|
|
148
|
+
swap.txId = tx.txid;
|
|
149
|
+
swap.vout = vout;
|
|
150
|
+
this.subscriptions.delete(outputScript);
|
|
151
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED);
|
|
152
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
153
|
+
}
|
|
154
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED) {
|
|
155
|
+
//Check if transaction still exists
|
|
156
|
+
if (tx == null || foundVout == null || tx.txid !== swap.txId) {
|
|
157
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CREATED);
|
|
158
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
//Check if it is confirmed
|
|
162
|
+
if (tx.confirmations > 0) {
|
|
163
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED);
|
|
164
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
//Check if it pays high enough fee AND has confirmed ancestors
|
|
168
|
+
const ancestors = await this.getAllAncestors(tx);
|
|
169
|
+
const allAncestorsConfirmed = ancestors.reduce((prev, curr) => prev && curr.tx.confirmations > 0, true);
|
|
170
|
+
const totalInput = ancestors.reduce((prev, curr) => prev + curr.tx.outs[curr.vout].value, 0);
|
|
171
|
+
const totalOutput = tx.outs.reduce((prev, curr) => prev + curr.value, 0);
|
|
172
|
+
const fee = totalInput - totalOutput;
|
|
173
|
+
const feePerVbyte = Math.ceil(fee / tx.vsize);
|
|
174
|
+
if (allAncestorsConfirmed &&
|
|
175
|
+
(feePerVbyte >= swap.recommendedFee || feePerVbyte >= await this.bitcoin.getFeeRate())) {
|
|
176
|
+
if (swap.state !== FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED)
|
|
203
177
|
return;
|
|
204
|
-
|
|
178
|
+
swap.txSize = tx.vsize;
|
|
179
|
+
swap.txFee = fee;
|
|
180
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED);
|
|
181
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
205
182
|
}
|
|
206
|
-
|
|
207
|
-
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDABLE) {
|
|
208
|
-
if (swap.refundAddress != null) {
|
|
209
|
-
yield this.refundSwap(swap);
|
|
183
|
+
else {
|
|
210
184
|
return;
|
|
211
185
|
}
|
|
212
186
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
if (!swap.doubleSpent) {
|
|
219
|
-
swap.doubleSpent = true;
|
|
220
|
-
try {
|
|
221
|
-
yield this.burn(swap);
|
|
222
|
-
this.doubleSpendWatchdogSwaps.delete(swap);
|
|
223
|
-
}
|
|
224
|
-
catch (e) {
|
|
225
|
-
this.swapLogger.error(swap, "processPastSwap(): Error burning swap: ", e);
|
|
226
|
-
swap.doubleSpent = false;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
187
|
+
}
|
|
188
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDABLE) {
|
|
189
|
+
if (swap.refundAddress != null) {
|
|
190
|
+
await this.refundSwap(swap);
|
|
229
191
|
return;
|
|
230
192
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
if (tx.confirmations > 0 && this.doubleSpendWatchdogSwaps.delete(swap)) {
|
|
238
|
-
this.swapLogger.debug(swap, "processPastSwap(): Removing confirmed swap transaction from double spend watchdog list: ", swap.txId);
|
|
193
|
+
}
|
|
194
|
+
if (swap.doubleSpent || tx == null || foundVout == null || tx.txid !== swap.txId) {
|
|
195
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDABLE) {
|
|
196
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CREATED);
|
|
197
|
+
return;
|
|
239
198
|
}
|
|
240
|
-
if (swap.
|
|
241
|
-
|
|
242
|
-
const balance = swapContract.getBalance(signer.getAddress(), swapContract.getNativeCurrencyAddress(), false);
|
|
199
|
+
if (!swap.doubleSpent) {
|
|
200
|
+
swap.doubleSpent = true;
|
|
243
201
|
try {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
swap.metadata.times.receivedBalanceChecked = Date.now();
|
|
202
|
+
await this.burn(swap);
|
|
203
|
+
this.doubleSpendWatchdogSwaps.delete(swap);
|
|
247
204
|
}
|
|
248
205
|
catch (e) {
|
|
249
|
-
this.swapLogger.error(swap, "processPastSwap(): Error
|
|
250
|
-
|
|
251
|
-
return;
|
|
206
|
+
this.swapLogger.error(swap, "processPastSwap(): Error burning swap: ", e);
|
|
207
|
+
swap.doubleSpent = false;
|
|
252
208
|
}
|
|
253
|
-
if (swap.state !== FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED)
|
|
254
|
-
return;
|
|
255
|
-
let unlock = swap.lock(30 * 1000);
|
|
256
|
-
if (unlock == null)
|
|
257
|
-
return;
|
|
258
|
-
const txns = yield swapContract.txsTransfer(signer.getAddress(), swapContract.getNativeCurrencyAddress(), swap.adjustedOutput, swap.dstAddress);
|
|
259
|
-
yield swapContract.sendAndConfirm(signer, txns, true, null, false, (txId, rawTx) => __awaiter(this, void 0, void 0, function* () {
|
|
260
|
-
swap.txIds = { init: txId };
|
|
261
|
-
swap.scRawTx = rawTx;
|
|
262
|
-
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED) {
|
|
263
|
-
yield swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.SENT);
|
|
264
|
-
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
265
|
-
}
|
|
266
|
-
if (unlock != null)
|
|
267
|
-
unlock();
|
|
268
|
-
unlock = null;
|
|
269
|
-
}));
|
|
270
209
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
swap.scRawTx = null;
|
|
278
|
-
yield swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED);
|
|
279
|
-
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
280
|
-
break;
|
|
281
|
-
case "reverted":
|
|
282
|
-
//Cancel invoice
|
|
283
|
-
yield this.refundSwap(swap);
|
|
284
|
-
this.swapLogger.info(swap, "processPastSwap(): transaction reverted, refunding btc on-chain: ", swap.btcAddress);
|
|
285
|
-
break;
|
|
286
|
-
case "success":
|
|
287
|
-
yield swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CONFIRMED);
|
|
288
|
-
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
289
|
-
break;
|
|
290
|
-
}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
if (tx.confirmations <= 0 && !this.doubleSpendWatchdogSwaps.has(swap)) {
|
|
214
|
+
this.swapLogger.debug(swap, "processPastSwap(): Adding swap transaction to double spend watchdog list: ", swap.txId);
|
|
215
|
+
this.doubleSpendWatchdogSwaps.add(swap);
|
|
291
216
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
217
|
+
}
|
|
218
|
+
if (tx.confirmations > 0 && this.doubleSpendWatchdogSwaps.delete(swap)) {
|
|
219
|
+
this.swapLogger.debug(swap, "processPastSwap(): Removing confirmed swap transaction from double spend watchdog list: ", swap.txId);
|
|
220
|
+
}
|
|
221
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED) {
|
|
222
|
+
//Send gas token
|
|
223
|
+
const balance = swapContract.getBalance(signer.getAddress(), swap.token, false);
|
|
224
|
+
try {
|
|
225
|
+
await this.checkBalance(swap.adjustedOutput, balance, null);
|
|
226
|
+
if (swap.metadata != null)
|
|
227
|
+
swap.metadata.times.receivedBalanceChecked = Date.now();
|
|
301
228
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
var _a, _b, _c;
|
|
306
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
307
|
-
const queriedData = yield this.storageManager.query([
|
|
308
|
-
{
|
|
309
|
-
key: "state",
|
|
310
|
-
value: [
|
|
311
|
-
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDABLE,
|
|
312
|
-
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CREATED,
|
|
313
|
-
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED,
|
|
314
|
-
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED,
|
|
315
|
-
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.SENT,
|
|
316
|
-
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CONFIRMED
|
|
317
|
-
]
|
|
318
|
-
}
|
|
319
|
-
]);
|
|
320
|
-
const startingBlockheight = queriedData.reduce((prev, swap) => Math.min(prev, swap.createdHeight), Infinity);
|
|
321
|
-
if (startingBlockheight === Infinity)
|
|
229
|
+
catch (e) {
|
|
230
|
+
this.swapLogger.error(swap, "processPastSwap(): Error not enough balance: ", e);
|
|
231
|
+
await this.refundSwap(swap);
|
|
322
232
|
return;
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
233
|
+
}
|
|
234
|
+
if (swap.state !== FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED)
|
|
235
|
+
return;
|
|
236
|
+
let unlock = swap.lock(30 * 1000);
|
|
237
|
+
if (unlock == null)
|
|
238
|
+
return;
|
|
239
|
+
const txns = await swapContract.txsTransfer(signer.getAddress(), swap.token, swap.adjustedOutput, swap.dstAddress);
|
|
240
|
+
await swapContract.sendAndConfirm(signer, txns, true, null, false, async (txId, rawTx) => {
|
|
241
|
+
swap.txIds = { init: txId };
|
|
242
|
+
swap.scRawTx = rawTx;
|
|
243
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED) {
|
|
244
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.SENT);
|
|
245
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
246
|
+
}
|
|
247
|
+
if (unlock != null)
|
|
248
|
+
unlock();
|
|
249
|
+
unlock = null;
|
|
335
250
|
});
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
251
|
+
}
|
|
252
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.SENT) {
|
|
253
|
+
const txStatus = await swapContract.getTxStatus(swap.scRawTx);
|
|
254
|
+
switch (txStatus) {
|
|
255
|
+
case "not_found":
|
|
256
|
+
//Retry
|
|
257
|
+
swap.txIds = { init: null };
|
|
258
|
+
swap.scRawTx = null;
|
|
259
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED);
|
|
260
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
261
|
+
break;
|
|
262
|
+
case "reverted":
|
|
263
|
+
//Cancel invoice
|
|
264
|
+
await this.refundSwap(swap);
|
|
265
|
+
this.swapLogger.info(swap, "processPastSwap(): transaction reverted, refunding btc on-chain: ", swap.btcAddress);
|
|
266
|
+
break;
|
|
267
|
+
case "success":
|
|
268
|
+
await swap.setState(FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CONFIRMED);
|
|
269
|
+
await this.storageManager.saveData(swap.getIdentifierHash(), swap.getSequence(), swap);
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (swap.state === FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CONFIRMED) {
|
|
274
|
+
this.processedTxIds.set(swap.getIdentifierHash(), {
|
|
275
|
+
txId: swap.txId,
|
|
276
|
+
scTxId: swap.txIds.init,
|
|
277
|
+
adjustedAmount: swap.adjustedInput,
|
|
278
|
+
adjustedTotal: swap.adjustedOutput
|
|
279
|
+
});
|
|
280
|
+
if (tx.confirmations > 0)
|
|
281
|
+
await this.removeSwapData(swap, FromBtcTrustedSwap_1.FromBtcTrustedSwapState.FINISHED);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
async processPastSwaps() {
|
|
285
|
+
const queriedData = await this.storageManager.query([
|
|
286
|
+
{
|
|
287
|
+
key: "state",
|
|
288
|
+
value: [
|
|
289
|
+
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.REFUNDABLE,
|
|
290
|
+
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CREATED,
|
|
291
|
+
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.RECEIVED,
|
|
292
|
+
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.BTC_CONFIRMED,
|
|
293
|
+
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.SENT,
|
|
294
|
+
FromBtcTrustedSwap_1.FromBtcTrustedSwapState.CONFIRMED
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
]);
|
|
298
|
+
const startingBlockheight = queriedData.reduce((prev, { obj: swap }) => Math.min(prev, swap.createdHeight), Infinity);
|
|
299
|
+
if (startingBlockheight === Infinity)
|
|
300
|
+
return;
|
|
301
|
+
const transactions = await this.bitcoin.getWalletTransactions(startingBlockheight);
|
|
302
|
+
const map = new Map();
|
|
303
|
+
transactions.forEach(tx => {
|
|
304
|
+
tx.outs.forEach((out, vout) => {
|
|
305
|
+
const existing = map.get(out.scriptPubKey.hex);
|
|
306
|
+
if (existing == null) {
|
|
307
|
+
map.set(out.scriptPubKey.hex, [{ tx, vout }]);
|
|
341
308
|
}
|
|
342
|
-
|
|
343
|
-
|
|
309
|
+
else {
|
|
310
|
+
existing.push({ tx, vout });
|
|
344
311
|
}
|
|
345
|
-
}
|
|
312
|
+
});
|
|
346
313
|
});
|
|
314
|
+
for (let { obj: swap } of queriedData) {
|
|
315
|
+
const outputScript = this.bitcoin.toOutputScript(swap.btcAddress).toString("hex");
|
|
316
|
+
const txs = map.get(outputScript) ?? [];
|
|
317
|
+
try {
|
|
318
|
+
await this.processPastSwap(swap, txs[0]?.tx, txs[0]?.vout);
|
|
319
|
+
}
|
|
320
|
+
catch (e) {
|
|
321
|
+
this.swapLogger.error(swap, "processPastSwaps(): Error ocurred while processing swap: ", e);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
347
324
|
}
|
|
348
325
|
isValidBitcoinAddress(address) {
|
|
349
326
|
try {
|
|
@@ -354,10 +331,10 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
354
331
|
return false;
|
|
355
332
|
}
|
|
356
333
|
startRestServer(restServer) {
|
|
357
|
-
const getAddress = (0, Utils_1.expressHandlerWrapper)((req, res) =>
|
|
334
|
+
const getAddress = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
358
335
|
var _a;
|
|
359
336
|
const metadata = { request: {}, times: {} };
|
|
360
|
-
const chainIdentifier =
|
|
337
|
+
const chainIdentifier = req.query.chain ?? this.chains.default;
|
|
361
338
|
const { swapContract, signer } = this.getChain(chainIdentifier);
|
|
362
339
|
metadata.times.requestReceived = Date.now();
|
|
363
340
|
/**
|
|
@@ -366,12 +343,20 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
366
343
|
* amount: string amount (in lamports/smart chain base units) of the invoice
|
|
367
344
|
* exactOut: boolean whether to create and exact output swap
|
|
368
345
|
*/
|
|
369
|
-
|
|
346
|
+
(_a = req.query).token ?? (_a.token = swapContract.getNativeCurrencyAddress());
|
|
347
|
+
const parsedBody = (0, SchemaVerifier_1.verifySchema)(req.query, {
|
|
370
348
|
address: (val) => val != null &&
|
|
371
349
|
typeof (val) === "string" &&
|
|
372
350
|
swapContract.isValidAddress(val) ? val : null,
|
|
373
|
-
|
|
374
|
-
|
|
351
|
+
refundAddress: (val) => val == null ? "" :
|
|
352
|
+
typeof (val) === "string" &&
|
|
353
|
+
this.isValidBitcoinAddress(val) ? val : null,
|
|
354
|
+
token: (val) => val != null &&
|
|
355
|
+
typeof (val) === "string" &&
|
|
356
|
+
this.isTokenSupported(chainIdentifier, val) ? val : null,
|
|
357
|
+
amount: SchemaVerifier_1.FieldTypeEnum.BigInt,
|
|
358
|
+
exactIn: (val) => val === "true" ? true :
|
|
359
|
+
(val === "false" || val === undefined) ? false : null
|
|
375
360
|
});
|
|
376
361
|
if (parsedBody == null)
|
|
377
362
|
throw {
|
|
@@ -379,41 +364,36 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
379
364
|
msg: "Invalid request body"
|
|
380
365
|
};
|
|
381
366
|
metadata.request = parsedBody;
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
typeof (val) === "string" &&
|
|
385
|
-
this.isValidBitcoinAddress(val) ? val : null
|
|
386
|
-
});
|
|
387
|
-
const refundAddress = refundAddressData === null || refundAddressData === void 0 ? void 0 : refundAddressData.refundAddress;
|
|
388
|
-
const requestedAmount = { input: !parsedBody.exactOut, amount: parsedBody.amount };
|
|
367
|
+
const refundAddress = parsedBody.refundAddress === "" ? null : parsedBody.refundAddress;
|
|
368
|
+
const requestedAmount = { input: parsedBody.exactIn, amount: parsedBody.amount };
|
|
389
369
|
const request = {
|
|
390
370
|
chainIdentifier,
|
|
391
371
|
raw: req,
|
|
392
372
|
parsed: parsedBody,
|
|
393
373
|
metadata
|
|
394
374
|
};
|
|
395
|
-
const useToken =
|
|
375
|
+
const useToken = parsedBody.token;
|
|
396
376
|
//Check request params
|
|
397
|
-
const fees =
|
|
377
|
+
const fees = await this.preCheckAmounts(request, requestedAmount, useToken);
|
|
398
378
|
metadata.times.requestChecked = Date.now();
|
|
399
379
|
//Create abortController for parallel prefetches
|
|
400
380
|
const responseStream = res.responseStream;
|
|
401
381
|
const abortController = this.getAbortController(responseStream);
|
|
402
382
|
//Pre-fetch data
|
|
403
|
-
const { pricePrefetchPromise } = this.getFromBtcPricePrefetches(chainIdentifier, useToken, abortController);
|
|
383
|
+
const { pricePrefetchPromise } = this.getFromBtcPricePrefetches(chainIdentifier, useToken, useToken, abortController);
|
|
404
384
|
const balancePrefetch = swapContract.getBalance(signer.getAddress(), useToken, false).catch(e => {
|
|
405
385
|
this.logger.error("getBalancePrefetch(): balancePrefetch error: ", e);
|
|
406
386
|
abortController.abort(e);
|
|
407
387
|
return null;
|
|
408
388
|
});
|
|
409
389
|
//Check valid amount specified (min/max)
|
|
410
|
-
const { amountBD, swapFee, swapFeeInToken, totalInToken } =
|
|
390
|
+
const { amountBD, swapFee, swapFeeInToken, totalInToken } = await this.checkFromBtcAmount(request, requestedAmount, fees, useToken, abortController.signal, pricePrefetchPromise);
|
|
411
391
|
metadata.times.priceCalculated = Date.now();
|
|
412
392
|
//Make sure we have MORE THAN ENOUGH to honor the swap request
|
|
413
|
-
|
|
393
|
+
await this.checkBalance(totalInToken * 4n, balancePrefetch, abortController.signal);
|
|
414
394
|
metadata.times.balanceChecked = Date.now();
|
|
415
|
-
const blockHeight =
|
|
416
|
-
const feeRate =
|
|
395
|
+
const blockHeight = await this.bitcoin.getBlockheight();
|
|
396
|
+
const feeRate = await this.bitcoin.getFeeRate();
|
|
417
397
|
const recommendedFee = Math.ceil(feeRate * this.config.recommendFeeMultiplier);
|
|
418
398
|
if (recommendedFee === 0)
|
|
419
399
|
throw {
|
|
@@ -422,22 +402,22 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
422
402
|
msg: "Cannot estimate bitcoin fee!"
|
|
423
403
|
};
|
|
424
404
|
metadata.times.feeEstimated = Date.now();
|
|
425
|
-
const receiveAddress =
|
|
405
|
+
const receiveAddress = await this.bitcoin.getAddress();
|
|
426
406
|
const outputScript = this.bitcoin.toOutputScript(receiveAddress).toString("hex");
|
|
427
407
|
abortController.signal.throwIfAborted();
|
|
428
408
|
metadata.times.addressCreated = Date.now();
|
|
429
|
-
const createdSwap = new FromBtcTrustedSwap_1.FromBtcTrustedSwap(chainIdentifier, swapFee, swapFeeInToken, receiveAddress, amountBD, parsedBody.address, totalInToken, blockHeight, Date.now() + (this.config.swapAddressExpiry * 1000), recommendedFee, refundAddress);
|
|
409
|
+
const createdSwap = new FromBtcTrustedSwap_1.FromBtcTrustedSwap(chainIdentifier, swapFee, swapFeeInToken, receiveAddress, amountBD, parsedBody.address, totalInToken, blockHeight, Date.now() + (this.config.swapAddressExpiry * 1000), recommendedFee, refundAddress, useToken);
|
|
430
410
|
metadata.times.swapCreated = Date.now();
|
|
431
411
|
createdSwap.metadata = metadata;
|
|
432
|
-
|
|
433
|
-
|
|
412
|
+
await PluginManager_1.PluginManager.swapCreate(createdSwap);
|
|
413
|
+
await this.storageManager.saveData(createdSwap.getIdentifierHash(), createdSwap.getSequence(), createdSwap);
|
|
434
414
|
this.subscriptions.set(outputScript, createdSwap);
|
|
435
415
|
this.swapLogger.info(createdSwap, "REST: /getAddress: Created swap address: " + createdSwap.btcAddress + " amount: " + amountBD.toString(10));
|
|
436
|
-
|
|
437
|
-
msg: "Success",
|
|
416
|
+
res.status(200).json({
|
|
438
417
|
code: 10000,
|
|
418
|
+
msg: "Success",
|
|
439
419
|
data: {
|
|
440
|
-
paymentHash: createdSwap.
|
|
420
|
+
paymentHash: createdSwap.getIdentifierHash(),
|
|
441
421
|
sequence: createdSwap.getSequence().toString(10),
|
|
442
422
|
btcAddress: receiveAddress,
|
|
443
423
|
amountSats: amountBD.toString(10),
|
|
@@ -449,10 +429,9 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
449
429
|
expiresAt: createdSwap.expiresAt
|
|
450
430
|
}
|
|
451
431
|
});
|
|
452
|
-
})
|
|
453
|
-
restServer.
|
|
454
|
-
|
|
455
|
-
const getInvoiceStatus = (0, Utils_1.expressHandlerWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
432
|
+
});
|
|
433
|
+
restServer.get(this.path + "/getAddress", getAddress);
|
|
434
|
+
const getInvoiceStatus = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
456
435
|
/**
|
|
457
436
|
* paymentHash: string payment hash of the invoice
|
|
458
437
|
* sequence: BN secret sequence for the swap,
|
|
@@ -462,7 +441,7 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
462
441
|
typeof (val) === "string" &&
|
|
463
442
|
val.length === 64 &&
|
|
464
443
|
Utils_1.HEX_REGEX.test(val) ? val : null,
|
|
465
|
-
sequence: SchemaVerifier_1.FieldTypeEnum.
|
|
444
|
+
sequence: SchemaVerifier_1.FieldTypeEnum.BigInt,
|
|
466
445
|
});
|
|
467
446
|
if (parsedBody == null)
|
|
468
447
|
throw {
|
|
@@ -502,7 +481,7 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
502
481
|
txId: doubleSpendTxId
|
|
503
482
|
}
|
|
504
483
|
};
|
|
505
|
-
const invoiceData =
|
|
484
|
+
const invoiceData = await this.storageManager.getData(parsedBody.paymentHash, parsedBody.sequence);
|
|
506
485
|
if (invoiceData == null)
|
|
507
486
|
throw {
|
|
508
487
|
_httpStatus: 200,
|
|
@@ -570,20 +549,20 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
570
549
|
adjustedAmount: invoiceData.adjustedInput.toString(10)
|
|
571
550
|
}
|
|
572
551
|
};
|
|
573
|
-
})
|
|
552
|
+
});
|
|
574
553
|
restServer.get(this.path + "/getAddressStatus", getInvoiceStatus);
|
|
575
|
-
const setRefundAddress = (0, Utils_1.expressHandlerWrapper)((req, res) =>
|
|
554
|
+
const setRefundAddress = (0, Utils_1.expressHandlerWrapper)(async (req, res) => {
|
|
576
555
|
/**
|
|
577
556
|
* paymentHash: string payment hash of the invoice
|
|
578
557
|
* sequence: BN secret sequence for the swap,
|
|
579
558
|
* refundAddress: string valid bitcoin address to be used for refunds
|
|
580
559
|
*/
|
|
581
|
-
const parsedBody = (0, SchemaVerifier_1.verifySchema)(
|
|
560
|
+
const parsedBody = (0, SchemaVerifier_1.verifySchema)({ ...req.body, ...req.query }, {
|
|
582
561
|
paymentHash: (val) => val != null &&
|
|
583
562
|
typeof (val) === "string" &&
|
|
584
563
|
val.length === 64 &&
|
|
585
564
|
Utils_1.HEX_REGEX.test(val) ? val : null,
|
|
586
|
-
sequence: SchemaVerifier_1.FieldTypeEnum.
|
|
565
|
+
sequence: SchemaVerifier_1.FieldTypeEnum.BigInt,
|
|
587
566
|
refundAddress: (val) => val != null &&
|
|
588
567
|
typeof (val) === "string" &&
|
|
589
568
|
this.isValidBitcoinAddress(val) ? val : null
|
|
@@ -593,8 +572,8 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
593
572
|
code: 20100,
|
|
594
573
|
msg: "Invalid request"
|
|
595
574
|
};
|
|
596
|
-
const invoiceData =
|
|
597
|
-
if (invoiceData == null ||
|
|
575
|
+
const invoiceData = await this.storageManager.getData(parsedBody.paymentHash, null);
|
|
576
|
+
if (invoiceData == null || invoiceData.getSequence() !== parsedBody.sequence)
|
|
598
577
|
throw {
|
|
599
578
|
code: 10001,
|
|
600
579
|
msg: "Swap not found"
|
|
@@ -618,31 +597,27 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
618
597
|
code: 10000,
|
|
619
598
|
msg: "Refund address set"
|
|
620
599
|
};
|
|
621
|
-
})
|
|
600
|
+
});
|
|
622
601
|
restServer.get(this.path + "/setRefundAddress", setRefundAddress);
|
|
623
602
|
restServer.post(this.path + "/setRefundAddress", setRefundAddress);
|
|
624
603
|
this.logger.info("started at path: ", this.path);
|
|
625
604
|
}
|
|
626
|
-
checkDoubleSpends() {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
this.processPastSwap(swap, null, null);
|
|
633
|
-
}
|
|
605
|
+
async checkDoubleSpends() {
|
|
606
|
+
for (let swap of this.doubleSpendWatchdogSwaps.keys()) {
|
|
607
|
+
const tx = await this.bitcoin.getWalletTransaction(swap.txId);
|
|
608
|
+
if (tx == null) {
|
|
609
|
+
this.swapLogger.debug(swap, "checkDoubleSpends(): Swap was double spent, burning... - original txId: " + swap.txId);
|
|
610
|
+
this.processPastSwap(swap, null, null);
|
|
634
611
|
}
|
|
635
|
-
}
|
|
612
|
+
}
|
|
636
613
|
}
|
|
637
|
-
startDoubleSpendWatchdog() {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
yield rerun();
|
|
645
|
-
});
|
|
614
|
+
async startDoubleSpendWatchdog() {
|
|
615
|
+
let rerun;
|
|
616
|
+
rerun = async () => {
|
|
617
|
+
await this.checkDoubleSpends().catch(e => console.error(e));
|
|
618
|
+
setTimeout(rerun, this.config.doubleSpendCheckInterval);
|
|
619
|
+
};
|
|
620
|
+
await rerun();
|
|
646
621
|
}
|
|
647
622
|
listenToTxns() {
|
|
648
623
|
this.bitcoin.subscribeToWalletTransactions((btcTx) => {
|
|
@@ -655,32 +630,25 @@ class FromBtcTrusted extends FromBtcBaseSwapHandler_1.FromBtcBaseSwapHandler {
|
|
|
655
630
|
}
|
|
656
631
|
});
|
|
657
632
|
}
|
|
658
|
-
startWatchdog() {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
});
|
|
662
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
663
|
-
yield _super.startWatchdog.call(this);
|
|
664
|
-
yield this.startDoubleSpendWatchdog();
|
|
665
|
-
});
|
|
633
|
+
async startWatchdog() {
|
|
634
|
+
await super.startWatchdog();
|
|
635
|
+
await this.startDoubleSpendWatchdog();
|
|
666
636
|
}
|
|
667
|
-
init() {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
yield PluginManager_1.PluginManager.serviceInitialize(this);
|
|
672
|
-
});
|
|
637
|
+
async init() {
|
|
638
|
+
await this.storageManager.loadData(FromBtcTrustedSwap_1.FromBtcTrustedSwap);
|
|
639
|
+
this.listenToTxns();
|
|
640
|
+
await PluginManager_1.PluginManager.serviceInitialize(this);
|
|
673
641
|
}
|
|
674
642
|
getInfoData() {
|
|
675
643
|
return {};
|
|
676
644
|
}
|
|
677
|
-
processClaimEvent(chainIdentifier, event) {
|
|
645
|
+
processClaimEvent(chainIdentifier, swap, event) {
|
|
678
646
|
return Promise.resolve(undefined);
|
|
679
647
|
}
|
|
680
|
-
processInitializeEvent(chainIdentifier, event) {
|
|
648
|
+
processInitializeEvent(chainIdentifier, swap, event) {
|
|
681
649
|
return Promise.resolve(undefined);
|
|
682
650
|
}
|
|
683
|
-
processRefundEvent(chainIdentifier, event) {
|
|
651
|
+
processRefundEvent(chainIdentifier, swap, event) {
|
|
684
652
|
return Promise.resolve(undefined);
|
|
685
653
|
}
|
|
686
654
|
}
|