@atomiqlabs/sdk 8.7.7 → 8.9.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/api/index.d.ts +1 -0
- package/api/index.js +3 -0
- package/dist/ApiList.d.ts +37 -0
- package/dist/ApiList.js +30 -0
- package/dist/api/ApiEndpoints.d.ts +393 -0
- package/dist/api/ApiEndpoints.js +2 -0
- package/dist/api/ApiParser.d.ts +10 -0
- package/dist/api/ApiParser.js +134 -0
- package/dist/api/ApiTypes.d.ts +157 -0
- package/dist/api/ApiTypes.js +75 -0
- package/dist/api/SerializedAction.d.ts +40 -0
- package/dist/api/SerializedAction.js +59 -0
- package/dist/api/SwapperApi.d.ts +50 -0
- package/dist/api/SwapperApi.js +431 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +24 -0
- package/dist/bitcoin/coinselect2/accumulative.d.ts +1 -0
- package/dist/bitcoin/coinselect2/accumulative.js +1 -1
- package/dist/bitcoin/coinselect2/blackjack.d.ts +1 -0
- package/dist/bitcoin/coinselect2/blackjack.js +1 -1
- package/dist/bitcoin/coinselect2/index.d.ts +3 -2
- package/dist/bitcoin/coinselect2/index.js +2 -2
- package/dist/bitcoin/coinselect2/utils.d.ts +7 -2
- package/dist/bitcoin/coinselect2/utils.js +45 -10
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +8 -25
- package/dist/bitcoin/wallet/BitcoinWallet.js +31 -18
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +40 -2
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +7 -2
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +10 -4
- package/dist/events/UnifiedSwapEventListener.d.ts +4 -3
- package/dist/events/UnifiedSwapEventListener.js +8 -2
- package/dist/http/HttpUtils.d.ts +4 -2
- package/dist/http/HttpUtils.js +10 -4
- package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +2 -1
- package/dist/http/paramcoders/client/StreamingFetchPromise.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +7 -2
- package/dist/intermediaries/IntermediaryDiscovery.js +4 -4
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +182 -15
- package/dist/intermediaries/apis/IntermediaryAPI.js +192 -31
- package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -0
- package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -0
- package/dist/storage/IUnifiedStorage.d.ts +45 -3
- package/dist/storage/UnifiedSwapStorage.d.ts +8 -2
- package/dist/storage/UnifiedSwapStorage.js +46 -8
- package/dist/swapper/Swapper.d.ts +77 -4
- package/dist/swapper/Swapper.js +117 -25
- package/dist/swapper/SwapperUtils.d.ts +18 -2
- package/dist/swapper/SwapperUtils.js +39 -1
- package/dist/swaps/ISwap.d.ts +70 -9
- package/dist/swaps/ISwap.js +28 -6
- package/dist/swaps/ISwapWrapper.d.ts +11 -1
- package/dist/swaps/ISwapWrapper.js +23 -3
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +1 -1
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +4 -2
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +2 -1
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +2 -2
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +3 -2
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +47 -31
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +201 -67
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +6 -6
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +82 -15
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +304 -98
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +6 -6
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +75 -42
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +424 -87
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +7 -7
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +54 -11
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +214 -41
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +2 -1
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +7 -8
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +3 -1
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +5 -5
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +85 -22
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +299 -56
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +41 -7
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +183 -58
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +53 -12
- package/dist/swaps/trusted/ln/LnForGasSwap.js +163 -49
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +1 -2
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +14 -13
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +30 -47
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +3 -1
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +4 -4
- package/dist/types/SwapExecutionAction.d.ts +141 -34
- package/dist/types/SwapExecutionAction.js +104 -0
- package/dist/types/SwapExecutionStep.d.ts +144 -0
- package/dist/types/SwapExecutionStep.js +87 -0
- package/dist/types/TokenAmount.d.ts +6 -0
- package/dist/types/TokenAmount.js +26 -1
- package/dist/utils/BitcoinUtils.d.ts +4 -0
- package/dist/utils/BitcoinUtils.js +73 -1
- package/dist/utils/BitcoinWalletUtils.d.ts +2 -2
- package/dist/utils/Utils.d.ts +3 -1
- package/dist/utils/Utils.js +7 -1
- package/package.json +7 -4
- package/src/api/ApiEndpoints.ts +427 -0
- package/src/api/ApiParser.ts +138 -0
- package/src/api/ApiTypes.ts +229 -0
- package/src/api/SerializedAction.ts +97 -0
- package/src/api/SwapperApi.ts +545 -0
- package/src/api/index.ts +5 -0
- package/src/bitcoin/coinselect2/accumulative.ts +2 -1
- package/src/bitcoin/coinselect2/blackjack.ts +2 -1
- package/src/bitcoin/coinselect2/index.ts +5 -4
- package/src/bitcoin/coinselect2/utils.ts +55 -14
- package/src/bitcoin/wallet/BitcoinWallet.ts +69 -57
- package/src/bitcoin/wallet/IBitcoinWallet.ts +44 -3
- package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +12 -4
- package/src/events/UnifiedSwapEventListener.ts +11 -3
- package/src/http/HttpUtils.ts +10 -4
- package/src/http/paramcoders/client/StreamingFetchPromise.ts +4 -2
- package/src/index.ts +1 -0
- package/src/intermediaries/IntermediaryDiscovery.ts +9 -2
- package/src/intermediaries/apis/IntermediaryAPI.ts +335 -35
- package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -0
- package/src/storage/IUnifiedStorage.ts +45 -4
- package/src/storage/UnifiedSwapStorage.ts +42 -8
- package/src/swapper/Swapper.ts +165 -24
- package/src/swapper/SwapperUtils.ts +42 -2
- package/src/swaps/ISwap.ts +88 -16
- package/src/swaps/ISwapWrapper.ts +28 -3
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +5 -3
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +3 -1
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +4 -1
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +264 -67
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +6 -4
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +390 -89
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +6 -4
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +548 -94
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -5
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +276 -45
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -6
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +5 -3
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +413 -64
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +239 -61
- package/src/swaps/trusted/ln/LnForGasSwap.ts +211 -47
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +1 -2
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +32 -51
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +5 -3
- package/src/types/SwapExecutionAction.ts +266 -43
- package/src/types/SwapExecutionStep.ts +224 -0
- package/src/types/TokenAmount.ts +36 -2
- package/src/utils/BitcoinUtils.ts +73 -0
- package/src/utils/BitcoinWalletUtils.ts +2 -2
- package/src/utils/Utils.ts +10 -1
- package/src/intermediaries/apis/TrustedIntermediaryAPI.ts +0 -258
|
@@ -73,6 +73,15 @@ function transactionBytes(inputs, outputs, changeType) {
|
|
|
73
73
|
}
|
|
74
74
|
return Math.ceil(size);
|
|
75
75
|
}
|
|
76
|
+
function numberOrNaN(v) {
|
|
77
|
+
if (typeof v !== 'number')
|
|
78
|
+
return NaN;
|
|
79
|
+
if (!isFinite(v))
|
|
80
|
+
return NaN;
|
|
81
|
+
if (v < 0)
|
|
82
|
+
return NaN;
|
|
83
|
+
return v;
|
|
84
|
+
}
|
|
76
85
|
function uintOrNaN(v) {
|
|
77
86
|
if (typeof v !== 'number')
|
|
78
87
|
return NaN;
|
|
@@ -91,26 +100,50 @@ function sumOrNaN(range) {
|
|
|
91
100
|
return range.reduce((a, x) => a + uintOrNaN(x.value), 0);
|
|
92
101
|
}
|
|
93
102
|
function finalize(inputs, outputs, feeRate, changeType, cpfpAddFee = 0) {
|
|
94
|
-
const bytesAccum = transactionBytes(inputs, outputs, changeType);
|
|
103
|
+
const bytesAccum = transactionBytes(inputs, outputs, changeType ?? undefined);
|
|
95
104
|
logger.debug("finalize(): Transaction bytes: ", bytesAccum);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
if (changeType != null) {
|
|
106
|
+
const feeAfterExtraOutput = (feeRate * (bytesAccum + outputBytes({ type: changeType }))) + cpfpAddFee;
|
|
107
|
+
logger.debug("finalize(): TX fee after adding change output: ", feeAfterExtraOutput);
|
|
108
|
+
const remainderAfterExtraOutput = Math.floor(sumOrNaN(inputs) - (sumOrNaN(outputs) + feeAfterExtraOutput));
|
|
109
|
+
logger.debug("finalize(): Leaves change (changeType=" + changeType + ") value: ", remainderAfterExtraOutput);
|
|
110
|
+
// is it worth a change output?
|
|
111
|
+
if (remainderAfterExtraOutput >= dustThreshold({ type: changeType })) {
|
|
112
|
+
outputs = outputs.concat({ value: remainderAfterExtraOutput, type: changeType });
|
|
113
|
+
}
|
|
103
114
|
}
|
|
104
115
|
const fee = sumOrNaN(inputs) - sumOrNaN(outputs);
|
|
105
116
|
logger.debug("finalize(): Re-calculated total fee: ", fee);
|
|
106
|
-
if (!isFinite(fee))
|
|
117
|
+
if (!isFinite(fee) || fee < 0)
|
|
107
118
|
return { fee: (feeRate * bytesAccum) + cpfpAddFee };
|
|
119
|
+
let txVSize = exports.utils.transactionBytes(inputs, outputs);
|
|
120
|
+
let txFee = fee;
|
|
121
|
+
const cpfpSortedInputs = [...inputs].sort((a, b) => (b.cpfp?.txEffectiveFeeRate ?? 0) - (a.cpfp?.txEffectiveFeeRate ?? 0));
|
|
122
|
+
cpfpSortedInputs.forEach(input => {
|
|
123
|
+
if (input.cpfp == null)
|
|
124
|
+
return;
|
|
125
|
+
const currentEffectiveFeeRate = txFee / txVSize;
|
|
126
|
+
if (currentEffectiveFeeRate > input.cpfp.txEffectiveFeeRate) {
|
|
127
|
+
txVSize += input.cpfp.txVsize;
|
|
128
|
+
txFee += input.cpfp.txVsize * input.cpfp.txEffectiveFeeRate;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
108
131
|
return {
|
|
109
132
|
inputs: inputs,
|
|
110
133
|
outputs: outputs,
|
|
134
|
+
effectiveFeeRate: txFee / txVSize,
|
|
111
135
|
fee: fee
|
|
112
136
|
};
|
|
113
137
|
}
|
|
138
|
+
function isDetrimentalInput(feeRate, utxo) {
|
|
139
|
+
const utxoBytes = exports.utils.inputBytes(utxo);
|
|
140
|
+
const utxoFee = feeRate * utxoBytes;
|
|
141
|
+
let cpfpFee = 0;
|
|
142
|
+
if (utxo.cpfp != null && utxo.cpfp.txEffectiveFeeRate < feeRate)
|
|
143
|
+
cpfpFee = Math.ceil(utxo.cpfp.txVsize * (feeRate - utxo.cpfp.txEffectiveFeeRate));
|
|
144
|
+
// skip detrimental input
|
|
145
|
+
return utxoFee + cpfpFee > utxo.value;
|
|
146
|
+
}
|
|
114
147
|
exports.utils = {
|
|
115
148
|
dustThreshold: dustThreshold,
|
|
116
149
|
finalize: finalize,
|
|
@@ -119,5 +152,7 @@ exports.utils = {
|
|
|
119
152
|
sumOrNaN: sumOrNaN,
|
|
120
153
|
sumForgiving: sumForgiving,
|
|
121
154
|
transactionBytes: transactionBytes,
|
|
122
|
-
uintOrNaN: uintOrNaN
|
|
155
|
+
uintOrNaN: uintOrNaN,
|
|
156
|
+
numberOrNaN: numberOrNaN,
|
|
157
|
+
isDetrimentalInput
|
|
123
158
|
};
|
|
@@ -1,29 +1,8 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
1
|
import { CoinselectAddressTypes } from "../coinselect2";
|
|
4
2
|
import { BTC_NETWORK } from "@scure/btc-signer/utils";
|
|
5
3
|
import { Transaction } from "@scure/btc-signer";
|
|
6
|
-
import { IBitcoinWallet } from "./IBitcoinWallet";
|
|
7
|
-
import { Buffer } from "buffer";
|
|
4
|
+
import { BitcoinWalletUtxo, BitcoinWalletUtxoBase, IBitcoinWallet } from "./IBitcoinWallet";
|
|
8
5
|
import { BitcoinNetwork, BitcoinRpcWithAddressIndex } from "@atomiqlabs/base";
|
|
9
|
-
/**
|
|
10
|
-
* UTXO data structure for Bitcoin wallets
|
|
11
|
-
*
|
|
12
|
-
* @category Bitcoin
|
|
13
|
-
*/
|
|
14
|
-
export type BitcoinWalletUtxo = {
|
|
15
|
-
vout: number;
|
|
16
|
-
txId: string;
|
|
17
|
-
value: number;
|
|
18
|
-
type: CoinselectAddressTypes;
|
|
19
|
-
outputScript: Buffer;
|
|
20
|
-
address: string;
|
|
21
|
-
cpfp?: {
|
|
22
|
-
txVsize: number;
|
|
23
|
-
txEffectiveFeeRate: number;
|
|
24
|
-
};
|
|
25
|
-
confirmed: boolean;
|
|
26
|
-
};
|
|
27
6
|
/**
|
|
28
7
|
* Identifies the address type of a Bitcoin address
|
|
29
8
|
*
|
|
@@ -96,7 +75,7 @@ export declare abstract class BitcoinWallet implements IBitcoinWallet {
|
|
|
96
75
|
pubkey: string;
|
|
97
76
|
address: string;
|
|
98
77
|
addressType: CoinselectAddressTypes;
|
|
99
|
-
}[], psbt: Transaction,
|
|
78
|
+
}[], psbt: Transaction, _feeRate?: number, utxos?: BitcoinWalletUtxo[], spendFully?: boolean): Promise<{
|
|
100
79
|
fee: number;
|
|
101
80
|
psbt?: Transaction;
|
|
102
81
|
inputAddressIndexes?: {
|
|
@@ -106,13 +85,13 @@ export declare abstract class BitcoinWallet implements IBitcoinWallet {
|
|
|
106
85
|
protected _getSpendableBalance(sendingAccounts: {
|
|
107
86
|
address: string;
|
|
108
87
|
addressType: CoinselectAddressTypes;
|
|
109
|
-
}[], psbt?: Transaction, feeRate?: number): Promise<{
|
|
88
|
+
}[], psbt?: Transaction, feeRate?: number, outputAddressType?: CoinselectAddressTypes, utxoPool?: BitcoinWalletUtxoBase[]): Promise<{
|
|
110
89
|
balance: bigint;
|
|
111
90
|
feeRate: number;
|
|
112
91
|
totalFee: number;
|
|
113
92
|
}>;
|
|
114
93
|
abstract sendTransaction(address: string, amount: bigint, feeRate?: number): Promise<string>;
|
|
115
|
-
abstract fundPsbt(psbt: Transaction, feeRate?: number): Promise<Transaction>;
|
|
94
|
+
abstract fundPsbt(psbt: Transaction, feeRate?: number, utxos?: BitcoinWalletUtxo[], spendFully?: boolean): Promise<Transaction>;
|
|
116
95
|
abstract signPsbt(psbt: Transaction, signInputs: number[]): Promise<Transaction>;
|
|
117
96
|
abstract getTransactionFee(address: string, amount: bigint, feeRate?: number): Promise<number>;
|
|
118
97
|
abstract getFundedPsbtFee(psbt: Transaction, feeRate?: number): Promise<number>;
|
|
@@ -127,4 +106,8 @@ export declare abstract class BitcoinWallet implements IBitcoinWallet {
|
|
|
127
106
|
totalFee: number;
|
|
128
107
|
}>;
|
|
129
108
|
static bitcoinNetworkToObject(network: BitcoinNetwork): BTC_NETWORK;
|
|
109
|
+
static getSpendableBalance(utxoPool: BitcoinWalletUtxoBase[], feeRate: number, psbt?: Transaction, outputAddressType?: CoinselectAddressTypes): {
|
|
110
|
+
balance: bigint;
|
|
111
|
+
totalFee: number;
|
|
112
|
+
};
|
|
130
113
|
}
|
|
@@ -5,10 +5,10 @@ const coinselect2_1 = require("../coinselect2");
|
|
|
5
5
|
const utils_1 = require("@scure/btc-signer/utils");
|
|
6
6
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
7
7
|
const buffer_1 = require("buffer");
|
|
8
|
-
const Utils_1 = require("../../utils/Utils");
|
|
9
8
|
const BitcoinUtils_1 = require("../../utils/BitcoinUtils");
|
|
10
9
|
const Logger_1 = require("../../utils/Logger");
|
|
11
10
|
const base_1 = require("@atomiqlabs/base");
|
|
11
|
+
const utils_2 = require("../coinselect2/utils");
|
|
12
12
|
/**
|
|
13
13
|
* Identifies the address type of a Bitcoin address
|
|
14
14
|
*
|
|
@@ -135,10 +135,11 @@ class BitcoinWallet {
|
|
|
135
135
|
});
|
|
136
136
|
return this._fundPsbt(sendingAccounts, psbt, feeRate);
|
|
137
137
|
}
|
|
138
|
-
async _fundPsbt(sendingAccounts, psbt,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
async _fundPsbt(sendingAccounts, psbt, _feeRate, utxos, spendFully) {
|
|
139
|
+
const feeRate = _feeRate ?? await this.getFeeRate();
|
|
140
|
+
const utxoPool = utxos ?? (await Promise.all(sendingAccounts.map(acc => this._getUtxoPool(acc.address, acc.addressType)))).flat();
|
|
141
|
+
if (spendFully && utxoPool == null)
|
|
142
|
+
throw new Error("Cannot fully spend when no utxos are passed!");
|
|
142
143
|
logger.debug("_fundPsbt(): fee rate: " + feeRate + " utxo pool: ", utxoPool);
|
|
143
144
|
const accountPubkeys = {};
|
|
144
145
|
sendingAccounts.forEach(acc => accountPubkeys[acc.address] = acc.pubkey);
|
|
@@ -177,13 +178,23 @@ class BitcoinWallet {
|
|
|
177
178
|
});
|
|
178
179
|
}
|
|
179
180
|
logger.debug("_fundPsbt(): Coinselect targets: ", targets);
|
|
180
|
-
let coinselectResult =
|
|
181
|
+
let coinselectResult = spendFully
|
|
182
|
+
? utils_2.utils.finalize(requiredInputs.concat(utxoPool.filter(utxo => !utils_2.utils.isDetrimentalInput(feeRate, utxo))), targets, feeRate, null)
|
|
183
|
+
: (0, coinselect2_1.coinSelect)(utxoPool, targets, feeRate, sendingAccounts[0].addressType, requiredInputs);
|
|
181
184
|
logger.debug("_fundPsbt(): Coinselect result: ", coinselectResult);
|
|
182
|
-
if (coinselectResult.inputs == null || coinselectResult.outputs == null) {
|
|
185
|
+
if (coinselectResult.inputs == null || coinselectResult.outputs == null || coinselectResult.effectiveFeeRate == null) {
|
|
183
186
|
return {
|
|
184
187
|
fee: coinselectResult.fee
|
|
185
188
|
};
|
|
186
189
|
}
|
|
190
|
+
if (spendFully && feeRate != null) {
|
|
191
|
+
const maximumAllowedFeeRate = (1.5 * feeRate) + 10;
|
|
192
|
+
if (coinselectResult.effectiveFeeRate > maximumAllowedFeeRate)
|
|
193
|
+
throw new Error(`Effective fee rate too high, feeRate: ${coinselectResult.effectiveFeeRate} sats/vB, maximum: ${maximumAllowedFeeRate} sats/vB!`);
|
|
194
|
+
const minimumAllowedFeeRate = 0.9 * feeRate;
|
|
195
|
+
if (coinselectResult.effectiveFeeRate < minimumAllowedFeeRate)
|
|
196
|
+
throw new Error(`Effective fee rate too low, feeRate: ${coinselectResult.effectiveFeeRate} sats/vB, minimum: ${minimumAllowedFeeRate} sats/vB!`);
|
|
197
|
+
}
|
|
187
198
|
// Remove in/outs that are already in the PSBT
|
|
188
199
|
coinselectResult.inputs.splice(0, psbt.inputsLength);
|
|
189
200
|
coinselectResult.outputs.splice(0, psbt.outputsLength);
|
|
@@ -264,9 +275,18 @@ class BitcoinWallet {
|
|
|
264
275
|
inputAddressIndexes
|
|
265
276
|
};
|
|
266
277
|
}
|
|
267
|
-
async _getSpendableBalance(sendingAccounts, psbt, feeRate) {
|
|
278
|
+
async _getSpendableBalance(sendingAccounts, psbt, feeRate, outputAddressType, utxoPool) {
|
|
268
279
|
feeRate ??= await this.getFeeRate();
|
|
269
|
-
|
|
280
|
+
utxoPool ??= (await Promise.all(sendingAccounts.map(acc => this._getUtxoPool(acc.address, acc.addressType)))).flat();
|
|
281
|
+
return {
|
|
282
|
+
...BitcoinWallet.getSpendableBalance(utxoPool ?? (await Promise.all(sendingAccounts.map(acc => this._getUtxoPool(acc.address, acc.addressType)))).flat(), feeRate ?? await this.getFeeRate(), psbt, outputAddressType),
|
|
283
|
+
feeRate
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
static bitcoinNetworkToObject(network) {
|
|
287
|
+
return btcNetworkMapping[network];
|
|
288
|
+
}
|
|
289
|
+
static getSpendableBalance(utxoPool, feeRate, psbt, outputAddressType) {
|
|
270
290
|
const requiredInputs = [];
|
|
271
291
|
if (psbt != null)
|
|
272
292
|
for (let i = 0; i < psbt.inputsLength; i++) {
|
|
@@ -303,20 +323,13 @@ class BitcoinWallet {
|
|
|
303
323
|
script: buffer_1.Buffer.from(output.script)
|
|
304
324
|
});
|
|
305
325
|
}
|
|
306
|
-
const target =
|
|
307
|
-
|
|
308
|
-
hash: (0, Utils_1.randomBytes)(32)
|
|
309
|
-
});
|
|
310
|
-
let coinselectResult = (0, coinselect2_1.maxSendable)(utxoPool, { script: buffer_1.Buffer.from(target), type: "p2wsh" }, feeRate, requiredInputs, additionalOutputs);
|
|
326
|
+
const target = (0, BitcoinUtils_1.getDummyOutputScript)(outputAddressType ?? "p2wsh");
|
|
327
|
+
let coinselectResult = (0, coinselect2_1.maxSendable)(utxoPool, { script: buffer_1.Buffer.from(target), type: outputAddressType ?? "p2wsh" }, feeRate, requiredInputs, additionalOutputs);
|
|
311
328
|
logger.debug("_getSpendableBalance(): Max spendable result: ", coinselectResult);
|
|
312
329
|
return {
|
|
313
|
-
feeRate: feeRate,
|
|
314
330
|
balance: BigInt(Math.floor(coinselectResult.value)),
|
|
315
331
|
totalFee: coinselectResult.fee
|
|
316
332
|
};
|
|
317
333
|
}
|
|
318
|
-
static bitcoinNetworkToObject(network) {
|
|
319
|
-
return btcNetworkMapping[network];
|
|
320
|
-
}
|
|
321
334
|
}
|
|
322
335
|
exports.BitcoinWallet = BitcoinWallet;
|
|
@@ -1,4 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
1
3
|
import { Transaction } from "@scure/btc-signer";
|
|
4
|
+
import { CoinselectAddressTypes } from "../coinselect2";
|
|
5
|
+
/**
|
|
6
|
+
* UTXO data structure for Bitcoin wallets
|
|
7
|
+
*
|
|
8
|
+
* @category Bitcoin
|
|
9
|
+
*/
|
|
10
|
+
export type BitcoinWalletUtxo = {
|
|
11
|
+
vout: number;
|
|
12
|
+
txId: string;
|
|
13
|
+
value: number;
|
|
14
|
+
type: CoinselectAddressTypes;
|
|
15
|
+
outputScript: Buffer;
|
|
16
|
+
address: string;
|
|
17
|
+
cpfp?: {
|
|
18
|
+
txVsize: number;
|
|
19
|
+
txEffectiveFeeRate: number;
|
|
20
|
+
};
|
|
21
|
+
confirmed: boolean;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Base UTXO data structure used for maximum spendable balance calculation, doesn't contain all the fields necessary
|
|
25
|
+
* for constructing the full transaction.
|
|
26
|
+
*
|
|
27
|
+
* @category Bitcoin
|
|
28
|
+
*/
|
|
29
|
+
export type BitcoinWalletUtxoBase = Omit<BitcoinWalletUtxo, "txId" | "vout" | "outputScript" | "address" | "confirmed">;
|
|
2
30
|
/**
|
|
3
31
|
* Type guard to check if an object implements {@link IBitcoinWallet}
|
|
4
32
|
*
|
|
@@ -25,8 +53,12 @@ export interface IBitcoinWallet {
|
|
|
25
53
|
*
|
|
26
54
|
* @param psbt PSBT to add the inputs to
|
|
27
55
|
* @param feeRate Optional fee rate in sats/vB to use for the transaction
|
|
56
|
+
* @param utxos Pre-fetched list of UTXOs to spend from
|
|
57
|
+
* @param spendFully Instructs the wallet to spend all the passed UTXOs in the transaction without creating any
|
|
58
|
+
* change output, if the `feeRate` is passed, it will also enforce that the feeRate in sats/vB for the resulting
|
|
59
|
+
* transaction is not more than 50% and 10 sats/vB larger (considering also the CPFP adjustments)
|
|
28
60
|
*/
|
|
29
|
-
fundPsbt(psbt: Transaction, feeRate?: number): Promise<Transaction>;
|
|
61
|
+
fundPsbt(psbt: Transaction, feeRate?: number, utxos?: BitcoinWalletUtxo[], spendFully?: boolean): Promise<Transaction>;
|
|
30
62
|
/**
|
|
31
63
|
* Signs inputs in the provided PSBT
|
|
32
64
|
*
|
|
@@ -69,10 +101,16 @@ export interface IBitcoinWallet {
|
|
|
69
101
|
*
|
|
70
102
|
* @param psbt A PSBT to which additional inputs from wallet's UTXO set will be added and fee estimated
|
|
71
103
|
* @param feeRate Optional fee rate in sats/vB to use for the transaction
|
|
104
|
+
* @param outputAddressType Expected output address type, if known
|
|
105
|
+
* @param utxos Optional pre-fetched UTXOs
|
|
72
106
|
*/
|
|
73
|
-
getSpendableBalance(psbt?: Transaction, feeRate?: number): Promise<{
|
|
107
|
+
getSpendableBalance(psbt?: Transaction, feeRate?: number, outputAddressType?: CoinselectAddressTypes, utxos?: BitcoinWalletUtxoBase[]): Promise<{
|
|
74
108
|
balance: bigint;
|
|
75
109
|
feeRate: number;
|
|
76
110
|
totalFee: number;
|
|
77
111
|
}>;
|
|
112
|
+
/**
|
|
113
|
+
* Returns a list of available UTXOs for the wallet
|
|
114
|
+
*/
|
|
115
|
+
getUtxoPool?(): Promise<BitcoinWalletUtxo[]>;
|
|
78
116
|
}
|
|
@@ -6,6 +6,7 @@ import { Transaction } from "@scure/btc-signer";
|
|
|
6
6
|
import { Buffer } from "buffer";
|
|
7
7
|
import { BitcoinWallet } from "./BitcoinWallet";
|
|
8
8
|
import { BitcoinNetwork, BitcoinRpcWithAddressIndex } from "@atomiqlabs/base";
|
|
9
|
+
import { BitcoinWalletUtxo, BitcoinWalletUtxoBase } from "./IBitcoinWallet";
|
|
9
10
|
/**
|
|
10
11
|
* Bitcoin wallet implementation deriving a single address from a WIF encoded private key
|
|
11
12
|
*
|
|
@@ -37,7 +38,7 @@ export declare class SingleAddressBitcoinWallet extends BitcoinWallet {
|
|
|
37
38
|
/**
|
|
38
39
|
* @inheritDoc
|
|
39
40
|
*/
|
|
40
|
-
fundPsbt(inputPsbt: Transaction, feeRate?: number): Promise<Transaction>;
|
|
41
|
+
fundPsbt(inputPsbt: Transaction, feeRate?: number, utxos?: BitcoinWalletUtxo[], spendFully?: boolean): Promise<Transaction>;
|
|
41
42
|
/**
|
|
42
43
|
* @inheritDoc
|
|
43
44
|
*/
|
|
@@ -68,11 +69,15 @@ export declare class SingleAddressBitcoinWallet extends BitcoinWallet {
|
|
|
68
69
|
/**
|
|
69
70
|
* @inheritDoc
|
|
70
71
|
*/
|
|
71
|
-
getSpendableBalance(psbt?: Transaction, feeRate?: number): Promise<{
|
|
72
|
+
getSpendableBalance(psbt?: Transaction, feeRate?: number, outputAddressType?: CoinselectAddressTypes, utxos?: BitcoinWalletUtxoBase[]): Promise<{
|
|
72
73
|
balance: bigint;
|
|
73
74
|
feeRate: number;
|
|
74
75
|
totalFee: number;
|
|
75
76
|
}>;
|
|
77
|
+
/**
|
|
78
|
+
* @inheritDoc
|
|
79
|
+
*/
|
|
80
|
+
getUtxoPool(): Promise<BitcoinWalletUtxo[]>;
|
|
76
81
|
/**
|
|
77
82
|
* Generates a new random private key WIF that can be used to instantiate the bitcoin wallet instance
|
|
78
83
|
*
|
|
@@ -80,8 +80,8 @@ class SingleAddressBitcoinWallet extends BitcoinWallet_1.BitcoinWallet {
|
|
|
80
80
|
/**
|
|
81
81
|
* @inheritDoc
|
|
82
82
|
*/
|
|
83
|
-
async fundPsbt(inputPsbt, feeRate) {
|
|
84
|
-
const { psbt } = await super._fundPsbt(this.toBitcoinWalletAccounts(), inputPsbt, feeRate);
|
|
83
|
+
async fundPsbt(inputPsbt, feeRate, utxos, spendFully) {
|
|
84
|
+
const { psbt } = await super._fundPsbt(this.toBitcoinWalletAccounts(), inputPsbt, feeRate, utxos, spendFully);
|
|
85
85
|
if (psbt == null) {
|
|
86
86
|
throw new Error("Not enough balance!");
|
|
87
87
|
}
|
|
@@ -133,8 +133,14 @@ class SingleAddressBitcoinWallet extends BitcoinWallet_1.BitcoinWallet {
|
|
|
133
133
|
/**
|
|
134
134
|
* @inheritDoc
|
|
135
135
|
*/
|
|
136
|
-
getSpendableBalance(psbt, feeRate) {
|
|
137
|
-
return this._getSpendableBalance([{ address: this.address, addressType: this.addressType }], psbt, feeRate);
|
|
136
|
+
getSpendableBalance(psbt, feeRate, outputAddressType, utxos) {
|
|
137
|
+
return this._getSpendableBalance([{ address: this.address, addressType: this.addressType }], psbt, feeRate, outputAddressType, utxos);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* @inheritDoc
|
|
141
|
+
*/
|
|
142
|
+
async getUtxoPool() {
|
|
143
|
+
return this._getUtxoPool(this.address, this.addressType);
|
|
138
144
|
}
|
|
139
145
|
/**
|
|
140
146
|
* Generates a new random private key WIF that can be used to instantiate the bitcoin wallet instance
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ChainEvent, ChainType } from "@atomiqlabs/base";
|
|
2
2
|
import { ISwap } from "../swaps/ISwap";
|
|
3
|
-
import { EventListener } from "@atomiqlabs/base/src/events/ChainEvents";
|
|
4
3
|
import { SwapType } from "../enums/SwapType";
|
|
5
4
|
import { UnifiedSwapStorage } from "../storage/UnifiedSwapStorage";
|
|
6
5
|
export type SwapEventListener<T extends ChainType, S extends ISwap<T>> = (event: ChainEvent<T["Data"]>, swap: S) => Promise<void>;
|
|
@@ -15,8 +14,10 @@ export declare class UnifiedSwapEventListener<T extends ChainType> {
|
|
|
15
14
|
};
|
|
16
15
|
constructor(unifiedStorage: UnifiedSwapStorage<T>, events: T["Events"]);
|
|
17
16
|
processEvents(events: ChainEvent<T["Data"]>[]): Promise<void>;
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
private noAutomaticPoll?;
|
|
18
|
+
private listener?;
|
|
19
|
+
start(noAutomaticPoll?: boolean): Promise<void>;
|
|
20
|
+
poll(previousState: any): Promise<any>;
|
|
20
21
|
stop(): Promise<void>;
|
|
21
22
|
registerListener<S extends ISwap<T>>(type: SwapType, listener: SwapEventListener<T, S>, reviver: new (val: any) => S): void;
|
|
22
23
|
unregisterListener(type: SwapType): boolean;
|
|
@@ -96,13 +96,14 @@ class UnifiedSwapEventListener {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
-
async start() {
|
|
99
|
+
async start(noAutomaticPoll) {
|
|
100
100
|
if (this.listener != null)
|
|
101
101
|
return;
|
|
102
102
|
logger.info("start(): Starting unified swap event listener");
|
|
103
103
|
await this.storage.init();
|
|
104
104
|
logger.debug("start(): Storage initialized");
|
|
105
|
-
await this.events.init();
|
|
105
|
+
await this.events.init(noAutomaticPoll);
|
|
106
|
+
this.noAutomaticPoll = noAutomaticPoll;
|
|
106
107
|
logger.debug("start(): Events initialized");
|
|
107
108
|
this.events.registerListener(this.listener = async (events) => {
|
|
108
109
|
await this.processEvents(events);
|
|
@@ -110,6 +111,11 @@ class UnifiedSwapEventListener {
|
|
|
110
111
|
});
|
|
111
112
|
logger.info("start(): Successfully initiated the unified swap event listener!");
|
|
112
113
|
}
|
|
114
|
+
poll(previousState) {
|
|
115
|
+
if (!this.noAutomaticPoll)
|
|
116
|
+
throw new Error("Only supported when no automatic events polling is configured!");
|
|
117
|
+
return this.events.poll(previousState);
|
|
118
|
+
}
|
|
113
119
|
stop() {
|
|
114
120
|
logger.info("stop(): Stopping unified swap event listener");
|
|
115
121
|
if (this.listener != null)
|
package/dist/http/HttpUtils.d.ts
CHANGED
|
@@ -13,15 +13,17 @@ export declare function fetchWithTimeout(input: RequestInfo | URL, init: Request
|
|
|
13
13
|
* @param timeout Timeout (in milliseconds) for the request to conclude
|
|
14
14
|
* @param abortSignal
|
|
15
15
|
* @param allowNon200 Whether to allow non-200 status code HTTP responses
|
|
16
|
+
* @param headers
|
|
16
17
|
* @throws {RequestError} if non 200 response code was returned or body cannot be parsed
|
|
17
18
|
*/
|
|
18
|
-
export declare function httpGet<T>(url: string, timeout?: number, abortSignal?: AbortSignal, allowNon200?: boolean): Promise<T>;
|
|
19
|
+
export declare function httpGet<T>(url: string, timeout?: number, abortSignal?: AbortSignal, allowNon200?: boolean, headers?: Record<string, string>): Promise<T>;
|
|
19
20
|
/**
|
|
20
21
|
* Sends an HTTP POST request through a fetch API, handles non 200 response codes as errors
|
|
21
22
|
* @param url Send request to this URL
|
|
22
23
|
* @param body A HTTP request body to send to the server
|
|
23
24
|
* @param timeout Timeout (in milliseconds) for the request to conclude
|
|
24
25
|
* @param abortSignal
|
|
26
|
+
* @param headers
|
|
25
27
|
* @throws {RequestError} if non 200 response code was returned
|
|
26
28
|
*/
|
|
27
|
-
export declare function httpPost<T>(url: string, body: any, timeout?: number, abortSignal?: AbortSignal): Promise<T>;
|
|
29
|
+
export declare function httpPost<T>(url: string, body: any, timeout?: number, abortSignal?: AbortSignal, headers?: Record<string, string>): Promise<T>;
|
package/dist/http/HttpUtils.js
CHANGED
|
@@ -30,13 +30,15 @@ exports.fetchWithTimeout = fetchWithTimeout;
|
|
|
30
30
|
* @param timeout Timeout (in milliseconds) for the request to conclude
|
|
31
31
|
* @param abortSignal
|
|
32
32
|
* @param allowNon200 Whether to allow non-200 status code HTTP responses
|
|
33
|
+
* @param headers
|
|
33
34
|
* @throws {RequestError} if non 200 response code was returned or body cannot be parsed
|
|
34
35
|
*/
|
|
35
|
-
async function httpGet(url, timeout, abortSignal, allowNon200 = false) {
|
|
36
|
+
async function httpGet(url, timeout, abortSignal, allowNon200 = false, headers = {}) {
|
|
36
37
|
const init = {
|
|
37
38
|
method: "GET",
|
|
38
39
|
timeout,
|
|
39
|
-
signal: abortSignal
|
|
40
|
+
signal: abortSignal,
|
|
41
|
+
headers
|
|
40
42
|
};
|
|
41
43
|
const response = await fetchWithTimeout(url, init);
|
|
42
44
|
if (response.status !== 200) {
|
|
@@ -65,14 +67,18 @@ exports.httpGet = httpGet;
|
|
|
65
67
|
* @param body A HTTP request body to send to the server
|
|
66
68
|
* @param timeout Timeout (in milliseconds) for the request to conclude
|
|
67
69
|
* @param abortSignal
|
|
70
|
+
* @param headers
|
|
68
71
|
* @throws {RequestError} if non 200 response code was returned
|
|
69
72
|
*/
|
|
70
|
-
async function httpPost(url, body, timeout, abortSignal) {
|
|
73
|
+
async function httpPost(url, body, timeout, abortSignal, headers = {}) {
|
|
71
74
|
const init = {
|
|
72
75
|
method: "POST",
|
|
73
76
|
timeout,
|
|
74
77
|
body: JSON.stringify(body),
|
|
75
|
-
headers: {
|
|
78
|
+
headers: {
|
|
79
|
+
...headers,
|
|
80
|
+
'Content-Type': 'application/json'
|
|
81
|
+
},
|
|
76
82
|
signal: abortSignal
|
|
77
83
|
};
|
|
78
84
|
const response = timeout == null ? await fetch(url, init) : await fetchWithTimeout(url, init);
|
|
@@ -11,6 +11,7 @@ export type RequestBody = {
|
|
|
11
11
|
* @param timeout Timeout in millseconds for the request to succeed & all its response properties to resolve
|
|
12
12
|
* @param signal Abort signal
|
|
13
13
|
* @param streamRequest Whether the request should be streamed or not
|
|
14
|
+
* @param _headers
|
|
14
15
|
* @throws {RequestError} When the response code is not 200
|
|
15
16
|
*/
|
|
16
|
-
export declare function streamingFetchPromise<T extends RequestSchema>(url: string, body: RequestBody, schema: T, timeout?: number, signal?: AbortSignal, streamRequest?: boolean): Promise<RequestSchemaResultPromise<T>>;
|
|
17
|
+
export declare function streamingFetchPromise<T extends RequestSchema>(url: string, body: RequestBody, schema: T, timeout?: number, signal?: AbortSignal, streamRequest?: boolean, _headers?: Record<string, string>): Promise<RequestSchemaResultPromise<T>>;
|
|
@@ -39,14 +39,15 @@ logger.info("Environment supports request stream: " + supportsRequestStreams);
|
|
|
39
39
|
* @param timeout Timeout in millseconds for the request to succeed & all its response properties to resolve
|
|
40
40
|
* @param signal Abort signal
|
|
41
41
|
* @param streamRequest Whether the request should be streamed or not
|
|
42
|
+
* @param _headers
|
|
42
43
|
* @throws {RequestError} When the response code is not 200
|
|
43
44
|
*/
|
|
44
|
-
async function streamingFetchPromise(url, body, schema, timeout, signal, streamRequest) {
|
|
45
|
+
async function streamingFetchPromise(url, body, schema, timeout, signal, streamRequest, _headers = {}) {
|
|
45
46
|
if (streamRequest == null)
|
|
46
47
|
streamRequest = supportsRequestStreams;
|
|
47
48
|
if (timeout != null)
|
|
48
49
|
signal = (0, TimeoutUtils_1.timeoutSignal)(timeout, new Error("Network request timed out"), signal);
|
|
49
|
-
const headers = {};
|
|
50
|
+
const headers = { ..._headers };
|
|
50
51
|
const init = {
|
|
51
52
|
method: "POST",
|
|
52
53
|
headers
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,7 @@ export * from "./types/SwapStateInfo";
|
|
|
78
78
|
export * from "./types/AmountData";
|
|
79
79
|
export * from "./types/CustomPriceFunction";
|
|
80
80
|
export * from "./types/SwapExecutionAction";
|
|
81
|
+
export * from "./types/SwapExecutionStep";
|
|
81
82
|
export * from "./types/SwapWithSigner";
|
|
82
83
|
export * from "./types/Token";
|
|
83
84
|
export * from "./types/TokenAmount";
|
package/dist/index.js
CHANGED
|
@@ -151,6 +151,7 @@ __exportStar(require("./types/SwapStateInfo"), exports);
|
|
|
151
151
|
__exportStar(require("./types/AmountData"), exports);
|
|
152
152
|
__exportStar(require("./types/CustomPriceFunction"), exports);
|
|
153
153
|
__exportStar(require("./types/SwapExecutionAction"), exports);
|
|
154
|
+
__exportStar(require("./types/SwapExecutionStep"), exports);
|
|
154
155
|
__exportStar(require("./types/SwapWithSigner"), exports);
|
|
155
156
|
__exportStar(require("./types/Token"), exports);
|
|
156
157
|
__exportStar(require("./types/TokenAmount"), exports);
|
|
@@ -3,6 +3,7 @@ import { Intermediary } from "./Intermediary";
|
|
|
3
3
|
import { SwapType } from "../enums/SwapType";
|
|
4
4
|
import { SpvVaultContract, SwapContract } from "@atomiqlabs/base";
|
|
5
5
|
import { EventEmitter } from "events";
|
|
6
|
+
import { IntermediaryAPI } from "./apis/IntermediaryAPI";
|
|
6
7
|
/**
|
|
7
8
|
* Swap handler type mapping for intermediary communication
|
|
8
9
|
*
|
|
@@ -109,6 +110,10 @@ export declare class IntermediaryDiscovery extends EventEmitter {
|
|
|
109
110
|
* @private
|
|
110
111
|
*/
|
|
111
112
|
private overrideNodeUrls?;
|
|
113
|
+
/**
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
private lpApi;
|
|
112
117
|
constructor(swapContracts: {
|
|
113
118
|
[chainIdentifier: string]: {
|
|
114
119
|
[contractVersion: string]: {
|
|
@@ -116,7 +121,7 @@ export declare class IntermediaryDiscovery extends EventEmitter {
|
|
|
116
121
|
spvVaultContract: SpvVaultContract;
|
|
117
122
|
};
|
|
118
123
|
};
|
|
119
|
-
}, registryUrl?: string, nodeUrls?: string[], httpRequestTimeout?: number, maxWaitForOthersTimeout?: number);
|
|
124
|
+
}, lpApi: IntermediaryAPI, registryUrl?: string, nodeUrls?: string[], httpRequestTimeout?: number, maxWaitForOthersTimeout?: number);
|
|
120
125
|
/**
|
|
121
126
|
* Fetches the URLs of swap intermediaries from registry or from a pre-defined array of node urls
|
|
122
127
|
*
|
|
@@ -193,7 +198,7 @@ export declare class IntermediaryDiscovery extends EventEmitter {
|
|
|
193
198
|
/**
|
|
194
199
|
* Returns swap candidates for a specific swap type & token address
|
|
195
200
|
*
|
|
196
|
-
* @
|
|
201
|
+
* @remarks Also filters the LPs based on supported swap versions
|
|
197
202
|
*
|
|
198
203
|
* @param chainIdentifier Chain identifier of the smart chain
|
|
199
204
|
* @param swapType Swap protocol type
|
|
@@ -6,7 +6,6 @@ const SwapType_1 = require("../enums/SwapType");
|
|
|
6
6
|
const events_1 = require("events");
|
|
7
7
|
const buffer_1 = require("buffer");
|
|
8
8
|
const Utils_1 = require("../utils/Utils");
|
|
9
|
-
const IntermediaryAPI_1 = require("./apis/IntermediaryAPI");
|
|
10
9
|
const Logger_1 = require("../utils/Logger");
|
|
11
10
|
const HttpUtils_1 = require("../http/HttpUtils");
|
|
12
11
|
const RetryUtils_1 = require("../utils/RetryUtils");
|
|
@@ -94,7 +93,7 @@ const DEFAULT_CHAIN = "SOLANA";
|
|
|
94
93
|
* @category LPs
|
|
95
94
|
*/
|
|
96
95
|
class IntermediaryDiscovery extends events_1.EventEmitter {
|
|
97
|
-
constructor(swapContracts, registryUrl = REGISTRY_URL, nodeUrls, httpRequestTimeout, maxWaitForOthersTimeout) {
|
|
96
|
+
constructor(swapContracts, lpApi, registryUrl = REGISTRY_URL, nodeUrls, httpRequestTimeout, maxWaitForOthersTimeout) {
|
|
98
97
|
super();
|
|
99
98
|
/**
|
|
100
99
|
* A current list of active intermediaries
|
|
@@ -105,6 +104,7 @@ class IntermediaryDiscovery extends events_1.EventEmitter {
|
|
|
105
104
|
this.overrideNodeUrls = nodeUrls;
|
|
106
105
|
this.httpRequestTimeout = httpRequestTimeout;
|
|
107
106
|
this.maxWaitForOthersTimeout = maxWaitForOthersTimeout;
|
|
107
|
+
this.lpApi = lpApi;
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
110
|
* Fetches the URLs of swap intermediaries from registry or from a pre-defined array of node urls
|
|
@@ -129,7 +129,7 @@ class IntermediaryDiscovery extends events_1.EventEmitter {
|
|
|
129
129
|
* @param abortSignal
|
|
130
130
|
*/
|
|
131
131
|
async getNodeInfo(url, abortSignal) {
|
|
132
|
-
const response = await (0, RetryUtils_1.tryWithRetries)(() =>
|
|
132
|
+
const response = await (0, RetryUtils_1.tryWithRetries)(() => this.lpApi.getIntermediaryInfo(url, this.httpRequestTimeout, abortSignal), { maxRetries: 3, delay: 100, exponential: true }, undefined, abortSignal, "debug");
|
|
133
133
|
abortSignal?.throwIfAborted();
|
|
134
134
|
const promises = [];
|
|
135
135
|
const addresses = {};
|
|
@@ -365,7 +365,7 @@ class IntermediaryDiscovery extends events_1.EventEmitter {
|
|
|
365
365
|
/**
|
|
366
366
|
* Returns swap candidates for a specific swap type & token address
|
|
367
367
|
*
|
|
368
|
-
* @
|
|
368
|
+
* @remarks Also filters the LPs based on supported swap versions
|
|
369
369
|
*
|
|
370
370
|
* @param chainIdentifier Chain identifier of the smart chain
|
|
371
371
|
* @param swapType Swap protocol type
|