@atomiqlabs/lp-lib 10.3.11 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -4
- package/dist/plugins/IPlugin.d.ts +3 -2
- package/dist/plugins/PluginManager.d.ts +3 -2
- package/dist/plugins/PluginManager.js +2 -2
- package/dist/swaps/FromBtcBaseSwap.d.ts +5 -1
- package/dist/swaps/FromBtcBaseSwap.js +20 -0
- package/dist/swaps/FromBtcBaseSwapHandler.d.ts +1 -0
- package/dist/swaps/FromBtcBaseSwapHandler.js +1 -1
- package/dist/swaps/FromBtcLnBaseSwapHandler.d.ts +8 -6
- package/dist/swaps/FromBtcLnBaseSwapHandler.js +7 -5
- package/dist/swaps/SwapHandler.d.ts +1 -4
- package/dist/swaps/SwapHandler.js +1 -2
- package/dist/swaps/SwapHandlerSwap.d.ts +4 -0
- package/dist/swaps/SwapHandlerSwap.js +9 -1
- package/dist/swaps/ToBtcBaseSwap.d.ts +3 -1
- package/dist/swaps/ToBtcBaseSwap.js +8 -2
- package/dist/swaps/ToBtcBaseSwapHandler.d.ts +1 -0
- package/dist/swaps/ToBtcBaseSwapHandler.js +1 -1
- package/dist/swaps/frombtc_abstract/FromBtcAbs.d.ts +3 -5
- package/dist/swaps/frombtc_abstract/FromBtcAbs.js +18 -25
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.d.ts +1 -4
- package/dist/swaps/frombtc_abstract/FromBtcSwapAbs.js +3 -16
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.d.ts +6 -9
- package/dist/swaps/frombtc_trusted/FromBtcTrusted.js +238 -137
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.d.ts +9 -6
- package/dist/swaps/frombtc_trusted/FromBtcTrustedSwap.js +15 -10
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.d.ts +2 -2
- package/dist/swaps/frombtcln_abstract/FromBtcLnAbs.js +42 -62
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +1 -6
- package/dist/swaps/frombtcln_abstract/FromBtcLnSwapAbs.js +2 -14
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.d.ts +3 -5
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrusted.js +64 -80
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.d.ts +1 -2
- package/dist/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.js +5 -8
- package/dist/swaps/tobtc_abstract/ToBtcAbs.d.ts +5 -125
- package/dist/swaps/tobtc_abstract/ToBtcAbs.js +41 -334
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.d.ts +1 -4
- package/dist/swaps/tobtc_abstract/ToBtcSwapAbs.js +2 -11
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.d.ts +5 -55
- package/dist/swaps/tobtcln_abstract/ToBtcLnAbs.js +152 -398
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.d.ts +1 -6
- package/dist/swaps/tobtcln_abstract/ToBtcLnSwapAbs.js +2 -15
- package/dist/utils/Utils.d.ts +0 -10
- package/dist/utils/Utils.js +1 -34
- package/dist/wallets/IBitcoinWallet.d.ts +62 -0
- package/dist/wallets/IBitcoinWallet.js +2 -0
- package/dist/wallets/ILightningWallet.d.ts +118 -0
- package/dist/wallets/ILightningWallet.js +37 -0
- package/package.json +4 -9
- package/src/index.ts +3 -5
- package/src/plugins/IPlugin.ts +4 -2
- package/src/plugins/PluginManager.ts +6 -3
- package/src/swaps/FromBtcBaseSwap.ts +24 -1
- package/src/swaps/FromBtcBaseSwapHandler.ts +6 -2
- package/src/swaps/FromBtcLnBaseSwapHandler.ts +22 -6
- package/src/swaps/SwapHandler.ts +1 -8
- package/src/swaps/SwapHandlerSwap.ts +14 -1
- package/src/swaps/ToBtcBaseSwap.ts +12 -3
- package/src/swaps/ToBtcBaseSwapHandler.ts +6 -2
- package/src/swaps/frombtc_abstract/FromBtcAbs.ts +24 -28
- package/src/swaps/frombtc_abstract/FromBtcSwapAbs.ts +3 -18
- package/src/swaps/frombtc_trusted/FromBtcTrusted.ts +260 -159
- package/src/swaps/frombtc_trusted/FromBtcTrustedSwap.ts +22 -15
- package/src/swaps/frombtcln_abstract/FromBtcLnAbs.ts +69 -79
- package/src/swaps/frombtcln_abstract/FromBtcLnSwapAbs.ts +3 -20
- package/src/swaps/frombtcln_trusted/FromBtcLnTrusted.ts +80 -97
- package/src/swaps/frombtcln_trusted/FromBtcLnTrustedSwap.ts +6 -9
- package/src/swaps/tobtc_abstract/ToBtcAbs.ts +52 -410
- package/src/swaps/tobtc_abstract/ToBtcSwapAbs.ts +3 -18
- package/src/swaps/tobtcln_abstract/ToBtcLnAbs.ts +157 -434
- package/src/swaps/tobtcln_abstract/ToBtcLnSwapAbs.ts +3 -20
- package/src/utils/Utils.ts +0 -31
- package/src/wallets/IBitcoinWallet.ts +66 -0
- package/src/wallets/ILightningWallet.ts +179 -0
- package/dist/fees/OneDollarFeeEstimator.d.ts +0 -16
- package/dist/fees/OneDollarFeeEstimator.js +0 -71
- package/dist/utils/coinselect2/accumulative.d.ts +0 -6
- package/dist/utils/coinselect2/accumulative.js +0 -44
- package/dist/utils/coinselect2/blackjack.d.ts +0 -6
- package/dist/utils/coinselect2/blackjack.js +0 -41
- package/dist/utils/coinselect2/index.d.ts +0 -16
- package/dist/utils/coinselect2/index.js +0 -40
- package/dist/utils/coinselect2/utils.d.ts +0 -64
- package/dist/utils/coinselect2/utils.js +0 -121
- package/src/fees/OneDollarFeeEstimator.ts +0 -95
- package/src/utils/coinselect2/accumulative.js +0 -32
- package/src/utils/coinselect2/accumulative.ts +0 -58
- package/src/utils/coinselect2/blackjack.js +0 -29
- package/src/utils/coinselect2/blackjack.ts +0 -54
- package/src/utils/coinselect2/index.js +0 -16
- package/src/utils/coinselect2/index.ts +0 -50
- package/src/utils/coinselect2/utils.js +0 -110
- package/src/utils/coinselect2/utils.ts +0 -183
|
@@ -11,15 +11,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.ToBtcAbs = void 0;
|
|
13
13
|
const BN = require("bn.js");
|
|
14
|
-
const bitcoin = require("bitcoinjs-lib");
|
|
15
|
-
const lncli = require("ln-service");
|
|
16
14
|
const ToBtcSwapAbs_1 = require("./ToBtcSwapAbs");
|
|
17
15
|
const SwapHandler_1 = require("../SwapHandler");
|
|
18
16
|
const base_1 = require("@atomiqlabs/base");
|
|
19
17
|
const Utils_1 = require("../../utils/Utils");
|
|
20
18
|
const PluginManager_1 = require("../../plugins/PluginManager");
|
|
21
|
-
const coinselect2_1 = require("../../utils/coinselect2");
|
|
22
|
-
const utils_1 = require("../../utils/coinselect2/utils");
|
|
23
19
|
const crypto_1 = require("crypto");
|
|
24
20
|
const SchemaVerifier_1 = require("../../utils/paramcoders/SchemaVerifier");
|
|
25
21
|
const ServerParamDecoder_1 = require("../../utils/paramcoders/server/ServerParamDecoder");
|
|
@@ -30,23 +26,14 @@ const OUTPUT_SCRIPT_MAX_LENGTH = 200;
|
|
|
30
26
|
* Handler for to BTC swaps, utilizing PTLCs (proof-time locked contracts) using btc relay (on-chain bitcoin SPV)
|
|
31
27
|
*/
|
|
32
28
|
class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
33
|
-
constructor(storageDirectory, path, chainData,
|
|
34
|
-
super(storageDirectory, path, chainData,
|
|
35
|
-
this.CONFIRMATIONS_REQUIRED = 1;
|
|
36
|
-
this.ADDRESS_FORMAT_MAP = {
|
|
37
|
-
"p2wpkh": "p2wpkh",
|
|
38
|
-
"np2wpkh": "p2sh-p2wpkh",
|
|
39
|
-
"p2tr": "p2tr"
|
|
40
|
-
};
|
|
41
|
-
this.LND_CHANGE_OUTPUT_TYPE = "p2tr";
|
|
42
|
-
this.UTXO_CACHE_TIMEOUT = 5 * 1000;
|
|
43
|
-
this.CHANNEL_COUNT_CACHE_TIMEOUT = 30 * 1000;
|
|
29
|
+
constructor(storageDirectory, path, chainData, bitcoin, swapPricing, bitcoinRpc, config) {
|
|
30
|
+
super(storageDirectory, path, chainData, swapPricing);
|
|
44
31
|
this.type = SwapHandler_1.SwapHandlerType.TO_BTC;
|
|
45
32
|
this.activeSubscriptions = {};
|
|
46
33
|
this.sendBtcQueue = new promise_queue_ts_1.PromiseQueue();
|
|
47
34
|
this.bitcoinRpc = bitcoinRpc;
|
|
35
|
+
this.bitcoin = bitcoin;
|
|
48
36
|
this.config = config;
|
|
49
|
-
this.config.onchainReservedPerChannel = this.config.onchainReservedPerChannel || 40000;
|
|
50
37
|
}
|
|
51
38
|
/**
|
|
52
39
|
* Returns the payment hash of the swap, takes swap nonce into account. Payment hash is chain-specific.
|
|
@@ -55,189 +42,17 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
55
42
|
* @param address
|
|
56
43
|
* @param nonce
|
|
57
44
|
* @param amount
|
|
58
|
-
* @param bitcoinNetwork
|
|
59
45
|
*/
|
|
60
|
-
getHash(chainIdentifier, address, nonce, amount
|
|
61
|
-
const parsedOutputScript = bitcoin.
|
|
46
|
+
getHash(chainIdentifier, address, nonce, amount) {
|
|
47
|
+
const parsedOutputScript = this.bitcoin.toOutputScript(address);
|
|
62
48
|
const { swapContract } = this.getChain(chainIdentifier);
|
|
63
49
|
return swapContract.getHashForOnchain(parsedOutputScript, amount, nonce);
|
|
64
50
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Returns spendable UTXOs, these are either confirmed UTXOs, or unconfirmed ones that are either whitelisted,
|
|
67
|
-
* or created by our transactions (and therefore only we could doublespend)
|
|
68
|
-
*
|
|
69
|
-
* @private
|
|
70
|
-
*/
|
|
71
|
-
getSpendableUtxos() {
|
|
72
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
-
const resBlockheight = yield lncli.getHeight({
|
|
74
|
-
lnd: this.LND
|
|
75
|
-
});
|
|
76
|
-
const blockheight = resBlockheight.current_block_height;
|
|
77
|
-
const resChainTxns = yield lncli.getChainTransactions({
|
|
78
|
-
lnd: this.LND,
|
|
79
|
-
after: blockheight - this.CONFIRMATIONS_REQUIRED
|
|
80
|
-
});
|
|
81
|
-
const selfUTXOs = PluginManager_1.PluginManager.getWhitelistedTxIds();
|
|
82
|
-
const transactions = resChainTxns.transactions;
|
|
83
|
-
for (let tx of transactions) {
|
|
84
|
-
if (tx.is_outgoing) {
|
|
85
|
-
selfUTXOs.add(tx.id);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
const resUtxos = yield lncli.getUtxos({
|
|
89
|
-
lnd: this.LND
|
|
90
|
-
});
|
|
91
|
-
return resUtxos.utxos.filter(utxo => utxo.confirmation_count >= this.CONFIRMATIONS_REQUIRED || selfUTXOs.has(utxo.transaction_id));
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Returns utxo pool to be used by the coinselection algorithm
|
|
96
|
-
*
|
|
97
|
-
* @private
|
|
98
|
-
*/
|
|
99
|
-
getUtxoPool(useCached = false) {
|
|
100
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
-
if (!useCached || this.cachedUtxos == null || this.cachedUtxos.timestamp < Date.now() - this.UTXO_CACHE_TIMEOUT) {
|
|
102
|
-
const utxos = yield this.getSpendableUtxos();
|
|
103
|
-
let totalSpendable = 0;
|
|
104
|
-
const utxoPool = utxos.map(utxo => {
|
|
105
|
-
totalSpendable += utxo.tokens;
|
|
106
|
-
return {
|
|
107
|
-
vout: utxo.transaction_vout,
|
|
108
|
-
txId: utxo.transaction_id,
|
|
109
|
-
value: utxo.tokens,
|
|
110
|
-
type: this.ADDRESS_FORMAT_MAP[utxo.address_format],
|
|
111
|
-
outputScript: Buffer.from(utxo.output_script, "hex"),
|
|
112
|
-
address: utxo.address,
|
|
113
|
-
confirmations: utxo.confirmation_count
|
|
114
|
-
};
|
|
115
|
-
});
|
|
116
|
-
this.cachedUtxos = {
|
|
117
|
-
utxos: utxoPool,
|
|
118
|
-
timestamp: Date.now()
|
|
119
|
-
};
|
|
120
|
-
this.logger.info("getUtxoPool(): total spendable value: " + totalSpendable + " num utxos: " + utxoPool.length);
|
|
121
|
-
}
|
|
122
|
-
return this.cachedUtxos.utxos;
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Checks whether a coinselect result leaves enough funds to cover potential lightning anchor transaction fees
|
|
127
|
-
*
|
|
128
|
-
* @param utxoPool
|
|
129
|
-
* @param obj
|
|
130
|
-
* @param satsPerVbyte
|
|
131
|
-
* @param useCached Whether to use a cached channel count
|
|
132
|
-
* @param initialOutputLength
|
|
133
|
-
* @private
|
|
134
|
-
* @returns true if alright, false if the coinselection doesn't leave enough funds for anchor fees
|
|
135
|
-
*/
|
|
136
|
-
isLeavingEnoughForLightningAnchors(utxoPool, obj, satsPerVbyte, useCached = false, initialOutputLength = 1) {
|
|
137
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
if (obj.inputs == null || obj.outputs == null)
|
|
139
|
-
return false;
|
|
140
|
-
const spentInputs = new Set();
|
|
141
|
-
obj.inputs.forEach(txIn => {
|
|
142
|
-
spentInputs.add(txIn.txId + ":" + txIn.vout);
|
|
143
|
-
});
|
|
144
|
-
let leavesValue = new BN(0);
|
|
145
|
-
utxoPool.forEach(val => {
|
|
146
|
-
const utxoEconomicalValue = new BN(val.value).sub(satsPerVbyte.mul(new BN(utils_1.utils.inputBytes(val).length)));
|
|
147
|
-
if (
|
|
148
|
-
//Utxo not spent
|
|
149
|
-
!spentInputs.has(val.txId + ":" + val.vout) &&
|
|
150
|
-
//Only economical utxos at current fees
|
|
151
|
-
!utxoEconomicalValue.isNeg()) {
|
|
152
|
-
leavesValue = leavesValue.add(utxoEconomicalValue);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
if (obj.outputs.length > initialOutputLength) {
|
|
156
|
-
const changeUtxo = obj.outputs[obj.outputs.length - 1];
|
|
157
|
-
leavesValue = leavesValue.add(new BN(changeUtxo.value).sub(satsPerVbyte.mul(new BN(utils_1.utils.inputBytes(changeUtxo).length))));
|
|
158
|
-
}
|
|
159
|
-
if (!useCached || this.cachedChannelCount == null || this.cachedChannelCount.timestamp < Date.now() - this.CHANNEL_COUNT_CACHE_TIMEOUT) {
|
|
160
|
-
const { channels } = yield lncli.getChannels({ lnd: this.LND });
|
|
161
|
-
this.cachedChannelCount = {
|
|
162
|
-
count: channels.length,
|
|
163
|
-
timestamp: Date.now()
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
return leavesValue.gt(new BN(this.config.onchainReservedPerChannel).mul(new BN(this.cachedChannelCount.count)));
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Gets the change address from the underlying LND instance
|
|
171
|
-
*
|
|
172
|
-
* @private
|
|
173
|
-
*/
|
|
174
|
-
getChangeAddress() {
|
|
175
|
-
return new Promise((resolve, reject) => {
|
|
176
|
-
this.LND.wallet.nextAddr({
|
|
177
|
-
type: 4,
|
|
178
|
-
change: true
|
|
179
|
-
}, (err, res) => {
|
|
180
|
-
if (err != null) {
|
|
181
|
-
reject([503, 'UnexpectedErrGettingNextAddr', { err }]);
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
resolve(res.addr);
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Computes bitcoin on-chain network fee, takes channel reserve & network fee multiplier into consideration
|
|
190
|
-
*
|
|
191
|
-
* @param targetAddress Bitcoin address to send the funds to
|
|
192
|
-
* @param targetAmount Amount of funds to send to the address
|
|
193
|
-
* @param estimate Whether the chain fee should be just estimated and therefore cached utxo set could be used
|
|
194
|
-
* @param multiplierPPM Multiplier for the sats/vB returned from the fee estimator in PPM (parts per million)
|
|
195
|
-
* @private
|
|
196
|
-
* @returns Fee estimate & inputs/outputs to use when constructing transaction, or null in case of not enough funds
|
|
197
|
-
*/
|
|
198
|
-
getChainFee(targetAddress, targetAmount, estimate = false, multiplierPPM) {
|
|
199
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
let feeRate = this.config.feeEstimator == null
|
|
201
|
-
? yield lncli.getChainFeeRate({ lnd: this.LND })
|
|
202
|
-
.then(res => res.tokens_per_vbyte)
|
|
203
|
-
.catch(e => this.logger.error("getChainFee(): LND getChainFeeRate error", e))
|
|
204
|
-
: yield this.config.feeEstimator.estimateFee();
|
|
205
|
-
if (feeRate == null)
|
|
206
|
-
return null;
|
|
207
|
-
let satsPerVbyte = new BN(Math.ceil(feeRate));
|
|
208
|
-
if (multiplierPPM != null)
|
|
209
|
-
satsPerVbyte = satsPerVbyte.mul(multiplierPPM).div(new BN(1000000));
|
|
210
|
-
const utxoPool = yield this.getUtxoPool(estimate);
|
|
211
|
-
let obj = (0, coinselect2_1.coinSelect)(utxoPool, [{
|
|
212
|
-
address: targetAddress,
|
|
213
|
-
value: targetAmount,
|
|
214
|
-
script: bitcoin.address.toOutputScript(targetAddress, this.config.bitcoinNetwork)
|
|
215
|
-
}], satsPerVbyte.toNumber(), this.LND_CHANGE_OUTPUT_TYPE);
|
|
216
|
-
if (obj.inputs == null || obj.outputs == null)
|
|
217
|
-
return null;
|
|
218
|
-
if (!(yield this.isLeavingEnoughForLightningAnchors(utxoPool, obj, satsPerVbyte, estimate)))
|
|
219
|
-
return null;
|
|
220
|
-
this.logger.info("getChainFee(): fee estimated," +
|
|
221
|
-
" target: " + targetAddress +
|
|
222
|
-
" amount: " + targetAmount.toString(10) +
|
|
223
|
-
" fee: " + obj.fee +
|
|
224
|
-
" sats/vB: " + satsPerVbyte +
|
|
225
|
-
" inputs: " + obj.inputs.length +
|
|
226
|
-
" outputs: " + obj.outputs.length +
|
|
227
|
-
" multiplier: " + (multiplierPPM == null ? 1 : multiplierPPM.toNumber() / 1000000));
|
|
228
|
-
return {
|
|
229
|
-
networkFee: new BN(obj.fee),
|
|
230
|
-
satsPerVbyte,
|
|
231
|
-
outputs: obj.outputs,
|
|
232
|
-
inputs: obj.inputs
|
|
233
|
-
};
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
51
|
/**
|
|
237
52
|
* Tries to claim the swap after our transaction was confirmed
|
|
238
53
|
*
|
|
239
54
|
* @param tx
|
|
240
|
-
* @param
|
|
55
|
+
* @param swap
|
|
241
56
|
* @param vout
|
|
242
57
|
*/
|
|
243
58
|
tryClaimSwap(tx, swap, vout) {
|
|
@@ -268,9 +83,8 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
268
83
|
processPastSwap(swap) {
|
|
269
84
|
return __awaiter(this, void 0, void 0, function* () {
|
|
270
85
|
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const isSignatureExpired = swap.signatureExpiry.lt(timestamp);
|
|
86
|
+
if (swap.state === ToBtcSwapAbs_1.ToBtcSwapState.SAVED) {
|
|
87
|
+
const isSignatureExpired = swapContract.isInitAuthorizationExpired(swap.data, swap);
|
|
274
88
|
if (isSignatureExpired) {
|
|
275
89
|
const isCommitted = yield swapContract.isCommited(swap.data);
|
|
276
90
|
if (!isCommitted) {
|
|
@@ -286,8 +100,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
286
100
|
}
|
|
287
101
|
}
|
|
288
102
|
if (swap.state === ToBtcSwapAbs_1.ToBtcSwapState.NON_PAYABLE || swap.state === ToBtcSwapAbs_1.ToBtcSwapState.SAVED) {
|
|
289
|
-
|
|
290
|
-
if (isSwapExpired) {
|
|
103
|
+
if (swapContract.isExpired(signer.getAddress(), swap.data)) {
|
|
291
104
|
this.swapLogger.info(swap, "processPastSwap(state=NON_PAYABLE|SAVED): swap expired, cancelling, address: " + swap.address);
|
|
292
105
|
yield this.removeSwapData(swap, ToBtcSwapAbs_1.ToBtcSwapState.CANCELED);
|
|
293
106
|
return;
|
|
@@ -349,7 +162,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
349
162
|
}
|
|
350
163
|
this.swapLogger.debug(swap, "processBtcTx(): address: " + swap.address + " amount: " + swap.amount.toString(10) + " btcTx: " + tx);
|
|
351
164
|
//Search for required transaction output (vout)
|
|
352
|
-
const outputScript = bitcoin.
|
|
165
|
+
const outputScript = this.bitcoin.toOutputScript(swap.address);
|
|
353
166
|
const vout = tx.outs.find(e => new BN(e.value).eq(swap.amount) && Buffer.from(e.scriptPubKey.hex, "hex").equals(outputScript));
|
|
354
167
|
if (vout == null) {
|
|
355
168
|
this.swapLogger.warn(swap, "processBtcTx(): cannot find correct vout," +
|
|
@@ -374,7 +187,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
374
187
|
const swap = this.activeSubscriptions[txId];
|
|
375
188
|
//TODO: RBF the transaction if it's already taking too long to confirm
|
|
376
189
|
try {
|
|
377
|
-
let tx = yield this.
|
|
190
|
+
let tx = yield this.bitcoin.getWalletTransaction(txId);
|
|
378
191
|
if (tx == null)
|
|
379
192
|
continue;
|
|
380
193
|
if (yield this.processBtcTx(swap, tx)) {
|
|
@@ -445,117 +258,11 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
445
258
|
code: 90003,
|
|
446
259
|
msg: "Fee changed too much!",
|
|
447
260
|
data: {
|
|
448
|
-
quotedFee:
|
|
449
|
-
actualFee:
|
|
261
|
+
quotedFee: quotedSatsPerVbyte.toString(10),
|
|
262
|
+
actualFee: actualSatsPerVbyte.toString(10)
|
|
450
263
|
}
|
|
451
264
|
};
|
|
452
265
|
}
|
|
453
|
-
/**
|
|
454
|
-
* Runs sanity check on the calculated fee for the transaction
|
|
455
|
-
*
|
|
456
|
-
* @param psbt
|
|
457
|
-
* @param tx
|
|
458
|
-
* @param maxAllowedSatsPerVbyte
|
|
459
|
-
* @param actualSatsPerVbyte
|
|
460
|
-
* @private
|
|
461
|
-
* @throws {Error} Will throw an error if the fee sanity check doesn't pass
|
|
462
|
-
*/
|
|
463
|
-
checkPsbtFee(psbt, tx, maxAllowedSatsPerVbyte, actualSatsPerVbyte) {
|
|
464
|
-
const txFee = new BN(psbt.getFee());
|
|
465
|
-
//Sanity check on sats/vB
|
|
466
|
-
const maxAllowedFee = new BN(tx.virtualSize())
|
|
467
|
-
//Considering the extra output was not added, because was detrminetal
|
|
468
|
-
.add(new BN(utils_1.utils.outputBytes({ type: this.LND_CHANGE_OUTPUT_TYPE })))
|
|
469
|
-
//Multiply by maximum allowed feerate
|
|
470
|
-
.mul(maxAllowedSatsPerVbyte)
|
|
471
|
-
//Possibility that extra output was not added due to it being lower than dust
|
|
472
|
-
.add(new BN(utils_1.utils.dustThreshold({ type: this.LND_CHANGE_OUTPUT_TYPE })));
|
|
473
|
-
if (txFee.gt(maxAllowedFee))
|
|
474
|
-
throw new Error("Generated tx fee too high: " + JSON.stringify({
|
|
475
|
-
maxAllowedFee: maxAllowedFee.toString(10),
|
|
476
|
-
actualFee: txFee.toString(10),
|
|
477
|
-
psbtHex: psbt.toHex(),
|
|
478
|
-
maxAllowedSatsPerVbyte: maxAllowedSatsPerVbyte.toString(10),
|
|
479
|
-
actualSatsPerVbyte: actualSatsPerVbyte.toString(10)
|
|
480
|
-
}));
|
|
481
|
-
return txFee;
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Create PSBT for swap payout from coinselection result
|
|
485
|
-
*
|
|
486
|
-
* @param address
|
|
487
|
-
* @param amount
|
|
488
|
-
* @param escrowNonce
|
|
489
|
-
* @param coinselectResult
|
|
490
|
-
* @private
|
|
491
|
-
*/
|
|
492
|
-
getPsbt(address, amount, escrowNonce, coinselectResult) {
|
|
493
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
494
|
-
let psbt = new bitcoin.Psbt();
|
|
495
|
-
//Apply nonce
|
|
496
|
-
const nonceBuffer = Buffer.from(escrowNonce.toArray("be", 8));
|
|
497
|
-
const locktimeBN = new BN(nonceBuffer.slice(0, 5), "be");
|
|
498
|
-
let locktime = locktimeBN.toNumber() + 500000000;
|
|
499
|
-
psbt.setLocktime(locktime);
|
|
500
|
-
const sequenceBN = new BN(nonceBuffer.slice(5, 8), "be");
|
|
501
|
-
const sequence = 0xFE000000 + sequenceBN.toNumber();
|
|
502
|
-
psbt.addInputs(coinselectResult.inputs.map(input => {
|
|
503
|
-
return {
|
|
504
|
-
hash: input.txId,
|
|
505
|
-
index: input.vout,
|
|
506
|
-
witnessUtxo: {
|
|
507
|
-
script: input.outputScript,
|
|
508
|
-
value: input.value
|
|
509
|
-
},
|
|
510
|
-
sighashType: 0x01,
|
|
511
|
-
sequence
|
|
512
|
-
};
|
|
513
|
-
}));
|
|
514
|
-
psbt.addOutput({
|
|
515
|
-
script: bitcoin.address.toOutputScript(address, this.config.bitcoinNetwork),
|
|
516
|
-
value: amount.toNumber()
|
|
517
|
-
});
|
|
518
|
-
//Add change output
|
|
519
|
-
if (coinselectResult.outputs.length > 1)
|
|
520
|
-
psbt.addOutput({
|
|
521
|
-
script: bitcoin.address.toOutputScript(yield this.getChangeAddress(), this.config.bitcoinNetwork),
|
|
522
|
-
value: coinselectResult.outputs[1].value
|
|
523
|
-
});
|
|
524
|
-
return psbt;
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Signs provided PSBT and also returns a raw signed transaction
|
|
529
|
-
*
|
|
530
|
-
* @param psbt
|
|
531
|
-
* @private
|
|
532
|
-
*/
|
|
533
|
-
signPsbt(psbt) {
|
|
534
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
535
|
-
const signedPsbt = yield lncli.signPsbt({
|
|
536
|
-
lnd: this.LND,
|
|
537
|
-
psbt: psbt.toHex()
|
|
538
|
-
});
|
|
539
|
-
return {
|
|
540
|
-
psbt: bitcoin.Psbt.fromHex(signedPsbt.psbt),
|
|
541
|
-
rawTx: signedPsbt.transaction
|
|
542
|
-
};
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Sends raw bitcoin transaction
|
|
547
|
-
*
|
|
548
|
-
* @param rawTx
|
|
549
|
-
* @private
|
|
550
|
-
*/
|
|
551
|
-
sendRawTransaction(rawTx) {
|
|
552
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
553
|
-
yield lncli.broadcastChainTransaction({
|
|
554
|
-
lnd: this.LND,
|
|
555
|
-
transaction: rawTx
|
|
556
|
-
});
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
266
|
/**
|
|
560
267
|
* Sends a bitcoin transaction to payout BTC for a swap
|
|
561
268
|
*
|
|
@@ -571,35 +278,27 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
571
278
|
this.checkExpiresTooSoon(swap);
|
|
572
279
|
if (swap.metadata != null)
|
|
573
280
|
swap.metadata.times.payCLTVChecked = Date.now();
|
|
574
|
-
const
|
|
575
|
-
|
|
281
|
+
const satsPerVbyte = yield this.bitcoin.getFeeRate();
|
|
282
|
+
this.checkCalculatedTxFee(swap.satsPerVbyte, new BN(satsPerVbyte));
|
|
283
|
+
if (swap.metadata != null)
|
|
284
|
+
swap.metadata.times.payChainFee = Date.now();
|
|
285
|
+
const signResult = yield this.bitcoin.getSignedTransaction(swap.address, swap.amount.toNumber(), satsPerVbyte, swap.data.getEscrowNonce(), swap.satsPerVbyte.toNumber());
|
|
286
|
+
if (signResult == null)
|
|
576
287
|
throw {
|
|
577
288
|
code: 90002,
|
|
578
|
-
msg: "Failed to
|
|
289
|
+
msg: "Failed to create signed transaction (not enough funds?)"
|
|
579
290
|
};
|
|
580
|
-
if (swap.metadata != null)
|
|
581
|
-
swap.metadata.times.payChainFee = Date.now();
|
|
582
|
-
this.checkCalculatedTxFee(swap.satsPerVbyte, coinselectResult.satsPerVbyte);
|
|
583
|
-
//Construct payment PSBT
|
|
584
|
-
let unsignedPsbt = yield this.getPsbt(swap.address, swap.amount, swap.data.getEscrowNonce(), coinselectResult);
|
|
585
|
-
this.swapLogger.debug(swap, "sendBitcoinPayment(): generated psbt: " + unsignedPsbt.toHex());
|
|
586
|
-
//Sign the PSBT
|
|
587
|
-
const { psbt, rawTx } = yield this.signPsbt(unsignedPsbt);
|
|
588
291
|
if (swap.metadata != null)
|
|
589
292
|
swap.metadata.times.paySignPSBT = Date.now();
|
|
590
|
-
this.swapLogger.debug(swap, "sendBitcoinPayment(): signed raw transaction: " +
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
swap.txId = tx.getId();
|
|
594
|
-
swap.setRealNetworkFee(txFee);
|
|
293
|
+
this.swapLogger.debug(swap, "sendBitcoinPayment(): signed raw transaction: " + signResult.raw);
|
|
294
|
+
swap.txId = signResult.tx.getId();
|
|
295
|
+
swap.setRealNetworkFee(new BN(signResult.networkFee));
|
|
595
296
|
yield swap.setState(ToBtcSwapAbs_1.ToBtcSwapState.BTC_SENDING);
|
|
596
297
|
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
597
|
-
yield this.sendRawTransaction(
|
|
298
|
+
yield this.bitcoin.sendRawTransaction(signResult.raw);
|
|
598
299
|
if (swap.metadata != null)
|
|
599
300
|
swap.metadata.times.payTxSent = Date.now();
|
|
600
|
-
this.swapLogger.info(swap, "sendBitcoinPayment(): btc transaction generated, signed & broadcasted, txId: " + tx.getId() + " address: " + swap.address);
|
|
601
|
-
//Invalidate the UTXO cache
|
|
602
|
-
this.cachedUtxos = null;
|
|
301
|
+
this.swapLogger.info(swap, "sendBitcoinPayment(): btc transaction generated, signed & broadcasted, txId: " + signResult.tx.getId() + " address: " + swap.address);
|
|
603
302
|
yield swap.setState(ToBtcSwapAbs_1.ToBtcSwapState.BTC_SENT);
|
|
604
303
|
yield this.storageManager.saveData(swap.getHash(), swap.getSequence(), swap);
|
|
605
304
|
}));
|
|
@@ -613,7 +312,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
613
312
|
return __awaiter(this, void 0, void 0, function* () {
|
|
614
313
|
if (swap.state === ToBtcSwapAbs_1.ToBtcSwapState.BTC_SENDING) {
|
|
615
314
|
//Bitcoin transaction was signed (maybe also sent)
|
|
616
|
-
const tx = yield this.
|
|
315
|
+
const tx = yield this.bitcoin.getWalletTransaction(swap.txId);
|
|
617
316
|
const isTxSent = tx != null;
|
|
618
317
|
if (!isTxSent) {
|
|
619
318
|
//Reset the state to COMMITED
|
|
@@ -782,7 +481,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
782
481
|
checkAddress(address) {
|
|
783
482
|
let parsedOutputScript;
|
|
784
483
|
try {
|
|
785
|
-
parsedOutputScript = bitcoin.
|
|
484
|
+
parsedOutputScript = this.bitcoin.toOutputScript(address);
|
|
786
485
|
}
|
|
787
486
|
catch (e) {
|
|
788
487
|
throw {
|
|
@@ -803,7 +502,8 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
803
502
|
* @throws {DefinedRuntimeError} will throw an error if the swap is expired
|
|
804
503
|
*/
|
|
805
504
|
checkExpired(swap) {
|
|
806
|
-
const
|
|
505
|
+
const { swapContract, signer } = this.getChain(swap.chainIdentifier);
|
|
506
|
+
const isExpired = swapContract.isExpired(signer.getAddress(), swap.data);
|
|
807
507
|
if (isExpired)
|
|
808
508
|
throw {
|
|
809
509
|
_httpStatus: 200,
|
|
@@ -820,14 +520,17 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
820
520
|
*/
|
|
821
521
|
checkAndGetNetworkFee(address, amount) {
|
|
822
522
|
return __awaiter(this, void 0, void 0, function* () {
|
|
823
|
-
let chainFeeResp = yield this.
|
|
523
|
+
let chainFeeResp = yield this.bitcoin.estimateFee(address, amount.toNumber(), null, this.config.networkFeeMultiplier);
|
|
824
524
|
const hasEnoughFunds = chainFeeResp != null;
|
|
825
525
|
if (!hasEnoughFunds)
|
|
826
526
|
throw {
|
|
827
527
|
code: 20002,
|
|
828
528
|
msg: "Not enough liquidity"
|
|
829
529
|
};
|
|
830
|
-
return
|
|
530
|
+
return {
|
|
531
|
+
networkFee: new BN(chainFeeResp.networkFee),
|
|
532
|
+
satsPerVbyte: new BN(chainFeeResp.satsPerVbyte)
|
|
533
|
+
};
|
|
831
534
|
});
|
|
832
535
|
}
|
|
833
536
|
startRestServer(restServer) {
|
|
@@ -898,7 +601,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
898
601
|
return resp;
|
|
899
602
|
}), abortController.signal, pricePrefetchPromise);
|
|
900
603
|
metadata.times.priceCalculated = Date.now();
|
|
901
|
-
const paymentHash = this.getHash(chainIdentifier, parsedBody.address, parsedBody.nonce, amountBD
|
|
604
|
+
const paymentHash = this.getHash(chainIdentifier, parsedBody.address, parsedBody.nonce, amountBD).toString("hex");
|
|
902
605
|
//Add grace period another time, so the user has 1 hour to commit
|
|
903
606
|
const expirySeconds = this.getExpiryFromCLTV(parsedBody.confirmationTarget, parsedBody.confirmations).add(new BN(this.config.gracePeriod));
|
|
904
607
|
const currentTimestamp = new BN(Math.floor(Date.now() / 1000));
|
|
@@ -909,9 +612,13 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
909
612
|
metadata.times.swapCreated = Date.now();
|
|
910
613
|
const sigData = yield this.getToBtcSignatureData(chainIdentifier, payObject, req, abortController.signal, signDataPrefetchPromise);
|
|
911
614
|
metadata.times.swapSigned = Date.now();
|
|
912
|
-
const createdSwap = new ToBtcSwapAbs_1.ToBtcSwapAbs(chainIdentifier, parsedBody.address, amountBD, swapFee, swapFeeInToken, networkFeeData.networkFee, networkFeeInToken, networkFeeData.satsPerVbyte, parsedBody.nonce, parsedBody.confirmationTarget
|
|
615
|
+
const createdSwap = new ToBtcSwapAbs_1.ToBtcSwapAbs(chainIdentifier, parsedBody.address, amountBD, swapFee, swapFeeInToken, networkFeeData.networkFee, networkFeeInToken, networkFeeData.satsPerVbyte, parsedBody.nonce, parsedBody.confirmationTarget);
|
|
913
616
|
createdSwap.data = payObject;
|
|
914
617
|
createdSwap.metadata = metadata;
|
|
618
|
+
createdSwap.prefix = sigData.prefix;
|
|
619
|
+
createdSwap.timeout = sigData.timeout;
|
|
620
|
+
createdSwap.signature = sigData.signature;
|
|
621
|
+
createdSwap.feeRate = sigData.feeRate;
|
|
915
622
|
yield PluginManager_1.PluginManager.swapCreate(createdSwap);
|
|
916
623
|
yield this.storageManager.saveData(paymentHash, sequence, createdSwap);
|
|
917
624
|
this.swapLogger.info(createdSwap, "REST: /payInvoice: created swap address: " + createdSwap.address + " amount: " + amountBD.toString(10));
|
|
@@ -959,7 +666,6 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
959
666
|
code: 20007,
|
|
960
667
|
msg: "Payment not found"
|
|
961
668
|
};
|
|
962
|
-
const { swapContract, signer } = this.getChain(payment.chainIdentifier);
|
|
963
669
|
this.checkExpired(payment);
|
|
964
670
|
if (payment.state === ToBtcSwapAbs_1.ToBtcSwapState.COMMITED)
|
|
965
671
|
throw {
|
|
@@ -976,6 +682,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
976
682
|
txId: payment.txId
|
|
977
683
|
}
|
|
978
684
|
};
|
|
685
|
+
const { swapContract, signer } = this.getChain(payment.chainIdentifier);
|
|
979
686
|
if (payment.state === ToBtcSwapAbs_1.ToBtcSwapState.NON_PAYABLE) {
|
|
980
687
|
const isCommited = yield swapContract.isCommited(payment.data);
|
|
981
688
|
if (!isCommited)
|
|
@@ -13,17 +13,14 @@ export declare enum ToBtcSwapState {
|
|
|
13
13
|
}
|
|
14
14
|
export declare class ToBtcSwapAbs<T extends SwapData = SwapData> extends ToBtcBaseSwap<T, ToBtcSwapState> {
|
|
15
15
|
readonly address: string;
|
|
16
|
-
readonly amount: BN;
|
|
17
16
|
readonly satsPerVbyte: BN;
|
|
18
17
|
readonly nonce: BN;
|
|
19
18
|
readonly preferedConfirmationTarget: number;
|
|
20
|
-
readonly signatureExpiry: BN;
|
|
21
19
|
txId: string;
|
|
22
|
-
constructor(chainIdentifier: string, address: string, amount: BN, swapFee: BN, swapFeeInToken: BN, networkFee: BN, networkFeeInToken: BN, satsPerVbyte: BN, nonce: BN, preferedConfirmationTarget: number
|
|
20
|
+
constructor(chainIdentifier: string, address: string, amount: BN, swapFee: BN, swapFeeInToken: BN, networkFee: BN, networkFeeInToken: BN, satsPerVbyte: BN, nonce: BN, preferedConfirmationTarget: number);
|
|
23
21
|
constructor(obj: any);
|
|
24
22
|
serialize(): any;
|
|
25
23
|
isInitiated(): boolean;
|
|
26
24
|
isFailed(): boolean;
|
|
27
25
|
isSuccess(): boolean;
|
|
28
|
-
getOutputAmount(): BN;
|
|
29
26
|
}
|
|
@@ -17,26 +17,22 @@ var ToBtcSwapState;
|
|
|
17
17
|
ToBtcSwapState[ToBtcSwapState["CLAIMED"] = 4] = "CLAIMED";
|
|
18
18
|
})(ToBtcSwapState = exports.ToBtcSwapState || (exports.ToBtcSwapState = {}));
|
|
19
19
|
class ToBtcSwapAbs extends ToBtcBaseSwap_1.ToBtcBaseSwap {
|
|
20
|
-
constructor(chainIdOrObj, address, amount, swapFee, swapFeeInToken, networkFee, networkFeeInToken, satsPerVbyte, nonce, preferedConfirmationTarget
|
|
20
|
+
constructor(chainIdOrObj, address, amount, swapFee, swapFeeInToken, networkFee, networkFeeInToken, satsPerVbyte, nonce, preferedConfirmationTarget) {
|
|
21
21
|
var _a;
|
|
22
22
|
if (typeof (chainIdOrObj) === "string") {
|
|
23
|
-
super(chainIdOrObj, swapFee, swapFeeInToken, networkFee, networkFeeInToken);
|
|
23
|
+
super(chainIdOrObj, amount, swapFee, swapFeeInToken, networkFee, networkFeeInToken);
|
|
24
24
|
this.state = ToBtcSwapState.SAVED;
|
|
25
25
|
this.address = address;
|
|
26
|
-
this.amount = amount;
|
|
27
26
|
this.satsPerVbyte = satsPerVbyte;
|
|
28
27
|
this.nonce = nonce;
|
|
29
28
|
this.preferedConfirmationTarget = preferedConfirmationTarget;
|
|
30
|
-
this.signatureExpiry = signatureExpiry;
|
|
31
29
|
}
|
|
32
30
|
else {
|
|
33
31
|
super(chainIdOrObj);
|
|
34
32
|
this.address = chainIdOrObj.address;
|
|
35
|
-
this.amount = new BN(chainIdOrObj.amount);
|
|
36
33
|
this.satsPerVbyte = new BN(chainIdOrObj.satsPerVbyte);
|
|
37
34
|
this.nonce = new BN(chainIdOrObj.nonce);
|
|
38
35
|
this.preferedConfirmationTarget = chainIdOrObj.preferedConfirmationTarget;
|
|
39
|
-
this.signatureExpiry = (0, Utils_1.deserializeBN)(chainIdOrObj.signatureExpiry);
|
|
40
36
|
this.txId = chainIdOrObj.txId;
|
|
41
37
|
//Compatibility
|
|
42
38
|
(_a = this.quotedNetworkFee) !== null && _a !== void 0 ? _a : (this.quotedNetworkFee = (0, Utils_1.deserializeBN)(chainIdOrObj.networkFee));
|
|
@@ -46,11 +42,9 @@ class ToBtcSwapAbs extends ToBtcBaseSwap_1.ToBtcBaseSwap {
|
|
|
46
42
|
serialize() {
|
|
47
43
|
const partialSerialized = super.serialize();
|
|
48
44
|
partialSerialized.address = this.address;
|
|
49
|
-
partialSerialized.amount = this.amount.toString(10);
|
|
50
45
|
partialSerialized.satsPerVbyte = this.satsPerVbyte.toString(10);
|
|
51
46
|
partialSerialized.nonce = this.nonce.toString(10);
|
|
52
47
|
partialSerialized.preferedConfirmationTarget = this.preferedConfirmationTarget;
|
|
53
|
-
partialSerialized.signatureExpiry = (0, Utils_1.serializeBN)(this.signatureExpiry);
|
|
54
48
|
partialSerialized.txId = this.txId;
|
|
55
49
|
return partialSerialized;
|
|
56
50
|
}
|
|
@@ -63,8 +57,5 @@ class ToBtcSwapAbs extends ToBtcBaseSwap_1.ToBtcBaseSwap {
|
|
|
63
57
|
isSuccess() {
|
|
64
58
|
return this.state === ToBtcSwapState.CLAIMED;
|
|
65
59
|
}
|
|
66
|
-
getOutputAmount() {
|
|
67
|
-
return this.amount;
|
|
68
|
-
}
|
|
69
60
|
}
|
|
70
61
|
exports.ToBtcSwapAbs = ToBtcSwapAbs;
|