UNPKG

@xspswap/smart-order-router

Version:
209 lines 19.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StaticV3UniSubgraphProvider = exports.Uni_V3_XDC_ADDITIONAL_BASES = exports.ADDITIONAL_BASES = void 0; /* eslint-disable @typescript-eslint/no-non-null-assertion */ const sdk_core_1 = require("@x-swap-protocol/sdk-core"); const v3_sdk_1 = require("@x-swap-protocol/v3-sdk"); const jsbi_1 = __importDefault(require("jsbi")); const lodash_1 = __importDefault(require("lodash")); const amounts_1 = require("../../util/amounts"); const log_1 = require("../../util/log"); const token_provider_1 = require("../token-provider"); const BASES_TO_CHECK_TRADES_AGAINST = { [sdk_core_1.ChainId.XDC]: [sdk_core_1.WETH9[sdk_core_1.ChainId.XDC], token_provider_1.USDC_XDC], [sdk_core_1.ChainId.APOTHEM]: [sdk_core_1.WETH9[sdk_core_1.ChainId.APOTHEM]], }; exports.ADDITIONAL_BASES = { [sdk_core_1.ChainId.XDC]: { [sdk_core_1.WETH9[sdk_core_1.ChainId.XDC].address]: [ [token_provider_1.USDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.GAMA_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.stgUSDT_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.SRX_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.CGO_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.BBB_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.SRX_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.USDC_XDC.address]: [ [token_provider_1.CGO_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.SRX_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.stgUSDT_XDC, v3_sdk_1.FeeAmount.LOW], ], [token_provider_1.GAMA_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.USDC_XDC, v3_sdk_1.FeeAmount.LOWEST], ], [token_provider_1.stgUSDT_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.USDC_XDC, v3_sdk_1.FeeAmount.LOW], ], [token_provider_1.CGO_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.USDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], ], [token_provider_1.BBB_XDC.address]: [[token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM]], [token_provider_1.SRX_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.USDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.HIGH], ], }, [sdk_core_1.ChainId.APOTHEM]: {}, }; exports.Uni_V3_XDC_ADDITIONAL_BASES = exports.ADDITIONAL_BASES[sdk_core_1.ChainId.XDC]; let paths = []; const recFinder = (path, used, lastToken, dest, hops) => { const hop = path.length; // if (hop > 0) { // lastToken = path[hop - 1]![1]; // } if (hop < hops) { if (!lastToken) { return; } const additional = exports.Uni_V3_XDC_ADDITIONAL_BASES[lastToken.address]; if (additional) { for (const ad of additional) { const adToken = ad; const newPair = [lastToken, ...adToken]; const newPath = [...path, newPair]; if (adToken[0].address === dest.address) { paths.push(newPath); continue; } if (!used[adToken[0].address]) { recFinder(newPath, Object.assign(Object.assign({}, used), { [adToken[0].address]: true }), adToken[0], dest, hops); } } } } }; /** * Provider that uses a hardcoded list of V3 pools to generate a list of subgraph pools. * * Since the pools are hardcoded and the data does not come from the Subgraph, the TVL values * are dummys and should not be depended on. * * Useful for instances where other data sources are unavailable. E.g. Subgraph not available. * * @export * @class StaticV3SubgraphProvider */ class StaticV3UniSubgraphProvider { constructor(chainId, poolProvider) { this.chainId = chainId; this.poolProvider = poolProvider; } async getPools(tokenIn, tokenOut) { paths = []; log_1.log.info('In static subgraph provider for V3'); const bases = BASES_TO_CHECK_TRADES_AGAINST[this.chainId]; const basePairs = lodash_1.default.flatMap(bases, (base) => bases.map((otherBase) => [base, otherBase])); let pairs = []; if (tokenIn && tokenOut) { const additionalIn = exports.ADDITIONAL_BASES[this.chainId][tokenIn.address]; const additionalOut = exports.ADDITIONAL_BASES[this.chainId][tokenOut.address]; if (!additionalIn || !additionalOut) { basePairs.push([tokenIn, tokenOut]); if (additionalIn) { basePairs.push(...additionalIn.map((v) => [tokenIn, v[0]])); } else { basePairs.push(...bases.map((base) => [tokenIn, base])); } if (additionalOut) { basePairs.push(...additionalOut.map((v) => [tokenOut, v[0]])); } else { basePairs.push(...bases.map((base) => [tokenOut, base])); } pairs = (0, lodash_1.default)(basePairs) .filter((tokens) => Boolean(tokens[0] && tokens[1])) .filter(([tokenA, tokenB]) => tokenA.address !== tokenB.address && !tokenA.equals(tokenB)) .flatMap(([tokenA, tokenB]) => { const additionalA = exports.ADDITIONAL_BASES[this.chainId][tokenA.address]; // const additionalB = ADDITIONAL_BASES[this.chainId][tokenB.address]; if (additionalA) { const additionalPool = additionalA.filter((v) => v[0].address.toLowerCase() === tokenB.address.toLowerCase()); const res = additionalPool.map((v) => { return [tokenA, v[0], v[1]]; }); return res; } return [ [tokenA, tokenB, v3_sdk_1.FeeAmount.LOWEST], [tokenA, tokenB, v3_sdk_1.FeeAmount.LOW], [tokenA, tokenB, v3_sdk_1.FeeAmount.MEDIUM], [tokenA, tokenB, v3_sdk_1.FeeAmount.HIGH], ]; }) .value(); } else { recFinder([], { [tokenIn.address]: true }, tokenIn, tokenOut, 5); // console.log( // paths.map((path) => // path // .map( // (p) => `(${p[0].symbol} - ${p[1].symbol} : ${p[2] / 10000}% )` // ) // .join(' --> ') // ) // ); const uniquePairs = {}; paths.forEach((path) => { path.forEach((pool) => { const id = `${pool[0].address}-${pool[1].address}-${pool[2]}`; uniquePairs[id] = pool; }); }); const direct = tokenIn && tokenOut ? [ [tokenIn, tokenOut, v3_sdk_1.FeeAmount.LOWEST], [tokenIn, tokenOut, v3_sdk_1.FeeAmount.LOW], [tokenIn, tokenOut, v3_sdk_1.FeeAmount.MEDIUM], [tokenIn, tokenOut, v3_sdk_1.FeeAmount.HIGH], ] : []; pairs = [...Object.values(uniquePairs), ...direct]; } } log_1.log.info(`V3-UNI Static subgraph provider about to get ${pairs.length} pools on-chain`); const poolAccessor = await this.poolProvider.getPools(pairs); const pools = poolAccessor.getAllPools(); const poolAddressSet = new Set(); const subgraphPools = (0, lodash_1.default)(pools) .map((pool) => { const { token0, token1, fee, liquidity } = pool; const poolAddress = v3_sdk_1.Pool.getAddress(pool.token0, pool.token1, pool.fee, v3_sdk_1.UniV3Factory); if (poolAddressSet.has(poolAddress)) { return undefined; } poolAddressSet.add(poolAddress); const liquidityNumber = jsbi_1.default.toNumber(liquidity); return { id: poolAddress, feeTier: (0, amounts_1.unparseFeeAmount)(fee), liquidity: liquidity.toString(), token0: { id: token0.address, }, token1: { id: token1.address, }, // As a very rough proxy we just use liquidity for TVL. tvlETH: liquidityNumber, tvlUSD: liquidityNumber, }; }) .compact() .value(); return subgraphPools; } } exports.StaticV3UniSubgraphProvider = StaticV3UniSubgraphProvider; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLXN1YmdyYXBoLXByb3ZpZGVyLXYzLXVuaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvdjMvc3RhdGljLXN1YmdyYXBoLXByb3ZpZGVyLXYzLXVuaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSw2REFBNkQ7QUFDN0Qsd0RBQWtFO0FBQ2xFLG9EQUF3RTtBQUN4RSxnREFBd0I7QUFDeEIsb0RBQXVCO0FBRXZCLGdEQUFzRDtBQUN0RCx3Q0FBcUM7QUFDckMsc0RBUTJCO0FBUzNCLE1BQU0sNkJBQTZCLEdBQW1CO0lBQ3BELENBQUMsa0JBQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLGdCQUFLLENBQUMsa0JBQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSx5QkFBUSxDQUFDO0lBQzdDLENBQUMsa0JBQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLGdCQUFLLENBQUMsa0JBQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztDQUM1QyxDQUFDO0FBRVcsUUFBQSxnQkFBZ0IsR0FFekI7SUFDRixDQUFDLGtCQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDYixDQUFDLGdCQUFLLENBQUMsa0JBQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUM1QixDQUFDLHlCQUFRLEVBQUUsa0JBQVMsQ0FBQyxNQUFNLENBQUM7WUFDNUIsQ0FBQyx5QkFBUSxFQUFFLGtCQUFTLENBQUMsTUFBTSxDQUFDO1lBQzVCLENBQUMsNEJBQVcsRUFBRSxrQkFBUyxDQUFDLE1BQU0sQ0FBQztZQUMvQixDQUFDLHdCQUFPLEVBQUUsa0JBQVMsQ0FBQyxNQUFNLENBQUM7WUFDM0IsQ0FBQyx3QkFBTyxFQUFFLGtCQUFTLENBQUMsTUFBTSxDQUFDO1lBQzNCLENBQUMsd0JBQU8sRUFBRSxrQkFBUyxDQUFDLE1BQU0sQ0FBQztZQUMzQixDQUFDLHdCQUFPLEVBQUUsa0JBQVMsQ0FBQyxJ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