From e04aea983465c36c7658ea5dec4a871c3533b8fe Mon Sep 17 00:00:00 2001 From: Viktor Baranov Date: Tue, 18 Jul 2023 16:53:04 +0300 Subject: [PATCH] Add EXCHANGE_RATES_COINMARKETCAP_COIN_ID env var --- CHANGELOG.md | 1 + .../exchange_rates/source/coin_market_cap.ex | 16 +++++++- .../exchange_rates/source/coin_gecko_test.exs | 32 ++++++++++++++++ .../source/coin_market_cap_test.exs | 37 +++++++++++++++++++ config/runtime.exs | 3 +- docker-compose/envs/common-blockscout.env | 1 + docker/Makefile | 3 ++ 7 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 776dfb3671..f87304fd26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - [#7771](https://github.com/blockscout/blockscout/pull/7771) - CSV export: speed up +- [#7962](https://github.com/blockscout/blockscout/pull/7962) - Allow indicate CMC id of the coin through env var - [#7946](https://github.com/blockscout/blockscout/pull/7946) - API v2 rate limit: Put token to cookies & change /api/v2/key method - [#7888](https://github.com/blockscout/blockscout/pull/7888) - Add token balances info to watchlist address response - [#7898](https://github.com/blockscout/blockscout/pull/7898) - Add possibility to add extra headers with JSON RPC URL diff --git a/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex b/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex index b8b1b8fd75..fb1b5472a3 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex @@ -55,8 +55,18 @@ defmodule Explorer.ExchangeRates.Source.CoinMarketCap do def source_url do coin = Explorer.coin() symbol = if coin, do: String.upcase(Explorer.coin()), else: nil + coin_id = coin_id() - if symbol, do: "#{api_quotes_latest_url()}?symbol=#{symbol}&CMC_PRO_API_KEY=#{api_key()}", else: nil + cond do + coin_id -> + "#{api_quotes_latest_url()}?id=#{coin_id}&CMC_PRO_API_KEY=#{api_key()}" + + symbol -> + "#{api_quotes_latest_url()}?symbol=#{symbol}&CMC_PRO_API_KEY=#{api_key()}" + + true -> + nil + end end @impl Source @@ -84,6 +94,10 @@ defmodule Explorer.ExchangeRates.Source.CoinMarketCap do config(:api_key) end + defp coin_id do + config(:coin_id) + end + defp get_token_properties(market_data) do token_values_list = market_data diff --git a/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs b/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs index 9f28e12814..cd5148c4fb 100644 --- a/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs +++ b/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs @@ -58,6 +58,38 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do ] """ + describe "source_url/1" do + setup do + bypass = Bypass.open() + Application.put_env(:explorer, CoinGecko, base_url: "https://api.coingecko.com/api/v3") + + {:ok, bypass: bypass} + end + + test "composes cg :coins_list URL" do + assert "https://api.coingecko.com/api/v3/coins/list?include_platform=true" == CoinGecko.source_url(:coins_list) + end + + test "composes cg url to list of contract address hashes" do + assert "https://api.coingecko.com/api/v3/simple/token_price/ethereum?vs_currencies=usd&include_market_cap=true&contract_addresses=0xdAC17F958D2ee523a2206206994597C13D831ec7" == + CoinGecko.source_url(["0xdAC17F958D2ee523a2206206994597C13D831ec7"]) + end + + test "composes cg url by contract address hash" do + assert "https://api.coingecko.com/api/v3/coins/ethereum/contract/0xdAC17F958D2ee523a2206206994597C13D831ec7" == + CoinGecko.source_url("0xdAC17F958D2ee523a2206206994597C13D831ec7") + end + + test "composes cg url by contract address hash with custom coin_id" do + Application.put_env(:explorer, CoinGecko, platform: "poa-network") + + assert "https://api.coingecko.com/api/v3/coins/poa-network/contract/0xdAC17F958D2ee523a2206206994597C13D831ec7" == + CoinGecko.source_url("0xdAC17F958D2ee523a2206206994597C13D831ec7") + + Application.put_env(:explorer, CoinGecko, platform: nil) + end + end + describe "format_data/1" do setup do bypass = Bypass.open() diff --git a/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs b/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs new file mode 100644 index 0000000000..c9bfea7ad1 --- /dev/null +++ b/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs @@ -0,0 +1,37 @@ +defmodule Explorer.ExchangeRates.Source.CoinMarketCapTest do + use ExUnit.Case + + alias Explorer.ExchangeRates.Source.CoinMarketCap + + describe "source_url/0" do + test "returns default cmc source url" do + assert "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol=ETH&CMC_PRO_API_KEY=" == + CoinMarketCap.source_url() + end + + test "returns cmc source url with not default symbol" do + Application.put_env(:explorer, :coin, "ETC") + + assert "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol=ETC&CMC_PRO_API_KEY=" == + CoinMarketCap.source_url() + + Application.put_env(:explorer, :coin, "ETH") + end + + test "returns cmc source url with id" do + Application.put_env(:explorer, CoinMarketCap, coin_id: 100_500) + + assert "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?id=100500&CMC_PRO_API_KEY=" == + CoinMarketCap.source_url() + + Application.put_env(:explorer, CoinMarketCap, coin_id: nil) + end + end + + describe "source_url/1" do + test "returns cmc source url for symbol" do + assert "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol=ETH&CMC_PRO_API_KEY=" == + CoinMarketCap.source_url("ETH") + end + end +end diff --git a/config/runtime.exs b/config/runtime.exs index 0619c6ad37..37818f36a5 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -269,7 +269,8 @@ config :explorer, Explorer.ExchangeRates, config :explorer, Explorer.ExchangeRates.Source, source: ConfigHelper.exchange_rates_source() config :explorer, Explorer.ExchangeRates.Source.CoinMarketCap, - api_key: System.get_env("EXCHANGE_RATES_COINMARKETCAP_API_KEY") + api_key: System.get_env("EXCHANGE_RATES_COINMARKETCAP_API_KEY"), + coin_id: System.get_env("EXCHANGE_RATES_COINMARKETCAP_COIN_ID") config :explorer, Explorer.ExchangeRates.Source.CoinGecko, platform: System.get_env("EXCHANGE_RATES_COINGECKO_PLATFORM_ID"), diff --git a/docker-compose/envs/common-blockscout.env b/docker-compose/envs/common-blockscout.env index 7ec20be1fc..c7dfa9eae6 100644 --- a/docker-compose/envs/common-blockscout.env +++ b/docker-compose/envs/common-blockscout.env @@ -35,6 +35,7 @@ EXCHANGE_RATES_COIN= # EXCHANGE_RATES_COINGECKO_COIN_ID= # EXCHANGE_RATES_COINGECKO_API_KEY= # EXCHANGE_RATES_COINMARKETCAP_API_KEY= +# EXCHANGE_RATES_COINMARKETCAP_COIN_ID= POOL_SIZE=90 # EXCHANGE_RATES_COINGECKO_PLATFORM_ID= # TOKEN_EXCHANGE_RATE_INTERVAL= diff --git a/docker/Makefile b/docker/Makefile index 36a704e224..d985b5ca21 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -240,6 +240,9 @@ endif ifdef EXCHANGE_RATES_COINMARKETCAP_API_KEY BLOCKSCOUT_CONTAINER_PARAMS += -e 'EXCHANGE_RATES_COINMARKETCAP_API_KEY=$(EXCHANGE_RATES_COINMARKETCAP_API_KEY)' endif +ifdef EXCHANGE_RATES_COINMARKETCAP_COIN_ID + BLOCKSCOUT_CONTAINER_PARAMS += -e 'EXCHANGE_RATES_COINMARKETCAP_COIN_ID=$(EXCHANGE_RATES_COINMARKETCAP_COIN_ID)' +endif ifdef DISABLE_EXCHANGE_RATES BLOCKSCOUT_CONTAINER_PARAMS += -e 'DISABLE_EXCHANGE_RATES=$(DISABLE_EXCHANGE_RATES)' endif