fix(rwallet): batch CoinGecko requests to 1 address each (free tier limit)

CoinGecko free tier now limits to 1 contract address per request.
Process in batches of 3 concurrent single-address requests with 1.5s delay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-25 16:17:03 -07:00
parent 55b973ebc2
commit 95246743c3
1 changed files with 16 additions and 10 deletions

View File

@ -74,7 +74,7 @@ export async function getNativePrice(chainId: string): Promise<number> {
return data?.[coinId]?.usd ?? 0;
}
/** Fetch token prices for a batch of contract addresses on a chain */
/** Fetch token prices for contract addresses on a chain (1 per request for free tier) */
export async function getTokenPrices(
chainId: string,
addresses: string[],
@ -82,16 +82,22 @@ export async function getTokenPrices(
const platform = CHAIN_PLATFORM[chainId];
if (!platform || addresses.length === 0) return new Map();
const lower = addresses.map((a) => a.toLowerCase());
const data = await cgFetch(
`https://api.coingecko.com/api/v3/simple/token_price/${platform}?contract_addresses=${lower.join(",")}&vs_currencies=usd`,
);
const lower = [...new Set(addresses.map((a) => a.toLowerCase()))];
const result = new Map<string, number>();
if (data) {
for (const addr of lower) {
if (data[addr]?.usd) result.set(addr, data[addr].usd);
}
// CoinGecko free tier: 1 contract address per request, ~30 req/min
// Process in batches of 3 with a short delay between batches
const BATCH = 3;
for (let i = 0; i < lower.length; i += BATCH) {
const batch = lower.slice(i, i + BATCH);
const fetches = batch.map(async (addr) => {
const data = await cgFetch(
`https://api.coingecko.com/api/v3/simple/token_price/${platform}?contract_addresses=${addr}&vs_currencies=usd`,
);
if (data?.[addr]?.usd) result.set(addr, data[addr].usd);
});
await Promise.allSettled(fetches);
if (i + BATCH < lower.length) await new Promise((r) => setTimeout(r, 1500));
}
return result;
}