Skip to content

Commit 296dbcf

Browse files
feat: allow pool data injection
1 parent 0d54b2e commit 296dbcf

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

src/cached.ts

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,62 @@
1-
import memoize from "memoizee";
21
import {IDict, IExtendedPoolDataFromApi, INetworkName, IPoolType} from "./interfaces.js";
32
import {uncached_getAllPoolsFromApi, uncached_getCrvApyFromApi, uncached_getUsdPricesFromApi} from './external-api.js'
43
import {curve} from "./curve";
54

6-
const _getCachedData = memoize(
7-
async (network: INetworkName, isLiteChain: boolean) => {
8-
const poolsDict = await uncached_getAllPoolsFromApi(network, isLiteChain);
9-
const poolLists = Object.values(poolsDict)
10-
const usdPrices = uncached_getUsdPricesFromApi(poolLists);
11-
const crvApy = uncached_getCrvApyFromApi(poolLists)
12-
return { poolsDict, poolLists, usdPrices, crvApy };
13-
},
14-
{
15-
promise: true,
16-
maxAge: 5 * 60 * 1000, // 5m
17-
primitive: true,
5+
const memoize = <TResult, TParams extends any[], TFunc extends (...args: TParams) => Promise<TResult>>(fn: TFunc, {maxAge}: {
6+
maxAge: number
7+
}) => {
8+
const cache: Record<string, Promise<TResult>> = {};
9+
const cachedFn = async (...args: TParams): Promise<TResult> => {
10+
const key = JSON.stringify(args);
11+
if (key in cache) {
12+
return cache[key];
13+
}
14+
const promise = fn(...args);
15+
cache[key] = promise;
16+
try {
17+
const result = await promise;
18+
setTimeout(() => delete cache[key], maxAge);
19+
return result;
20+
} catch (e) {
21+
delete cache[key];
22+
throw e;
23+
}
24+
};
25+
cachedFn.set = (result: TResult, ...args: TParams) => {
26+
const key = JSON.stringify(args);
27+
setTimeout(() => delete cache[key], maxAge);
28+
cache[key] = Promise.resolve(result);
1829
}
19-
)
30+
return cachedFn as TFunc & { set: (result: TResult, ...args: TParams) => void };
31+
}
32+
33+
function createCache(poolsDict: Record<"main" | "crypto" | "factory" | "factory-crvusd" | "factory-eywa" | "factory-crypto" | "factory-twocrypto" | "factory-tricrypto" | "factory-stable-ng", IExtendedPoolDataFromApi>) {
34+
const poolLists = Object.values(poolsDict)
35+
const usdPrices = uncached_getUsdPricesFromApi(poolLists);
36+
const crvApy = uncached_getCrvApyFromApi(poolLists)
37+
return {poolsDict, poolLists, usdPrices, crvApy};
38+
}
39+
40+
const _getCachedData = memoize(
41+
async (network: INetworkName, isLiteChain: boolean) => createCache(await uncached_getAllPoolsFromApi(network, isLiteChain))
42+
, {
43+
maxAge: 1000 * 60 * 5, // 5 minutes
44+
})
2045

2146
export const _getPoolsFromApi =
2247
async (network: INetworkName, poolType: IPoolType, isLiteChain = false): Promise<IExtendedPoolDataFromApi> => {
2348
const {poolsDict} = await _getCachedData(network, isLiteChain);
2449
return poolsDict[poolType]
2550
}
2651

52+
export const _setPoolsFromApi =
53+
(network: INetworkName, isLiteChain: boolean, data: Record<IPoolType, IExtendedPoolDataFromApi>): void =>
54+
_getCachedData.set(
55+
createCache(data),
56+
network,
57+
isLiteChain
58+
)
59+
2760
export const _getAllPoolsFromApi = async (network: INetworkName, isLiteChain = false): Promise<IExtendedPoolDataFromApi[]> => {
2861
const {poolLists} = await _getCachedData(network, isLiteChain);
2962
return poolLists

src/curve.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,17 @@ import { getFactoryPoolData } from "./factory/factory.js";
1616
import { getFactoryPoolsDataFromApi } from "./factory/factory-api.js";
1717
import { getCryptoFactoryPoolData } from "./factory/factory-crypto.js";
1818
import { getTricryptoFactoryPoolData } from "./factory/factory-tricrypto.js";
19-
import {IPoolData, IDict, ICurve, IChainId, IFactoryPoolType, Abi, INetworkConstants} from "./interfaces";
19+
import {
20+
IPoolData,
21+
IDict,
22+
ICurve,
23+
IChainId,
24+
IFactoryPoolType,
25+
Abi,
26+
INetworkConstants,
27+
IPoolType,
28+
IExtendedPoolDataFromApi
29+
} from "./interfaces";
2030
import ERC20Abi from './constants/abis/ERC20.json' with { type: 'json' };
2131
import cERC20Abi from './constants/abis/cERC20.json' with { type: 'json' };
2232
import yERC20Abi from './constants/abis/yERC20.json' with { type: 'json' };
@@ -56,6 +66,7 @@ import {_getHiddenPools} from "./external-api.js";
5666
import { L2Networks } from "./constants/L2Networks.js";
5767
import { getTwocryptoFactoryPoolData } from "./factory/factory-twocrypto.js";
5868
import {getNetworkConstants} from "./utils.js";
69+
import {_setPoolsFromApi} from "./cached";
5970

6071

6172
export const OLD_CHAINS = [1, 10, 56, 100, 137, 250, 1284, 2222, 8453, 42161, 42220, 43114, 1313161554]; // these chains have non-ng pools
@@ -147,7 +158,7 @@ class Curve implements ICurve {
147158
async init(
148159
providerType: 'JsonRpc' | 'Web3' | 'Infura' | 'Alchemy' | 'NoRPC',
149160
providerSettings: { url?: string, privateKey?: string, batchMaxCount? : number } | { externalProvider: ethers.Eip1193Provider } | { network?: Networkish, apiKey?: string } | 'NoRPC',
150-
options: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number, chainId?: number } = {} // gasPrice in Gwei
161+
options: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number, chainId?: number, poolsData?: Record<IPoolType, IExtendedPoolDataFromApi> } = {} // gasPrice in Gwei
151162
): Promise<void> {
152163
// @ts-ignore
153164
this.provider = null;
@@ -294,6 +305,10 @@ class Curve implements ICurve {
294305
}
295306

296307
this.feeData = { gasPrice: options.gasPrice, maxFeePerGas: options.maxFeePerGas, maxPriorityFeePerGas: options.maxPriorityFeePerGas };
308+
if (options.poolsData) {
309+
_setPoolsFromApi(this.constants.NETWORK_NAME, this.isLiteChain, options.poolsData);
310+
}
311+
297312
await this.updateFeeData();
298313

299314
for (const pool of Object.values({...this.constants.POOLS_DATA, ...this.constants.LLAMMAS_DATA})) {

0 commit comments

Comments
 (0)