|
| 1 | +const {queryContract, queryContractWithRetries} = require('../helper/chain/cosmos') |
| 2 | +const {PromisePool} = require('@supercharge/promise-pool') |
| 3 | +const {transformDexBalances} = require('../helper/portedTokens') |
| 4 | + |
| 5 | +function extractTokenInfo(asset) { |
| 6 | + const {native_token, token, native} = asset.info |
| 7 | + for (const tObject of [native_token, token, native]) { |
| 8 | + if (!tObject) continue |
| 9 | + if (typeof tObject === 'string') return tObject |
| 10 | + const token = tObject.denom || tObject.contract_addr |
| 11 | + if (token) return token |
| 12 | + } |
| 13 | +} |
| 14 | + |
| 15 | +function getAssetInfo(asset) { |
| 16 | + return [extractTokenInfo(asset), Number(asset.amount)] |
| 17 | +} |
| 18 | + |
| 19 | +async function getAllPairs(factory, chain, {blacklistedPairs = []} = {}) { |
| 20 | + const blacklist = new Set(blacklistedPairs) |
| 21 | + let allPairs = [] |
| 22 | + let currentPairs; |
| 23 | + const limit = 30 |
| 24 | + do { |
| 25 | + const queryStr = `{"pairs": { "limit": ${limit} ${allPairs.length ? `,"start_after":${JSON.stringify(allPairs[allPairs.length - 1].contract_addr)}` : ""} }}` |
| 26 | + currentPairs = (await queryContract({contract: factory, chain, data: queryStr})) |
| 27 | + allPairs.push(...currentPairs.filter(pair => !blacklist.has(pair.contract_addr))) |
| 28 | + } while (currentPairs.length > 0) |
| 29 | + const dtos = [] |
| 30 | + const getPairPool = (async (pair) => { |
| 31 | + const pairRes = await queryContractWithRetries({contract: pair.contract_addr, chain, data: {pool: {}}}) |
| 32 | + // console.log("pairRes: ", pairRes, " pair: ", pair, ""); |
| 33 | + const pairDto = {} |
| 34 | + pairDto.assets = [] |
| 35 | + pairDto.addr = pair.contract_addr |
| 36 | + pairRes.assets.forEach((asset, idx) => { |
| 37 | + const [addr, balance] = getAssetInfo(asset) |
| 38 | + pairDto.assets.push({addr, balance}) |
| 39 | + }) |
| 40 | + pairDto.pair_type = pair.pair_type |
| 41 | + dtos.push(pairDto) |
| 42 | + }) |
| 43 | + const {errors} = await PromisePool |
| 44 | + .withConcurrency(10) |
| 45 | + .for(allPairs) |
| 46 | + .process(getPairPool) |
| 47 | + if ((errors?.length ?? 0) > 50) { |
| 48 | + throw new Error(`Too many errors: ${errors.length}/${allPairs.length} on ${chain}`) |
| 49 | + } |
| 50 | + return dtos |
| 51 | +} |
| 52 | + |
| 53 | +const isNotXYK = (pair) => pair.pair_type && pair.pair_type.custom === 'concentrated' |
| 54 | + |
| 55 | +function getFactoryTvl(factory, {blacklistedPairs = []} = {}) { |
| 56 | + return async (api) => { |
| 57 | + const pairs = (await getAllPairs(factory, api.chain, {blacklistedPairs})).filter(pair => (pair.assets[0].balance && pair.assets[1].balance)) |
| 58 | + |
| 59 | + const otherPairs = pairs.filter(isNotXYK) |
| 60 | + const xykPairs = pairs.filter(pair => !isNotXYK(pair)) |
| 61 | + otherPairs.forEach(({assets}) => { |
| 62 | + api.add(assets[0].addr, assets[0].balance) |
| 63 | + api.add(assets[1].addr, assets[1].balance) |
| 64 | + }) |
| 65 | + const data = xykPairs.map(({assets}) => ({ |
| 66 | + token0: assets[0].addr, |
| 67 | + token0Bal: assets[0].balance, |
| 68 | + token1: assets[1].addr, |
| 69 | + token1Bal: assets[1].balance, |
| 70 | + })) |
| 71 | + return transformDexBalances({api, data}) |
| 72 | + } |
| 73 | +} |
| 74 | + |
| 75 | +module.exports = { |
| 76 | + getFactoryTvl, |
| 77 | +} |
0 commit comments