Skip to content

Commit

Permalink
Swap expiration with time of fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
mudrila committed Mar 7, 2024
1 parent 2248280 commit 621771c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 30 deletions.
6 changes: 2 additions & 4 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ NEXT_PUBLIC_SITE_URL="https://app.dev.fractalframework.xyz/"
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=""
# CoinGecko API key
COINGECKO_API_KEY=""
# Minutes to cache prices for valid token addresses
TOKEN_PRICE_VALID_CACHE_MINUTES=""
# Minutes to cache "0" for invalid token addresses
TOKEN_PRICE_INVALID_CACHE_MINUTES=""
# Minutes to cache prices for token addresses
TOKEN_PRICE_CACHE_INTERVAL_MINUTES=""
# Shutter Public Key
NEXT_PUBLIC_SHUTTER_EON_PUBKEY=0x0e6493bbb4ee8b19aa9b70367685049ff01dc9382c46aed83f8bc07d2a5ba3e6030bd83b942c1fd3dff5b79bef3b40bf6b666e51e7f0be14ed62daaffad47435265f5c9403b1a801921981f7d8659a9bd91fe92fb1cf9afdb16178a532adfaf51a237103874bb03afafe9cab2118dae1be5f08a0a28bf488c1581e9db4bc23ca
38 changes: 12 additions & 26 deletions netlify/functions/tokenPrices.mts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ type TokenPriceWithMetadata = {
price: number;
};
metadata: {
expiration: number;
fetched: number;
};
};

type Config = {
store: Store;
now: number;
invalidAddressCacheTime: number;
validAddressCacheTime: number;
cacheTime: number;
};

const SUPPORTED_NETWORKS = ['ethereum'] as const;
Expand Down Expand Up @@ -62,7 +61,7 @@ async function splitData(

// Let's pull out all of the expired addresses from our cache.
const expiredCachedTokenAddresses = cachedTokenPrices
.filter(tokenPrice => tokenPrice.metadata.expiration < config.now)
.filter(tokenPrice => tokenPrice.metadata.fetched > config.now + config.cacheTime)
.map(tokenPrice => tokenPrice.data.tokenAddress);

// Finally let's get a list of all of the token addresses that
Expand Down Expand Up @@ -97,13 +96,12 @@ async function storeTokenPrice(
config: Config,
tokenAddress: string,
price: number,
expiration: number,
network: SupportedNetworks
) {
await config.store.setJSON(
`${network}/${tokenAddress}`,
{ tokenAddress, price },
{ metadata: { expiration: config.now + expiration } }
{ metadata: { fetched: config.now } }
);
}

Expand All @@ -115,20 +113,14 @@ async function processTokenPricesResponse(
) {
const coinGeckoResponseAddresses = Object.keys(tokenPricesResponseJson);
for await (const tokenAddress of coinGeckoResponseAddresses) {
const price = tokenPricesResponseJson[tokenAddress].usd;
const price = tokenPricesResponseJson[tokenAddress].usd || 0;
const sanitizedAddress = tokenAddress.toLowerCase();

// Sometimes no USD price is returned. If this happens,
// we should consider it as though CoinGecko doesn't support
// this address and not query it again for a while.
if (price === undefined) {
await storeTokenPrice(config, sanitizedAddress, 0, config.invalidAddressCacheTime, network);
} else {
// Otherwise, update the cache with the new price and update
// the response object.
responseBodyCallback(sanitizedAddress, price);
await storeTokenPrice(config, sanitizedAddress, price, config.validAddressCacheTime, network);
}
responseBodyCallback(sanitizedAddress, price);
await storeTokenPrice(config, sanitizedAddress, price, network);
}

return coinGeckoResponseAddresses;
Expand All @@ -144,7 +136,7 @@ async function processUnknownAddresses(
.filter(x => !responseAddresses.includes(x))
.map(address => address.toLowerCase());
for await (const tokenAddress of unknownAddresses) {
await storeTokenPrice(config, tokenAddress, 0, config.invalidAddressCacheTime, network);
await storeTokenPrice(config, tokenAddress, 0, network);
}
}

Expand Down Expand Up @@ -185,13 +177,8 @@ export default async function getTokenPrices(request: Request) {
return Response.json({ error: 'Error while fetching prices' }, { status: 503 });
}

if (!process.env.TOKEN_PRICE_INVALID_CACHE_MINUTES) {
console.error('TOKEN_PRICE_INVALID_CACHE_MINUTES is not set');
return Response.json({ error: 'Error while fetching prices' }, { status: 503 });
}

if (!process.env.TOKEN_PRICE_VALID_CACHE_MINUTES) {
console.error('TOKEN_PRICE_VALID_CACHE_MINUTES is not set');
if (!process.env.TOKEN_PRICE_CACHE_INTERVAL_MINUTES) {
console.error('TOKEN_PRICE_CACHE_INTERVAL_MINUTES is not set');
return Response.json({ error: 'Error while fetching prices' }, { status: 503 });
}

Expand All @@ -208,9 +195,8 @@ export default async function getTokenPrices(request: Request) {

const store = getStore('token-prices');
const now = Math.floor(Date.now() / 1000);
const invalidAddressCacheTime = parseInt(process.env.TOKEN_PRICE_INVALID_CACHE_MINUTES);
const validAddressCacheTime = parseInt(process.env.TOKEN_PRICE_VALID_CACHE_MINUTES);
const config = { store, now, invalidAddressCacheTime, validAddressCacheTime };
const cacheTime = parseInt(process.env.TOKEN_PRICE_CACHE_INTERVAL_MINUTES);
const config = { store, now, cacheTime };

const { tokens, needNativeAsset } = sanitizeUserInput(tokensStringParam, networkParam);

Expand Down

0 comments on commit 621771c

Please sign in to comment.