UNPKG

@xspswap/smart-order-router

Version:
284 lines 27.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StaticV3SubgraphProvider = exports.V3_XDC_ADDITIONAL_BASES = exports.ADDITIONAL_BASES = void 0; 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 chains_1 = require("../../util/chains"); const log_1 = require("../../util/log"); const token_provider_1 = require("../token-provider"); const BASES_TO_CHECK_TRADES_AGAINST = { [chains_1.ChainId.XDC]: [chains_1.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.XDC], token_provider_1.USDC_XDC], [chains_1.ChainId.XDC_APOTHEM]: [ chains_1.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.XDC_APOTHEM], token_provider_1.USDT_XDC_APOTHEM, token_provider_1.WBTC_XDC_APOTHEM, ], }; exports.ADDITIONAL_BASES = { [chains_1.ChainId.XDC]: { [chains_1.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.XDC].address]: [ [token_provider_1.USDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.pstXDC_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.GAMA_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.GAMA_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.BBB_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.DOPU_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.BTCx_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.PLI_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.CHUPAV2_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.CIFI_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.WTK_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.LBT_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.XSP_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.EURS_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.USDT_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.SRX_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.PWM3_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.PRNT_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.XZO_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.BIC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.FTHM_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.XTT_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.REFI_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.FXD_XDC.address]: [ [token_provider_1.USDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.EURS_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.USDT_XDC, v3_sdk_1.FeeAmount.LOW], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.SRX_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.CGO_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.EURS_XDC, v3_sdk_1.FeeAmount.LOW], [token_provider_1.CGO_XDC, v3_sdk_1.FeeAmount.LOW], ], [token_provider_1.USDC_XDC.address]: [ [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], ], [token_provider_1.EURS_XDC.address]: [ [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.SRX_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.LOW], ], [token_provider_1.USDT_XDC.address]: [ [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.LOW], [token_provider_1.SRX_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], ], [token_provider_1.DOPU_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.BBB_XDC, v3_sdk_1.FeeAmount.MEDIUM], ], [token_provider_1.SRX_XDC.address]: [ [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.USDT_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.EURS_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.PLI_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.PLI_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.CIFI_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.CIFI_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.PLI_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.REFI_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.CHUPAV2_XDC.address]: [[token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.HIGH]], [token_provider_1.XSP_XDC.address]: [ [token_provider_1.XTT_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.BIC_XDC, v3_sdk_1.FeeAmount.MEDIUM], ], [token_provider_1.CGO_XDC.address]: [ [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.LOWEST], [token_provider_1.FXD_XDC, v3_sdk_1.FeeAmount.LOW], ], [token_provider_1.WTK_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.PLI_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.XTT_XDC.address]: [ [token_provider_1.XSP_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], ], [token_provider_1.LBT_XDC.address]: [[token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM]], [token_provider_1.BIC_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.USDT_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.PRNT_XDC.address]: [ [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.HIGH], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM], ], [token_provider_1.BBB_XDC.address]: [ [token_provider_1.DOPU_XDC, v3_sdk_1.FeeAmount.MEDIUM], [token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.HIGH], ], [token_provider_1.FTHM_XDC.address]: [[token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM]], [token_provider_1.XZO_XDC.address]: [[token_provider_1.WXDC_XDC, v3_sdk_1.FeeAmount.MEDIUM]], }, [chains_1.ChainId.XDC_APOTHEM]: {}, }; exports.V3_XDC_ADDITIONAL_BASES = exports.ADDITIONAL_BASES[chains_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.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 StaticV3SubgraphProvider { 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 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); 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.StaticV3SubgraphProvider = StaticV3SubgraphProvider; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLXN1YmdyYXBoLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy92My9zdGF0aWMtc3ViZ3JhcGgtcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUEsb0RBQTBEO0FBQzFELGdEQUF3QjtBQUN4QixvREFBdUI7QUFFdkIsZ0RBQXNEO0FBQ3RELDhDQUFxRTtBQUNyRSx3Q0FBcUM7QUFDckMsc0RBNEIyQjtBQVMzQixNQUFNLDZCQUE2QixHQUFtQjtJQUNwRCxDQUFDLGdCQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxnQ0FBdUIsQ0FBQyxnQkFBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLHlCQUFRLENBQUM7SUFDL0QsQ0FBQyxnQkFBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFO1FBQ3JCLGdDQUF1QixDQUFDLGdCQUFPLENBQUMsV0FBVyxDQUFDO1FBQzVDLGlDQUFnQjtRQUNoQixpQ0FBZ0I7S0FDakI7Q0FDRixDQUFDO0FBRVcsUUFBQSxnQkFBZ0IsR0FFekI7SUFDRixDQUFDLGdCQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDYixDQUFDLGdDQUF1QixDQUFDLGdCQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDOUMsQ0FBQyx5QkFBUSxFQUFFLGtCQUFTLENBQUMsTUFBTSxDQUFDO1lBQzVCLENBQUMsMkJBQVUsRUFBRSxrQkFBUyxDQUFDLElBQUksQ0FBQztZQUM1QixDQUFDLHlCQUFRLEVBQUUsa0JBQVMsQ0FBQyxNQUFNLENBQUM7WUFDNUIsQ0FBQyx5QkFBUSxFQUFFLGtCQUFTLENBQUMsTUFBTSxDQUFDO1lBQzVCLENBQUMsd0JBQU8sRUFBRSxrQkFBUyxDQUFDLE1BQU0sQ0FBQztZQUMzQixDQUFDLHlCQUFRLEVBQUUsa0JBQVMsQ0FBQyxNQUFNLENBQUM7WUFDNUIsQ0FBQyx5QkFBUSxFQUFFLGtCQUFTLENB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