Skip to content

feat(pricing): expose CoinGecko /simple/price proxy endpoint #3712

@TaprootFreak

Description

@TaprootFreak

Context

The dfx-wallet app currently calls CoinGecko directly for dynamic token price discovery:

Goal: route this traffic through api.dfx.swiss so we

  • avoid leaking client IPs / fingerprints to CoinGecko,
  • benefit from the central CoinGecko Pro key + caching,
  • protect the app against CoinGecko free-tier rate limits.

Proposal

Add a public, unauthenticated endpoint that mirrors the upstream shape:

GET /v1/pricing/simple-price?ids=<comma-list>&vs_currencies=<comma-list>

Response identical to CoinGecko's simple/price (so the wallet only needs to swap the base URL):

{
  "bitcoin":  { "usd": 67000, "eur": 62000 },
  "ethereum": { "usd": 3500,  "eur": 3240  }
}

Implementation notes

  • Live next to existing PricingController (src/subdomains/supporting/pricing/pricing.controller.ts).
  • Reuse CoinGeckoService / CoinGeckoClientclient.simplePrice({ ids, vs_currencies }) already returns the right shape (coin-gecko.service.ts:94).
  • Validate inputs: cap ids at 100 (CoinGecko free-tier URL length limit, also what the wallet already chunks at), whitelist vs_currencies against simpleSupportedCurrencies().
  • Cache responses (60s TTL matches the internal pricing-proxy).
  • Alternatively front this with the existing pricing-proxy service on dfxprd/dfxdev — same cache, same key. Either approach is fine; pass-through via CoinGeckoService is the smaller diff.

Out of scope

  • /coins/list endpoint (separate issue — also called by the wallet for token discovery validation).
  • Contract-based price lookups (existing internal getRawPrice already covers that path for backend consumers).

Follow-up (wallet side)

Once the endpoint is live, the wallet swaps the constant in coingecko-simple-price.ts to \${DFX_API_URL}/v1/pricing/simple-price and drops the direct CoinGecko call.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions