UNPKG

@maxosllc/smart-order-router

Version:
215 lines 17.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.StaticV3SubgraphProvider = void 0; /* eslint-disable @typescript-eslint/no-non-null-assertion */ const chains_1 = require("../../../src/util/chains"); const v3_sdk_1 = require("@uniswap/v3-sdk"); const jsbi_1 = __importDefault(require("jsbi")); const lodash_1 = __importDefault(require("lodash")); const amounts_1 = require("../../util/amounts"); const chains_2 = 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.MAINNET]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.MAINNET], token_provider_1.DAI_MAINNET, token_provider_1.USDC_MAINNET, token_provider_1.USDT_MAINNET, token_provider_1.WBTC_MAINNET, token_provider_1.WSTETH_MAINNET, ], [chains_1.ChainId.GOERLI]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.GOERLI], token_provider_1.USDT_GOERLI, token_provider_1.USDC_GOERLI, token_provider_1.WBTC_GOERLI, token_provider_1.DAI_GOERLI, ], [chains_1.ChainId.SEPOLIA]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.SEPOLIA], token_provider_1.USDC_SEPOLIA], [chains_1.ChainId.OPTIMISM]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.OPTIMISM], token_provider_1.USDC_OPTIMISM, token_provider_1.DAI_OPTIMISM, token_provider_1.USDT_OPTIMISM, token_provider_1.WBTC_OPTIMISM, token_provider_1.OP_OPTIMISM, ], // todo: once subgraph is created [chains_1.ChainId.OPTIMISM_SEPOLIA]: [ // WRAPPED_NATIVE_CURRENCY[ChainId.OPTIMISM_SEPOLIA]!, ], [chains_1.ChainId.ARBITRUM_ONE]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.ARBITRUM_ONE], token_provider_1.WBTC_ARBITRUM, token_provider_1.DAI_ARBITRUM, token_provider_1.USDC_ARBITRUM, token_provider_1.USDT_ARBITRUM, token_provider_1.ARB_ARBITRUM, ], [chains_1.ChainId.ARBITRUM_GOERLI]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.ARBITRUM_GOERLI], token_provider_1.USDC_ARBITRUM_GOERLI, ], [chains_1.ChainId.ARBITRUM_SEPOLIA]: [ // WRAPPED_NATIVE_CURRENCY[ChainId.ARBITRUM_SEPOLIA]!, ], [chains_1.ChainId.OPTIMISM_GOERLI]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.OPTIMISM_GOERLI], token_provider_1.USDC_OPTIMISM_GOERLI, token_provider_1.DAI_OPTIMISM_GOERLI, token_provider_1.USDT_OPTIMISM_GOERLI, token_provider_1.WBTC_OPTIMISM_GOERLI, ], [chains_1.ChainId.POLYGON]: [token_provider_1.USDC_POLYGON, token_provider_1.WETH_POLYGON, token_provider_1.WMATIC_POLYGON], [chains_1.ChainId.POLYGON_MUMBAI]: [ token_provider_1.DAI_POLYGON_MUMBAI, chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.POLYGON_MUMBAI], token_provider_1.WMATIC_POLYGON_MUMBAI, ], [chains_1.ChainId.CELO]: [token_provider_1.CELO, token_provider_1.CUSD_CELO, token_provider_1.CEUR_CELO, token_provider_1.DAI_CELO], [chains_1.ChainId.CELO_ALFAJORES]: [ token_provider_1.CELO_ALFAJORES, token_provider_1.CUSD_CELO_ALFAJORES, token_provider_1.CEUR_CELO_ALFAJORES, token_provider_1.DAI_CELO_ALFAJORES, ], [chains_1.ChainId.GNOSIS]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.GNOSIS], token_provider_1.WBTC_GNOSIS, token_provider_1.WXDAI_GNOSIS, token_provider_1.USDC_ETHEREUM_GNOSIS, ], [chains_1.ChainId.BNB]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.BNB], token_provider_1.BUSD_BNB, token_provider_1.DAI_BNB, token_provider_1.USDC_BNB, token_provider_1.USDT_BNB, token_provider_1.BTC_BNB, token_provider_1.ETH_BNB, ], [chains_1.ChainId.AVALANCHE]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.AVALANCHE], token_provider_1.USDC_AVAX, token_provider_1.DAI_AVAX, ], [chains_1.ChainId.MOONBEAM]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.MOONBEAM], token_provider_1.DAI_MOONBEAM, token_provider_1.USDC_MOONBEAM, token_provider_1.WBTC_MOONBEAM, ], [chains_1.ChainId.BASE_GOERLI]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.BASE_GOERLI]], [chains_1.ChainId.BASE]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.BASE], token_provider_1.USDC_BASE], [chains_1.ChainId.ZORA]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.ZORA]], [chains_1.ChainId.ZORA_SEPOLIA]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.ZORA_SEPOLIA]], [chains_1.ChainId.ROOTSTOCK]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.ROOTSTOCK]], [chains_1.ChainId.BLAST]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.BLAST], token_provider_1.USDB_BLAST], [chains_1.ChainId.ZKSYNC]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.ZKSYNC], token_provider_1.USDCE_ZKSYNC, token_provider_1.USDC_ZKSYNC, ], [chains_1.ChainId.WORLDCHAIN]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.WORLDCHAIN], token_provider_1.USDC_WORLDCHAIN, token_provider_1.WLD_WORLDCHAIN, token_provider_1.WBTC_WORLDCHAIN, ], [chains_1.ChainId.UNICHAIN_SEPOLIA]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.UNICHAIN_SEPOLIA], token_provider_1.USDC_UNICHAIN_SEPOLIA, ], [chains_1.ChainId.UNICHAIN]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.UNICHAIN], token_provider_1.DAI_UNICHAIN, token_provider_1.USDC_UNICHAIN, ], [chains_1.ChainId.MONAD_TESTNET]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.MONAD_TESTNET], token_provider_1.USDT_MONAD_TESTNET, ], [chains_1.ChainId.BASE_SEPOLIA]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.BASE_SEPOLIA], token_provider_1.USDC_BASE_SEPOLIA, ], [chains_1.ChainId.SONEIUM]: [chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.SONEIUM], token_provider_1.USDC_SONEIUM], [chains_1.ChainId.BLOCKDAG_TESTNET]: [ chains_2.WRAPPED_NATIVE_CURRENCY[chains_1.ChainId.BLOCKDAG_TESTNET], token_provider_1.USDT_BLOCKDAG_TESTNET, ], }; /** * 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, providerConfig) { 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])); if (tokenIn && tokenOut) { basePairs.push([tokenIn, tokenOut], ...bases.map((base) => [tokenIn, base]), ...bases.map((base) => [tokenOut, base])); } const 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]) => { 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(); log_1.log.info(`V3 Static subgraph provider about to get ${pairs.length} pools on-chain`); const poolAccessor = await this.poolProvider.getPools(pairs, providerConfig); 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLXN1YmdyYXBoLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy92My9zdGF0aWMtc3ViZ3JhcGgtcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsNkRBQTZEO0FBQzdELHFEQUFtRDtBQUVuRCw0Q0FBa0Q7QUFDbEQsZ0RBQXdCO0FBQ3hCLG9EQUF1QjtBQUV2QixnREFBc0Q7QUFDdEQsOENBQTREO0FBQzVELHdDQUFxQztBQUVyQyxzREFtRTJCO0FBUzNCLE1BQU0sNkJBQTZCLEdBQW1CO0lBQ3BELENBQUMsZ0JBQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUNqQixnQ0FBdUIsQ0FBQyxnQkFBTyxDQUFDLE9BQU8sQ0FBRTtRQUN6Qyw0QkFBVztRQUNYLDZCQUFZO1FBQ1osNkJBQVk7UUFDWiw2QkFBWTtRQUNaLCtCQUFjO0tBQ2Y7SUFDRCxDQUFDLGdCQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDaEIsZ0NBQXVCLENBQUMsZ0JBQU8sQ0FBQyxNQUFNLENBQUU7UUFDeEMsNEJBQVc7UUFDWCw0QkFBVztRQUNYLDRCQUFXO1FBQ1gsMkJBQVU7S0FDWDtJQUNELENBQUMsZ0JBQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLGdDQUF1QixDQUFDLGdCQUFPLENBQUMsT0FBTyxDQUFFLEVBQUUsNkJBQVksQ0FBQztJQUM1RSxDQUFDLGdCQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDbEIsZ0NBQXVCLENBQUMsZ0JBQU8sQ0FBQyxRQUFRLENBQUU7UUFDMUMsOEJBQWE7UUFDYiw2QkFBWTtRQUNaLDhCQUFhO1FBQ2IsOEJBQWE7UUFDYiw0QkFBVztLQUNaO0lBQ0QsaUNBQWlDO0lBQ2pDLENBQUMsZ0JBQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO0lBQzFCLHdEQUF3RDtLQUN6RDtJQUNELENBQUMsZ0JBQU8sQ0FBQyxZQUFZLENBQUMsRUFB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