From 609d87e9c596587854d4f2b66b0c816539144aa5 Mon Sep 17 00:00:00 2001 From: RampantDespair Date: Sun, 23 Nov 2025 17:15:32 -0500 Subject: [PATCH] Enhance CoinGecko integration by adding support for plan parameter in downloader. Updated NewCoinGeckoDownloader and related methods to handle different API keys based on the plan type. --- fiat/coingecko.go | 30 ++++++++++++++++++++---------- fiat/fiat_rates.go | 3 ++- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/fiat/coingecko.go b/fiat/coingecko.go index 7e79dd42..3a83c647 100644 --- a/fiat/coingecko.go +++ b/fiat/coingecko.go @@ -38,6 +38,7 @@ type Coingecko struct { updatingCurrent bool updatingTokens bool metrics *common.Metrics + plan string } // simpleSupportedVSCurrencies https://api.coingecko.com/api/v3/simple/supported_vs_currencies @@ -59,7 +60,7 @@ type marketChartPrices struct { } // NewCoinGeckoDownloader creates a coingecko structure that implements the RatesDownloaderInterface -func NewCoinGeckoDownloader(db *db.RocksDB, network string, url string, coin string, platformIdentifier string, platformVsCurrency string, allowedVsCurrencies string, timeFormat string, metrics *common.Metrics, throttleDown bool) RatesDownloaderInterface { +func NewCoinGeckoDownloader(db *db.RocksDB, network string, url string, coin string, platformIdentifier string, platformVsCurrency string, allowedVsCurrencies string, timeFormat string, plan string, metrics *common.Metrics, throttleDown bool) RatesDownloaderInterface { throttlingDelayMs := 0 // No delay by default if throttleDown { throttlingDelayMs = DefaultThrottleDelayMs @@ -74,10 +75,15 @@ func NewCoinGeckoDownloader(db *db.RocksDB, network string, url string, coin str // use default address if not overridden, with respect to existence of apiKey if url == "" { - if apiKey != "" { - url = "https://pro-api.coingecko.com/api/v3/" + const ( + proURL = "https://pro-api.coingecko.com/api/v3" + freeURL = "https://api.coingecko.com/api/v3" + ) + + if apiKey != "" && (plan == "pro" || plan == "") { + url = proURL } else { - url = "https://api.coingecko.com/api/v3" + url = freeURL } } glog.Info("Coingecko downloader url ", url) @@ -129,7 +135,7 @@ func doReq(req *http.Request, client *http.Client) ([]byte, error) { } // makeReq HTTP request helper - will retry the call after 1 minute on error -func (cg *Coingecko) makeReq(url string, endpoint string) ([]byte, error) { +func (cg *Coingecko) makeReq(url string, endpoint string, plan string) ([]byte, error) { for { // glog.Infof("Coingecko makeReq %v", url) req, err := http.NewRequest("GET", url, nil) @@ -138,7 +144,11 @@ func (cg *Coingecko) makeReq(url string, endpoint string) ([]byte, error) { } req.Header.Set("Content-Type", "application/json") if cg.apiKey != "" { - req.Header.Set("x-cg-pro-api-key", cg.apiKey) + if plan == "pro" { + req.Header.Set("x-cg-pro-api-key", cg.apiKey) + } else { + req.Header.Set("x-cg-demo-api-key", cg.apiKey) + } } resp, err := doReq(req, cg.httpClient) if err == nil { @@ -166,7 +176,7 @@ func (cg *Coingecko) makeReq(url string, endpoint string) ([]byte, error) { // SimpleSupportedVSCurrencies /simple/supported_vs_currencies func (cg *Coingecko) simpleSupportedVSCurrencies() (simpleSupportedVSCurrencies, error) { url := cg.url + "/simple/supported_vs_currencies" - resp, err := cg.makeReq(url, "supported_vs_currencies") + resp, err := cg.makeReq(url, "supported_vs_currencies", cg.plan) if err != nil { return nil, err } @@ -197,7 +207,7 @@ func (cg *Coingecko) simplePrice(ids []string, vsCurrencies []string) (*map[stri params.Add("vs_currencies", vsCurrenciesParam) url := fmt.Sprintf("%s/simple/price?%s", cg.url, params.Encode()) - resp, err := cg.makeReq(url, "simple/price") + resp, err := cg.makeReq(url, "simple/price", cg.plan) if err != nil { return nil, err } @@ -220,7 +230,7 @@ func (cg *Coingecko) coinsList() (coinList, error) { } params.Add("include_platform", platform) url := fmt.Sprintf("%s/coins/list?%s", cg.url, params.Encode()) - resp, err := cg.makeReq(url, "coins/list") + resp, err := cg.makeReq(url, "coins/list", cg.plan) if err != nil { return nil, err } @@ -247,7 +257,7 @@ func (cg *Coingecko) coinMarketChart(id string, vs_currency string, days string, params.Add("days", days) url := fmt.Sprintf("%s/coins/%s/market_chart?%s", cg.url, id, params.Encode()) - resp, err := cg.makeReq(url, "market_chart") + resp, err := cg.makeReq(url, "market_chart", cg.plan) if err != nil { return nil, err } diff --git a/fiat/fiat_rates.go b/fiat/fiat_rates.go index 8a2d4bd4..8689bb11 100644 --- a/fiat/fiat_rates.go +++ b/fiat/fiat_rates.go @@ -80,6 +80,7 @@ func NewFiatRates(db *db.RocksDB, config *common.Config, metrics *common.Metrics PlatformIdentifier string `json:"platformIdentifier"` PlatformVsCurrency string `json:"platformVsCurrency"` PeriodSeconds int64 `json:"periodSeconds"` + Plan string `json:"plan"` } rdParams := &fiatRatesParams{} err := json.Unmarshal([]byte(config.FiatRatesParams), &rdParams) @@ -108,7 +109,7 @@ func NewFiatRates(db *db.RocksDB, config *common.Config, metrics *common.Metrics // a small hack - in tests the callback is not used, therefore there is no delay slowing down the test throttle = false } - fr.downloader = NewCoinGeckoDownloader(db, db.GetInternalState().GetNetwork(), rdParams.URL, rdParams.Coin, rdParams.PlatformIdentifier, rdParams.PlatformVsCurrency, fr.allowedVsCurrencies, fr.timeFormat, metrics, throttle) + fr.downloader = NewCoinGeckoDownloader(db, db.GetInternalState().GetNetwork(), rdParams.URL, rdParams.Coin, rdParams.PlatformIdentifier, rdParams.PlatformVsCurrency, fr.allowedVsCurrencies, fr.timeFormat, rdParams.Plan, metrics, throttle) if is != nil { is.HasFiatRates = true is.HasTokenFiatRates = fr.downloadTokens