use CoinGecko instead of CoinMarketcap for exchange rates

CoinMarketcap deprecated and took offline its v1 API. They have
v2 API which has free plan and requires API keys. But as part of
https://github.com/poanetwork/blockscout/issues/234 we alresy
implemented fetching from CoinGecko.

Now, coin id should be set for CoinGecko for the required coin.
```
config :explorer, Explorer.ExchangeRates.Source.CoinGecko,
  coin_id: System.get_env("COIN_GECKO_ID", "poa-network")
```
Or the `COIN_GECKO_ID` env var should be set. For example, COIN_GECKO_ID=poa-network
pull/2610/head
Ayrat Badykov 5 years ago
parent e9d7b7cf51
commit 0da2afb1ca
No known key found for this signature in database
GPG Key ID: B44668E265E9396F
  1. 2
      apps/explorer/config/config.exs
  2. 2
      apps/explorer/lib/explorer/chain.ex
  3. 4
      apps/explorer/lib/explorer/chain/supply/exchange_rate.ex
  4. 2
      apps/explorer/lib/explorer/exchange_rates/source.ex
  5. 38
      apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex

@ -34,6 +34,8 @@ config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: true
config :explorer, Explorer.ExchangeRates.Source.CoinMarketCap, config :explorer, Explorer.ExchangeRates.Source.CoinMarketCap,
pages: String.to_integer(System.get_env("COINMARKETCAP_PAGES") || "10") pages: String.to_integer(System.get_env("COINMARKETCAP_PAGES") || "10")
config :explorer, Explorer.ExchangeRates.Source.CoinGecko, coin_id: System.get_env("COIN_GECKO_ID", "poa-network")
balances_update_interval = balances_update_interval =
if System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL") do if System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL") do
case Integer.parse(System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL")) do case Integer.parse(System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL")) do

@ -2717,7 +2717,7 @@ defmodule Explorer.Chain do
end end
defp supply_module do defp supply_module do
Application.get_env(:explorer, :supply, Explorer.Chain.Supply.CoinMarketCap) Application.get_env(:explorer, :supply, Explorer.Chain.Supply.ExchangeRate)
end end
@doc """ @doc """

@ -1,6 +1,6 @@
defmodule Explorer.Chain.Supply.CoinMarketCap do defmodule Explorer.Chain.Supply.ExchangeRate do
@moduledoc """ @moduledoc """
Defines the supply API for calculating supply for coins from coinmarketcap. Defines the supply API for calculating supply for coins from exchange_rate..
""" """
use Explorer.Chain.Supply use Explorer.Chain.Supply

@ -83,7 +83,7 @@ defmodule Explorer.ExchangeRates.Source do
@spec exchange_rates_source() :: module() @spec exchange_rates_source() :: module()
defp exchange_rates_source do defp exchange_rates_source do
config(:source) || Explorer.ExchangeRates.Source.CoinMarketCap config(:source) || Explorer.ExchangeRates.Source.CoinGecko
end end
@spec config(atom()) :: term @spec config(atom()) :: term

@ -15,39 +15,45 @@ defmodule Explorer.ExchangeRates.Source.CoinGecko do
{:ok, price} = get_btc_price() {:ok, price} = get_btc_price()
btc_price = to_decimal(price) btc_price = to_decimal(price)
for item <- decode_json(data), json_data = decode_json(data)
not is_nil(item["total_supply"]) and not is_nil(item["current_price"]) do
{:ok, last_updated, 0} = DateTime.from_iso8601(item["last_updated"])
current_price = to_decimal(item["current_price"]) market_data = json_data["market_data"]
{:ok, last_updated, 0} = DateTime.from_iso8601(market_data["last_updated"])
id = item["id"] current_price = to_decimal(market_data["current_price"]["usd"])
btc_value = if id != "btc", do: Decimal.div(current_price, btc_price), else: 1
id = json_data["id"]
btc_value = if id != "btc", do: Decimal.div(current_price, btc_price), else: 1
[
%Token{ %Token{
available_supply: to_decimal(item["total_supply"]), available_supply: to_decimal(market_data["circulating_supply"]),
total_supply: to_decimal(item["total_supply"]), total_supply: to_decimal(market_data["total_supply"]),
btc_value: btc_value, btc_value: btc_value,
id: id, id: json_data["id"],
last_updated: last_updated, last_updated: last_updated,
market_cap_usd: to_decimal(item["market_cap"]), market_cap_usd: to_decimal(market_data["market_cap"]["usd"]),
name: item["name"], name: json_data["name"],
symbol: item["symbol"], symbol: String.upcase(json_data["symbol"]),
usd_value: current_price, usd_value: current_price,
volume_24h_usd: to_decimal(item["total_volume"]) volume_24h_usd: to_decimal(market_data["total_volume"]["usd"])
} }
end ]
end end
@impl Source @impl Source
def source_url(currency \\ "usd") do def source_url do
"#{base_url()}/coins/markets?vs_currency=#{currency}" "#{base_url()}/coins/#{coin_id()}"
end end
defp base_url do defp base_url do
config(:base_url) || "https://api.coingecko.com/api/v3" config(:base_url) || "https://api.coingecko.com/api/v3"
end end
defp coin_id do
Application.get_env(:explorer, __MODULE__)[:coin_id]
end
defp get_btc_price(currency \\ "usd") do defp get_btc_price(currency \\ "usd") do
url = "#{base_url()}/exchange_rates" url = "#{base_url()}/exchange_rates"

Loading…
Cancel
Save