@cowprotocol/sdk-bridging 0.3.3 → 0.4.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/index.d.mts +56 -12
- package/dist/index.d.ts +56 -12
- package/dist/index.js +175 -40
- package/dist/index.mjs +176 -41
- package/package.json +12 -12
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { cowAppDataLatestScheme } from '@cowprotocol/sdk-app-data';
|
|
|
2
2
|
import { Amounts, OrderKind, Address, EnrichedOrder, OrderBookApi } from '@cowprotocol/sdk-order-book';
|
|
3
3
|
import { ChainInfo, TargetChainId, SupportedChainId, TokenInfo, EvmCall, ChainId, CowEnv } from '@cowprotocol/sdk-config';
|
|
4
4
|
import { QuoterParameters, TraderParameters, TradeOptionalParameters, QuoteAndPost, QuoteResults, SwapAdvancedSettings, SigningStepManager, OrderPostingResult, TradingSdk } from '@cowprotocol/sdk-trading';
|
|
5
|
-
import { AccountAddress, SignerLike, AbstractProviderAdapter } from '@cowprotocol/sdk-common';
|
|
5
|
+
import { AccountAddress, SignerLike, TTLCache, AbstractProviderAdapter } from '@cowprotocol/sdk-common';
|
|
6
6
|
import { CowShedSdk, CowShedSdkOptions } from '@cowprotocol/sdk-cow-shed';
|
|
7
7
|
|
|
8
8
|
interface BridgeProviderInfo {
|
|
@@ -363,6 +363,8 @@ interface MultiQuoteOptions {
|
|
|
363
363
|
}
|
|
364
364
|
interface MultiQuoteRequest {
|
|
365
365
|
quoteBridgeRequest: QuoteBridgeRequest;
|
|
366
|
+
intermediateTokensCache?: TTLCache<TokenInfo[]>;
|
|
367
|
+
intermediateTokensTtl?: number;
|
|
366
368
|
providerDappIds?: string[];
|
|
367
369
|
advancedSettings?: SwapAdvancedSettings;
|
|
368
370
|
options?: MultiQuoteOptions;
|
|
@@ -417,24 +419,24 @@ declare function assertIsQuoteAndPost(quote: CrossChainQuoteAndPost): asserts qu
|
|
|
417
419
|
declare function getPostHooks(fullAppData?: string): cowAppDataLatestScheme.CoWHook[];
|
|
418
420
|
declare function isAppDoc(appData: unknown): appData is cowAppDataLatestScheme.AppDataRootSchema;
|
|
419
421
|
|
|
422
|
+
type BridgingSdkConfig = Required<Omit<BridgingSdkOptions, 'enableLogging' | 'cacheConfig'>>;
|
|
420
423
|
/**
|
|
421
|
-
*
|
|
424
|
+
* Cache configuration for BridgingSdk
|
|
422
425
|
*/
|
|
423
|
-
interface
|
|
426
|
+
interface BridgingSdkCacheConfig {
|
|
424
427
|
/**
|
|
425
|
-
*
|
|
428
|
+
* Enable caching for target networks and buy tokens
|
|
426
429
|
*/
|
|
427
|
-
|
|
430
|
+
enabled: boolean;
|
|
428
431
|
/**
|
|
429
|
-
*
|
|
432
|
+
* TTL in milliseconds for getIntermediateTokens cache
|
|
430
433
|
*/
|
|
431
|
-
|
|
434
|
+
intermediateTokensTtl: number;
|
|
432
435
|
/**
|
|
433
|
-
*
|
|
436
|
+
* TTL in milliseconds for getBuyTokens cache
|
|
434
437
|
*/
|
|
435
|
-
|
|
438
|
+
buyTokensTtl: number;
|
|
436
439
|
}
|
|
437
|
-
|
|
438
440
|
interface BridgingSdkOptions {
|
|
439
441
|
/**
|
|
440
442
|
* Providers for the bridging.
|
|
@@ -452,14 +454,41 @@ interface BridgingSdkOptions {
|
|
|
452
454
|
* Enable logging for the bridging SDK.
|
|
453
455
|
*/
|
|
454
456
|
enableLogging?: boolean;
|
|
457
|
+
/**
|
|
458
|
+
* Cache configuration for BridgingSdk
|
|
459
|
+
*/
|
|
460
|
+
cacheConfig?: BridgingSdkCacheConfig;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Parameters for the `getOrder` method.
|
|
464
|
+
*/
|
|
465
|
+
interface GetOrderParams {
|
|
466
|
+
/**
|
|
467
|
+
* Id of a network where order was settled
|
|
468
|
+
*/
|
|
469
|
+
chainId: SupportedChainId;
|
|
470
|
+
/**
|
|
471
|
+
* The unique identifier of the order.
|
|
472
|
+
*/
|
|
473
|
+
orderId: string;
|
|
474
|
+
/**
|
|
475
|
+
* The environment of the order
|
|
476
|
+
*/
|
|
477
|
+
env?: CowEnv;
|
|
455
478
|
}
|
|
456
|
-
|
|
479
|
+
|
|
457
480
|
/**
|
|
458
481
|
* SDK for bridging for swapping tokens between different chains.
|
|
459
482
|
*/
|
|
460
483
|
declare class BridgingSdk {
|
|
461
484
|
readonly options: BridgingSdkOptions;
|
|
462
485
|
protected config: BridgingSdkConfig;
|
|
486
|
+
private cacheConfig;
|
|
487
|
+
private intermediateTokensCache;
|
|
488
|
+
private buyTokensCache;
|
|
489
|
+
private singleQuoteStrategy;
|
|
490
|
+
private multiQuoteStrategy;
|
|
491
|
+
private bestQuoteStrategy;
|
|
463
492
|
constructor(options: BridgingSdkOptions, adapter?: AbstractProviderAdapter);
|
|
464
493
|
private get provider();
|
|
465
494
|
/**
|
|
@@ -531,6 +560,21 @@ declare class BridgingSdk {
|
|
|
531
560
|
getOrder(params: GetOrderParams): Promise<CrossChainOrder | null>;
|
|
532
561
|
getOrderBridgingStatus(bridgingId: string, originChainId: SupportedChainId): Promise<BridgeStatusResult>;
|
|
533
562
|
getProviderFromAppData(fullAppData: string): BridgeProvider<BridgeQuoteResult> | undefined;
|
|
563
|
+
/**
|
|
564
|
+
* Clear all caches. Useful for testing and debugging.
|
|
565
|
+
*/
|
|
566
|
+
clearCache(): void;
|
|
567
|
+
/**
|
|
568
|
+
* Clean up expired cache entries. Useful for maintenance.
|
|
569
|
+
*/
|
|
570
|
+
cleanupExpiredCache(): void;
|
|
571
|
+
/**
|
|
572
|
+
* Get cache statistics for debugging.
|
|
573
|
+
*/
|
|
574
|
+
getCacheStats(): {
|
|
575
|
+
intermediateTokens: number;
|
|
576
|
+
buyTokens: number;
|
|
577
|
+
};
|
|
534
578
|
getProviderByDappId(dappId: string): BridgeProvider<BridgeQuoteResult> | undefined;
|
|
535
579
|
}
|
|
536
580
|
|
|
@@ -1152,4 +1196,4 @@ declare class BungeeBridgeProvider implements BridgeProvider<BungeeQuoteResult>
|
|
|
1152
1196
|
private isExtraGasRequired;
|
|
1153
1197
|
}
|
|
1154
1198
|
|
|
1155
|
-
export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BestQuoteProgressCallback, type BestQuoteProviderContext, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk,
|
|
1199
|
+
export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BestQuoteProgressCallback, type BestQuoteProviderContext, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk, BungeeBridgeProvider, type BungeeBridgeProviderOptions, type BungeeQuoteResult, type BuyTokensParams, COW_SHED_PROXY_CREATION_GAS, type CrossChainOrder, type CrossChainQuoteAndPost, DEFAULT_EXTRA_GAS_FOR_HOOK_ESTIMATION, DEFAULT_EXTRA_GAS_PROXY_CREATION, DEFAULT_GAS_COST_FOR_HOOK_ESTIMATION, type GetProviderBuyTokens, HOOK_DAPP_BRIDGE_PROVIDER_PREFIX, type MultiQuoteOptions, type MultiQuoteProgressCallback, type MultiQuoteRequest, type MultiQuoteResult, type ProviderQuoteContext, type QuoteBridgeRequest, type QuoteBridgeRequestWithoutAmount, RAW_PROVIDERS_FILES_PATH, assertIsBridgeQuoteAndPost, assertIsQuoteAndPost, getCrossChainOrder, getPostHooks, isAppDoc, isBridgeQuoteAndPost, isQuoteAndPost };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { cowAppDataLatestScheme } from '@cowprotocol/sdk-app-data';
|
|
|
2
2
|
import { Amounts, OrderKind, Address, EnrichedOrder, OrderBookApi } from '@cowprotocol/sdk-order-book';
|
|
3
3
|
import { ChainInfo, TargetChainId, SupportedChainId, TokenInfo, EvmCall, ChainId, CowEnv } from '@cowprotocol/sdk-config';
|
|
4
4
|
import { QuoterParameters, TraderParameters, TradeOptionalParameters, QuoteAndPost, QuoteResults, SwapAdvancedSettings, SigningStepManager, OrderPostingResult, TradingSdk } from '@cowprotocol/sdk-trading';
|
|
5
|
-
import { AccountAddress, SignerLike, AbstractProviderAdapter } from '@cowprotocol/sdk-common';
|
|
5
|
+
import { AccountAddress, SignerLike, TTLCache, AbstractProviderAdapter } from '@cowprotocol/sdk-common';
|
|
6
6
|
import { CowShedSdk, CowShedSdkOptions } from '@cowprotocol/sdk-cow-shed';
|
|
7
7
|
|
|
8
8
|
interface BridgeProviderInfo {
|
|
@@ -363,6 +363,8 @@ interface MultiQuoteOptions {
|
|
|
363
363
|
}
|
|
364
364
|
interface MultiQuoteRequest {
|
|
365
365
|
quoteBridgeRequest: QuoteBridgeRequest;
|
|
366
|
+
intermediateTokensCache?: TTLCache<TokenInfo[]>;
|
|
367
|
+
intermediateTokensTtl?: number;
|
|
366
368
|
providerDappIds?: string[];
|
|
367
369
|
advancedSettings?: SwapAdvancedSettings;
|
|
368
370
|
options?: MultiQuoteOptions;
|
|
@@ -417,24 +419,24 @@ declare function assertIsQuoteAndPost(quote: CrossChainQuoteAndPost): asserts qu
|
|
|
417
419
|
declare function getPostHooks(fullAppData?: string): cowAppDataLatestScheme.CoWHook[];
|
|
418
420
|
declare function isAppDoc(appData: unknown): appData is cowAppDataLatestScheme.AppDataRootSchema;
|
|
419
421
|
|
|
422
|
+
type BridgingSdkConfig = Required<Omit<BridgingSdkOptions, 'enableLogging' | 'cacheConfig'>>;
|
|
420
423
|
/**
|
|
421
|
-
*
|
|
424
|
+
* Cache configuration for BridgingSdk
|
|
422
425
|
*/
|
|
423
|
-
interface
|
|
426
|
+
interface BridgingSdkCacheConfig {
|
|
424
427
|
/**
|
|
425
|
-
*
|
|
428
|
+
* Enable caching for target networks and buy tokens
|
|
426
429
|
*/
|
|
427
|
-
|
|
430
|
+
enabled: boolean;
|
|
428
431
|
/**
|
|
429
|
-
*
|
|
432
|
+
* TTL in milliseconds for getIntermediateTokens cache
|
|
430
433
|
*/
|
|
431
|
-
|
|
434
|
+
intermediateTokensTtl: number;
|
|
432
435
|
/**
|
|
433
|
-
*
|
|
436
|
+
* TTL in milliseconds for getBuyTokens cache
|
|
434
437
|
*/
|
|
435
|
-
|
|
438
|
+
buyTokensTtl: number;
|
|
436
439
|
}
|
|
437
|
-
|
|
438
440
|
interface BridgingSdkOptions {
|
|
439
441
|
/**
|
|
440
442
|
* Providers for the bridging.
|
|
@@ -452,14 +454,41 @@ interface BridgingSdkOptions {
|
|
|
452
454
|
* Enable logging for the bridging SDK.
|
|
453
455
|
*/
|
|
454
456
|
enableLogging?: boolean;
|
|
457
|
+
/**
|
|
458
|
+
* Cache configuration for BridgingSdk
|
|
459
|
+
*/
|
|
460
|
+
cacheConfig?: BridgingSdkCacheConfig;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Parameters for the `getOrder` method.
|
|
464
|
+
*/
|
|
465
|
+
interface GetOrderParams {
|
|
466
|
+
/**
|
|
467
|
+
* Id of a network where order was settled
|
|
468
|
+
*/
|
|
469
|
+
chainId: SupportedChainId;
|
|
470
|
+
/**
|
|
471
|
+
* The unique identifier of the order.
|
|
472
|
+
*/
|
|
473
|
+
orderId: string;
|
|
474
|
+
/**
|
|
475
|
+
* The environment of the order
|
|
476
|
+
*/
|
|
477
|
+
env?: CowEnv;
|
|
455
478
|
}
|
|
456
|
-
|
|
479
|
+
|
|
457
480
|
/**
|
|
458
481
|
* SDK for bridging for swapping tokens between different chains.
|
|
459
482
|
*/
|
|
460
483
|
declare class BridgingSdk {
|
|
461
484
|
readonly options: BridgingSdkOptions;
|
|
462
485
|
protected config: BridgingSdkConfig;
|
|
486
|
+
private cacheConfig;
|
|
487
|
+
private intermediateTokensCache;
|
|
488
|
+
private buyTokensCache;
|
|
489
|
+
private singleQuoteStrategy;
|
|
490
|
+
private multiQuoteStrategy;
|
|
491
|
+
private bestQuoteStrategy;
|
|
463
492
|
constructor(options: BridgingSdkOptions, adapter?: AbstractProviderAdapter);
|
|
464
493
|
private get provider();
|
|
465
494
|
/**
|
|
@@ -531,6 +560,21 @@ declare class BridgingSdk {
|
|
|
531
560
|
getOrder(params: GetOrderParams): Promise<CrossChainOrder | null>;
|
|
532
561
|
getOrderBridgingStatus(bridgingId: string, originChainId: SupportedChainId): Promise<BridgeStatusResult>;
|
|
533
562
|
getProviderFromAppData(fullAppData: string): BridgeProvider<BridgeQuoteResult> | undefined;
|
|
563
|
+
/**
|
|
564
|
+
* Clear all caches. Useful for testing and debugging.
|
|
565
|
+
*/
|
|
566
|
+
clearCache(): void;
|
|
567
|
+
/**
|
|
568
|
+
* Clean up expired cache entries. Useful for maintenance.
|
|
569
|
+
*/
|
|
570
|
+
cleanupExpiredCache(): void;
|
|
571
|
+
/**
|
|
572
|
+
* Get cache statistics for debugging.
|
|
573
|
+
*/
|
|
574
|
+
getCacheStats(): {
|
|
575
|
+
intermediateTokens: number;
|
|
576
|
+
buyTokens: number;
|
|
577
|
+
};
|
|
534
578
|
getProviderByDappId(dappId: string): BridgeProvider<BridgeQuoteResult> | undefined;
|
|
535
579
|
}
|
|
536
580
|
|
|
@@ -1152,4 +1196,4 @@ declare class BungeeBridgeProvider implements BridgeProvider<BungeeQuoteResult>
|
|
|
1152
1196
|
private isExtraGasRequired;
|
|
1153
1197
|
}
|
|
1154
1198
|
|
|
1155
|
-
export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BestQuoteProgressCallback, type BestQuoteProviderContext, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk,
|
|
1199
|
+
export { AcrossBridgeProvider, type AcrossBridgeProviderOptions, type AcrossQuoteResult, type BestQuoteProgressCallback, type BestQuoteProviderContext, type BridgeCallDetails, type BridgeCosts, type BridgeDeposit, type BridgeHook, BridgeOrderParsingError, type BridgeProvider, BridgeProviderError, type BridgeProviderInfo, BridgeProviderQuoteError, type BridgeQuoteAmountsAndCosts, type BridgeQuoteAndPost, BridgeQuoteErrors, type BridgeQuoteResult, type BridgeQuoteResults, BridgeStatus, type BridgeStatusResult, type BridgingDepositParams, BridgingSdk, BungeeBridgeProvider, type BungeeBridgeProviderOptions, type BungeeQuoteResult, type BuyTokensParams, COW_SHED_PROXY_CREATION_GAS, type CrossChainOrder, type CrossChainQuoteAndPost, DEFAULT_EXTRA_GAS_FOR_HOOK_ESTIMATION, DEFAULT_EXTRA_GAS_PROXY_CREATION, DEFAULT_GAS_COST_FOR_HOOK_ESTIMATION, type GetProviderBuyTokens, HOOK_DAPP_BRIDGE_PROVIDER_PREFIX, type MultiQuoteOptions, type MultiQuoteProgressCallback, type MultiQuoteRequest, type MultiQuoteResult, type ProviderQuoteContext, type QuoteBridgeRequest, type QuoteBridgeRequestWithoutAmount, RAW_PROVIDERS_FILES_PATH, assertIsBridgeQuoteAndPost, assertIsQuoteAndPost, getCrossChainOrder, getPostHooks, isAppDoc, isBridgeQuoteAndPost, isQuoteAndPost };
|
package/dist/index.js
CHANGED
|
@@ -199,6 +199,16 @@ var import_sdk_order_book2 = require("@cowprotocol/sdk-order-book");
|
|
|
199
199
|
var import_sdk_config2 = require("@cowprotocol/sdk-config");
|
|
200
200
|
var import_sdk_common4 = require("@cowprotocol/sdk-common");
|
|
201
201
|
|
|
202
|
+
// src/BridgingSdk/helpers.ts
|
|
203
|
+
var getCacheKey = ({
|
|
204
|
+
id,
|
|
205
|
+
buyChainId,
|
|
206
|
+
sellChainId = "noSellChainID",
|
|
207
|
+
tokenAddress = "noTokenAddress"
|
|
208
|
+
}) => {
|
|
209
|
+
return `${id}-${buyChainId}-${sellChainId}-${tokenAddress.toLowerCase()}`;
|
|
210
|
+
};
|
|
211
|
+
|
|
202
212
|
// src/BridgingSdk/getQuoteWithoutBridge.ts
|
|
203
213
|
var import_sdk_common = require("@cowprotocol/sdk-common");
|
|
204
214
|
function getQuoteWithoutBridge(params) {
|
|
@@ -218,6 +228,8 @@ function getQuoteWithoutBridge(params) {
|
|
|
218
228
|
|
|
219
229
|
// src/BridgingSdk/getQuoteWithBridge.ts
|
|
220
230
|
var import_sdk_trading = require("@cowprotocol/sdk-trading");
|
|
231
|
+
var import_sdk_common3 = require("@cowprotocol/sdk-common");
|
|
232
|
+
var import_sdk_order_book = require("@cowprotocol/sdk-order-book");
|
|
221
233
|
|
|
222
234
|
// src/BridgingSdk/getBridgeSignedHook.ts
|
|
223
235
|
var import_sdk_common2 = require("@cowprotocol/sdk-common");
|
|
@@ -245,10 +257,6 @@ async function getBridgeSignedHook(bridgeRequest, { provider, signer, hookGasLim
|
|
|
245
257
|
};
|
|
246
258
|
}
|
|
247
259
|
|
|
248
|
-
// src/BridgingSdk/getQuoteWithBridge.ts
|
|
249
|
-
var import_sdk_order_book = require("@cowprotocol/sdk-order-book");
|
|
250
|
-
var import_sdk_common3 = require("@cowprotocol/sdk-common");
|
|
251
|
-
|
|
252
260
|
// src/hooks/utils.ts
|
|
253
261
|
function getHookMockForCostEstimation(gasLimit) {
|
|
254
262
|
return {
|
|
@@ -282,7 +290,8 @@ async function getQuoteWithBridge(params) {
|
|
|
282
290
|
);
|
|
283
291
|
const bridgeRequestWithoutAmount = await getBaseBridgeQuoteRequest({
|
|
284
292
|
swapAndBridgeRequest,
|
|
285
|
-
provider
|
|
293
|
+
provider,
|
|
294
|
+
intermediateTokensCache: params.intermediateTokensCache
|
|
286
295
|
});
|
|
287
296
|
const hookEstimatedGasLimit = await provider.getGasLimitEstimationForHook(bridgeRequestWithoutAmount);
|
|
288
297
|
const mockedHook = getHookMockForCostEstimation(hookEstimatedGasLimit);
|
|
@@ -324,7 +333,7 @@ async function getQuoteWithBridge(params) {
|
|
|
324
333
|
});
|
|
325
334
|
const intermediateTokenAmount = swapResult.amountsAndCosts.afterSlippage.buyAmount;
|
|
326
335
|
(0, import_sdk_common3.log)(
|
|
327
|
-
`Expected to receive ${intermediateTokenAmount} of the intermediate token (${(intermediateTokenAmount /
|
|
336
|
+
`Expected to receive ${intermediateTokenAmount} of the intermediate token (${(intermediateTokenAmount / 10n ** BigInt(intermediaryTokenDecimals)).toString()} formatted)`
|
|
328
337
|
);
|
|
329
338
|
async function signHooksAndSetSwapResult(signer2, hookGasLimit, advancedSettings2) {
|
|
330
339
|
const appDataOverride = advancedSettings2?.appData;
|
|
@@ -418,13 +427,26 @@ async function getQuoteWithBridge(params) {
|
|
|
418
427
|
};
|
|
419
428
|
}
|
|
420
429
|
async function getBaseBridgeQuoteRequest(params) {
|
|
421
|
-
const { provider, swapAndBridgeRequest: quoteBridgeRequest } = params;
|
|
422
|
-
|
|
430
|
+
const { provider, swapAndBridgeRequest: quoteBridgeRequest, intermediateTokensCache } = params;
|
|
431
|
+
let intermediateTokens = [];
|
|
432
|
+
const cacheKey = getCacheKey({
|
|
433
|
+
id: provider.info.dappId,
|
|
434
|
+
buyChainId: quoteBridgeRequest.buyTokenChainId.toString(),
|
|
435
|
+
sellChainId: quoteBridgeRequest.sellTokenChainId.toString(),
|
|
436
|
+
tokenAddress: quoteBridgeRequest.buyTokenAddress
|
|
437
|
+
});
|
|
438
|
+
const cached = intermediateTokensCache?.get(cacheKey);
|
|
439
|
+
if (cached) {
|
|
440
|
+
intermediateTokens = cached;
|
|
441
|
+
} else {
|
|
442
|
+
intermediateTokens = await provider.getIntermediateTokens(quoteBridgeRequest);
|
|
443
|
+
intermediateTokensCache?.set(cacheKey, intermediateTokens);
|
|
444
|
+
}
|
|
423
445
|
if (intermediateTokens.length === 0) {
|
|
424
446
|
throw new BridgeProviderQuoteError("NO_INTERMEDIATE_TOKENS" /* NO_INTERMEDIATE_TOKENS */);
|
|
425
447
|
}
|
|
426
448
|
const intermediateToken = intermediateTokens[0];
|
|
427
|
-
(0, import_sdk_common3.log)(`Using ${intermediateToken} as intermediate tokens`);
|
|
449
|
+
(0, import_sdk_common3.log)(`Using ${intermediateToken?.name ?? intermediateToken?.address} as intermediate tokens`);
|
|
428
450
|
if (!intermediateToken) {
|
|
429
451
|
throw new BridgeProviderQuoteError("NO_INTERMEDIATE_TOKENS" /* NO_INTERMEDIATE_TOKENS */, { intermediateTokens });
|
|
430
452
|
}
|
|
@@ -472,9 +494,25 @@ async function getBridgeResult(context) {
|
|
|
472
494
|
return { bridgeResult, bridgeHook, appDataInfo };
|
|
473
495
|
}
|
|
474
496
|
|
|
497
|
+
// src/BridgingSdk/strategies/QuoteStrategy.ts
|
|
498
|
+
var QuoteStrategy = class {
|
|
499
|
+
constructor(intermediateTokensCache) {
|
|
500
|
+
this.intermediateTokensCache = intermediateTokensCache;
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
var BaseSingleQuoteStrategy = class extends QuoteStrategy {
|
|
504
|
+
};
|
|
505
|
+
var BaseMultiQuoteStrategy = class extends QuoteStrategy {
|
|
506
|
+
};
|
|
507
|
+
var BaseBestQuoteStrategy = class extends QuoteStrategy {
|
|
508
|
+
};
|
|
509
|
+
|
|
475
510
|
// src/BridgingSdk/strategies/SingleQuoteStrategy.ts
|
|
476
|
-
var
|
|
511
|
+
var SingleQuoteStrategy = class extends BaseSingleQuoteStrategy {
|
|
477
512
|
strategyName = "SingleQuoteStrategy";
|
|
513
|
+
constructor(intermediateTokensCache) {
|
|
514
|
+
super(intermediateTokensCache);
|
|
515
|
+
}
|
|
478
516
|
async execute(request, config) {
|
|
479
517
|
const { quoteBridgeRequest, advancedSettings } = request;
|
|
480
518
|
const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
|
|
@@ -484,13 +522,18 @@ var SingleQuoteStrategyImpl = class {
|
|
|
484
522
|
if (!provider) {
|
|
485
523
|
throw new Error("No provider found for cross-chain swap");
|
|
486
524
|
}
|
|
487
|
-
|
|
525
|
+
const baseParams = {
|
|
488
526
|
swapAndBridgeRequest: quoteBridgeRequest,
|
|
489
527
|
advancedSettings,
|
|
490
528
|
tradingSdk,
|
|
491
529
|
provider,
|
|
492
530
|
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
493
|
-
}
|
|
531
|
+
};
|
|
532
|
+
const request2 = this.intermediateTokensCache ? {
|
|
533
|
+
...baseParams,
|
|
534
|
+
intermediateTokensCache: this.intermediateTokensCache
|
|
535
|
+
} : baseParams;
|
|
536
|
+
return getQuoteWithBridge(request2);
|
|
494
537
|
} else {
|
|
495
538
|
return getQuoteWithoutBridge({
|
|
496
539
|
quoteBridgeRequest,
|
|
@@ -589,8 +632,11 @@ function resolveProvidersToQuery(providerDappIds, providers) {
|
|
|
589
632
|
// src/BridgingSdk/strategies/MultiQuoteStrategy.ts
|
|
590
633
|
var DEFAULT_TOTAL_TIMEOUT_MS = 4e4;
|
|
591
634
|
var DEFAULT_PROVIDER_TIMEOUT_MS = 2e4;
|
|
592
|
-
var
|
|
635
|
+
var MultiQuoteStrategy = class extends BaseMultiQuoteStrategy {
|
|
593
636
|
strategyName = "MultiQuoteStrategy";
|
|
637
|
+
constructor(intermediateTokensCache) {
|
|
638
|
+
super(intermediateTokensCache);
|
|
639
|
+
}
|
|
594
640
|
async execute(request, config) {
|
|
595
641
|
const { quoteBridgeRequest, providerDappIds, advancedSettings, options } = request;
|
|
596
642
|
const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
|
|
@@ -635,14 +681,19 @@ var MultiQuoteStrategyImpl = class {
|
|
|
635
681
|
const { provider, quoteBridgeRequest, advancedSettings, providerTimeout, onQuoteResult, results, index } = context;
|
|
636
682
|
return (async () => {
|
|
637
683
|
try {
|
|
684
|
+
const baseParams = {
|
|
685
|
+
swapAndBridgeRequest: quoteBridgeRequest,
|
|
686
|
+
advancedSettings,
|
|
687
|
+
tradingSdk: config.tradingSdk,
|
|
688
|
+
provider,
|
|
689
|
+
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
690
|
+
};
|
|
691
|
+
const request = this.intermediateTokensCache ? {
|
|
692
|
+
...baseParams,
|
|
693
|
+
intermediateTokensCache: this.intermediateTokensCache
|
|
694
|
+
} : baseParams;
|
|
638
695
|
const quote = await Promise.race([
|
|
639
|
-
getQuoteWithBridge(
|
|
640
|
-
swapAndBridgeRequest: quoteBridgeRequest,
|
|
641
|
-
advancedSettings,
|
|
642
|
-
tradingSdk: config.tradingSdk,
|
|
643
|
-
provider,
|
|
644
|
-
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
645
|
-
}),
|
|
696
|
+
getQuoteWithBridge(request),
|
|
646
697
|
createBridgeQuoteTimeoutPromise(providerTimeout, `Provider ${provider.info.dappId}`)
|
|
647
698
|
]);
|
|
648
699
|
const result = {
|
|
@@ -668,8 +719,11 @@ var MultiQuoteStrategyImpl = class {
|
|
|
668
719
|
// src/BridgingSdk/strategies/BestQuoteStrategy.ts
|
|
669
720
|
var DEFAULT_TOTAL_TIMEOUT_MS2 = 4e4;
|
|
670
721
|
var DEFAULT_PROVIDER_TIMEOUT_MS2 = 2e4;
|
|
671
|
-
var
|
|
722
|
+
var BestQuoteStrategy = class extends BaseBestQuoteStrategy {
|
|
672
723
|
strategyName = "BestQuoteStrategy";
|
|
724
|
+
constructor(intermediateTokensCache) {
|
|
725
|
+
super(intermediateTokensCache);
|
|
726
|
+
}
|
|
673
727
|
async execute(request, config) {
|
|
674
728
|
const { quoteBridgeRequest, providerDappIds, advancedSettings, options } = request;
|
|
675
729
|
const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
|
|
@@ -703,14 +757,19 @@ var BestQuoteStrategyImpl = class {
|
|
|
703
757
|
const { provider, quoteBridgeRequest, advancedSettings, providerTimeout, onQuoteResult, bestResult, firstError } = context;
|
|
704
758
|
return (async () => {
|
|
705
759
|
try {
|
|
760
|
+
const baseParams = {
|
|
761
|
+
swapAndBridgeRequest: quoteBridgeRequest,
|
|
762
|
+
advancedSettings,
|
|
763
|
+
tradingSdk: config.tradingSdk,
|
|
764
|
+
provider,
|
|
765
|
+
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
766
|
+
};
|
|
767
|
+
const request = this.intermediateTokensCache ? {
|
|
768
|
+
...baseParams,
|
|
769
|
+
intermediateTokensCache: this.intermediateTokensCache
|
|
770
|
+
} : baseParams;
|
|
706
771
|
const quote = await Promise.race([
|
|
707
|
-
getQuoteWithBridge(
|
|
708
|
-
swapAndBridgeRequest: quoteBridgeRequest,
|
|
709
|
-
advancedSettings,
|
|
710
|
-
tradingSdk: config.tradingSdk,
|
|
711
|
-
provider,
|
|
712
|
-
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
713
|
-
}),
|
|
772
|
+
getQuoteWithBridge(request),
|
|
714
773
|
createBridgeQuoteTimeoutPromise(providerTimeout, `Provider ${provider.info.dappId}`)
|
|
715
774
|
]);
|
|
716
775
|
const result = {
|
|
@@ -736,17 +795,30 @@ var BestQuoteStrategyImpl = class {
|
|
|
736
795
|
}
|
|
737
796
|
};
|
|
738
797
|
|
|
798
|
+
// src/BridgingSdk/strategies/createStrategies.ts
|
|
799
|
+
function createStrategies(intermediateTokensCache) {
|
|
800
|
+
return {
|
|
801
|
+
singleQuoteStrategy: new SingleQuoteStrategy(intermediateTokensCache),
|
|
802
|
+
multiQuoteStrategy: new MultiQuoteStrategy(intermediateTokensCache),
|
|
803
|
+
bestQuoteStrategy: new BestQuoteStrategy(intermediateTokensCache)
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
|
|
739
807
|
// src/BridgingSdk/BridgingSdk.ts
|
|
740
|
-
var
|
|
741
|
-
|
|
742
|
-
|
|
808
|
+
var DEFAULT_CACHE_CONFIG = {
|
|
809
|
+
enabled: true,
|
|
810
|
+
intermediateTokensTtl: 5 * 60 * 1e3,
|
|
811
|
+
// 5 minutes
|
|
812
|
+
buyTokensTtl: 2 * 60 * 1e3
|
|
813
|
+
// 2 minutes
|
|
814
|
+
};
|
|
743
815
|
var BridgingSdk = class {
|
|
744
816
|
constructor(options, adapter) {
|
|
745
817
|
this.options = options;
|
|
746
818
|
if (adapter) {
|
|
747
819
|
(0, import_sdk_common4.setGlobalAdapter)(adapter);
|
|
748
820
|
}
|
|
749
|
-
const { providers, ...restOptions } = options;
|
|
821
|
+
const { providers, cacheConfig, ...restOptions } = options;
|
|
750
822
|
if (!providers || providers.length === 0) {
|
|
751
823
|
throw new Error("At least one bridge provider is required");
|
|
752
824
|
}
|
|
@@ -761,8 +833,31 @@ var BridgingSdk = class {
|
|
|
761
833
|
tradingSdk,
|
|
762
834
|
orderBookApi
|
|
763
835
|
};
|
|
836
|
+
this.cacheConfig = { ...DEFAULT_CACHE_CONFIG, ...cacheConfig };
|
|
837
|
+
this.intermediateTokensCache = new import_sdk_common4.TTLCache(
|
|
838
|
+
"bridging-intermediate-tokens",
|
|
839
|
+
this.cacheConfig.enabled,
|
|
840
|
+
this.cacheConfig.intermediateTokensTtl
|
|
841
|
+
);
|
|
842
|
+
this.buyTokensCache = new import_sdk_common4.TTLCache(
|
|
843
|
+
"bridging-buy-tokens",
|
|
844
|
+
this.cacheConfig.enabled,
|
|
845
|
+
this.cacheConfig.buyTokensTtl
|
|
846
|
+
);
|
|
847
|
+
const { singleQuoteStrategy, multiQuoteStrategy, bestQuoteStrategy } = createStrategies(
|
|
848
|
+
this.cacheConfig.enabled ? this.intermediateTokensCache : void 0
|
|
849
|
+
);
|
|
850
|
+
this.singleQuoteStrategy = singleQuoteStrategy;
|
|
851
|
+
this.multiQuoteStrategy = multiQuoteStrategy;
|
|
852
|
+
this.bestQuoteStrategy = bestQuoteStrategy;
|
|
764
853
|
}
|
|
765
854
|
config;
|
|
855
|
+
cacheConfig;
|
|
856
|
+
intermediateTokensCache;
|
|
857
|
+
buyTokensCache;
|
|
858
|
+
singleQuoteStrategy;
|
|
859
|
+
multiQuoteStrategy;
|
|
860
|
+
bestQuoteStrategy;
|
|
766
861
|
get provider() {
|
|
767
862
|
const { providers } = this.config;
|
|
768
863
|
if (!providers[0]) {
|
|
@@ -794,7 +889,22 @@ var BridgingSdk = class {
|
|
|
794
889
|
* @param params
|
|
795
890
|
*/
|
|
796
891
|
async getBuyTokens(params) {
|
|
797
|
-
|
|
892
|
+
const providerId = this.provider.info.dappId;
|
|
893
|
+
const cacheKey = getCacheKey({
|
|
894
|
+
id: providerId,
|
|
895
|
+
buyChainId: params.buyChainId.toString(),
|
|
896
|
+
sellChainId: params.sellChainId?.toString(),
|
|
897
|
+
tokenAddress: params.sellTokenAddress
|
|
898
|
+
});
|
|
899
|
+
const cached = this.cacheConfig.enabled && this.buyTokensCache.get(cacheKey);
|
|
900
|
+
if (cached) {
|
|
901
|
+
return cached;
|
|
902
|
+
}
|
|
903
|
+
const result = await this.provider.getBuyTokens(params);
|
|
904
|
+
if (this.cacheConfig.enabled) {
|
|
905
|
+
this.buyTokensCache.set(cacheKey, result);
|
|
906
|
+
}
|
|
907
|
+
return result;
|
|
798
908
|
}
|
|
799
909
|
/**
|
|
800
910
|
* Get quote details, including a callback function to post the order on-chain.
|
|
@@ -812,11 +922,13 @@ var BridgingSdk = class {
|
|
|
812
922
|
* @throws Error if no path is found
|
|
813
923
|
*/
|
|
814
924
|
async getQuote(quoteBridgeRequest, advancedSettings) {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
925
|
+
return this.singleQuoteStrategy.execute(
|
|
926
|
+
{
|
|
927
|
+
quoteBridgeRequest,
|
|
928
|
+
advancedSettings
|
|
929
|
+
},
|
|
930
|
+
this.config
|
|
931
|
+
);
|
|
820
932
|
}
|
|
821
933
|
/**
|
|
822
934
|
* Get quotes from multiple bridge providers in parallel with progressive results.
|
|
@@ -834,7 +946,7 @@ var BridgingSdk = class {
|
|
|
834
946
|
* ```
|
|
835
947
|
*/
|
|
836
948
|
async getMultiQuotes(request) {
|
|
837
|
-
return multiQuoteStrategy.execute(request, this.config);
|
|
949
|
+
return this.multiQuoteStrategy.execute(request, this.config);
|
|
838
950
|
}
|
|
839
951
|
/**
|
|
840
952
|
* Get the best quote from multiple bridge providers with progressive updates.
|
|
@@ -852,7 +964,7 @@ var BridgingSdk = class {
|
|
|
852
964
|
* @throws Error if the request is for a single-chain swap (sellTokenChainId === buyTokenChainId)
|
|
853
965
|
*/
|
|
854
966
|
async getBestQuote(request) {
|
|
855
|
-
return bestQuoteStrategy.execute(request, this.config);
|
|
967
|
+
return this.bestQuoteStrategy.execute(request, this.config);
|
|
856
968
|
}
|
|
857
969
|
async getOrder(params) {
|
|
858
970
|
const { orderBookApi } = this.config;
|
|
@@ -871,6 +983,29 @@ var BridgingSdk = class {
|
|
|
871
983
|
getProviderFromAppData(fullAppData) {
|
|
872
984
|
return findBridgeProviderFromHook(fullAppData, this.getProviders());
|
|
873
985
|
}
|
|
986
|
+
/**
|
|
987
|
+
* Clear all caches. Useful for testing and debugging.
|
|
988
|
+
*/
|
|
989
|
+
clearCache() {
|
|
990
|
+
this.intermediateTokensCache.clear();
|
|
991
|
+
this.buyTokensCache.clear();
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Clean up expired cache entries. Useful for maintenance.
|
|
995
|
+
*/
|
|
996
|
+
cleanupExpiredCache() {
|
|
997
|
+
this.intermediateTokensCache.cleanup();
|
|
998
|
+
this.buyTokensCache.cleanup();
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Get cache statistics for debugging.
|
|
1002
|
+
*/
|
|
1003
|
+
getCacheStats() {
|
|
1004
|
+
return {
|
|
1005
|
+
intermediateTokens: this.intermediateTokensCache.size(),
|
|
1006
|
+
buyTokens: this.buyTokensCache.size()
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
874
1009
|
getProviderByDappId(dappId) {
|
|
875
1010
|
return this.config.providers.find((provider) => provider.info.dappId === dappId);
|
|
876
1011
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -151,7 +151,17 @@ async function getCrossChainOrder(params) {
|
|
|
151
151
|
import { TradingSdk } from "@cowprotocol/sdk-trading";
|
|
152
152
|
import { OrderBookApi } from "@cowprotocol/sdk-order-book";
|
|
153
153
|
import { ALL_SUPPORTED_CHAINS } from "@cowprotocol/sdk-config";
|
|
154
|
-
import { enableLogging, setGlobalAdapter } from "@cowprotocol/sdk-common";
|
|
154
|
+
import { enableLogging, setGlobalAdapter, TTLCache as TTLCache2 } from "@cowprotocol/sdk-common";
|
|
155
|
+
|
|
156
|
+
// src/BridgingSdk/helpers.ts
|
|
157
|
+
var getCacheKey = ({
|
|
158
|
+
id,
|
|
159
|
+
buyChainId,
|
|
160
|
+
sellChainId = "noSellChainID",
|
|
161
|
+
tokenAddress = "noTokenAddress"
|
|
162
|
+
}) => {
|
|
163
|
+
return `${id}-${buyChainId}-${sellChainId}-${tokenAddress.toLowerCase()}`;
|
|
164
|
+
};
|
|
155
165
|
|
|
156
166
|
// src/BridgingSdk/getQuoteWithoutBridge.ts
|
|
157
167
|
import { jsonWithBigintReplacer, log } from "@cowprotocol/sdk-common";
|
|
@@ -176,6 +186,8 @@ import {
|
|
|
176
186
|
mergeAppDataDoc,
|
|
177
187
|
postSwapOrderFromQuote
|
|
178
188
|
} from "@cowprotocol/sdk-trading";
|
|
189
|
+
import { getGlobalAdapter as getGlobalAdapter2, jsonWithBigintReplacer as jsonWithBigintReplacer2, log as log2 } from "@cowprotocol/sdk-common";
|
|
190
|
+
import { OrderKind } from "@cowprotocol/sdk-order-book";
|
|
179
191
|
|
|
180
192
|
// src/BridgingSdk/getBridgeSignedHook.ts
|
|
181
193
|
import { getGlobalAdapter } from "@cowprotocol/sdk-common";
|
|
@@ -203,10 +215,6 @@ async function getBridgeSignedHook(bridgeRequest, { provider, signer, hookGasLim
|
|
|
203
215
|
};
|
|
204
216
|
}
|
|
205
217
|
|
|
206
|
-
// src/BridgingSdk/getQuoteWithBridge.ts
|
|
207
|
-
import { OrderKind } from "@cowprotocol/sdk-order-book";
|
|
208
|
-
import { getGlobalAdapter as getGlobalAdapter2, jsonWithBigintReplacer as jsonWithBigintReplacer2, log as log2 } from "@cowprotocol/sdk-common";
|
|
209
|
-
|
|
210
218
|
// src/hooks/utils.ts
|
|
211
219
|
function getHookMockForCostEstimation(gasLimit) {
|
|
212
220
|
return {
|
|
@@ -240,7 +248,8 @@ async function getQuoteWithBridge(params) {
|
|
|
240
248
|
);
|
|
241
249
|
const bridgeRequestWithoutAmount = await getBaseBridgeQuoteRequest({
|
|
242
250
|
swapAndBridgeRequest,
|
|
243
|
-
provider
|
|
251
|
+
provider,
|
|
252
|
+
intermediateTokensCache: params.intermediateTokensCache
|
|
244
253
|
});
|
|
245
254
|
const hookEstimatedGasLimit = await provider.getGasLimitEstimationForHook(bridgeRequestWithoutAmount);
|
|
246
255
|
const mockedHook = getHookMockForCostEstimation(hookEstimatedGasLimit);
|
|
@@ -282,7 +291,7 @@ async function getQuoteWithBridge(params) {
|
|
|
282
291
|
});
|
|
283
292
|
const intermediateTokenAmount = swapResult.amountsAndCosts.afterSlippage.buyAmount;
|
|
284
293
|
log2(
|
|
285
|
-
`Expected to receive ${intermediateTokenAmount} of the intermediate token (${(intermediateTokenAmount /
|
|
294
|
+
`Expected to receive ${intermediateTokenAmount} of the intermediate token (${(intermediateTokenAmount / 10n ** BigInt(intermediaryTokenDecimals)).toString()} formatted)`
|
|
286
295
|
);
|
|
287
296
|
async function signHooksAndSetSwapResult(signer2, hookGasLimit, advancedSettings2) {
|
|
288
297
|
const appDataOverride = advancedSettings2?.appData;
|
|
@@ -376,13 +385,26 @@ async function getQuoteWithBridge(params) {
|
|
|
376
385
|
};
|
|
377
386
|
}
|
|
378
387
|
async function getBaseBridgeQuoteRequest(params) {
|
|
379
|
-
const { provider, swapAndBridgeRequest: quoteBridgeRequest } = params;
|
|
380
|
-
|
|
388
|
+
const { provider, swapAndBridgeRequest: quoteBridgeRequest, intermediateTokensCache } = params;
|
|
389
|
+
let intermediateTokens = [];
|
|
390
|
+
const cacheKey = getCacheKey({
|
|
391
|
+
id: provider.info.dappId,
|
|
392
|
+
buyChainId: quoteBridgeRequest.buyTokenChainId.toString(),
|
|
393
|
+
sellChainId: quoteBridgeRequest.sellTokenChainId.toString(),
|
|
394
|
+
tokenAddress: quoteBridgeRequest.buyTokenAddress
|
|
395
|
+
});
|
|
396
|
+
const cached = intermediateTokensCache?.get(cacheKey);
|
|
397
|
+
if (cached) {
|
|
398
|
+
intermediateTokens = cached;
|
|
399
|
+
} else {
|
|
400
|
+
intermediateTokens = await provider.getIntermediateTokens(quoteBridgeRequest);
|
|
401
|
+
intermediateTokensCache?.set(cacheKey, intermediateTokens);
|
|
402
|
+
}
|
|
381
403
|
if (intermediateTokens.length === 0) {
|
|
382
404
|
throw new BridgeProviderQuoteError("NO_INTERMEDIATE_TOKENS" /* NO_INTERMEDIATE_TOKENS */);
|
|
383
405
|
}
|
|
384
406
|
const intermediateToken = intermediateTokens[0];
|
|
385
|
-
log2(`Using ${intermediateToken} as intermediate tokens`);
|
|
407
|
+
log2(`Using ${intermediateToken?.name ?? intermediateToken?.address} as intermediate tokens`);
|
|
386
408
|
if (!intermediateToken) {
|
|
387
409
|
throw new BridgeProviderQuoteError("NO_INTERMEDIATE_TOKENS" /* NO_INTERMEDIATE_TOKENS */, { intermediateTokens });
|
|
388
410
|
}
|
|
@@ -430,9 +452,25 @@ async function getBridgeResult(context) {
|
|
|
430
452
|
return { bridgeResult, bridgeHook, appDataInfo };
|
|
431
453
|
}
|
|
432
454
|
|
|
455
|
+
// src/BridgingSdk/strategies/QuoteStrategy.ts
|
|
456
|
+
var QuoteStrategy = class {
|
|
457
|
+
constructor(intermediateTokensCache) {
|
|
458
|
+
this.intermediateTokensCache = intermediateTokensCache;
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
var BaseSingleQuoteStrategy = class extends QuoteStrategy {
|
|
462
|
+
};
|
|
463
|
+
var BaseMultiQuoteStrategy = class extends QuoteStrategy {
|
|
464
|
+
};
|
|
465
|
+
var BaseBestQuoteStrategy = class extends QuoteStrategy {
|
|
466
|
+
};
|
|
467
|
+
|
|
433
468
|
// src/BridgingSdk/strategies/SingleQuoteStrategy.ts
|
|
434
|
-
var
|
|
469
|
+
var SingleQuoteStrategy = class extends BaseSingleQuoteStrategy {
|
|
435
470
|
strategyName = "SingleQuoteStrategy";
|
|
471
|
+
constructor(intermediateTokensCache) {
|
|
472
|
+
super(intermediateTokensCache);
|
|
473
|
+
}
|
|
436
474
|
async execute(request, config) {
|
|
437
475
|
const { quoteBridgeRequest, advancedSettings } = request;
|
|
438
476
|
const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
|
|
@@ -442,13 +480,18 @@ var SingleQuoteStrategyImpl = class {
|
|
|
442
480
|
if (!provider) {
|
|
443
481
|
throw new Error("No provider found for cross-chain swap");
|
|
444
482
|
}
|
|
445
|
-
|
|
483
|
+
const baseParams = {
|
|
446
484
|
swapAndBridgeRequest: quoteBridgeRequest,
|
|
447
485
|
advancedSettings,
|
|
448
486
|
tradingSdk,
|
|
449
487
|
provider,
|
|
450
488
|
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
451
|
-
}
|
|
489
|
+
};
|
|
490
|
+
const request2 = this.intermediateTokensCache ? {
|
|
491
|
+
...baseParams,
|
|
492
|
+
intermediateTokensCache: this.intermediateTokensCache
|
|
493
|
+
} : baseParams;
|
|
494
|
+
return getQuoteWithBridge(request2);
|
|
452
495
|
} else {
|
|
453
496
|
return getQuoteWithoutBridge({
|
|
454
497
|
quoteBridgeRequest,
|
|
@@ -547,8 +590,11 @@ function resolveProvidersToQuery(providerDappIds, providers) {
|
|
|
547
590
|
// src/BridgingSdk/strategies/MultiQuoteStrategy.ts
|
|
548
591
|
var DEFAULT_TOTAL_TIMEOUT_MS = 4e4;
|
|
549
592
|
var DEFAULT_PROVIDER_TIMEOUT_MS = 2e4;
|
|
550
|
-
var
|
|
593
|
+
var MultiQuoteStrategy = class extends BaseMultiQuoteStrategy {
|
|
551
594
|
strategyName = "MultiQuoteStrategy";
|
|
595
|
+
constructor(intermediateTokensCache) {
|
|
596
|
+
super(intermediateTokensCache);
|
|
597
|
+
}
|
|
552
598
|
async execute(request, config) {
|
|
553
599
|
const { quoteBridgeRequest, providerDappIds, advancedSettings, options } = request;
|
|
554
600
|
const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
|
|
@@ -593,14 +639,19 @@ var MultiQuoteStrategyImpl = class {
|
|
|
593
639
|
const { provider, quoteBridgeRequest, advancedSettings, providerTimeout, onQuoteResult, results, index } = context;
|
|
594
640
|
return (async () => {
|
|
595
641
|
try {
|
|
642
|
+
const baseParams = {
|
|
643
|
+
swapAndBridgeRequest: quoteBridgeRequest,
|
|
644
|
+
advancedSettings,
|
|
645
|
+
tradingSdk: config.tradingSdk,
|
|
646
|
+
provider,
|
|
647
|
+
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
648
|
+
};
|
|
649
|
+
const request = this.intermediateTokensCache ? {
|
|
650
|
+
...baseParams,
|
|
651
|
+
intermediateTokensCache: this.intermediateTokensCache
|
|
652
|
+
} : baseParams;
|
|
596
653
|
const quote = await Promise.race([
|
|
597
|
-
getQuoteWithBridge(
|
|
598
|
-
swapAndBridgeRequest: quoteBridgeRequest,
|
|
599
|
-
advancedSettings,
|
|
600
|
-
tradingSdk: config.tradingSdk,
|
|
601
|
-
provider,
|
|
602
|
-
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
603
|
-
}),
|
|
654
|
+
getQuoteWithBridge(request),
|
|
604
655
|
createBridgeQuoteTimeoutPromise(providerTimeout, `Provider ${provider.info.dappId}`)
|
|
605
656
|
]);
|
|
606
657
|
const result = {
|
|
@@ -626,8 +677,11 @@ var MultiQuoteStrategyImpl = class {
|
|
|
626
677
|
// src/BridgingSdk/strategies/BestQuoteStrategy.ts
|
|
627
678
|
var DEFAULT_TOTAL_TIMEOUT_MS2 = 4e4;
|
|
628
679
|
var DEFAULT_PROVIDER_TIMEOUT_MS2 = 2e4;
|
|
629
|
-
var
|
|
680
|
+
var BestQuoteStrategy = class extends BaseBestQuoteStrategy {
|
|
630
681
|
strategyName = "BestQuoteStrategy";
|
|
682
|
+
constructor(intermediateTokensCache) {
|
|
683
|
+
super(intermediateTokensCache);
|
|
684
|
+
}
|
|
631
685
|
async execute(request, config) {
|
|
632
686
|
const { quoteBridgeRequest, providerDappIds, advancedSettings, options } = request;
|
|
633
687
|
const { sellTokenChainId, buyTokenChainId } = quoteBridgeRequest;
|
|
@@ -661,14 +715,19 @@ var BestQuoteStrategyImpl = class {
|
|
|
661
715
|
const { provider, quoteBridgeRequest, advancedSettings, providerTimeout, onQuoteResult, bestResult, firstError } = context;
|
|
662
716
|
return (async () => {
|
|
663
717
|
try {
|
|
718
|
+
const baseParams = {
|
|
719
|
+
swapAndBridgeRequest: quoteBridgeRequest,
|
|
720
|
+
advancedSettings,
|
|
721
|
+
tradingSdk: config.tradingSdk,
|
|
722
|
+
provider,
|
|
723
|
+
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
724
|
+
};
|
|
725
|
+
const request = this.intermediateTokensCache ? {
|
|
726
|
+
...baseParams,
|
|
727
|
+
intermediateTokensCache: this.intermediateTokensCache
|
|
728
|
+
} : baseParams;
|
|
664
729
|
const quote = await Promise.race([
|
|
665
|
-
getQuoteWithBridge(
|
|
666
|
-
swapAndBridgeRequest: quoteBridgeRequest,
|
|
667
|
-
advancedSettings,
|
|
668
|
-
tradingSdk: config.tradingSdk,
|
|
669
|
-
provider,
|
|
670
|
-
bridgeHookSigner: advancedSettings?.quoteSigner
|
|
671
|
-
}),
|
|
730
|
+
getQuoteWithBridge(request),
|
|
672
731
|
createBridgeQuoteTimeoutPromise(providerTimeout, `Provider ${provider.info.dappId}`)
|
|
673
732
|
]);
|
|
674
733
|
const result = {
|
|
@@ -694,17 +753,30 @@ var BestQuoteStrategyImpl = class {
|
|
|
694
753
|
}
|
|
695
754
|
};
|
|
696
755
|
|
|
756
|
+
// src/BridgingSdk/strategies/createStrategies.ts
|
|
757
|
+
function createStrategies(intermediateTokensCache) {
|
|
758
|
+
return {
|
|
759
|
+
singleQuoteStrategy: new SingleQuoteStrategy(intermediateTokensCache),
|
|
760
|
+
multiQuoteStrategy: new MultiQuoteStrategy(intermediateTokensCache),
|
|
761
|
+
bestQuoteStrategy: new BestQuoteStrategy(intermediateTokensCache)
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
|
|
697
765
|
// src/BridgingSdk/BridgingSdk.ts
|
|
698
|
-
var
|
|
699
|
-
|
|
700
|
-
|
|
766
|
+
var DEFAULT_CACHE_CONFIG = {
|
|
767
|
+
enabled: true,
|
|
768
|
+
intermediateTokensTtl: 5 * 60 * 1e3,
|
|
769
|
+
// 5 minutes
|
|
770
|
+
buyTokensTtl: 2 * 60 * 1e3
|
|
771
|
+
// 2 minutes
|
|
772
|
+
};
|
|
701
773
|
var BridgingSdk = class {
|
|
702
774
|
constructor(options, adapter) {
|
|
703
775
|
this.options = options;
|
|
704
776
|
if (adapter) {
|
|
705
777
|
setGlobalAdapter(adapter);
|
|
706
778
|
}
|
|
707
|
-
const { providers, ...restOptions } = options;
|
|
779
|
+
const { providers, cacheConfig, ...restOptions } = options;
|
|
708
780
|
if (!providers || providers.length === 0) {
|
|
709
781
|
throw new Error("At least one bridge provider is required");
|
|
710
782
|
}
|
|
@@ -719,8 +791,31 @@ var BridgingSdk = class {
|
|
|
719
791
|
tradingSdk,
|
|
720
792
|
orderBookApi
|
|
721
793
|
};
|
|
794
|
+
this.cacheConfig = { ...DEFAULT_CACHE_CONFIG, ...cacheConfig };
|
|
795
|
+
this.intermediateTokensCache = new TTLCache2(
|
|
796
|
+
"bridging-intermediate-tokens",
|
|
797
|
+
this.cacheConfig.enabled,
|
|
798
|
+
this.cacheConfig.intermediateTokensTtl
|
|
799
|
+
);
|
|
800
|
+
this.buyTokensCache = new TTLCache2(
|
|
801
|
+
"bridging-buy-tokens",
|
|
802
|
+
this.cacheConfig.enabled,
|
|
803
|
+
this.cacheConfig.buyTokensTtl
|
|
804
|
+
);
|
|
805
|
+
const { singleQuoteStrategy, multiQuoteStrategy, bestQuoteStrategy } = createStrategies(
|
|
806
|
+
this.cacheConfig.enabled ? this.intermediateTokensCache : void 0
|
|
807
|
+
);
|
|
808
|
+
this.singleQuoteStrategy = singleQuoteStrategy;
|
|
809
|
+
this.multiQuoteStrategy = multiQuoteStrategy;
|
|
810
|
+
this.bestQuoteStrategy = bestQuoteStrategy;
|
|
722
811
|
}
|
|
723
812
|
config;
|
|
813
|
+
cacheConfig;
|
|
814
|
+
intermediateTokensCache;
|
|
815
|
+
buyTokensCache;
|
|
816
|
+
singleQuoteStrategy;
|
|
817
|
+
multiQuoteStrategy;
|
|
818
|
+
bestQuoteStrategy;
|
|
724
819
|
get provider() {
|
|
725
820
|
const { providers } = this.config;
|
|
726
821
|
if (!providers[0]) {
|
|
@@ -752,7 +847,22 @@ var BridgingSdk = class {
|
|
|
752
847
|
* @param params
|
|
753
848
|
*/
|
|
754
849
|
async getBuyTokens(params) {
|
|
755
|
-
|
|
850
|
+
const providerId = this.provider.info.dappId;
|
|
851
|
+
const cacheKey = getCacheKey({
|
|
852
|
+
id: providerId,
|
|
853
|
+
buyChainId: params.buyChainId.toString(),
|
|
854
|
+
sellChainId: params.sellChainId?.toString(),
|
|
855
|
+
tokenAddress: params.sellTokenAddress
|
|
856
|
+
});
|
|
857
|
+
const cached = this.cacheConfig.enabled && this.buyTokensCache.get(cacheKey);
|
|
858
|
+
if (cached) {
|
|
859
|
+
return cached;
|
|
860
|
+
}
|
|
861
|
+
const result = await this.provider.getBuyTokens(params);
|
|
862
|
+
if (this.cacheConfig.enabled) {
|
|
863
|
+
this.buyTokensCache.set(cacheKey, result);
|
|
864
|
+
}
|
|
865
|
+
return result;
|
|
756
866
|
}
|
|
757
867
|
/**
|
|
758
868
|
* Get quote details, including a callback function to post the order on-chain.
|
|
@@ -770,11 +880,13 @@ var BridgingSdk = class {
|
|
|
770
880
|
* @throws Error if no path is found
|
|
771
881
|
*/
|
|
772
882
|
async getQuote(quoteBridgeRequest, advancedSettings) {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
883
|
+
return this.singleQuoteStrategy.execute(
|
|
884
|
+
{
|
|
885
|
+
quoteBridgeRequest,
|
|
886
|
+
advancedSettings
|
|
887
|
+
},
|
|
888
|
+
this.config
|
|
889
|
+
);
|
|
778
890
|
}
|
|
779
891
|
/**
|
|
780
892
|
* Get quotes from multiple bridge providers in parallel with progressive results.
|
|
@@ -792,7 +904,7 @@ var BridgingSdk = class {
|
|
|
792
904
|
* ```
|
|
793
905
|
*/
|
|
794
906
|
async getMultiQuotes(request) {
|
|
795
|
-
return multiQuoteStrategy.execute(request, this.config);
|
|
907
|
+
return this.multiQuoteStrategy.execute(request, this.config);
|
|
796
908
|
}
|
|
797
909
|
/**
|
|
798
910
|
* Get the best quote from multiple bridge providers with progressive updates.
|
|
@@ -810,7 +922,7 @@ var BridgingSdk = class {
|
|
|
810
922
|
* @throws Error if the request is for a single-chain swap (sellTokenChainId === buyTokenChainId)
|
|
811
923
|
*/
|
|
812
924
|
async getBestQuote(request) {
|
|
813
|
-
return bestQuoteStrategy.execute(request, this.config);
|
|
925
|
+
return this.bestQuoteStrategy.execute(request, this.config);
|
|
814
926
|
}
|
|
815
927
|
async getOrder(params) {
|
|
816
928
|
const { orderBookApi } = this.config;
|
|
@@ -829,6 +941,29 @@ var BridgingSdk = class {
|
|
|
829
941
|
getProviderFromAppData(fullAppData) {
|
|
830
942
|
return findBridgeProviderFromHook(fullAppData, this.getProviders());
|
|
831
943
|
}
|
|
944
|
+
/**
|
|
945
|
+
* Clear all caches. Useful for testing and debugging.
|
|
946
|
+
*/
|
|
947
|
+
clearCache() {
|
|
948
|
+
this.intermediateTokensCache.clear();
|
|
949
|
+
this.buyTokensCache.clear();
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Clean up expired cache entries. Useful for maintenance.
|
|
953
|
+
*/
|
|
954
|
+
cleanupExpiredCache() {
|
|
955
|
+
this.intermediateTokensCache.cleanup();
|
|
956
|
+
this.buyTokensCache.cleanup();
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Get cache statistics for debugging.
|
|
960
|
+
*/
|
|
961
|
+
getCacheStats() {
|
|
962
|
+
return {
|
|
963
|
+
intermediateTokens: this.intermediateTokensCache.size(),
|
|
964
|
+
buyTokens: this.buyTokensCache.size()
|
|
965
|
+
};
|
|
966
|
+
}
|
|
832
967
|
getProviderByDappId(dappId) {
|
|
833
968
|
return this.config.providers.find((provider) => provider.info.dappId === dappId);
|
|
834
969
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cowprotocol/sdk-bridging",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Bridging for CoW Protocol",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@cowprotocol/sdk-
|
|
18
|
-
"@cowprotocol/sdk-
|
|
17
|
+
"@cowprotocol/sdk-common": "0.2.0",
|
|
18
|
+
"@cowprotocol/sdk-app-data": "4.0.1",
|
|
19
19
|
"@cowprotocol/sdk-config": "0.1.0",
|
|
20
|
-
"@cowprotocol/sdk-
|
|
21
|
-
"@cowprotocol/sdk-
|
|
22
|
-
"@cowprotocol/sdk-
|
|
23
|
-
"@cowprotocol/sdk-
|
|
24
|
-
"@cowprotocol/sdk-weiroll": "0.1.
|
|
20
|
+
"@cowprotocol/sdk-order-book": "0.1.1",
|
|
21
|
+
"@cowprotocol/sdk-contracts-ts": "0.3.0",
|
|
22
|
+
"@cowprotocol/sdk-trading": "0.2.1",
|
|
23
|
+
"@cowprotocol/sdk-cow-shed": "0.1.4",
|
|
24
|
+
"@cowprotocol/sdk-weiroll": "0.1.1"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"ethers-v5": "npm:ethers@^5.7.2",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"ts-jest": "^29.0.0",
|
|
37
37
|
"ethers": "^5.7.2",
|
|
38
38
|
"viem": "^2.28.4",
|
|
39
|
+
"@cowprotocol/sdk-order-signing": "0.1.4",
|
|
39
40
|
"@cow-sdk/typescript-config": "0.0.0-beta.0",
|
|
40
|
-
"@cowprotocol/sdk-
|
|
41
|
-
"@cowprotocol/sdk-ethers-v6-adapter": "0.1.
|
|
42
|
-
"@cowprotocol/sdk-viem-adapter": "0.1.
|
|
43
|
-
"@cowprotocol/sdk-ethers-v5-adapter": "0.1.0"
|
|
41
|
+
"@cowprotocol/sdk-ethers-v5-adapter": "0.1.1",
|
|
42
|
+
"@cowprotocol/sdk-ethers-v6-adapter": "0.1.1",
|
|
43
|
+
"@cowprotocol/sdk-viem-adapter": "0.1.1"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|