@atomiqlabs/lp-lib 15.0.9 → 15.0.11
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/plugins/IPlugin.d.ts +2 -1
- package/dist/plugins/PluginManager.d.ts +2 -1
- package/dist/plugins/PluginManager.js +15 -0
- package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +1 -1
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +5 -2
- package/dist/swaps/spv_vault_swap/SpvVaults.js +1 -1
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +1 -1
- package/dist/utils/BitcoinUtils.d.ts +1 -3
- package/dist/utils/BitcoinUtils.js +2 -16
- package/package.json +1 -1
- package/src/plugins/IPlugin.ts +8 -2
- package/src/plugins/PluginManager.ts +20 -2
- package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +1 -1
- package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +12 -4
- package/src/swaps/spv_vault_swap/SpvVaults.ts +2 -2
- package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +1 -1
- package/src/utils/BitcoinUtils.ts +1 -13
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BitcoinRpc } from "@atomiqlabs/base";
|
|
2
|
-
import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
|
|
2
|
+
import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
|
|
3
3
|
import { SwapHandlerSwap } from "../swaps/SwapHandlerSwap";
|
|
4
4
|
import { Command } from "@atomiqlabs/server-base";
|
|
5
5
|
import { FromBtcLnTrustedRequestType } from "../swaps/trusted/frombtcln_trusted/FromBtcLnTrusted";
|
|
@@ -128,6 +128,7 @@ export interface IPlugin {
|
|
|
128
128
|
feePPM: bigint;
|
|
129
129
|
networkFeeGetter: (amount: bigint) => Promise<bigint>;
|
|
130
130
|
}): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh | ToBtcPluginQuote>;
|
|
131
|
+
onHandlePostedFromBtcQuote?(swapType: SwapHandlerType.FROM_BTC_SPV, request: RequestData<SpvVaultPostQuote>, swap: SpvVaultSwap): Promise<QuoteThrow | null>;
|
|
131
132
|
onVaultSelection?(chainIdentifier: string, totalSats: bigint, requestedAmount: {
|
|
132
133
|
amount: bigint;
|
|
133
134
|
token: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BitcoinRpc, SwapData } from "@atomiqlabs/base";
|
|
2
2
|
import { IPlugin, PluginQuote, QuoteAmountTooHigh, QuoteAmountTooLow, QuoteSetFees, QuoteThrow, ToBtcPluginQuote } from "./IPlugin";
|
|
3
|
-
import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
|
|
3
|
+
import { FromBtcLnRequestType, FromBtcRequestType, FromBtcTrustedRequestType, ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType, SwapHandler, SwapHandlerType, ToBtcLnRequestType, ToBtcRequestType } from "..";
|
|
4
4
|
import { SwapHandlerSwap } from "../swaps/SwapHandlerSwap";
|
|
5
5
|
import { FromBtcLnTrustedRequestType } from "../swaps/trusted/frombtcln_trusted/FromBtcLnTrusted";
|
|
6
6
|
import { IBitcoinWallet } from "../wallets/IBitcoinWallet";
|
|
@@ -101,6 +101,7 @@ export declare class PluginManager {
|
|
|
101
101
|
baseFeeInBtc: bigint;
|
|
102
102
|
feePPM: bigint;
|
|
103
103
|
}): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh>;
|
|
104
|
+
static onHandlePostedFromBtcQuote(swapType: SwapHandlerType.FROM_BTC_SPV, request: RequestData<SpvVaultPostQuote>, swap: SpvVaultSwap): Promise<QuoteThrow | null>;
|
|
104
105
|
static onVaultSelection(chainIdentifier: string, totalSats: bigint, requestedAmount: {
|
|
105
106
|
amount: bigint;
|
|
106
107
|
token: string;
|
|
@@ -214,6 +214,21 @@ class PluginManager {
|
|
|
214
214
|
}
|
|
215
215
|
return null;
|
|
216
216
|
}
|
|
217
|
+
static async onHandlePostedFromBtcQuote(swapType, request, swap) {
|
|
218
|
+
for (let plugin of PluginManager.plugins.values()) {
|
|
219
|
+
try {
|
|
220
|
+
if (plugin.onHandlePostedFromBtcQuote != null) {
|
|
221
|
+
const result = await plugin.onHandlePostedFromBtcQuote(swapType, request, swap);
|
|
222
|
+
if (result != null && (0, IPlugin_1.isQuoteThrow)(result))
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
pluginLogger.error(plugin, "onHandlePostedFromBtcQuote(): plugin error", e);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
217
232
|
static async onVaultSelection(chainIdentifier, totalSats, requestedAmount, gasAmount) {
|
|
218
233
|
for (let plugin of PluginManager.plugins.values()) {
|
|
219
234
|
try {
|
|
@@ -309,7 +309,7 @@ class ToBtcAbs extends ToBtcBaseSwapHandler_1.ToBtcBaseSwapHandler {
|
|
|
309
309
|
if (swap.sending)
|
|
310
310
|
return;
|
|
311
311
|
//Bitcoin transaction was signed (maybe also sent)
|
|
312
|
-
const tx = await (0, BitcoinUtils_1.checkTransactionReplaced)(swap.txId, swap.btcRawTx, this.
|
|
312
|
+
const tx = await (0, BitcoinUtils_1.checkTransactionReplaced)(swap.txId, swap.btcRawTx, this.bitcoinRpc);
|
|
313
313
|
const isTxSent = tx != null;
|
|
314
314
|
if (!isTxSent) {
|
|
315
315
|
//Reset the state to COMMITED
|
|
@@ -13,6 +13,7 @@ const crypto_1 = require("crypto");
|
|
|
13
13
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
14
14
|
const SpvVaults_1 = require("./SpvVaults");
|
|
15
15
|
const BitcoinUtils_1 = require("../../utils/BitcoinUtils");
|
|
16
|
+
const AmountAssertions_1 = require("../assertions/AmountAssertions");
|
|
16
17
|
const TX_MAX_VSIZE = 16 * 1024;
|
|
17
18
|
class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
|
|
18
19
|
constructor(storageDirectory, vaultStorage, path, chainsData, swapPricing, bitcoin, bitcoinRpc, spvVaultSigner, config) {
|
|
@@ -105,7 +106,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
|
|
|
105
106
|
const foundWithdrawal = vault.pendingWithdrawals.find(val => val.btcTx.txid === swap.btcTxId);
|
|
106
107
|
let tx = foundWithdrawal?.btcTx;
|
|
107
108
|
if (tx == null)
|
|
108
|
-
tx = await this.
|
|
109
|
+
tx = await this.bitcoinRpc.getTransaction(swap.btcTxId);
|
|
109
110
|
if (tx == null) {
|
|
110
111
|
await this.removeSwapData(swap, SpvVaultSwap_1.SpvVaultSwapState.FAILED);
|
|
111
112
|
return;
|
|
@@ -128,7 +129,7 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
|
|
|
128
129
|
const foundWithdrawal = vault.pendingWithdrawals.find(val => val.btcTx.txid === swap.btcTxId);
|
|
129
130
|
let tx = foundWithdrawal?.btcTx;
|
|
130
131
|
if (tx == null)
|
|
131
|
-
tx = await this.
|
|
132
|
+
tx = await this.bitcoinRpc.getTransaction(swap.btcTxId);
|
|
132
133
|
if (tx == null) {
|
|
133
134
|
await this.removeSwapData(swap, SpvVaultSwap_1.SpvVaultSwapState.DOUBLE_SPENT);
|
|
134
135
|
return;
|
|
@@ -343,6 +344,8 @@ class SpvVaultSwapHandler extends SwapHandler_1.SwapHandler {
|
|
|
343
344
|
msg: "Used vault not found!"
|
|
344
345
|
};
|
|
345
346
|
}
|
|
347
|
+
//Check the posted quote with the plugins
|
|
348
|
+
AmountAssertions_1.AmountAssertions.handlePluginErrorResponses(await PluginManager_1.PluginManager.onHandlePostedFromBtcQuote(this.type, { chainIdentifier: swap.chainIdentifier, raw: req, parsed: parsedBody, metadata }, swap));
|
|
346
349
|
//Try parse psbt
|
|
347
350
|
let transaction;
|
|
348
351
|
try {
|
|
@@ -330,7 +330,7 @@ class SpvVaults {
|
|
|
330
330
|
if (pendingWithdrawal.sending)
|
|
331
331
|
continue;
|
|
332
332
|
//Check all the pending withdrawals that were not finalized yet
|
|
333
|
-
const btcTx = await (0, BitcoinUtils_1.
|
|
333
|
+
const btcTx = await (0, BitcoinUtils_1.checkTransactionReplaced)(pendingWithdrawal.btcTx.txid, pendingWithdrawal.btcTx.raw, this.bitcoinRpc);
|
|
334
334
|
if (btcTx == null) {
|
|
335
335
|
//Probable double-spend, remove from pending withdrawals
|
|
336
336
|
if (!vault.doubleSpendPendingWithdrawal(pendingWithdrawal)) {
|
|
@@ -608,7 +608,7 @@ class FromBtcTrusted extends SwapHandler_1.SwapHandler {
|
|
|
608
608
|
}
|
|
609
609
|
async checkDoubleSpends() {
|
|
610
610
|
for (let swap of this.doubleSpendWatchdogSwaps.keys()) {
|
|
611
|
-
const tx = await this.
|
|
611
|
+
const tx = await this.bitcoinRpc.getTransaction(swap.txId);
|
|
612
612
|
if (tx == null) {
|
|
613
613
|
this.swapLogger.debug(swap, "checkDoubleSpends(): Swap was double spent, burning... - original txId: " + swap.txId);
|
|
614
614
|
this.processPastSwap(swap, null, null);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { TransactionInput } from "@scure/btc-signer/psbt";
|
|
2
2
|
import { BitcoinRpc, BtcTx } from "@atomiqlabs/base";
|
|
3
|
-
import { IBitcoinWallet } from "../wallets/IBitcoinWallet";
|
|
4
3
|
export declare function isLegacyInput(input: TransactionInput): boolean;
|
|
5
|
-
export declare function checkTransactionReplaced(txId: string, txRaw: string, bitcoin:
|
|
6
|
-
export declare function checkTransactionReplacedRpc(txId: string, txRaw: string, bitcoin: BitcoinRpc<any>): Promise<BtcTx>;
|
|
4
|
+
export declare function checkTransactionReplaced(txId: string, txRaw: string, bitcoin: BitcoinRpc<any>): Promise<BtcTx>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.checkTransactionReplaced = exports.isLegacyInput = void 0;
|
|
4
4
|
const utxo_1 = require("@scure/btc-signer/utxo");
|
|
5
5
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
6
6
|
const Utils_1 = require("./Utils");
|
|
@@ -46,20 +46,6 @@ function isLegacyInput(input) {
|
|
|
46
46
|
}
|
|
47
47
|
exports.isLegacyInput = isLegacyInput;
|
|
48
48
|
async function checkTransactionReplaced(txId, txRaw, bitcoin) {
|
|
49
|
-
const existingTx = await bitcoin.getWalletTransaction(txId);
|
|
50
|
-
if (existingTx != null)
|
|
51
|
-
return existingTx;
|
|
52
|
-
//Try to re-broadcast
|
|
53
|
-
try {
|
|
54
|
-
await bitcoin.sendRawTransaction(txRaw);
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
logger.error("checkTransactionReplaced(" + txId + "): Error when trying to re-broadcast raw transaction: ", e);
|
|
58
|
-
}
|
|
59
|
-
return await bitcoin.getWalletTransaction(txId);
|
|
60
|
-
}
|
|
61
|
-
exports.checkTransactionReplaced = checkTransactionReplaced;
|
|
62
|
-
async function checkTransactionReplacedRpc(txId, txRaw, bitcoin) {
|
|
63
49
|
const existingTx = await bitcoin.getTransaction(txId);
|
|
64
50
|
if (existingTx != null)
|
|
65
51
|
return existingTx;
|
|
@@ -72,4 +58,4 @@ async function checkTransactionReplacedRpc(txId, txRaw, bitcoin) {
|
|
|
72
58
|
}
|
|
73
59
|
return await bitcoin.getTransaction(txId);
|
|
74
60
|
}
|
|
75
|
-
exports.
|
|
61
|
+
exports.checkTransactionReplaced = checkTransactionReplaced;
|
package/package.json
CHANGED
package/src/plugins/IPlugin.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {BitcoinRpc
|
|
1
|
+
import {BitcoinRpc} from "@atomiqlabs/base";
|
|
2
2
|
import {
|
|
3
3
|
FromBtcLnRequestType,
|
|
4
4
|
FromBtcRequestType, FromBtcTrustedRequestType,
|
|
5
|
-
ISwapPrice, MultichainData, RequestData, SpvVaultSwapRequestType,
|
|
5
|
+
ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType,
|
|
6
6
|
SwapHandler, SwapHandlerType,
|
|
7
7
|
ToBtcLnRequestType,
|
|
8
8
|
ToBtcRequestType
|
|
@@ -151,6 +151,12 @@ export interface IPlugin {
|
|
|
151
151
|
fees: {baseFeeInBtc: bigint, feePPM: bigint, networkFeeGetter: (amount: bigint) => Promise<bigint>}
|
|
152
152
|
): Promise<QuoteThrow | QuoteSetFees | QuoteAmountTooLow | QuoteAmountTooHigh | ToBtcPluginQuote>;
|
|
153
153
|
|
|
154
|
+
onHandlePostedFromBtcQuote?(
|
|
155
|
+
swapType: SwapHandlerType.FROM_BTC_SPV,
|
|
156
|
+
request: RequestData<SpvVaultPostQuote>,
|
|
157
|
+
swap: SpvVaultSwap
|
|
158
|
+
): Promise<QuoteThrow | null>;
|
|
159
|
+
|
|
154
160
|
onVaultSelection?(
|
|
155
161
|
chainIdentifier: string,
|
|
156
162
|
totalSats: bigint,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {BitcoinRpc,
|
|
1
|
+
import {BitcoinRpc, SwapData} from "@atomiqlabs/base";
|
|
2
2
|
import {
|
|
3
3
|
IPlugin, isPluginQuote, isQuoteAmountTooHigh, isQuoteAmountTooLow, isQuoteSetFees,
|
|
4
4
|
isQuoteThrow, isToBtcPluginQuote, PluginQuote,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
FromBtcLnRequestType,
|
|
12
12
|
FromBtcRequestType, FromBtcTrustedRequestType,
|
|
13
|
-
ISwapPrice, MultichainData, RequestData, SpvVaultSwapRequestType,
|
|
13
|
+
ISwapPrice, MultichainData, RequestData, SpvVaultPostQuote, SpvVaultSwap, SpvVaultSwapRequestType,
|
|
14
14
|
SwapHandler, SwapHandlerType,
|
|
15
15
|
ToBtcLnRequestType,
|
|
16
16
|
ToBtcRequestType
|
|
@@ -291,6 +291,24 @@ export class PluginManager {
|
|
|
291
291
|
return null;
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
static async onHandlePostedFromBtcQuote(
|
|
295
|
+
swapType: SwapHandlerType.FROM_BTC_SPV,
|
|
296
|
+
request: RequestData<SpvVaultPostQuote>,
|
|
297
|
+
swap: SpvVaultSwap
|
|
298
|
+
): Promise<QuoteThrow | null> {
|
|
299
|
+
for(let plugin of PluginManager.plugins.values()) {
|
|
300
|
+
try {
|
|
301
|
+
if(plugin.onHandlePostedFromBtcQuote!=null) {
|
|
302
|
+
const result = await plugin.onHandlePostedFromBtcQuote(swapType, request, swap);
|
|
303
|
+
if(result!=null && isQuoteThrow(result)) return result;
|
|
304
|
+
}
|
|
305
|
+
} catch (e) {
|
|
306
|
+
pluginLogger.error(plugin, "onHandlePostedFromBtcQuote(): plugin error", e);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
|
|
294
312
|
static async onVaultSelection(
|
|
295
313
|
chainIdentifier: string,
|
|
296
314
|
totalSats: bigint,
|
|
@@ -396,7 +396,7 @@ export class ToBtcAbs extends ToBtcBaseSwapHandler<ToBtcSwapAbs, ToBtcSwapState>
|
|
|
396
396
|
if(swap.state===ToBtcSwapState.BTC_SENDING) {
|
|
397
397
|
if(swap.sending) return;
|
|
398
398
|
//Bitcoin transaction was signed (maybe also sent)
|
|
399
|
-
const tx = await checkTransactionReplaced(swap.txId, swap.btcRawTx, this.
|
|
399
|
+
const tx = await checkTransactionReplaced(swap.txId, swap.btcRawTx, this.bitcoinRpc);
|
|
400
400
|
|
|
401
401
|
const isTxSent = tx!=null;
|
|
402
402
|
if(!isTxSent) {
|
|
@@ -27,9 +27,10 @@ import {ServerParamEncoder} from "../../utils/paramcoders/server/ServerParamEnco
|
|
|
27
27
|
import {FieldTypeEnum} from "../../utils/paramcoders/SchemaVerifier";
|
|
28
28
|
import {FromBtcAmountAssertions} from "../assertions/FromBtcAmountAssertions";
|
|
29
29
|
import {randomBytes} from "crypto";
|
|
30
|
-
import {
|
|
30
|
+
import {Transaction} from "@scure/btc-signer";
|
|
31
31
|
import {SpvVaults, VAULT_DUST_AMOUNT} from "./SpvVaults";
|
|
32
|
-
import {
|
|
32
|
+
import {isLegacyInput} from "../../utils/BitcoinUtils";
|
|
33
|
+
import {AmountAssertions} from "../assertions/AmountAssertions";
|
|
33
34
|
|
|
34
35
|
export type SpvVaultSwapHandlerConfig = SwapBaseConfig & {
|
|
35
36
|
vaultsCheckInterval: number,
|
|
@@ -170,7 +171,7 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
|
|
|
170
171
|
const vault = await this.Vaults.getVault(swap.chainIdentifier, swap.vaultOwner, swap.vaultId);
|
|
171
172
|
const foundWithdrawal = vault.pendingWithdrawals.find(val => val.btcTx.txid === swap.btcTxId);
|
|
172
173
|
let tx = foundWithdrawal?.btcTx;
|
|
173
|
-
if(tx==null) tx = await this.
|
|
174
|
+
if(tx==null) tx = await this.bitcoinRpc.getTransaction(swap.btcTxId);
|
|
174
175
|
|
|
175
176
|
if(tx==null) {
|
|
176
177
|
await this.removeSwapData(swap, SpvVaultSwapState.FAILED);
|
|
@@ -191,7 +192,7 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
|
|
|
191
192
|
const vault = await this.Vaults.getVault(swap.chainIdentifier, swap.vaultOwner, swap.vaultId);
|
|
192
193
|
const foundWithdrawal = vault.pendingWithdrawals.find(val => val.btcTx.txid === swap.btcTxId);
|
|
193
194
|
let tx = foundWithdrawal?.btcTx;
|
|
194
|
-
if(tx==null) tx = await this.
|
|
195
|
+
if(tx==null) tx = await this.bitcoinRpc.getTransaction(swap.btcTxId);
|
|
195
196
|
|
|
196
197
|
if(tx==null) {
|
|
197
198
|
await this.removeSwapData(swap, SpvVaultSwapState.DOUBLE_SPENT);
|
|
@@ -470,6 +471,13 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
|
|
|
470
471
|
};
|
|
471
472
|
}
|
|
472
473
|
|
|
474
|
+
//Check the posted quote with the plugins
|
|
475
|
+
AmountAssertions.handlePluginErrorResponses(await PluginManager.onHandlePostedFromBtcQuote(
|
|
476
|
+
this.type,
|
|
477
|
+
{chainIdentifier: swap.chainIdentifier, raw: req, parsed: parsedBody, metadata},
|
|
478
|
+
swap
|
|
479
|
+
));
|
|
480
|
+
|
|
473
481
|
//Try parse psbt
|
|
474
482
|
let transaction: Transaction;
|
|
475
483
|
try {
|
|
@@ -15,7 +15,7 @@ import {ISpvVaultSigner} from "../../wallets/ISpvVaultSigner";
|
|
|
15
15
|
import {AmountAssertions} from "../assertions/AmountAssertions";
|
|
16
16
|
import {ChainData} from "../SwapHandler";
|
|
17
17
|
import {Transaction} from "@scure/btc-signer";
|
|
18
|
-
import {
|
|
18
|
+
import {checkTransactionReplaced} from "../../utils/BitcoinUtils";
|
|
19
19
|
|
|
20
20
|
export const VAULT_DUST_AMOUNT = 600;
|
|
21
21
|
const VAULT_INIT_CONFIRMATIONS = 2;
|
|
@@ -389,7 +389,7 @@ export class SpvVaults {
|
|
|
389
389
|
if(pendingWithdrawal.sending) continue;
|
|
390
390
|
|
|
391
391
|
//Check all the pending withdrawals that were not finalized yet
|
|
392
|
-
const btcTx = await
|
|
392
|
+
const btcTx = await checkTransactionReplaced(pendingWithdrawal.btcTx.txid, pendingWithdrawal.btcTx.raw, this.bitcoinRpc);
|
|
393
393
|
if(btcTx==null) {
|
|
394
394
|
//Probable double-spend, remove from pending withdrawals
|
|
395
395
|
if(!vault.doubleSpendPendingWithdrawal(pendingWithdrawal)) {
|
|
@@ -702,7 +702,7 @@ export class FromBtcTrusted extends SwapHandler<FromBtcTrustedSwap, FromBtcTrust
|
|
|
702
702
|
|
|
703
703
|
private async checkDoubleSpends(): Promise<void> {
|
|
704
704
|
for(let swap of this.doubleSpendWatchdogSwaps.keys()) {
|
|
705
|
-
const tx = await this.
|
|
705
|
+
const tx = await this.bitcoinRpc.getTransaction(swap.txId);
|
|
706
706
|
if(tx==null) {
|
|
707
707
|
this.swapLogger.debug(swap, "checkDoubleSpends(): Swap was double spent, burning... - original txId: "+swap.txId);
|
|
708
708
|
this.processPastSwap(swap, null, null);
|
|
@@ -46,19 +46,7 @@ export function isLegacyInput(input: TransactionInput): boolean {
|
|
|
46
46
|
return true;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export async function checkTransactionReplaced(txId: string, txRaw: string, bitcoin:
|
|
50
|
-
const existingTx = await bitcoin.getWalletTransaction(txId);
|
|
51
|
-
if(existingTx!=null) return existingTx;
|
|
52
|
-
//Try to re-broadcast
|
|
53
|
-
try {
|
|
54
|
-
await bitcoin.sendRawTransaction(txRaw);
|
|
55
|
-
} catch (e) {
|
|
56
|
-
logger.error("checkTransactionReplaced("+txId+"): Error when trying to re-broadcast raw transaction: ", e);
|
|
57
|
-
}
|
|
58
|
-
return await bitcoin.getWalletTransaction(txId);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export async function checkTransactionReplacedRpc(txId: string, txRaw: string, bitcoin: BitcoinRpc<any>): Promise<BtcTx> {
|
|
49
|
+
export async function checkTransactionReplaced(txId: string, txRaw: string, bitcoin: BitcoinRpc<any>): Promise<BtcTx> {
|
|
62
50
|
const existingTx = await bitcoin.getTransaction(txId);
|
|
63
51
|
if(existingTx!=null) return existingTx;
|
|
64
52
|
//Try to re-broadcast
|