UNPKG

@maxosllc/smart-order-router

Version:
135 lines 15.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.SubgraphProvider = void 0; const router_sdk_1 = require("@uniswap/router-sdk"); const async_retry_1 = __importDefault(require("async-retry")); const await_timeout_1 = __importDefault(require("await-timeout")); const graphql_request_1 = require("graphql-request"); const lodash_1 = __importDefault(require("lodash")); const util_1 = require("../util"); const PAGE_SIZE = 1000; // 1k is max possible query size from subgraph. class SubgraphProvider { constructor(protocol, chainId, retries = 2, timeout = 30000, rollback = true, trackedEthThreshold = 0.01, untrackedUsdThreshold = Number.MAX_VALUE, subgraphUrl) { this.protocol = protocol; this.chainId = chainId; this.retries = retries; this.timeout = timeout; this.rollback = rollback; this.trackedEthThreshold = trackedEthThreshold; this.untrackedUsdThreshold = untrackedUsdThreshold; this.subgraphUrl = subgraphUrl; this.protocol = protocol; if (!this.subgraphUrl) { throw new Error(`No subgraph url for chain id: ${this.chainId}`); } this.client = new graphql_request_1.GraphQLClient(this.subgraphUrl); } async getPools(_currencyIn, _currencyOut, providerConfig) { const beforeAll = Date.now(); let blockNumber = (providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.blockNumber) ? await providerConfig.blockNumber : undefined; const query = (0, graphql_request_1.gql) ` ${this.subgraphQuery(blockNumber)} `; let pools = []; util_1.log.info(`Getting ${this.protocol} pools from the subgraph with page size ${PAGE_SIZE}${(providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.blockNumber) ? ` as of block ${providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.blockNumber}` : ''}.`); let retries = 0; await (0, async_retry_1.default)(async () => { const timeout = new await_timeout_1.default(); const getPools = async () => { let lastId = ''; let pools = []; let poolsPage = []; // metrics variables let totalPages = 0; do { totalPages += 1; const poolsResult = await this.client.request(query, { pageSize: PAGE_SIZE, id: lastId, }); poolsPage = poolsResult.pools; pools = pools.concat(poolsPage); lastId = pools[pools.length - 1].id; util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.paginate.pageSize`, poolsPage.length); } while (poolsPage.length > 0); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.paginate`, totalPages); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.pools.length`, pools.length); return pools; }; try { const getPoolsPromise = getPools(); const timerPromise = timeout.set(this.timeout).then(() => { throw new Error(`Timed out getting pools from subgraph: ${this.timeout}`); }); pools = await Promise.race([getPoolsPromise, timerPromise]); return; } catch (err) { util_1.log.error({ err }, `Error fetching ${this.protocol} Subgraph Pools.`); throw err; } finally { timeout.clear(); } }, { retries: this.retries, onRetry: (err, retry) => { retries += 1; if (this.rollback && blockNumber && lodash_1.default.includes(err.message, 'indexed up to')) { util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.indexError`, 1); blockNumber = blockNumber - 10; util_1.log.info(`Detected subgraph indexing error. Rolled back block number to: ${blockNumber}`); } util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.timeout`, 1); pools = []; util_1.log.info({ err }, `Failed to get pools from subgraph. Retry attempt: ${retry}`); }, }); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.retries`, retries); const untrackedPools = pools.filter((pool) => parseInt(pool.liquidity) > 0 || parseFloat(pool.totalValueLockedETH) > this.trackedEthThreshold || parseFloat(pool.totalValueLockedUSDUntracked) > this.untrackedUsdThreshold); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.untracked.length`, untrackedPools.length); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.untracked.percent`, (untrackedPools.length / pools.length) * 100); const beforeFilter = Date.now(); let poolsSanitized = []; if (this.protocol === router_sdk_1.Protocol.V3) { // Special treatment for all V3 pools in order to reduce latency due to thousands of pools with very low TVL locked // - Include "parseFloat(pool.totalValueLockedETH) === 0" as in certain occasions we have no way of calculating derivedETH so this is 0 poolsSanitized = pools .filter((pool) => (parseInt(pool.liquidity) > 0 && parseFloat(pool.totalValueLockedETH) === 0) || parseFloat(pool.totalValueLockedETH) > this.trackedEthThreshold) .map((pool) => { return this.mapSubgraphPool(pool); }); } else { poolsSanitized = pools .filter((pool) => parseInt(pool.liquidity) > 0 || parseFloat(pool.totalValueLockedETH) > this.trackedEthThreshold) .map((pool) => { return this.mapSubgraphPool(pool); }); } util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.filter.latency`, Date.now() - beforeFilter); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.filter.length`, poolsSanitized.length); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.filter.percent`, (poolsSanitized.length / pools.length) * 100); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools`, 1); util_1.metric.putMetric(`${this.protocol}SubgraphProvider.chain_${this.chainId}.getPools.latency`, Date.now() - beforeAll); util_1.log.info(`Got ${pools.length} ${this.protocol} pools from the subgraph. ${poolsSanitized.length} after filtering`); return poolsSanitized; } } exports.SubgraphProvider = SubgraphProvider; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ViZ3JhcGgtcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3N1YmdyYXBoLXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLG9EQUErQztBQUcvQyw4REFBZ0M7QUFDaEMsa0VBQW9DO0FBQ3BDLHFEQUFxRDtBQUNyRCxvREFBdUI7QUFHdkIsa0NBQXNDO0FBWXRDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFDLCtDQUErQztBQWlDdkUsTUFBc0IsZ0JBQWdCO0lBTXBDLFlBQ1UsUUFBa0IsRUFDbEIsT0FBZ0IsRUFDaEIsVUFBVSxDQUFDLEVBQ1gsVUFBVSxLQUFLLEVBQ2YsV0FBVyxJQUFJLEVBQ2Ysc0JBQXNCLElBQUksRUFDMUIsd0JBQXdCLE1BQU0sQ0FBQyxTQUFTLEVBQ3hDLFdBQW9CO1FBUHBCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUNoQixZQUFPLEdBQVAsT0FBTyxDQUFJO1FBQ1gsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQUNmLGFBQVEsR0FBUixRQUFRLENBQU87UUFDZix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQU87UUFDMUIsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUFtQjtRQUN4QyxnQkFBVyxHQUFYLFdBQVcsQ0FBUztRQUU1QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztTQUNsRTtRQUNELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSwrQkFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRU0sS0FBSyxDQUFDLFFBQVEsQ0FDbkIsV0FBc0IsRUFDdEIsWUFBdUIsRUFDdkIsY0FBK0I7UUFFL0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzdCLElBQUksV0FBVyxHQUFHLENBQUEsY0FBYyxhQUFkLGNBQWMsdUJBQWQsY0FBYyxDQUFFLFdBQVc7WUFDM0MsQ0FBQyxDQUFDLE1BQU0sY0FBYyxDQUFDLFdBQVc7WUFDbEMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUVkLE1BQU0sS0FBSyxHQUFHLElBQUEscUJBQUcsRUFBQTtRQUNiLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO0tBQ2xDLENBQUM7UUFFRixJQUFJLEtBQUssR0FBdUIsRUFBRSxDQUFDO1FBRW5DLFVBQUcsQ0FBQyxJQUFJLENBQ04sV0FBVyxJQUFJLENBQUMsUUFDaEIsMkNBQTJDLFNBQVMsR0FBRyxDQUFBLGNBQWMsYUFBZCxjQUFjLHVCQUFkLGNBQWMsQ0FBRSxXQUFXO1lBQ2hGLENBQUMsQ0FBQyxnQkFBZ0IsY0FBYyxhQUFkLGNBQWMsdUJBQWQsY0FBYyxDQUFFLFdBQVcsRUFBRTtZQUMvQyxDQUFDLENBQUMsRUFDSixHQUFHLENBQ0osQ0FBQztRQUVGLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztRQUVoQixNQUFNLElBQUEscUJBQUssRUFDVCxLQUFLLElBQUksRUFBRTtZQUNULE1BQU0sT0FBTyxHQUFHLElBQUksdUJBQU8sRUFBRSxDQUFDO1lBRTlCLE1BQU0sUUFBUSxHQUFHLEtBQUssSUFBaUMsRUFBRTtnQkFDdkQsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO2dCQUNoQixJQUFJLEtBQUssR0FBdUIsRUFBRSxDQUFDO2dCQUNuQyxJQUFJLFNBQVMsR0FBdUIsRUFBRSxDQUFDO2dCQUV2QyxvQkFBb0I7Z0JBQ3BCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztnQkFFbkIsR0FBRztvQkFDRCxVQUFVLElBQUksQ0FBQyxDQUFDO29CQUVoQixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUUxQyxLQUFLLEVBQUU7d0JBQ1IsUUFBUSxFQUFFLFNBQVM7d0JBQ25CLEVBQUUsRUFBRSxNQUFNO3FCQUNYLENBQUMsQ0FBQztvQkFFSCxTQUFTLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQztvQkFFOUIsS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBRWhDLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ3JDLGFBQU0sQ0FBQyxTQUFTLENBQ2QsR0FBRyxJQUFJLENBQUMsUUFBUSwwQkFBMEIsSUFBSSxDQUFDLE9BQU8sNkJBQTZCLEVBQ25GLFNBQVMsQ0FBQyxNQUFNLENBQ2pCLENBQUM7aUJBQ0gsUUFBUSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFFL0IsYUFBTSxDQUFDLFNBQVMsQ0FDZCxHQUFHLElBQUksQ0FBQyxRQUFRLDBCQUEwQixJQUFJLENBQUMsT0FBTyxvQkFBb0IsRUFDMUUsVUFBVSxDQUNYLENBQUM7Z0JBQ0YsYUFBTSxDQUFDLFNBQVMsQ0FDZCxHQUFHLElBQUksQ0FBQyxRQUFRLDBCQUEwQixJQUFJLENBQUMsT0FBTyx3QkFBd0IsRUFDOUUsS0FBSyxDQUFDLE1BQU0sQ0FDYixDQUFDO2dCQUVGLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQyxDQUFDO1lBRUYsSUFBSTtnQkFDRixNQUFNLGVBQWUsR0FBRyxRQUFRLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtvQkFDdkQsTUFBTSxJQUFJLEtBQUssQ0FDYiwwQ0FBMEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUN6RCxDQUFDO2dCQUNKLENBQUMsQ0FBQyxDQUFDO2dCQUNILEtBQUssR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztnQkFDNUQsT0FBTzthQUNSO1lBQUMsT0FBTyxHQUFHLEVBQUU7Z0JBQ1osVUFBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLGtCQUFrQixJQUFJLENBQUMsUUFBUSxrQkFBa0IsQ0FBQyxDQUFDO2dCQUN0RSxNQUFNLEdBQUcsQ0FBQzthQUNYO29CQUFTO2dCQUNSLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUNqQjtRQUNILENBQUMsRUFDRDtZQUNFLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQ3RCLE9BQU8sSUFBSSxDQUFDLENBQUM7Z0JBQ2IsSUFDRSxJQUFJLENBQUMsUUFBUTtvQkFDYixXQUFXO29CQUNYLGdCQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLEVBQ3hDO29CQUNBLGFBQU0sQ0FBQyxTQUFTLENBQ2QsR0FBRyxJQUFJLENBQUMsUUFBUSwwQkFBMEIsSUFBSSxDQUFDLE9BQU8sc0JBQXNCLEVBQzVFLENBQUMsQ0FDRixDQUFDO29CQUNGLFdBQVcsR0FBRyxXQUFXLEdBQUcsRUFBRSxDQUFDO29CQUMvQixVQUFHLENBQUMsSUFBSSxDQUNOLGtFQUFrRSxXQUFXLEVBQUUsQ0FDaEYsQ0FBQztpQkFDSDtnQkFDRCxhQUFNLENBQUMsU0FBUyxDQUNkLEdBQUcsSUFBSSxDQUFDLFFBQVEsMEJBQTBCLElBQUksQ0FBQyxPQUFPLG1CQUFtQixFQUN6RSxDQUFDLENBQ0YsQ0FBQztnQkFDRixLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUNYLFVBQUcsQ0FBQyxJQUFJLENBQ04sRUFBRSxHQUFHLEVBQUUsRUFDUCxxREFBcUQsS0FBSyxFQUFFLENBQzdELENBQUM7WUFDSixDQUFDO1NBQ0YsQ0FDRixDQUFDO1FBRUYsYUFBTSxDQUFDLFNBQVMsQ0FDZCxHQUFHLElBQUksQ0FBQyxRQUFRLDBCQUEwQixJQUFJLENBQUMsT0FBTyxtQkFBbUIsRUFDekUsT0FBTyxDQUNSLENBQUM7UUFFRixNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUNqQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQ1AsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO1lBQzVCLFVBQVUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1CO1lBQy9ELFVBQVUsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUM7Z0JBQzdDLElBQUksQ0FBQyxxQkFBcUIsQ0FDN0IsQ0FBQztRQUNGLGFBQU0sQ0FBQyxTQUFTLENBQ2QsR0FBRyxJQUFJLENBQUMsUUFBUSwwQkFBMEIsSUFBSSxDQUFDLE9BQU8sNEJBQTRCLEVBQ2xGLGNBQWMsQ0FBQyxNQUFNLENBQ3RCLENBQUM7UUFDRixhQUFNLENBQUMsU0FBUyxDQUNkLEdBQUcsSUFBSSxDQUFDLFFBQVEsMEJBQTBCLElBQUksQ0FBQyxPQUFPLDZCQUE2QixFQUNuRixDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FDN0MsQ0FBQztRQUVGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNoQyxJQUFJLGNBQWMsR0FBb0IsRUFBRSxDQUFDO1FBQ3pDLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxxQkFBUSxDQUFDLEVBQUUsRUFBRTtZQUNqQyxtSEFBbUg7WUFDbkgsdUlBQXVJO1lBQ3ZJLGNBQWMsR0FBRyxLQUFLO2lCQUNuQixNQUFNLENBQ0wsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUNQLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO2dCQUMzQixVQUFVLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM3QyxVQUFVLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUNsRTtpQkFDQSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDWixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsQ0FBQyxDQUFDLENBQUM7U0FDTjthQUFNO1lBQ0wsY0FBYyxHQUFHLEtBQUs7aUJBQ25CLE1BQU0sQ0FDTCxDQUFDLElBQUksRUFBRSxFQUFFLENBQ1AsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO2dCQUM1QixVQUFVLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUNsRTtpQkFDQSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDWixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUVELGFBQU0sQ0FBQyxTQUFTLENBQ2QsR0FBRyxJQUFJLENBQUMsUUFBUSwwQkFBMEIsSUFBSSxDQUFDLE9BQU8sMEJBQTBCLEVBQ2hGLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxZQUFZLENBQzFCLENBQUM7UUFDRixhQUFNLENBQUMsU0FBUyxDQUNkLEdBQUcsSUFBSSxDQUFDLFFBQVEsMEJBQTBCLElBQUksQ0FBQyxPQUFPLHlCQUF5QixFQUMvRSxjQUFjLENBQUMsTUFBTSxDQUN0QixDQUFDO1FBQ0YsYUFBTSxDQUFDLFNBQVMsQ0FDZCxHQUFHLElBQUksQ0FBQyxRQUFRLDBCQUEwQixJQUFJLENBQUMsT0FBTywwQkFBMEIsRUFDaEYsQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQzdDLENBQUM7UUFDRixhQUFNLENBQUMsU0FBUyxDQUNkLEdBQUcsSUFBSSxDQUFDLFFBQVEsMEJBQTBCLElBQUksQ0FBQyxPQUFPLFdBQVcsRUFDakUsQ0FBQyxDQUNGLENBQUM7UUFDRixhQUFNLENBQUMsU0FBUyxDQUNkLEdBQUcsSUFBSSxDQUFDLFFBQVEsMEJBQTBCLElBQUksQ0FBQyxPQUFPLG1CQUFtQixFQUN6RSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUN2QixDQUFDO1FBRUYsVUFBRyxDQUFDLElBQUksQ0FDTixPQUFPLEtBQUssQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFFBQVEsNkJBQTZCLGNBQWMsQ0FBQyxNQUFNLGtCQUFrQixDQUN6RyxDQUFDO1FBRUYsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztDQU9GO0FBOU5ELDRDQThOQyJ9