Skip to content

Commit

Permalink
Add coingecko api key option
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmota committed Mar 18, 2024
1 parent fccbc3b commit 4094796
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 35 deletions.
5 changes: 4 additions & 1 deletion cmd/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func RootCmd() *cobra.Command {
config := os.Getenv("COINTOP_CONFIG")
apiChoice := os.Getenv("COINTOP_API")
cmcAPIKey := os.Getenv("CMC_PRO_API_KEY")
coingeckoAPIKey := os.Getenv("COINGECKO_PRO_API_KEY")
perPage := cointop.DefaultPerPage
maxPages := cointop.DefaultMaxPages

Expand Down Expand Up @@ -102,6 +103,7 @@ See git.io/cointop for more info.`,
NoCache: noCache,
ConfigFilepath: config,
CoinMarketCapAPIKey: cmcAPIKey,
CoinGeckoAPIKey: coingeckoAPIKey,
APIChoice: apiChoice,
Colorscheme: colorscheme,
HideMarketbar: hideMarketbar,
Expand Down Expand Up @@ -140,7 +142,8 @@ See git.io/cointop for more info.`,
rootCmd.Flags().UintVarP(&perPage, "per-page", "", perPage, "Per page")
rootCmd.Flags().UintVarP(&maxPages, "max-pages", "", maxPages, "Max number of pages")
rootCmd.Flags().StringVarP(&config, "config", "c", config, fmt.Sprintf("Config filepath. (default %s)", cointop.DefaultConfigFilepath))
rootCmd.Flags().StringVarP(&cmcAPIKey, "coinmarketcap-api-key", "", cmcAPIKey, "Set the CoinMarketCap API key")
rootCmd.Flags().StringVarP(&cmcAPIKey, "coinmarketcap-api-key", "", cmcAPIKey, "Set the CoinMarketCap Pro API key")
rootCmd.Flags().StringVarP(&coingeckoAPIKey, "coingecko-api-key", "", coingeckoAPIKey, "Set the CoinGecko Pro API key")
rootCmd.Flags().StringVarP(&apiChoice, "api", "", apiChoice, "API choice. Available choices are \"coinmarketcap\" and \"coingecko\"")
rootCmd.Flags().StringVarP(&colorscheme, "colorscheme", "", colorscheme, fmt.Sprintf("Colorscheme to use (default \"cointop\").\n%s", cointop.ColorschemeHelpString()))
rootCmd.Flags().StringVarP(&cacheDir, "cache-dir", "", cacheDir, fmt.Sprintf("Cache directory (default %s)", cointop.DefaultCacheDir))
Expand Down
38 changes: 36 additions & 2 deletions cointop/cointop.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ type Config struct {
Colorscheme string
ConfigFilepath string
CoinMarketCapAPIKey string
CoinGeckoAPIKey string
NoPrompts bool
HideMarketbar bool
HideChart bool
Expand All @@ -185,7 +186,8 @@ type Config struct {

// APIKeys is api keys structure
type APIKeys struct {
cmc string
cmc string
coingecko string
}

// DefaultCurrency ...
Expand Down Expand Up @@ -383,6 +385,14 @@ func NewCointop(config *Config) (*Cointop, error) {
}
}

// prompt for CoinGecko api key if not found
if config.CoinGeckoAPIKey != "" {
ct.apiKeys.coingecko = config.CoinGeckoAPIKey
if err := ct.SaveConfig(); err != nil {
return nil, err
}
}

if config.Colorscheme != "" {
ct.colorschemeName = config.Colorscheme
}
Expand Down Expand Up @@ -420,10 +430,34 @@ func NewCointop(config *Config) (*Cointop, error) {
}
}

if ct.apiChoice == CoinGecko && ct.apiKeys.coingecko == "" {
apiKey := os.Getenv("COINGECKO_PRO_API_KEY")
if apiKey == "" {
// if !config.NoPrompts {
// apiKey, err = ct.ReadAPIKeyFromStdin("CoinGecko Pro")
// if err != nil {
// return nil, err
// }

// ct.apiKeys.coingecko = apiKey
// }
} else {
ct.apiKeys.coingecko = apiKey
}

if err := ct.SaveConfig(); err != nil {
return nil, err
}
}

if ct.apiChoice == CoinMarketCap {
ct.api = api.NewCMC(ct.apiKeys.cmc)
} else if ct.apiChoice == CoinGecko {
ct.api = api.NewCG(perPage, maxPages)
ct.api = api.NewCG(&api.CoinGeckoConfig{
PerPage: perPage,
MaxPages: maxPages,
ApiKey: ct.apiKeys.coingecko,
})
} else {
return nil, ErrInvalidAPIChoice
}
Expand Down
14 changes: 13 additions & 1 deletion cointop/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type ConfigFileConfig struct {
DefaultView interface{} `toml:"default_view"`
DefaultChartRange interface{} `toml:"default_chart_range"`
CoinMarketCap map[string]interface{} `toml:"coinmarketcap"`
CoinGecko map[string]interface{} `toml:"coingecko"`
API interface{} `toml:"api"`
Colorscheme interface{} `toml:"colorscheme"`
RefreshRate interface{} `toml:"refresh_rate"`
Expand Down Expand Up @@ -253,6 +254,10 @@ func (ct *Cointop) ConfigToToml() ([]byte, error) {
"pro_api_key": ct.apiKeys.cmc,
}

coingeckoIfc := map[string]interface{}{
"pro_api_key": ct.apiKeys.coingecko,
}

var priceAlertsIfc []interface{}
for _, priceAlert := range ct.State.priceAlerts.Entries {
if priceAlert.Expired {
Expand Down Expand Up @@ -287,6 +292,7 @@ func (ct *Cointop) ConfigToToml() ([]byte, error) {
API: ct.apiChoice,
Colorscheme: ct.colorschemeName,
CoinMarketCap: cmcIfc,
CoinGecko: coingeckoIfc,
Currency: ct.State.currencyConversion,
DefaultView: ct.State.defaultView,
DefaultChartRange: ct.State.defaultChartRange,
Expand Down Expand Up @@ -476,6 +482,12 @@ func (ct *Cointop) loadAPIKeysFromConfig() error {
ct.apiKeys.cmc = value.(string)
}
}
for key, value := range ct.config.CoinGecko {
k := strings.TrimSpace(strings.ToLower(key))
if k == "pro_api_key" {
ct.apiKeys.coingecko = value.(string)
}
}
return nil
}

Expand Down Expand Up @@ -541,7 +553,7 @@ func (ct *Cointop) loadAltCoinLinkFromConfig() error {

// LoadAPIChoiceFromConfig loads API choices from config file to struct
func (ct *Cointop) loadAPIChoiceFromConfig() error {
log.Debug("loadAPIKeysFromConfig()")
log.Debug("loadAPIChoiceFromConfig()")
apiChoice, ok := ct.config.API.(string)
if ok {
apiChoice = strings.TrimSpace(strings.ToLower(apiChoice))
Expand Down
5 changes: 4 additions & 1 deletion cointop/dominance.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cointop

import (
"fmt"
"os"

"github.com/cointop-sh/cointop/pkg/api"
)
Expand All @@ -22,7 +23,9 @@ func PrintBitcoinDominance(config *DominanceConfig) error {
if config.APIChoice == CoinMarketCap {
coinAPI = api.NewCMC("")
} else if config.APIChoice == CoinGecko {
coinAPI = api.NewCG(0, 0)
coinAPI = api.NewCG(&api.CoinGeckoConfig{
ApiKey: os.Getenv("COINGECKO_PRO_API_KEY"),
})
} else {
return ErrInvalidAPIChoice
}
Expand Down
5 changes: 4 additions & 1 deletion cointop/price.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cointop
import (
"fmt"
"math"
"os"
"strings"

"github.com/cointop-sh/cointop/pkg/api"
Expand Down Expand Up @@ -57,7 +58,9 @@ func GetCoinPrices(config *PricesConfig) ([]string, error) {
if config.APIChoice == CoinMarketCap {
priceAPI = api.NewCMC("")
} else if config.APIChoice == CoinGecko {
priceAPI = api.NewCG(0, 0)
priceAPI = api.NewCG(&api.CoinGeckoConfig{
ApiKey: os.Getenv("COINGECKO_PRO_API_KEY"),
})
} else {
return nil, ErrInvalidAPIChoice
}
Expand Down
21 changes: 21 additions & 0 deletions docs/content/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,27 @@ draft: false
cointop --coinmarketcap-api-key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

## How do I add my CoinGecko Pro API key?

Add the API key in the cointop config file:

```toml
[coingecko]
pro_api_key = "CG-xxxxxxxxxxxxxxxxxxxxxxxx"
```

Alternatively, you can export the environment variable `COINGECKO_PRO_API_KEY` containing the API key in your `~/.bashrc`

```bash
export COINGECKO_PRO_API_KEY=CG-xxxxxxxxxxxxxxxxxxxxxxxx
```

You may also set the API key on start:

```bash
cointop --coingecko-api-key=CG-xxxxxxxxxxxxxxxxxxxxxxxx
```

## I can I add my own API to cointop?

Fork cointop and add the API that implements the API [interface](https://github.com/cointop-sh/cointop/blob/master/cointop/common/api/interface.go) to [`cointop/cointop/common/api/impl/`](https://github.com/cointop-sh/cointop/tree/master/cointop/common/api/impl). You can use the CoinGecko [implementation](https://github.com/cointop-sh/cointop/blob/master/cointop/common/api/impl/coingecko/coingecko.go) as reference.
Expand Down
13 changes: 10 additions & 3 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import (
cmc "github.com/cointop-sh/cointop/pkg/api/impl/coinmarketcap"
)

type CoinGeckoConfig struct {
PerPage uint
MaxPages uint
ApiKey string
}

// NewCMC new CoinMarketCap API
func NewCMC(apiKey string) Interface {
return cmc.NewCMC(apiKey)
Expand All @@ -16,9 +22,10 @@ func NewCC() {
}

// NewCG new CoinGecko API
func NewCG(perPage, maxPages uint) Interface {
func NewCG(config *CoinGeckoConfig) Interface {
return cg.NewCoinGecko(&cg.Config{
PerPage: perPage,
MaxPages: maxPages,
PerPage: config.PerPage,
MaxPages: config.MaxPages,
ApiKey: config.ApiKey,
})
}
3 changes: 2 additions & 1 deletion pkg/api/impl/coingecko/coingecko.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var ErrNotFound = errors.New("not found")
type Config struct {
PerPage uint
MaxPages uint
ApiKey string
}

// Service service
Expand All @@ -52,7 +53,7 @@ func NewCoinGecko(config *Config) *Service {
maxPages = uint(math.Ceil(math.Max(float64(maxResults)/float64(maxResultsPerPage), 1)))
}

client := gecko.NewClient(nil)
client := gecko.NewClient(nil, config.ApiKey)
svc := &Service{
client: client,
maxResultsPerPage: uint(math.Min(float64(maxResults), float64(maxResultsPerPage))),
Expand Down

0 comments on commit 4094796

Please sign in to comment.