From e0e9802bd7a94453efcadb58a0c9f3f69f4a09b3 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 25 Mar 2026 16:45:45 -0700 Subject: [PATCH] feat(rwallet): use CoinGecko Demo API key for batch token pricing Reads COINGECKO_API_KEY from env (injected via Infisical) and appends x_cg_demo_api_key param. Enables batch lookups + spam filtering. Co-Authored-By: Claude Opus 4.6 --- modules/rwallet/lib/price-feed.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/rwallet/lib/price-feed.ts b/modules/rwallet/lib/price-feed.ts index 10f0d29..0f888e5 100644 --- a/modules/rwallet/lib/price-feed.ts +++ b/modules/rwallet/lib/price-feed.ts @@ -42,15 +42,23 @@ const TTL = 5 * 60 * 1000; // 5 minutes const cache = new Map(); const inFlight = new Map>(); +const CG_API_KEY = process.env.COINGECKO_API_KEY || ""; + +function cgUrl(url: string): string { + if (!CG_API_KEY) return url; + const sep = url.includes("?") ? "&" : "?"; + return `${url}${sep}x_cg_demo_api_key=${CG_API_KEY}`; +} + async function cgFetch(url: string): Promise { - const res = await fetch(url, { + const res = await fetch(cgUrl(url), { headers: { accept: "application/json" }, signal: AbortSignal.timeout(10000), }); if (res.status === 429) { console.warn("[price-feed] CoinGecko rate limited, waiting 60s..."); await new Promise((r) => setTimeout(r, 60000)); - const retry = await fetch(url, { + const retry = await fetch(cgUrl(url), { headers: { accept: "application/json" }, signal: AbortSignal.timeout(10000), });