Skip to content

Commit

Permalink
Add option for coingecko demo api key
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmota committed Apr 7, 2024
1 parent 4094796 commit cbe3557
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 29 deletions.
7 changes: 5 additions & 2 deletions cmd/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ 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")
coingeckoAPIKey := os.Getenv("COINGECKO_API_KEY")
coingeckoProAPIKey := os.Getenv("COINGECKO_PRO_API_KEY")
perPage := cointop.DefaultPerPage
maxPages := cointop.DefaultMaxPages

Expand Down Expand Up @@ -104,6 +105,7 @@ See git.io/cointop for more info.`,
ConfigFilepath: config,
CoinMarketCapAPIKey: cmcAPIKey,
CoinGeckoAPIKey: coingeckoAPIKey,
CoinGeckoProAPIKey: coingeckoProAPIKey,
APIChoice: apiChoice,
Colorscheme: colorscheme,
HideMarketbar: hideMarketbar,
Expand Down Expand Up @@ -143,7 +145,8 @@ See git.io/cointop for more info.`,
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 Pro API key")
rootCmd.Flags().StringVarP(&coingeckoAPIKey, "coingecko-api-key", "", coingeckoAPIKey, "Set the CoinGecko Pro API key")
rootCmd.Flags().StringVarP(&coingeckoAPIKey, "coingecko-api-key", "", coingeckoAPIKey, "Set the CoinGecko Demo API key")
rootCmd.Flags().StringVarP(&coingeckoProAPIKey, "coingecko-pro-api-key", "", coingeckoProAPIKey, "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
45 changes: 37 additions & 8 deletions cointop/cointop.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ type Config struct {
ConfigFilepath string
CoinMarketCapAPIKey string
CoinGeckoAPIKey string
CoinGeckoProAPIKey string
NoPrompts bool
HideMarketbar bool
HideChart bool
Expand All @@ -186,8 +187,9 @@ type Config struct {

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

// DefaultCurrency ...
Expand Down Expand Up @@ -385,14 +387,20 @@ 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.CoinGeckoProAPIKey != "" {
ct.apiKeys.coingeckoPro = config.CoinGeckoProAPIKey
if err := ct.SaveConfig(); err != nil {
return nil, err
}
}

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

if ct.apiChoice == CoinGecko && ct.apiKeys.coingecko == "" {
apiKey := os.Getenv("COINGECKO_PRO_API_KEY")
apiKey := os.Getenv("COINGECKO_API_KEY")
if apiKey == "" {
// if !config.NoPrompts {
// apiKey, err = ct.ReadAPIKeyFromStdin("CoinGecko Pro")
// apiKey, err = ct.ReadAPIKeyFromStdin("CoinGecko")
// if err != nil {
// return nil, err
// }
Expand All @@ -450,13 +458,34 @@ func NewCointop(config *Config) (*Cointop, error) {
}
}

if ct.apiChoice == CoinGecko && ct.apiKeys.coingeckoPro == "" {
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.coingeckoPro = apiKey
// }
} else {
ct.apiKeys.coingeckoPro = 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(&api.CoinGeckoConfig{
PerPage: perPage,
MaxPages: maxPages,
ApiKey: ct.apiKeys.coingecko,
PerPage: perPage,
MaxPages: maxPages,
ApiKey: ct.apiKeys.coingecko,
ProApiKey: ct.apiKeys.coingeckoPro,
})
} else {
return nil, ErrInvalidAPIChoice
Expand Down
8 changes: 6 additions & 2 deletions cointop/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ func (ct *Cointop) ConfigToToml() ([]byte, error) {
}

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

var priceAlertsIfc []interface{}
Expand Down Expand Up @@ -484,9 +485,12 @@ func (ct *Cointop) loadAPIKeysFromConfig() error {
}
for key, value := range ct.config.CoinGecko {
k := strings.TrimSpace(strings.ToLower(key))
if k == "pro_api_key" {
if k == "api_key" {
ct.apiKeys.coingecko = value.(string)
}
if k == "pro_api_key" {
ct.apiKeys.coingeckoPro = value.(string)
}
}
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion cointop/price.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ func GetCoinPrices(config *PricesConfig) ([]string, error) {
priceAPI = api.NewCMC("")
} else if config.APIChoice == CoinGecko {
priceAPI = api.NewCG(&api.CoinGeckoConfig{
ApiKey: os.Getenv("COINGECKO_PRO_API_KEY"),
ApiKey: os.Getenv("COINGECKO_API_KEY"),
ProApiKey: os.Getenv("COINGECKO_PRO_API_KEY"),
})
} else {
return nil, ErrInvalidAPIChoice
Expand Down
3 changes: 3 additions & 0 deletions docs/content/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ refresh_rate = 60

[coinmarketcap]
pro_api_key = ""

[coingecko]
pro_api_key = ""
```

## List of actions
Expand Down
27 changes: 24 additions & 3 deletions docs/content/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ draft: false

Run cointop with the `--clean` flag to delete the cache. If you're still not seeing any data, then please [submit an issue](https://github.com/cointop-sh/cointop/issues/new).

## How do I get a CoinMarketCap Pro API key?
## How do I get a CoinMarketCap Pro (Paid) API key?

Create an account on [CoinMarketCap](https://pro.coinmarketcap.com/signup) and visit the [Account](https://pro.coinmarketcap.com/account) page to copy your Pro API key.

Expand All @@ -122,7 +122,28 @@ draft: false
cointop --coinmarketcap-api-key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

## How do I add my CoinGecko Pro API key?
## How do I add my CoinGecko Demo (Free) API key?

Add the API key in the cointop config file:

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

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

```bash
export COINGECKO_API_KEY=CG-xxxxxxxxxxxxxxxxxxxxxxxx
```

You may also set the API key on start:

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

## How do I add my CoinGecko Pro (Paid) API key?

Add the API key in the cointop config file:

Expand All @@ -140,7 +161,7 @@ draft: false
You may also set the API key on start:

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

## I can I add my own API to cointop?
Expand Down
14 changes: 8 additions & 6 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import (
)

type CoinGeckoConfig struct {
PerPage uint
MaxPages uint
ApiKey string
PerPage uint
MaxPages uint
ApiKey string
ProApiKey string
}

// NewCMC new CoinMarketCap API
Expand All @@ -24,8 +25,9 @@ func NewCC() {
// NewCG new CoinGecko API
func NewCG(config *CoinGeckoConfig) Interface {
return cg.NewCoinGecko(&cg.Config{
PerPage: config.PerPage,
MaxPages: config.MaxPages,
ApiKey: config.ApiKey,
PerPage: config.PerPage,
MaxPages: config.MaxPages,
ApiKey: config.ApiKey,
ProApiKey: config.ProApiKey,
})
}
9 changes: 5 additions & 4 deletions pkg/api/impl/coingecko/coingecko.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ var ErrNotFound = errors.New("not found")

// Config config
type Config struct {
PerPage uint
MaxPages uint
ApiKey string
PerPage uint
MaxPages uint
ApiKey string
ProApiKey string
}

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

client := gecko.NewClient(nil, config.ApiKey)
client := gecko.NewClient(nil, config.ApiKey, config.ProApiKey)
svc := &Service{
client: client,
maxResultsPerPage: uint(math.Min(float64(maxResults), float64(maxResultsPerPage))),
Expand Down
10 changes: 7 additions & 3 deletions pkg/api/vendors/coingecko/v3/v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ import (
type Client struct {
httpClient *http.Client
apiKey string
proApiKey string
}

// NewClient create new client object
func NewClient(httpClient *http.Client, apiKey string) *Client {
func NewClient(httpClient *http.Client, apiKey string, proApiKey string) *Client {
if httpClient == nil {
httpClient = http.DefaultClient
}
return &Client{httpClient: httpClient, apiKey: apiKey}
return &Client{httpClient: httpClient, apiKey: apiKey, proApiKey: proApiKey}
}

// helper
Expand Down Expand Up @@ -64,8 +65,11 @@ func (c *Client) getApiUrl(path string, params *url.Values) string {
urlParams = *params
}
if c.apiKey != "" {
urlParams.Add("x_cg_demo_api_key", c.apiKey)
}
if c.proApiKey != "" {
subdomain = "pro-api"
urlParams.Add("x_cg_pro_api_key", c.apiKey)
urlParams.Add("x_cg_pro_api_key", c.proApiKey)
}
url := fmt.Sprintf("https://%s.coingecko.com/api/v3%s?%s", subdomain, path, urlParams.Encode())
return url
Expand Down

0 comments on commit cbe3557

Please sign in to comment.