@xspswap/smart-order-router
Version:
XSwap Protocol V3 Smart Order Router
83 lines • 7.81 kB
JavaScript
import _ from 'lodash';
import { log } from '../../util/log';
/**
* Provider for getting V2 pools, with functionality for caching the results per block.
*
* @export
* @class CachingV2PoolProvider
*/
export class CachingV2PoolProvider {
/**
* Creates an instance of CachingV3PoolProvider.
* @param protocol Protocol V2 or FATHOM
* @param chainId The chain id to use.
* @param poolProvider The provider to use to get the pools when not in the cache.
* @param cache Cache instance to hold cached pools.
*/
constructor(protocol, chainId, poolProvider,
// Cache is block aware. For V2 pools we need to use the current blocks reserves values since
// we compute quotes off-chain.
// If no block is specified in the call to getPools we just return whatever is in the cache.
cache) {
this.protocol = protocol;
this.chainId = chainId;
this.poolProvider = poolProvider;
this.cache = cache;
this.POOL_KEY = (chainId, address) => `pool-${this.protocol}-${chainId}-${address}`;
}
async getPools(tokenPairs, providerConfig) {
const poolAddressSet = new Set();
const poolsToGetTokenPairs = [];
const poolsToGetAddresses = [];
const poolAddressToPool = {};
const blockNumber = await (providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.blockNumber);
for (const [tokenA, tokenB] of tokenPairs) {
const { poolAddress, token0, token1 } = this.getPoolAddress(tokenA, tokenB);
if (poolAddressSet.has(poolAddress)) {
continue;
}
poolAddressSet.add(poolAddress);
const cachedPool = await this.cache.get(this.POOL_KEY(this.chainId, poolAddress));
if (cachedPool) {
// If a block was specified by the caller, ensure that the result in our cache matches the
// expected block number. If a block number is not specified, just return whatever is in the
// cache.
if (!blockNumber || (blockNumber && cachedPool.block == blockNumber)) {
poolAddressToPool[poolAddress] = cachedPool.pair;
continue;
}
}
poolsToGetTokenPairs.push([token0, token1]);
poolsToGetAddresses.push(poolAddress);
}
log.info({
poolsFound: _.map(Object.values(poolAddressToPool), (p) => p.token0.symbol + ' ' + p.token1.symbol),
poolsToGetTokenPairs: _.map(poolsToGetTokenPairs, (t) => t[0].symbol + ' ' + t[1].symbol),
}, `Found ${Object.keys(poolAddressToPool).length} V2 pools already in local cache for block ${blockNumber}. About to get reserves for ${poolsToGetTokenPairs.length} pools.`);
if (poolsToGetAddresses.length > 0) {
const poolAccessor = await this.poolProvider.getPools(poolsToGetTokenPairs, providerConfig);
for (const address of poolsToGetAddresses) {
const pool = poolAccessor.getPoolByAddress(address);
if (pool) {
poolAddressToPool[address] = pool;
await this.cache.set(this.POOL_KEY(this.chainId, address), {
pair: pool,
block: blockNumber,
});
}
}
}
return {
getPool: (tokenA, tokenB) => {
const { poolAddress } = this.getPoolAddress(tokenA, tokenB);
return poolAddressToPool[poolAddress];
},
getPoolByAddress: (address) => poolAddressToPool[address],
getAllPools: () => Object.values(poolAddressToPool),
};
}
getPoolAddress(tokenA, tokenB) {
return this.poolProvider.getPoolAddress(tokenA, tokenB);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGluZy1wb29sLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy92Mi9jYWNoaW5nLXBvb2wtcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQU1yQzs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxxQkFBcUI7SUFJaEM7Ozs7OztPQU1HO0lBQ0gsWUFDWSxRQUFrQixFQUNsQixPQUFnQixFQUNoQixZQUE2QjtJQUN2Qyw2RkFBNkY7SUFDN0YsK0JBQStCO0lBQy9CLDRGQUE0RjtJQUNwRixLQUE2QztRQU4zQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xCLFlBQU8sR0FBUCxPQUFPLENBQVM7UUFDaEIsaUJBQVksR0FBWixZQUFZLENBQWlCO1FBSS9CLFVBQUssR0FBTCxLQUFLLENBQXdDO1FBakIvQyxhQUFRLEdBQUcsQ0FBQyxPQUFnQixFQUFFLE9BQWUsRUFBRSxFQUFFLENBQ3ZELFFBQVEsSUFBSSxDQUFDLFFBQVEsSUFBSSxPQUFPLElBQUksT0FBTyxFQUFFLENBQUM7SUFpQjdDLENBQUM7SUFFRyxLQUFLLENBQUMsUUFBUSxDQUNuQixVQUE0QixFQUM1QixjQUErQjtRQUUvQixNQUFNLGNBQWMsR0FBZ0IsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUN0RCxNQUFNLG9CQUFvQixHQUEwQixFQUFFLENBQUM7UUFDdkQsTUFBTSxtQkFBbUIsR0FBYSxFQUFFLENBQUM7UUFDekMsTUFBTSxpQkFBaUIsR0FBb0MsRUFBRSxDQUFDO1FBRTlELE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQSxjQUFjLGFBQWQsY0FBYyx1QkFBZCxjQUFjLENBQUUsV0FBVyxDQUFBLENBQUM7UUFFdEQsS0FBSyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJ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