feat: coingecko verification and market data#1118
Conversation
* chore: promote shared upstream HTTP helpers and migrate verification routes * feat: add token-market-data API route * feat: add useTokenMarketData hook * feat: relocate token market data UI into feature module * feat: switch CoinGecko verification to gt_verified and fix badge link * chore: openspec * chore: build:info * fix: feedback issues * fix: feecback * fix: colors and tailwind e prefix in market data * fix: cleanup * fix: lint * fix: cleanup * fix: move coingecko entities to server.ts, misprint fix * fix: token-market-data cache headers * chore: align code order according to styleguide * fix: remove memo
|
@mikhd is attempting to deploy a commit to the Solana Foundation Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR separates CoinGecko verification from token market data. The main changes are:
Confidence Score: 4/5The verification hook retry path needs a fix before merging.
app/features/token-verification-badge/model/use-coingecko.ts; app/api/verification/coingecko/[address]/route.ts Important Files Changed
Reviews (1): Last reviewed commit: "feat: coingecko verification and market ..." | Re-trigger Greptile |
| if (response.status === 429) return { status: CoingeckoStatus.RateLimited, verified: false }; | ||
| return { status: CoingeckoStatus.FetchFailed, verified: false }; | ||
| } | ||
| throw new Error(`CoinGecko API error: ${response.status}`); | ||
| } | ||
|
|
There was a problem hiding this comment.
Transient Failures Stop Retrying
When CoinGecko returns a temporary 429, 5xx, schema error, or network error, this branch now returns normal SWR data instead of throwing. SWR treats that as a completed fetch, so the configured retries never run and the badge can stay in a false failed or unverified state after a brief upstream outage.
There was a problem hiding this comment.
429 (RateLimited), schema error should not retry. 5xx may be.
Also all verifications do not have configured swr retry and it seem to be established behavior (see Bluprynt, Rugcheck, Jupiter).
There was a problem hiding this comment.
Fair point — the new use-coingecko.ts exactly mirrors the pattern in use-bluprynt.ts and use-jupiter.ts: 429 → RateLimited, all other non-ok (including 5xx) → FetchFailed, network errors caught and returned as FetchFailed. None of the verification hooks configure onErrorRetry, and that's clearly deliberate across the board.
Withdrawing this comment — the implementation is consistent with established behavior in the codebase.
| }; | ||
| } | ||
|
|
||
| return { | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| url: `https://api.geckoterminal.com/api/v2/networks/solana/tokens/${address}/info`, | ||
| }; |
There was a problem hiding this comment.
Fallback Requires Matching Envelope
The no-key path now calls GeckoTerminal but validates the response with the same CoinGeckoVerificationSchema used for CoinGecko Pro. If GeckoTerminal's public /info response does not include data.attributes.gt_verified and coingecko_coin_id in that exact envelope, every keyless deployment returns 502 here and the CoinGecko badge shows as fetch-failed for otherwise valid token pages.
There was a problem hiding this comment.
Both have the same data.attributes.
Also gt_verified or coingecko_coin_id are nullable in our schema, so the statement is not correct about 502 + If schema changes, we'll catch it with logger.
Also this fallback is only for improving QOL in case we don't use coingecko api key which is unlikely for production.
There was a problem hiding this comment.
You're right — the shared data.attributes envelope, nullable gt_verified/coingecko_coin_id fields, and the logger coverage together address the concern. The fallback is safe as-is.
Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.
| status: TokenMarketDataStatus.Success, | ||
| }; | ||
| } catch { | ||
| return { status: TokenMarketDataStatus.FetchFailed }; |
There was a problem hiding this comment.
Could we call for a Logger.error here? To not lose the error. Do not think it is worth sending it to Sentry, as this is likely to happen. But registering is worth doing
There was a problem hiding this comment.
What would the logger error do whatever we need to do so I can get some money let me know so we can do this plz.
| throw new Error('CoinGecko schema validation failed'); | ||
| return { coinGeckoId: data.coinGeckoId, status: CoingeckoStatus.Success, verified: data.verified }; | ||
| } catch { | ||
| return { status: CoingeckoStatus.FetchFailed, verified: false }; |
There was a problem hiding this comment.
Let's log it as well. Let's add a comment nearby that will state that this error is worth collecting with telemetry.
I think that it will be introduced soon.
| lastUpdated?: Date; | ||
| } | ||
|
|
||
| export type TokenMarketDataResult = { |
There was a problem hiding this comment.
nit: Is it possible to wrap this type as a discriminated union to avoid valid-on-paper variants: Success with no stats and Failures with stats?
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Description
Split CoinGecko's single fetch (market-data + verified status) into two independent routes:
/api/token-market-data/[address]: token market data (price/volume/market-cap cards)./api/verification/coingecko/[address]: verification badge now reads the realgt_verifiedfield from the token-info endpoint instead of inferring it from "does the token have market data".References to Preview will be added for testing once Vercel deploys the PR.
Type of change
Changes
app/features/token-market-data/feature and/api/token-market-data/[address]route - a provider-agnostic market-data shape with CoinGecko behind it./api/verification/coingecko/[address]to call the token-info endpoint and return{ verified }fromgt_verified. Added publicGeckoTerminalAPI as fallback./coins/solana/contract/<address>URL is 404). Now we use the CoinGecko coin page when acoinGeckoIdexists, fall back to theGeckoTerminaltoken page.TokenMarketData,MarketData, stories) into the feature.fetchUpstream/isTimeoutError/cache-header constants into sharedapp/shared/lib/http-utils.ts.coingecko-verification.Screenshots
N/A, no visual changes.
Testing
Verified the verified/market-data combinations are now independent:
Related Issues
Closes HOO-485
Checklist
pnpm test,pnpm lint,pnpm typecheck)build:infoscript to update build information