From f5e9dac302f71865b072c6000235e2c607d96dd8 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 9 Apr 2025 10:15:15 +0200 Subject: [PATCH 1/5] perf: cache usd rate map from API --- src/cached.ts | 32 ++++++++ src/external-api.ts | 123 +++++++++++++++++++++++------- src/factory/factory-api.ts | 2 +- src/pools/subClasses/corePool.ts | 6 +- src/pools/subClasses/statsPool.ts | 2 +- src/pools/utils.ts | 2 +- src/utils.ts | 73 +----------------- 7 files changed, 135 insertions(+), 105 deletions(-) create mode 100644 src/cached.ts diff --git a/src/cached.ts b/src/cached.ts new file mode 100644 index 00000000..63aaaa70 --- /dev/null +++ b/src/cached.ts @@ -0,0 +1,32 @@ +import memoize from "memoizee"; +import {IDict, IExtendedPoolDataFromApi, INetworkName, IPoolType} from "./interfaces.js"; +import {uncached_getAllPoolsFromApi, uncached_getUsdPricesFromApi} from './external-api.js' + +const _getCachedData = memoize( + async (network: INetworkName, isLiteChain: boolean) => { + const allPools = await uncached_getAllPoolsFromApi(network, isLiteChain); + const poolLists = Object.values(allPools) + const usdPrices = uncached_getUsdPricesFromApi(poolLists); + return { allPools, poolLists, usdPrices } + }, + { + promise: true, + maxAge: 5 * 60 * 1000, // 5m + } +) + +export const _getPoolsFromApi = + async (network: INetworkName, poolType: IPoolType, isLiteChain = false): Promise => { + const {allPools} = await _getCachedData(network, isLiteChain); + return allPools[poolType] + } + +export const _getAllPoolsFromApi = async (network: INetworkName, isLiteChain = false): Promise => { + const {poolLists} = await _getCachedData(network, isLiteChain); + return poolLists +} + +export const _getUsdPricesFromApi = async (): Promise> => { + const {usdPrices} = await _getCachedData("ethereum", false); + return usdPrices +} diff --git a/src/external-api.ts b/src/external-api.ts index 5b93d097..97da7666 100644 --- a/src/external-api.ts +++ b/src/external-api.ts @@ -12,38 +12,103 @@ import { } from "./interfaces"; -export const _getPoolsFromApi = memoize( - async (network: INetworkName, poolType: IPoolType, isLiteChain = false): Promise => { - const api = isLiteChain ? "https://api-core.curve.fi/v1/" : "https://api.curve.fi/api"; - const url = `${api}/getPools/${network}/${poolType}`; - return await fetchData(url) ?? { poolData: [], tvl: 0, tvlAll: 0 }; - }, - { - promise: true, - maxAge: 5 * 60 * 1000, // 5m +const uncached_getPoolsFromApi = async (network: INetworkName, poolType: IPoolType, isLiteChain = false): Promise => { + const api = isLiteChain ? "https://api-core.curve.fi/v1/" : "https://api.curve.fi/api"; + const url = `${api}/getPools/${network}/${poolType}`; + return await fetchData(url) ?? { poolData: [], tvl: 0, tvlAll: 0 }; +} + +export const uncached_getAllPoolsFromApi = async (network: INetworkName, isLiteChain = false): Promise> => { + const poolTypes = isLiteChain ? [ + "factory-twocrypto", + "factory-tricrypto", + "factory-stable-ng", + ] as const : [ + "main", + "crypto", + "factory", + "factory-crvusd", + "factory-eywa", + "factory-crypto", + "factory-twocrypto", + "factory-tricrypto", + "factory-stable-ng", + ] as const; + return Object.fromEntries( + await Promise.all(poolTypes.map(async (poolType) => { + const data = await uncached_getPoolsFromApi(network, poolType, isLiteChain); + return [poolType, data]; + })) + ) +} + +export const uncached_getUsdPricesFromApi = async (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): Promise> => { + const priceDict: IDict[]> = {}; + const priceDictByMaxTvl: IDict = {}; + + for (const extendedPoolData of allTypesExtendedPoolData) { + for (const pool of extendedPoolData.poolData) { + const lpTokenAddress = pool.lpTokenAddress ?? pool.address; + const totalSupply = pool.totalSupply / (10 ** 18); + if(lpTokenAddress.toLowerCase() in priceDict) { + priceDict[lpTokenAddress.toLowerCase()].push({ + price: pool.usdTotal && totalSupply ? pool.usdTotal / totalSupply : 0, + tvl: pool.usdTotal, + }) + } else { + priceDict[lpTokenAddress.toLowerCase()] = [] + priceDict[lpTokenAddress.toLowerCase()].push({ + price: pool.usdTotal && totalSupply ? pool.usdTotal / totalSupply : 0, + tvl: pool.usdTotal, + }) + } + + for (const coin of pool.coins) { + if (typeof coin.usdPrice === "number") { + if(coin.address.toLowerCase() in priceDict) { + priceDict[coin.address.toLowerCase()].push({ + price: coin.usdPrice, + tvl: pool.usdTotal, + }) + } else { + priceDict[coin.address.toLowerCase()] = [] + priceDict[coin.address.toLowerCase()].push({ + price: coin.usdPrice, + tvl: pool.usdTotal, + }) + } + } + } + + for (const coin of pool.gaugeRewards ?? []) { + if (typeof coin.tokenPrice === "number") { + if(coin.tokenAddress.toLowerCase() in priceDict) { + priceDict[coin.tokenAddress.toLowerCase()].push({ + price: coin.tokenPrice, + tvl: pool.usdTotal, + }); + } else { + priceDict[coin.tokenAddress.toLowerCase()] = [] + priceDict[coin.tokenAddress.toLowerCase()].push({ + price: coin.tokenPrice, + tvl: pool.usdTotal, + }); + } + } + } + } } -) -export const _getAllPoolsFromApi = async (network: INetworkName, isLiteChain = false): Promise => { - if(isLiteChain) { - return await Promise.all([ - _getPoolsFromApi(network, "factory-twocrypto", isLiteChain), - _getPoolsFromApi(network, "factory-tricrypto", isLiteChain), - _getPoolsFromApi(network, "factory-stable-ng", isLiteChain), - ]); - } else { - return await Promise.all([ - _getPoolsFromApi(network, "main", isLiteChain), - _getPoolsFromApi(network, "crypto", isLiteChain), - _getPoolsFromApi(network, "factory", isLiteChain), - _getPoolsFromApi(network, "factory-crvusd", isLiteChain), - _getPoolsFromApi(network, "factory-eywa", isLiteChain), - _getPoolsFromApi(network, "factory-crypto", isLiteChain), - _getPoolsFromApi(network, "factory-twocrypto", isLiteChain), - _getPoolsFromApi(network, "factory-tricrypto", isLiteChain), - _getPoolsFromApi(network, "factory-stable-ng", isLiteChain), - ]); + for(const address in priceDict) { + if (priceDict[address].length) { + const maxTvlItem = priceDict[address].reduce((prev, current) => +current.tvl > +prev.tvl ? current : prev); + priceDictByMaxTvl[address] = maxTvlItem.price + } else { + priceDictByMaxTvl[address] = 0 + } } + + return priceDictByMaxTvl } export const _getSubgraphData = memoize( diff --git a/src/factory/factory-api.ts b/src/factory/factory-api.ts index ba51ae5c..8760e540 100644 --- a/src/factory/factory-api.ts +++ b/src/factory/factory-api.ts @@ -8,7 +8,7 @@ import twocryptoFactorySwapABI from "../constants/abis/factory-twocrypto/factory import tricryptoFactorySwapABI from "../constants/abis/factory-tricrypto/factory-tricrypto-pool.json" with { type: 'json' }; import tricryptoFactoryEthDisabledSwapABI from "../constants/abis/factory-tricrypto/factory-tricrypto-pool-eth-disabled.json" with { type: 'json' }; import { getPoolIdByAddress, setFactoryZapContracts } from "./common.js"; -import { _getPoolsFromApi } from "../external-api.js"; +import { _getPoolsFromApi } from "../cached.js"; import {assetTypeNameHandler, getPoolName, isStableNgPool} from "../utils.js"; import StableNgBasePoolZapABI from "../constants/abis/stable-ng-base-pool-zap.json" with { type: 'json' }; import MetaStableSwapNGABI from "../constants/abis/factory-stable-ng/meta-stableswap-ng.json" with { type: 'json' }; diff --git a/src/pools/subClasses/corePool.ts b/src/pools/subClasses/corePool.ts index 3a4bee73..1134dfd2 100644 --- a/src/pools/subClasses/corePool.ts +++ b/src/pools/subClasses/corePool.ts @@ -69,7 +69,11 @@ export class CorePool implements ICorePool { inApi: boolean; constructor(id: string) { - const poolData = curve.getPoolsData()[id]; + const poolsData = curve.getPoolsData(); + if (!poolsData[id]) { + throw new Error(`Pool ${id} not found. Available pools: ${Object.keys(poolsData).join(', ')}`); + } + const poolData = poolsData[id]; this.id = id; this.name = poolData.name; diff --git a/src/pools/subClasses/statsPool.ts b/src/pools/subClasses/statsPool.ts index 1505c01c..ddc26ef1 100644 --- a/src/pools/subClasses/statsPool.ts +++ b/src/pools/subClasses/statsPool.ts @@ -1,6 +1,6 @@ import { curve } from "../../curve.js"; import {IPoolType, IReward} from '../../interfaces.js'; -import {_getPoolsFromApi} from '../../external-api.js'; +import {_getPoolsFromApi} from '../../cached.js'; import { _getUsdRate, BN, diff --git a/src/pools/utils.ts b/src/pools/utils.ts index c7f44405..eb84c07b 100644 --- a/src/pools/utils.ts +++ b/src/pools/utils.ts @@ -2,7 +2,7 @@ import { getPool } from "./poolConstructor.js"; import { IDict } from "../interfaces"; import { curve } from "../curve.js"; import { _getRewardsFromApi, _getUsdRate, _setContracts, toBN } from "../utils.js"; -import { _getAllPoolsFromApi } from "../external-api.js"; +import { _getAllPoolsFromApi } from "../cached.js"; import ERC20Abi from "../constants/abis/ERC20.json" with { type: 'json' }; // _userLpBalance: { address: { poolId: { _lpBalance: 0, time: 0 } } } diff --git a/src/utils.ts b/src/utils.ts index ff898c9e..75dea5e4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -15,13 +15,13 @@ import { } from './interfaces'; import {curve} from "./curve.js"; import { - _getAllPoolsFromApi, _getCurveLiteNetworks, _getFactoryAPYs, _getLiteNetworksData, _getSubgraphData, _getVolumes, } from "./external-api.js"; +import {_getAllPoolsFromApi, _getUsdPricesFromApi} from "./cached.js"; import ERC20Abi from './constants/abis/ERC20.json' with { type: 'json' }; import {L2Networks} from './constants/L2Networks.js'; import {volumeNetworks} from "./constants/volumeNetworks.js"; @@ -316,77 +316,6 @@ export const getPoolIdBySwapAddress = (swapAddress: string): string => { return poolIds[0][0]; } -export const _getUsdPricesFromApi = async (): Promise> => { - const network = curve.constants.NETWORK_NAME; - const allTypesExtendedPoolData = await _getAllPoolsFromApi(network, curve.isLiteChain); - const priceDict: IDict[]> = {}; - const priceDictByMaxTvl: IDict = {}; - - for (const extendedPoolData of allTypesExtendedPoolData) { - for (const pool of extendedPoolData.poolData) { - const lpTokenAddress = pool.lpTokenAddress ?? pool.address; - const totalSupply = pool.totalSupply / (10 ** 18); - if(lpTokenAddress.toLowerCase() in priceDict) { - priceDict[lpTokenAddress.toLowerCase()].push({ - price: pool.usdTotal && totalSupply ? pool.usdTotal / totalSupply : 0, - tvl: pool.usdTotal, - }) - } else { - priceDict[lpTokenAddress.toLowerCase()] = [] - priceDict[lpTokenAddress.toLowerCase()].push({ - price: pool.usdTotal && totalSupply ? pool.usdTotal / totalSupply : 0, - tvl: pool.usdTotal, - }) - } - - for (const coin of pool.coins) { - if (typeof coin.usdPrice === "number") { - if(coin.address.toLowerCase() in priceDict) { - priceDict[coin.address.toLowerCase()].push({ - price: coin.usdPrice, - tvl: pool.usdTotal, - }) - } else { - priceDict[coin.address.toLowerCase()] = [] - priceDict[coin.address.toLowerCase()].push({ - price: coin.usdPrice, - tvl: pool.usdTotal, - }) - } - } - } - - for (const coin of pool.gaugeRewards ?? []) { - if (typeof coin.tokenPrice === "number") { - if(coin.tokenAddress.toLowerCase() in priceDict) { - priceDict[coin.tokenAddress.toLowerCase()].push({ - price: coin.tokenPrice, - tvl: pool.usdTotal, - }); - } else { - priceDict[coin.tokenAddress.toLowerCase()] = [] - priceDict[coin.tokenAddress.toLowerCase()].push({ - price: coin.tokenPrice, - tvl: pool.usdTotal, - }); - } - } - } - } - } - - for(const address in priceDict) { - if (priceDict[address].length) { - const maxTvlItem = priceDict[address].reduce((prev, current) => +current.tvl > +prev.tvl ? current : prev); - priceDictByMaxTvl[address] = maxTvlItem.price - } else { - priceDictByMaxTvl[address] = 0 - } - } - - return priceDictByMaxTvl -} - export const _getCrvApyFromApi = async (): Promise> => { const network = curve.constants.NETWORK_NAME; const allTypesExtendedPoolData = await _getAllPoolsFromApi(network, curve.isLiteChain); From e22c8bc8f199035b715653778d0cd48dccc42fb5 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 9 Apr 2025 10:23:26 +0200 Subject: [PATCH 2/5] perf: cache crv APY dict --- src/cached.ts | 23 ++++++++++++++++------- src/external-api.ts | 20 ++++++++++++++++++++ src/pools/subClasses/statsPool.ts | 3 +-- src/utils.ts | 20 -------------------- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/cached.ts b/src/cached.ts index 63aaaa70..9ee880d5 100644 --- a/src/cached.ts +++ b/src/cached.ts @@ -1,13 +1,15 @@ import memoize from "memoizee"; import {IDict, IExtendedPoolDataFromApi, INetworkName, IPoolType} from "./interfaces.js"; -import {uncached_getAllPoolsFromApi, uncached_getUsdPricesFromApi} from './external-api.js' +import {uncached_getAllPoolsFromApi, uncached_getCrvApyFromApi, uncached_getUsdPricesFromApi} from './external-api.js' +import {curve} from "./curve"; const _getCachedData = memoize( async (network: INetworkName, isLiteChain: boolean) => { - const allPools = await uncached_getAllPoolsFromApi(network, isLiteChain); - const poolLists = Object.values(allPools) + const poolsDict = await uncached_getAllPoolsFromApi(network, isLiteChain); + const poolLists = Object.values(poolsDict) const usdPrices = uncached_getUsdPricesFromApi(poolLists); - return { allPools, poolLists, usdPrices } + const crvApy = uncached_getCrvApyFromApi(poolLists) + return { poolsDict, poolLists, usdPrices, crvApy }; }, { promise: true, @@ -17,8 +19,8 @@ const _getCachedData = memoize( export const _getPoolsFromApi = async (network: INetworkName, poolType: IPoolType, isLiteChain = false): Promise => { - const {allPools} = await _getCachedData(network, isLiteChain); - return allPools[poolType] + const {poolsDict} = await _getCachedData(network, isLiteChain); + return poolsDict[poolType] } export const _getAllPoolsFromApi = async (network: INetworkName, isLiteChain = false): Promise => { @@ -27,6 +29,13 @@ export const _getAllPoolsFromApi = async (network: INetworkName, isLiteChain = f } export const _getUsdPricesFromApi = async (): Promise> => { - const {usdPrices} = await _getCachedData("ethereum", false); + const network = curve.constants.NETWORK_NAME; + const {usdPrices} = await _getCachedData(network, false); return usdPrices } + +export const _getCrvApyFromApi = async (): Promise> => { + const network = curve.constants.NETWORK_NAME; + const {crvApy} = await _getCachedData(network, false); + return crvApy +} diff --git a/src/external-api.ts b/src/external-api.ts index 97da7666..79db3b12 100644 --- a/src/external-api.ts +++ b/src/external-api.ts @@ -10,6 +10,8 @@ import { IPoolType, IVolumeAndAPYs, } from "./interfaces"; +import {curve} from "./curve"; +import {_getAllPoolsFromApi} from "./cached"; const uncached_getPoolsFromApi = async (network: INetworkName, poolType: IPoolType, isLiteChain = false): Promise => { @@ -111,6 +113,24 @@ export const uncached_getUsdPricesFromApi = async (allTypesExtendedPoolData: IE return priceDictByMaxTvl } +export const uncached_getCrvApyFromApi = (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): IDict<[number, number]> => { + const apyDict: IDict<[number, number]> = {}; + + for (const extendedPoolData of allTypesExtendedPoolData) { + for (const pool of extendedPoolData.poolData) { + if (pool.gaugeAddress) { + if (!pool.gaugeCrvApy) { + apyDict[pool.gaugeAddress.toLowerCase()] = [0, 0]; + } else { + apyDict[pool.gaugeAddress.toLowerCase()] = [pool.gaugeCrvApy[0] ?? 0, pool.gaugeCrvApy[1] ?? 0]; + } + } + } + } + + return apyDict +} + export const _getSubgraphData = memoize( async (network: INetworkName): Promise => { const data = await fetchData(`https://api.curve.fi/api/getSubgraphData/${network}`); diff --git a/src/pools/subClasses/statsPool.ts b/src/pools/subClasses/statsPool.ts index ddc26ef1..36b4e55b 100644 --- a/src/pools/subClasses/statsPool.ts +++ b/src/pools/subClasses/statsPool.ts @@ -1,11 +1,10 @@ import { curve } from "../../curve.js"; import {IPoolType, IReward} from '../../interfaces.js'; -import {_getPoolsFromApi} from '../../cached.js'; +import {_getPoolsFromApi,_getCrvApyFromApi} from '../../cached.js'; import { _getUsdRate, BN, toBN, - _getCrvApyFromApi, _getRewardsFromApi, getVolumeApiController, } from '../../utils.js'; diff --git a/src/utils.ts b/src/utils.ts index 75dea5e4..438a4f99 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -316,26 +316,6 @@ export const getPoolIdBySwapAddress = (swapAddress: string): string => { return poolIds[0][0]; } -export const _getCrvApyFromApi = async (): Promise> => { - const network = curve.constants.NETWORK_NAME; - const allTypesExtendedPoolData = await _getAllPoolsFromApi(network, curve.isLiteChain); - const apyDict: IDict<[number, number]> = {}; - - for (const extendedPoolData of allTypesExtendedPoolData) { - for (const pool of extendedPoolData.poolData) { - if (pool.gaugeAddress) { - if (!pool.gaugeCrvApy) { - apyDict[pool.gaugeAddress.toLowerCase()] = [0, 0]; - } else { - apyDict[pool.gaugeAddress.toLowerCase()] = [pool.gaugeCrvApy[0] ?? 0, pool.gaugeCrvApy[1] ?? 0]; - } - } - } - } - - return apyDict -} - export const _getRewardsFromApi = async (): Promise> => { const network = curve.constants.NETWORK_NAME; const allTypesExtendedPoolData = await _getAllPoolsFromApi(network, curve.isLiteChain); From 0d54b2e8d245147176ab0990325427aa1a79c6c8 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 9 Apr 2025 10:27:51 +0200 Subject: [PATCH 3/5] chore: self-review --- src/cached.ts | 1 + src/external-api.ts | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cached.ts b/src/cached.ts index 9ee880d5..90a9d052 100644 --- a/src/cached.ts +++ b/src/cached.ts @@ -14,6 +14,7 @@ const _getCachedData = memoize( { promise: true, maxAge: 5 * 60 * 1000, // 5m + primitive: true, } ) diff --git a/src/external-api.ts b/src/external-api.ts index 79db3b12..14119a33 100644 --- a/src/external-api.ts +++ b/src/external-api.ts @@ -10,8 +10,6 @@ import { IPoolType, IVolumeAndAPYs, } from "./interfaces"; -import {curve} from "./curve"; -import {_getAllPoolsFromApi} from "./cached"; const uncached_getPoolsFromApi = async (network: INetworkName, poolType: IPoolType, isLiteChain = false): Promise => { From cfea777c246137c94754aca458e3e16a1a956885 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 9 Apr 2025 10:55:14 +0200 Subject: [PATCH 4/5] fix: remove async --- src/external-api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/external-api.ts b/src/external-api.ts index 14119a33..8f24112d 100644 --- a/src/external-api.ts +++ b/src/external-api.ts @@ -42,7 +42,7 @@ export const uncached_getAllPoolsFromApi = async (network: INetworkName, isLiteC ) } -export const uncached_getUsdPricesFromApi = async (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): Promise> => { +export const uncached_getUsdPricesFromApi = (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): IDict => { const priceDict: IDict[]> = {}; const priceDictByMaxTvl: IDict = {}; From fd9b4dab644fefa2a713e58fb79ef0ff5db7d24d Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 9 Apr 2025 12:38:02 +0200 Subject: [PATCH 5/5] chore: review comments --- src/cached.ts | 10 +++++++--- src/external-api.ts | 29 ++++++++--------------------- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/cached.ts b/src/cached.ts index 90a9d052..8f6ca58e 100644 --- a/src/cached.ts +++ b/src/cached.ts @@ -1,14 +1,18 @@ import memoize from "memoizee"; import {IDict, IExtendedPoolDataFromApi, INetworkName, IPoolType} from "./interfaces.js"; -import {uncached_getAllPoolsFromApi, uncached_getCrvApyFromApi, uncached_getUsdPricesFromApi} from './external-api.js' +import {uncached_getAllPoolsFromApi, createCrvApyDict, createUsdPricesDict} from './external-api.js' import {curve} from "./curve"; +/** + * This function is used to cache the data fetched from the API and the data derived from it. + * Note: do not expose this function to the outside world, instead encapsulate it in a function that returns the data you need. + */ const _getCachedData = memoize( async (network: INetworkName, isLiteChain: boolean) => { const poolsDict = await uncached_getAllPoolsFromApi(network, isLiteChain); const poolLists = Object.values(poolsDict) - const usdPrices = uncached_getUsdPricesFromApi(poolLists); - const crvApy = uncached_getCrvApyFromApi(poolLists) + const usdPrices = createUsdPricesDict(poolLists); + const crvApy = createCrvApyDict(poolLists) return { poolsDict, poolLists, usdPrices, crvApy }; }, { diff --git a/src/external-api.ts b/src/external-api.ts index 8f24112d..4b67f1f2 100644 --- a/src/external-api.ts +++ b/src/external-api.ts @@ -18,31 +18,18 @@ const uncached_getPoolsFromApi = async (network: INetworkName, poolType: IPoolTy return await fetchData(url) ?? { poolData: [], tvl: 0, tvlAll: 0 }; } -export const uncached_getAllPoolsFromApi = async (network: INetworkName, isLiteChain = false): Promise> => { - const poolTypes = isLiteChain ? [ - "factory-twocrypto", - "factory-tricrypto", - "factory-stable-ng", - ] as const : [ - "main", - "crypto", - "factory", - "factory-crvusd", - "factory-eywa", - "factory-crypto", - "factory-twocrypto", - "factory-tricrypto", - "factory-stable-ng", - ] as const; - return Object.fromEntries( - await Promise.all(poolTypes.map(async (poolType) => { +const getPoolTypes = (isLiteChain: boolean) => isLiteChain ? ["factory-twocrypto", "factory-tricrypto", "factory-stable-ng"] as const : + ["main", "crypto", "factory", "factory-crvusd", "factory-eywa", "factory-crypto", "factory-twocrypto", "factory-tricrypto", "factory-stable-ng"] as const; + +export const uncached_getAllPoolsFromApi = async (network: INetworkName, isLiteChain = false): Promise> => + Object.fromEntries( + await Promise.all(getPoolTypes(isLiteChain).map(async (poolType) => { const data = await uncached_getPoolsFromApi(network, poolType, isLiteChain); return [poolType, data]; })) ) -} -export const uncached_getUsdPricesFromApi = (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): IDict => { +export const createUsdPricesDict = (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): IDict => { const priceDict: IDict[]> = {}; const priceDictByMaxTvl: IDict = {}; @@ -111,7 +98,7 @@ export const uncached_getUsdPricesFromApi = (allTypesExtendedPoolData: IExtende return priceDictByMaxTvl } -export const uncached_getCrvApyFromApi = (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): IDict<[number, number]> => { +export const createCrvApyDict = (allTypesExtendedPoolData: IExtendedPoolDataFromApi[]): IDict<[number, number]> => { const apyDict: IDict<[number, number]> = {}; for (const extendedPoolData of allTypesExtendedPoolData) {