@atomiqlabs/sdk 8.6.3 → 8.7.1
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/events/UnifiedSwapEventListener.js +4 -2
- package/dist/intermediaries/Intermediary.d.ts +21 -0
- package/dist/intermediaries/Intermediary.js +25 -1
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +15 -3
- package/dist/intermediaries/IntermediaryDiscovery.js +21 -3
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +1 -0
- package/dist/swapper/Swapper.d.ts +9 -4
- package/dist/swapper/Swapper.js +89 -41
- package/dist/swapper/SwapperUtils.js +2 -1
- package/dist/swaps/ISwap.d.ts +5 -0
- package/dist/swaps/ISwap.js +4 -1
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +5 -5
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +4 -0
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +4 -3
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +19 -6
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +54 -21
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +7 -3
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +3 -4
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +3 -3
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +8 -2
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +12 -8
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +18 -18
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +12 -6
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +38 -24
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +9 -9
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +14 -7
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +54 -38
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +5 -5
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +18 -7
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +61 -33
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +12 -12
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +8 -2
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +13 -8
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +1 -1
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +13 -4
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +44 -28
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +2 -2
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +8 -4
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +29 -21
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +1 -0
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +13 -12
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +21 -10
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +136 -73
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +2 -1
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +2 -1
- package/dist/utils/Utils.d.ts +9 -0
- package/dist/utils/Utils.js +15 -1
- package/package.json +2 -2
- package/src/events/UnifiedSwapEventListener.ts +4 -2
- package/src/intermediaries/Intermediary.ts +31 -1
- package/src/intermediaries/IntermediaryDiscovery.ts +27 -8
- package/src/intermediaries/apis/IntermediaryAPI.ts +2 -1
- package/src/swapper/Swapper.ts +133 -61
- package/src/swapper/SwapperUtils.ts +3 -1
- package/src/swaps/ISwap.ts +10 -2
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +5 -5
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +10 -3
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +64 -26
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +8 -5
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +3 -3
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +22 -12
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +18 -18
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +52 -31
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +9 -9
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +76 -52
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +5 -5
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +82 -38
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +12 -12
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +21 -9
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +1 -1
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +56 -33
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +2 -2
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +40 -22
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +17 -13
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +149 -83
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +2 -1
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +2 -1
- package/src/utils/Utils.ts +14 -0
|
@@ -6,6 +6,7 @@ const base_1 = require("@atomiqlabs/base");
|
|
|
6
6
|
const SpvFromBTCSwap_1 = require("./SpvFromBTCSwap");
|
|
7
7
|
const utils_1 = require("@scure/btc-signer/utils");
|
|
8
8
|
const SwapType_1 = require("../../enums/SwapType");
|
|
9
|
+
const Intermediary_1 = require("../../intermediaries/Intermediary");
|
|
9
10
|
const Utils_1 = require("../../utils/Utils");
|
|
10
11
|
const BitcoinUtils_1 = require("../../utils/BitcoinUtils");
|
|
11
12
|
const IntermediaryAPI_1 = require("../../intermediaries/apis/IntermediaryAPI");
|
|
@@ -27,17 +28,15 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
27
28
|
* @param unifiedStorage Storage interface for the current environment
|
|
28
29
|
* @param unifiedChainEvents On-chain event listener
|
|
29
30
|
* @param chain
|
|
30
|
-
* @param contract Underlying contract handling the swaps
|
|
31
31
|
* @param prices Pricing to use
|
|
32
32
|
* @param tokens
|
|
33
|
-
* @param
|
|
34
|
-
* @param
|
|
35
|
-
* @param synchronizer Btc relay synchronizer
|
|
33
|
+
* @param versionedContracts
|
|
34
|
+
* @param versionedSynchronizer
|
|
36
35
|
* @param btcRpc Bitcoin RPC which also supports getting transactions by txoHash
|
|
37
36
|
* @param options
|
|
38
37
|
* @param events Instance to use for emitting events
|
|
39
38
|
*/
|
|
40
|
-
constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain,
|
|
39
|
+
constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, versionedContracts, versionedSynchronizer, btcRpc, options, events) {
|
|
41
40
|
super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, {
|
|
42
41
|
...options,
|
|
43
42
|
bitcoinNetwork: options?.bitcoinNetwork ?? utils_1.TEST_NETWORK,
|
|
@@ -57,6 +56,16 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
57
56
|
* @internal
|
|
58
57
|
*/
|
|
59
58
|
this._swapDeserializer = SpvFromBTCSwap_1.SpvFromBTCSwap;
|
|
59
|
+
/**
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
this.btcRelay = (version) => {
|
|
63
|
+
const _version = version ?? "v1";
|
|
64
|
+
const data = this.versionedContracts[_version];
|
|
65
|
+
if (data == null)
|
|
66
|
+
throw new Error(`Invalid contract version ${_version} requested`);
|
|
67
|
+
return data.btcRelay;
|
|
68
|
+
};
|
|
60
69
|
/**
|
|
61
70
|
* @internal
|
|
62
71
|
*/
|
|
@@ -67,6 +76,36 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
67
76
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.POSTED,
|
|
68
77
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED
|
|
69
78
|
];
|
|
79
|
+
/**
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
this._synchronizer = (version) => {
|
|
83
|
+
const _version = version ?? "v1";
|
|
84
|
+
const data = this.versionedSynchronizer[_version];
|
|
85
|
+
if (data == null)
|
|
86
|
+
throw new Error(`Invalid contract version ${_version} requested`);
|
|
87
|
+
return data.synchronizer;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
this._contract = (version) => {
|
|
93
|
+
const _version = version ?? "v1";
|
|
94
|
+
const data = this.versionedContracts[_version];
|
|
95
|
+
if (data == null)
|
|
96
|
+
throw new Error(`Invalid contract version ${_version} requested`);
|
|
97
|
+
return data.spvVaultContract;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
this._spvWithdrawalDataDeserializer = (version) => {
|
|
103
|
+
const _version = version ?? "v1";
|
|
104
|
+
const data = this.versionedContracts[_version];
|
|
105
|
+
if (data == null)
|
|
106
|
+
throw new Error(`Invalid contract version ${_version} requested`);
|
|
107
|
+
return data.spvVaultWithdrawalDataConstructor;
|
|
108
|
+
};
|
|
70
109
|
/**
|
|
71
110
|
* @internal
|
|
72
111
|
*/
|
|
@@ -79,10 +118,10 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
79
118
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED,
|
|
80
119
|
SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED
|
|
81
120
|
];
|
|
82
|
-
this.
|
|
83
|
-
this.
|
|
84
|
-
this.
|
|
85
|
-
this.
|
|
121
|
+
this.versionedContracts = {};
|
|
122
|
+
this.versionedSynchronizer = {};
|
|
123
|
+
this.versionedContracts = versionedContracts;
|
|
124
|
+
this.versionedSynchronizer = versionedSynchronizer;
|
|
86
125
|
this._btcRpc = btcRpc;
|
|
87
126
|
}
|
|
88
127
|
async processEventFront(event, swap) {
|
|
@@ -173,19 +212,20 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
173
212
|
* @param pricePrefetch
|
|
174
213
|
* @param nativeTokenPricePrefetch
|
|
175
214
|
* @param abortController
|
|
215
|
+
* @param contractVersion
|
|
176
216
|
* @private
|
|
177
217
|
*/
|
|
178
|
-
async preFetchCallerFeeShare(amountData, options, pricePrefetch, nativeTokenPricePrefetch, abortController) {
|
|
218
|
+
async preFetchCallerFeeShare(amountData, options, pricePrefetch, nativeTokenPricePrefetch, abortController, contractVersion) {
|
|
179
219
|
if (options.unsafeZeroWatchtowerFee)
|
|
180
220
|
return 0n;
|
|
181
221
|
if (amountData.amount === 0n)
|
|
182
222
|
return 0n;
|
|
183
223
|
try {
|
|
184
224
|
const [feePerBlock, btcRelayData, currentBtcBlock, claimFeeRate, nativeTokenPrice] = await Promise.all([
|
|
185
|
-
this.btcRelay.getFeePerBlock(),
|
|
186
|
-
this.btcRelay.getTipData(),
|
|
225
|
+
this.btcRelay(contractVersion).getFeePerBlock(),
|
|
226
|
+
this.btcRelay(contractVersion).getTipData(),
|
|
187
227
|
this._btcRpc.getTipHeight(),
|
|
188
|
-
this._contract.getClaimFee(this._chain.randomAddress()),
|
|
228
|
+
this._contract(contractVersion).getClaimFee(this._chain.randomAddress()),
|
|
189
229
|
nativeTokenPricePrefetch ?? (amountData.token === this._chain.getNativeCurrencyAddress() ?
|
|
190
230
|
pricePrefetch :
|
|
191
231
|
this._prices.preFetchPrice(this.chainIdentifier, this._chain.getNativeCurrencyAddress(), abortController.signal))
|
|
@@ -243,6 +283,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
243
283
|
abortSignal.throwIfAborted();
|
|
244
284
|
if (btcFeeRate != null && resp.btcFeeRate > btcFeeRate)
|
|
245
285
|
throw new IntermediaryError_1.IntermediaryError(`Required bitcoin fee rate returned from the LP is too high! Maximum accepted: ${btcFeeRate} sats/vB, required by LP: ${resp.btcFeeRate} sats/vB`);
|
|
286
|
+
const lpVersion = lp.getContractVersion(this.chainIdentifier);
|
|
246
287
|
//Vault related
|
|
247
288
|
let vaultScript;
|
|
248
289
|
let vaultAddressType;
|
|
@@ -288,7 +329,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
288
329
|
//Fetch vault data
|
|
289
330
|
let vault;
|
|
290
331
|
try {
|
|
291
|
-
vault = await this._contract.getVaultData(resp.address, resp.vaultId);
|
|
332
|
+
vault = await this._contract(lpVersion).getVaultData(resp.address, resp.vaultId);
|
|
292
333
|
}
|
|
293
334
|
catch (e) {
|
|
294
335
|
this.logger.error("Error getting spv vault (owner: " + resp.address + " vaultId: " + resp.vaultId.toString(10) + "): ", e);
|
|
@@ -367,7 +408,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
367
408
|
throw new IntermediaryError_1.IntermediaryError("Invalid ancestor transaction (not found)");
|
|
368
409
|
btcTx = _btcTx;
|
|
369
410
|
}
|
|
370
|
-
const withdrawalData = await this._contract.getWithdrawalData(btcTx);
|
|
411
|
+
const withdrawalData = await this._contract(lpVersion).getWithdrawalData(btcTx);
|
|
371
412
|
abortSignal.throwIfAborted();
|
|
372
413
|
pendingWithdrawals.unshift(withdrawalData);
|
|
373
414
|
utxo = pendingWithdrawals[0].getSpentVaultUtxo();
|
|
@@ -393,7 +434,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
393
434
|
//Also verify that all the withdrawal txns are valid, this is an extra sanity check
|
|
394
435
|
try {
|
|
395
436
|
for (let withdrawal of pendingWithdrawals) {
|
|
396
|
-
await this._contract.checkWithdrawalTx(withdrawal);
|
|
437
|
+
await this._contract(lpVersion).checkWithdrawalTx(withdrawal);
|
|
397
438
|
}
|
|
398
439
|
}
|
|
399
440
|
catch (e) {
|
|
@@ -427,6 +468,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
427
468
|
};
|
|
428
469
|
if (amountData.token === this._chain.getNativeCurrencyAddress() && _options.gasAmount !== 0n)
|
|
429
470
|
throw new UserError_1.UserError("Cannot specify `gasAmount` for swaps to a native token!");
|
|
471
|
+
const lpVersions = Intermediary_1.Intermediary.getContractVersionsForLps(this.chainIdentifier, lps);
|
|
430
472
|
const _abortController = (0, Utils_1.extendAbortController)(abortSignal);
|
|
431
473
|
const pricePrefetchPromise = this.preFetchPrice(amountData, _abortController.signal);
|
|
432
474
|
const usdPricePrefetchPromise = this.preFetchUsdPrice(_abortController.signal);
|
|
@@ -435,7 +477,9 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
435
477
|
const gasTokenPricePrefetchPromise = _options.gasAmount === 0n ?
|
|
436
478
|
undefined :
|
|
437
479
|
this.preFetchPrice({ token: nativeTokenAddress }, _abortController.signal);
|
|
438
|
-
const callerFeePrefetchPromise =
|
|
480
|
+
const callerFeePrefetchPromise = (0, Utils_1.mapArrayToObject)(lpVersions, (contractVersion) => {
|
|
481
|
+
return this.preFetchCallerFeeShare(amountData, _options, pricePrefetchPromise, gasTokenPricePrefetchPromise, _abortController, contractVersion);
|
|
482
|
+
});
|
|
439
483
|
const bitcoinFeeRatePromise = _options.maxAllowedBitcoinFeeRate != Infinity ?
|
|
440
484
|
Promise.resolve(_options.maxAllowedBitcoinFeeRate) :
|
|
441
485
|
this._btcRpc.getFeeRate().then(x => this._options.maxBtcFeeOffset + (x * this._options.maxBtcFeeMultiplier)).catch(e => {
|
|
@@ -448,6 +492,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
448
492
|
quote: (0, RetryUtils_1.tryWithRetries)(async () => {
|
|
449
493
|
if (lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC] == null)
|
|
450
494
|
throw new Error("LP service for processing spv vault swaps not found!");
|
|
495
|
+
const version = lp.getContractVersion(this.chainIdentifier);
|
|
451
496
|
const abortController = (0, Utils_1.extendAbortController)(_abortController.signal);
|
|
452
497
|
try {
|
|
453
498
|
const resp = await (0, RetryUtils_1.tryWithRetries)(async (retryCount) => {
|
|
@@ -458,13 +503,13 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
458
503
|
exactOut: !amountData.exactIn,
|
|
459
504
|
gasToken: nativeTokenAddress,
|
|
460
505
|
gasAmount: _options.gasAmount,
|
|
461
|
-
callerFeeRate: (0, Utils_1.throwIfUndefined)(callerFeePrefetchPromise, "Caller fee prefetch failed!"),
|
|
506
|
+
callerFeeRate: (0, Utils_1.throwIfUndefined)(callerFeePrefetchPromise[version], "Caller fee prefetch failed!"),
|
|
462
507
|
frontingFeeRate: 0n,
|
|
463
508
|
additionalParams
|
|
464
509
|
}, this._options.postRequestTimeout, abortController.signal, retryCount > 0 ? false : undefined);
|
|
465
510
|
}, undefined, e => e instanceof RequestError_1.RequestError, abortController.signal);
|
|
466
511
|
this.logger.debug("create(" + lp.url + "): LP response: ", resp);
|
|
467
|
-
const callerFeeShare = (await callerFeePrefetchPromise);
|
|
512
|
+
const callerFeeShare = (await callerFeePrefetchPromise[version]);
|
|
468
513
|
const [pricingInfo, gasPricingInfo, { vault, vaultUtxoValue }] = await Promise.all([
|
|
469
514
|
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], false, resp.btcAmountSwap, resp.total * (100000n + callerFeeShare) / 100000n, amountData.token, {}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
470
515
|
_options.gasAmount === 0n ? Promise.resolve(undefined) : this.verifyReturnedPrice({ ...lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], swapBaseFee: 0 }, //Base fee should be charged only on the amount, not on gas
|
|
@@ -502,7 +547,8 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
502
547
|
callerFeeShare: resp.callerFeeShare,
|
|
503
548
|
frontingFeeShare: resp.frontingFeeShare,
|
|
504
549
|
executionFeeShare: resp.executionFeeShare,
|
|
505
|
-
genesisSmartChainBlockHeight: await (0, Utils_1.throwIfUndefined)(finalizedBlockHeightPrefetchPromise, "Finalize block height promise failed!")
|
|
550
|
+
genesisSmartChainBlockHeight: await (0, Utils_1.throwIfUndefined)(finalizedBlockHeightPrefetchPromise, "Finalize block height promise failed!"),
|
|
551
|
+
contractVersion: version
|
|
506
552
|
};
|
|
507
553
|
const quote = new SpvFromBTCSwap_1.SpvFromBTCSwap(this, swapInit);
|
|
508
554
|
return quote;
|
|
@@ -522,9 +568,9 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
522
568
|
* @param vault SPV vault processing the swap
|
|
523
569
|
* @param lp Intermediary (LP) used as a counterparty for the swap
|
|
524
570
|
*/
|
|
525
|
-
async recoverFromState(state, vault, lp) {
|
|
571
|
+
async recoverFromState(state, contractVersion, vault, lp) {
|
|
526
572
|
//Get the vault
|
|
527
|
-
vault ??= await this._contract.getVaultData(state.owner, state.vaultId);
|
|
573
|
+
vault ??= await this._contract(contractVersion).getVaultData(state.owner, state.vaultId);
|
|
528
574
|
if (vault == null)
|
|
529
575
|
return null;
|
|
530
576
|
if (state.btcTxId == null)
|
|
@@ -532,7 +578,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
532
578
|
const btcTx = await this._btcRpc.getTransaction(state.btcTxId);
|
|
533
579
|
if (btcTx == null)
|
|
534
580
|
return null;
|
|
535
|
-
const withdrawalData = await this._contract.getWithdrawalData(btcTx)
|
|
581
|
+
const withdrawalData = await this._contract(contractVersion).getWithdrawalData(btcTx)
|
|
536
582
|
.catch(e => {
|
|
537
583
|
this.logger.warn(`Error parsing withdrawal data for tx ${btcTx.txid}: `, e);
|
|
538
584
|
return null;
|
|
@@ -590,7 +636,8 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
590
636
|
callerFeeShare: withdrawalData.callerFeeRate,
|
|
591
637
|
frontingFeeShare: withdrawalData.frontingFeeRate,
|
|
592
638
|
executionFeeShare: withdrawalData.executionFeeRate,
|
|
593
|
-
genesisSmartChainBlockHeight: txBlock?.blockHeight ?? 0
|
|
639
|
+
genesisSmartChainBlockHeight: txBlock?.blockHeight ?? 0,
|
|
640
|
+
contractVersion
|
|
594
641
|
};
|
|
595
642
|
const quote = new SpvFromBTCSwap_1.SpvFromBTCSwap(this, swapInit);
|
|
596
643
|
quote._data = withdrawalData;
|
|
@@ -644,11 +691,20 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
644
691
|
script: randomVaultOutScript,
|
|
645
692
|
amount: 600n
|
|
646
693
|
});
|
|
647
|
-
|
|
694
|
+
let longestOpReturnData = undefined;
|
|
695
|
+
for (let contractVersion in this.versionedContracts) {
|
|
696
|
+
if (this.versionedContracts[contractVersion].spvVaultContract == null)
|
|
697
|
+
continue;
|
|
698
|
+
const opReturnData = this._contract(contractVersion).toOpReturnData(this._chain.randomAddress(), includeGasToken ? [0xffffffffffffffffn, 0xffffffffffffffffn] : [0xffffffffffffffffn]);
|
|
699
|
+
if (longestOpReturnData == null || longestOpReturnData.length < opReturnData.length)
|
|
700
|
+
longestOpReturnData = opReturnData;
|
|
701
|
+
}
|
|
702
|
+
if (longestOpReturnData == null)
|
|
703
|
+
throw new Error(`No contract version supporting the Spv Vault BTC -> ${this.chainIdentifier} swaps found!`);
|
|
648
704
|
psbt.addOutput({
|
|
649
705
|
script: Buffer.concat([
|
|
650
|
-
|
|
651
|
-
|
|
706
|
+
longestOpReturnData.length <= 75 ? Buffer.from([0x6a, longestOpReturnData.length]) : Buffer.from([0x6a, 0x4c, longestOpReturnData.length]),
|
|
707
|
+
longestOpReturnData
|
|
652
708
|
]),
|
|
653
709
|
amount: 0n
|
|
654
710
|
});
|
|
@@ -661,7 +717,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
661
717
|
async _checkPastSwaps(pastSwaps) {
|
|
662
718
|
const changedSwaps = new Set();
|
|
663
719
|
const removeSwaps = [];
|
|
664
|
-
const broadcastedOrConfirmedSwaps =
|
|
720
|
+
const broadcastedOrConfirmedSwaps = {};
|
|
665
721
|
for (let pastSwap of pastSwaps) {
|
|
666
722
|
let changed = false;
|
|
667
723
|
if (pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.SIGNED ||
|
|
@@ -695,56 +751,63 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
695
751
|
changedSwaps.add(pastSwap);
|
|
696
752
|
if (pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || pastSwap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
697
753
|
if (pastSwap._data != null)
|
|
698
|
-
broadcastedOrConfirmedSwaps.push(pastSwap);
|
|
754
|
+
(broadcastedOrConfirmedSwaps[pastSwap._contractVersion ?? "v1"] ??= []).push(pastSwap);
|
|
699
755
|
}
|
|
700
756
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
withdrawal: val._data
|
|
705
|
-
})));
|
|
706
|
-
const _vaultUtxos = await this._contract.getVaultLatestUtxos(broadcastedOrConfirmedSwaps.map(val => val.getSpvVaultData()));
|
|
707
|
-
for (const pastSwap of broadcastedOrConfirmedSwaps) {
|
|
708
|
-
const fronterAddress = _fronts[pastSwap._data.getTxId()];
|
|
709
|
-
const vault = pastSwap.getSpvVaultData();
|
|
710
|
-
const latestVaultUtxo = _vaultUtxos[vault.owner]?.[vault.vaultId.toString(10)];
|
|
711
|
-
if (fronterAddress === undefined)
|
|
712
|
-
this.logger.warn(`_checkPastSwaps(): No fronter address returned for ${pastSwap._data.getTxId()}`);
|
|
713
|
-
if (latestVaultUtxo === undefined)
|
|
714
|
-
this.logger.warn(`_checkPastSwaps(): No last vault utxo returned for ${pastSwap._data.getTxId()}`);
|
|
715
|
-
if (await pastSwap._shouldCheckWithdrawalState(fronterAddress, latestVaultUtxo))
|
|
716
|
-
checkWithdrawalStateSwaps.push(pastSwap);
|
|
717
|
-
}
|
|
718
|
-
const withdrawalStates = await this._contract.getWithdrawalStates(checkWithdrawalStateSwaps.map(val => ({
|
|
719
|
-
withdrawal: val._data,
|
|
720
|
-
scStartBlockheight: val._genesisSmartChainBlockHeight
|
|
721
|
-
})));
|
|
722
|
-
for (const pastSwap of checkWithdrawalStateSwaps) {
|
|
723
|
-
const status = withdrawalStates[pastSwap._data.getTxId()];
|
|
724
|
-
if (status == null) {
|
|
725
|
-
this.logger.warn(`_checkPastSwaps(): No withdrawal state returned for ${pastSwap._data.getTxId()}`);
|
|
757
|
+
for (let contractVersion in broadcastedOrConfirmedSwaps) {
|
|
758
|
+
if (this.versionedContracts[contractVersion] == null) {
|
|
759
|
+
this.logger.warn(`_checkPastSwaps(): No contract was found for ${this.chainIdentifier} version ${contractVersion}! Skipping these swaps!`);
|
|
726
760
|
continue;
|
|
727
761
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
762
|
+
const _broadcastedOrConfirmedSwaps = broadcastedOrConfirmedSwaps[contractVersion];
|
|
763
|
+
const checkWithdrawalStateSwaps = [];
|
|
764
|
+
const _fronts = await this._contract(contractVersion).getFronterAddresses(_broadcastedOrConfirmedSwaps.map(val => ({
|
|
765
|
+
...val.getSpvVaultData(),
|
|
766
|
+
withdrawal: val._data
|
|
767
|
+
})));
|
|
768
|
+
const _vaultUtxos = await this._contract(contractVersion).getVaultLatestUtxos(_broadcastedOrConfirmedSwaps.map(val => val.getSpvVaultData()));
|
|
769
|
+
for (const pastSwap of _broadcastedOrConfirmedSwaps) {
|
|
770
|
+
const fronterAddress = _fronts[pastSwap._data.getTxId()];
|
|
771
|
+
const vault = pastSwap.getSpvVaultData();
|
|
772
|
+
const latestVaultUtxo = _vaultUtxos[vault.owner]?.[vault.vaultId.toString(10)];
|
|
773
|
+
if (fronterAddress === undefined)
|
|
774
|
+
this.logger.warn(`_checkPastSwaps(): No fronter address returned for ${pastSwap._data.getTxId()}`);
|
|
775
|
+
if (latestVaultUtxo === undefined)
|
|
776
|
+
this.logger.warn(`_checkPastSwaps(): No last vault utxo returned for ${pastSwap._data.getTxId()}`);
|
|
777
|
+
if (await pastSwap._shouldCheckWithdrawalState(fronterAddress, latestVaultUtxo))
|
|
778
|
+
checkWithdrawalStateSwaps.push(pastSwap);
|
|
779
|
+
}
|
|
780
|
+
const withdrawalStates = await this._contract(contractVersion).getWithdrawalStates(checkWithdrawalStateSwaps.map(val => ({
|
|
781
|
+
withdrawal: val._data,
|
|
782
|
+
scStartBlockheight: val._genesisSmartChainBlockHeight
|
|
783
|
+
})));
|
|
784
|
+
for (const pastSwap of checkWithdrawalStateSwaps) {
|
|
785
|
+
const status = withdrawalStates[pastSwap._data.getTxId()];
|
|
786
|
+
if (status == null) {
|
|
787
|
+
this.logger.warn(`_checkPastSwaps(): No withdrawal state returned for ${pastSwap._data.getTxId()}`);
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
this.logger.debug("syncStateFromChain(): status of " + pastSwap._data.btcTx.txid, status?.type);
|
|
791
|
+
let changed = false;
|
|
792
|
+
switch (status.type) {
|
|
793
|
+
case base_1.SpvWithdrawalStateType.FRONTED:
|
|
794
|
+
pastSwap._frontTxId = status.txId;
|
|
795
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
|
|
796
|
+
changed ||= true;
|
|
797
|
+
break;
|
|
798
|
+
case base_1.SpvWithdrawalStateType.CLAIMED:
|
|
799
|
+
pastSwap._claimTxId = status.txId;
|
|
800
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
|
|
801
|
+
changed ||= true;
|
|
802
|
+
break;
|
|
803
|
+
case base_1.SpvWithdrawalStateType.CLOSED:
|
|
804
|
+
pastSwap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLOSED;
|
|
805
|
+
changed ||= true;
|
|
806
|
+
break;
|
|
807
|
+
}
|
|
808
|
+
if (changed)
|
|
809
|
+
changedSwaps.add(pastSwap);
|
|
745
810
|
}
|
|
746
|
-
if (changed)
|
|
747
|
-
changedSwaps.add(pastSwap);
|
|
748
811
|
}
|
|
749
812
|
return {
|
|
750
813
|
changedSwaps: Array.from(changedSwaps),
|
|
@@ -73,7 +73,8 @@ class LnForGasWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
73
73
|
swapFee: resp.swapFee,
|
|
74
74
|
swapFeeBtc: resp.swapFeeSats,
|
|
75
75
|
token,
|
|
76
|
-
exactIn: false
|
|
76
|
+
exactIn: false,
|
|
77
|
+
contractVersion: "v1"
|
|
77
78
|
};
|
|
78
79
|
const quote = new LnForGasSwap_1.LnForGasSwap(this, quoteInit);
|
|
79
80
|
return quote;
|
package/dist/utils/Utils.d.ts
CHANGED
|
@@ -17,6 +17,15 @@ export declare function throwIfUndefined<T>(promise: Promise<T | undefined>, msg
|
|
|
17
17
|
* @category Utilities
|
|
18
18
|
*/
|
|
19
19
|
export declare function promiseAny<T>(promises: Promise<T>[]): Promise<T>;
|
|
20
|
+
/**
|
|
21
|
+
* Maps an array to object properties using the translation function
|
|
22
|
+
*
|
|
23
|
+
* @param array
|
|
24
|
+
* @param translator
|
|
25
|
+
*/
|
|
26
|
+
export declare function mapArrayToObject<T extends string[], O>(array: T, translator: (key: T[number]) => O): {
|
|
27
|
+
[key in T[number]]: O;
|
|
28
|
+
};
|
|
20
29
|
/**
|
|
21
30
|
* Maps a JS object to another JS object based on the translation function, the translation function is called for every
|
|
22
31
|
* property (value/key) of the old object and returns the new value of for this property
|
package/dist/utils/Utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseHashValueExact32Bytes = exports.toDecimal = exports.fromDecimal = exports.getTxoHash = exports.randomBytes = exports.toBigInt = exports.bigIntCompare = exports.bigIntMax = exports.bigIntMin = exports.extendAbortController = exports.mapToArray = exports.objectMap = exports.promiseAny = exports.throwIfUndefined = void 0;
|
|
3
|
+
exports.parseHashValueExact32Bytes = exports.toDecimal = exports.fromDecimal = exports.getTxoHash = exports.randomBytes = exports.toBigInt = exports.bigIntCompare = exports.bigIntMax = exports.bigIntMin = exports.extendAbortController = exports.mapToArray = exports.objectMap = exports.mapArrayToObject = exports.promiseAny = exports.throwIfUndefined = void 0;
|
|
4
4
|
const buffer_1 = require("buffer");
|
|
5
5
|
const utils_1 = require("@noble/hashes/utils");
|
|
6
6
|
const sha2_1 = require("@noble/hashes/sha2");
|
|
@@ -48,6 +48,20 @@ function promiseAny(promises) {
|
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
exports.promiseAny = promiseAny;
|
|
51
|
+
/**
|
|
52
|
+
* Maps an array to object properties using the translation function
|
|
53
|
+
*
|
|
54
|
+
* @param array
|
|
55
|
+
* @param translator
|
|
56
|
+
*/
|
|
57
|
+
function mapArrayToObject(array, translator) {
|
|
58
|
+
const obj = {};
|
|
59
|
+
array.forEach((item) => {
|
|
60
|
+
obj[item] = translator(item);
|
|
61
|
+
});
|
|
62
|
+
return obj;
|
|
63
|
+
}
|
|
64
|
+
exports.mapArrayToObject = mapArrayToObject;
|
|
51
65
|
/**
|
|
52
66
|
* Maps a JS object to another JS object based on the translation function, the translation function is called for every
|
|
53
67
|
* property (value/key) of the old object and returns the new value of for this property
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomiqlabs/sdk",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.1",
|
|
4
4
|
"description": "atomiq labs SDK for cross-chain swaps between smart chains and bitcoin",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types:": "./dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"author": "adambor",
|
|
24
24
|
"license": "ISC",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@atomiqlabs/base": "^13.
|
|
26
|
+
"@atomiqlabs/base": "^13.5.0",
|
|
27
27
|
"@atomiqlabs/bolt11": "1.6.1",
|
|
28
28
|
"@atomiqlabs/btc-mempool": "^1.0.4",
|
|
29
29
|
"@atomiqlabs/messenger-nostr": "^2.0.0",
|
|
@@ -82,9 +82,10 @@ export class UnifiedSwapEventListener<
|
|
|
82
82
|
|
|
83
83
|
for(let event of events) {
|
|
84
84
|
const escrowHash = chainEventToEscrowHash(event);
|
|
85
|
+
const eventVersion = event.contractVersion ?? "v1";
|
|
85
86
|
if(escrowHash!=null) {
|
|
86
87
|
const swap = swapsByEscrowHash[escrowHash];
|
|
87
|
-
if(swap!=null) {
|
|
88
|
+
if(swap!=null && (swap._contractVersion ?? "v1")===eventVersion) {
|
|
88
89
|
const obj = this.listeners[swap.getType()];
|
|
89
90
|
if(obj==null) continue;
|
|
90
91
|
await obj.listener(event, swap);
|
|
@@ -124,8 +125,9 @@ export class UnifiedSwapEventListener<
|
|
|
124
125
|
|
|
125
126
|
for(let claimData in htlcCheckInitializeEvents) {
|
|
126
127
|
const event = htlcCheckInitializeEvents[claimData];
|
|
128
|
+
const eventVersion = event.contractVersion ?? "v1";
|
|
127
129
|
const swap = swapsByClaimDataHash[claimData];
|
|
128
|
-
if(swap!=null) {
|
|
130
|
+
if(swap!=null && (swap._contractVersion ?? "v1")===eventVersion) {
|
|
129
131
|
const obj = this.listeners[swap.getType()];
|
|
130
132
|
if(obj==null) continue;
|
|
131
133
|
await obj.listener(event, swap);
|
|
@@ -55,6 +55,10 @@ export class Intermediary {
|
|
|
55
55
|
* Addresses of the intermediary on smart chains, used for checking the provided signatures
|
|
56
56
|
*/
|
|
57
57
|
readonly addresses: {[chainIdentifier: string]: string};
|
|
58
|
+
/**
|
|
59
|
+
* Contract versions of the intermediary on smart chains
|
|
60
|
+
*/
|
|
61
|
+
readonly contractVersions: {[chainIdentifier: string]: string};
|
|
58
62
|
/**
|
|
59
63
|
* Swap protocol services offered by the intermediary
|
|
60
64
|
*/
|
|
@@ -99,12 +103,14 @@ export class Intermediary {
|
|
|
99
103
|
url: string,
|
|
100
104
|
addresses: {[chainIdentifier: string]: string},
|
|
101
105
|
services: ServicesType,
|
|
102
|
-
reputation: { [chainIdentifier: string]: SingleChainReputationType } = {}
|
|
106
|
+
reputation: { [chainIdentifier: string]: SingleChainReputationType } = {},
|
|
107
|
+
contractVersions: {[chainIdentifier: string]: string} = {},
|
|
103
108
|
) {
|
|
104
109
|
this.url = url;
|
|
105
110
|
this.addresses = addresses;
|
|
106
111
|
this.services = services;
|
|
107
112
|
this.reputation = reputation;
|
|
113
|
+
this.contractVersions = contractVersions;
|
|
108
114
|
|
|
109
115
|
this.swapBounds = {};
|
|
110
116
|
for(let _swapType in this.services) {
|
|
@@ -247,4 +253,28 @@ export class Intermediary {
|
|
|
247
253
|
return this.addresses[chainIdentifier];
|
|
248
254
|
}
|
|
249
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Returns the contract version used by the intermediary for a given chain
|
|
258
|
+
*
|
|
259
|
+
* @param chainIdentifier
|
|
260
|
+
*/
|
|
261
|
+
getContractVersion(chainIdentifier: string): string {
|
|
262
|
+
return this.contractVersions[chainIdentifier] ?? "v1";
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Returns the range of contract versions used by the LPs
|
|
267
|
+
*
|
|
268
|
+
* @param chainIdentifier
|
|
269
|
+
* @param lps
|
|
270
|
+
*/
|
|
271
|
+
static getContractVersionsForLps(chainIdentifier: string, lps: Intermediary[]): string[] {
|
|
272
|
+
const versions: string[] = [];
|
|
273
|
+
lps.forEach((lp) => {
|
|
274
|
+
const lpVersion = lp.getContractVersion(chainIdentifier);
|
|
275
|
+
if(!versions.includes(lpVersion)) versions.push(lpVersion);
|
|
276
|
+
});
|
|
277
|
+
return versions;
|
|
278
|
+
}
|
|
279
|
+
|
|
250
280
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Intermediary, ServicesType} from "./Intermediary";
|
|
2
2
|
import {SwapType} from "../enums/SwapType";
|
|
3
|
-
import {SwapContract} from "@atomiqlabs/base";
|
|
3
|
+
import {SpvVaultContract, SwapContract} from "@atomiqlabs/base";
|
|
4
4
|
import {EventEmitter} from "events";
|
|
5
5
|
import {Buffer} from "buffer";
|
|
6
6
|
import {bigIntMax, bigIntMin, extendAbortController} from "../utils/Utils";
|
|
@@ -169,7 +169,7 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
169
169
|
/**
|
|
170
170
|
* Swap contracts for checking intermediary signatures
|
|
171
171
|
*/
|
|
172
|
-
swapContracts: {[
|
|
172
|
+
swapContracts: {[chainIdentifier: string]: {[contractVersion: string]: {swapContract: SwapContract, spvVaultContract: SpvVaultContract}}};
|
|
173
173
|
/**
|
|
174
174
|
* Registry URL used as a source for the list of intermediaries, this should be a link to a
|
|
175
175
|
* github-hosted JSON file
|
|
@@ -193,7 +193,7 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
193
193
|
private overrideNodeUrls?: string[];
|
|
194
194
|
|
|
195
195
|
constructor(
|
|
196
|
-
swapContracts: {[
|
|
196
|
+
swapContracts: {[chainIdentifier: string]: {[contractVersion: string]: {swapContract: SwapContract, spvVaultContract: SpvVaultContract}}},
|
|
197
197
|
registryUrl: string = REGISTRY_URL,
|
|
198
198
|
nodeUrls?: string[],
|
|
199
199
|
httpRequestTimeout?: number,
|
|
@@ -236,7 +236,11 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
236
236
|
* @param url
|
|
237
237
|
* @param abortSignal
|
|
238
238
|
*/
|
|
239
|
-
private async getNodeInfo(url: string, abortSignal?: AbortSignal) : Promise<{
|
|
239
|
+
private async getNodeInfo(url: string, abortSignal?: AbortSignal) : Promise<{
|
|
240
|
+
addresses: {[chainIdentifier: string]: string},
|
|
241
|
+
contractVersions: {[chainIdentifier: string]: string},
|
|
242
|
+
info: InfoHandlerResponseEnvelope
|
|
243
|
+
}> {
|
|
240
244
|
const response = await tryWithRetries(
|
|
241
245
|
() => IntermediaryAPI.getIntermediaryInfo(url, this.httpRequestTimeout, abortSignal),
|
|
242
246
|
{maxRetries: 3, delay: 100, exponential: true},
|
|
@@ -247,14 +251,22 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
247
251
|
abortSignal?.throwIfAborted();
|
|
248
252
|
|
|
249
253
|
const promises: Promise<void>[] = [];
|
|
250
|
-
const addresses: {[
|
|
254
|
+
const addresses: {[chainIdentifier: string]: string} = {};
|
|
255
|
+
const contractVersions: {[chainIdentifier: string]: string} = {};
|
|
251
256
|
for(let chain in response.chains) {
|
|
252
257
|
if(this.swapContracts[chain]!=null) {
|
|
258
|
+
const {signature, address, contractVersion} = response.chains[chain];
|
|
259
|
+
const _contractVersion = contractVersion ?? "v1";
|
|
260
|
+
const contract = this.swapContracts[chain][_contractVersion];
|
|
261
|
+
if(contract==null) {
|
|
262
|
+
logger.warn("getNodeInfo(): Unknown chain contract version "+_contractVersion+" for "+chain+" reported by intermediary: "+url);
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
253
265
|
promises.push((async () => {
|
|
254
|
-
const {signature, address} = response.chains[chain];
|
|
255
266
|
try {
|
|
256
|
-
await
|
|
267
|
+
await contract.swapContract.isValidDataSignature(Buffer.from(response.envelope), signature, address);
|
|
257
268
|
addresses[chain] = address;
|
|
269
|
+
contractVersions[chain] = _contractVersion;
|
|
258
270
|
} catch (e) {
|
|
259
271
|
logger.warn("getNodeInfo(): Failed to verify "+chain+" signature for intermediary: "+url);
|
|
260
272
|
}
|
|
@@ -285,6 +297,7 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
285
297
|
|
|
286
298
|
return {
|
|
287
299
|
addresses,
|
|
300
|
+
contractVersions,
|
|
288
301
|
info
|
|
289
302
|
};
|
|
290
303
|
}
|
|
@@ -303,7 +316,7 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
303
316
|
for(let key in nodeInfo.info.services) {
|
|
304
317
|
services[swapHandlerTypeToSwapType(key as SwapHandlerType)] = nodeInfo.info.services[key as SwapHandlerType];
|
|
305
318
|
}
|
|
306
|
-
return new Intermediary(url, nodeInfo.addresses, services);
|
|
319
|
+
return new Intermediary(url, nodeInfo.addresses, services, undefined, nodeInfo.contractVersions);
|
|
307
320
|
} catch (e: any) {
|
|
308
321
|
logger.warn("fetchIntermediaries(): Intermediary "+url+` is unreachable due to ${e.name ?? e.message} error, skipping...`);
|
|
309
322
|
logger.debug("fetchIntermediaries(): Error contacting intermediary "+url+": ", e);
|
|
@@ -476,6 +489,8 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
476
489
|
/**
|
|
477
490
|
* Returns swap candidates for a specific swap type & token address
|
|
478
491
|
*
|
|
492
|
+
* @remark Also filters the LPs based on supported swap versions
|
|
493
|
+
*
|
|
479
494
|
* @param chainIdentifier Chain identifier of the smart chain
|
|
480
495
|
* @param swapType Swap protocol type
|
|
481
496
|
* @param tokenAddress Token address
|
|
@@ -491,6 +506,10 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
491
506
|
if(swapService.chainTokens==null) return false;
|
|
492
507
|
if(swapService.chainTokens[chainIdentifier]==null) return false;
|
|
493
508
|
if(!swapService.chainTokens[chainIdentifier].includes(tokenAddress.toString())) return false;
|
|
509
|
+
const contracts = this.swapContracts[chainIdentifier][e.getContractVersion(chainIdentifier) ?? "v1"];
|
|
510
|
+
if(contracts==null) return false;
|
|
511
|
+
if(swapType===SwapType.FROM_BTCLN_AUTO && !contracts.swapContract?.supportsInitWithoutClaimer) return false;
|
|
512
|
+
if(swapType===SwapType.SPV_VAULT_FROM_BTC && contracts.spvVaultContract==null) return false;
|
|
494
513
|
return true;
|
|
495
514
|
});
|
|
496
515
|
|