diff --git a/apps/block_scout_web/assets/css/components/_dashboard-banner.scss b/apps/block_scout_web/assets/css/components/_dashboard-banner.scss index 47e9ce2d9d..4cedaefe3b 100644 --- a/apps/block_scout_web/assets/css/components/_dashboard-banner.scss +++ b/apps/block_scout_web/assets/css/components/_dashboard-banner.scss @@ -63,6 +63,8 @@ .dashboard-banner-chart { grid-area: chart; padding: 1rem 1rem 1rem 0; + width: calc(350px + 1rem); + height: calc(152px + 1rem); } .dashboard-banner-chart-legend { diff --git a/apps/block_scout_web/assets/js/lib/market_history_chart.js b/apps/block_scout_web/assets/js/lib/market_history_chart.js index db6c112876..a54ac50935 100644 --- a/apps/block_scout_web/assets/js/lib/market_history_chart.js +++ b/apps/block_scout_web/assets/js/lib/market_history_chart.js @@ -1,3 +1,4 @@ +import $ from 'jquery' import Chart from 'chart.js' import humps from 'humps' import numeral from 'numeral' @@ -122,8 +123,28 @@ class MarketHistoryChart { } export function createMarketHistoryChart (el) { - const availableSupply = JSON.parse(el.dataset.available_supply) - const marketHistoryData = humps.camelizeKeys(JSON.parse(el.dataset.market_history_data)) - - return new MarketHistoryChart(el, availableSupply, marketHistoryData) + const dataPath = el.dataset.market_history_chart_path + const $chartLoading = $('[data-chart-loading-message]') + const $chartError = $('[data-chart-error-message]') + const chart = new MarketHistoryChart(el, 0, []) + $.getJSON(dataPath, {type: 'JSON'}) + .done(data => { + const availableSupply = JSON.parse(data.supply_data) + const marketHistoryData = humps.camelizeKeys(JSON.parse(data.history_data)) + $(el).show() + chart.update(availableSupply, marketHistoryData) + }) + .fail(() => { + $chartError.show() + }) + .always(() => { + $chartLoading.hide() + }) + return chart } + +$('[data-chart-error-message]').on('click', _event => { + $('[data-chart-loading-message]').show() + $('[data-chart-error-message]').hide() + createMarketHistoryChart($('[data-chart="marketHistoryChart"]')[0]) +}) diff --git a/apps/block_scout_web/assets/js/pages/chain.js b/apps/block_scout_web/assets/js/pages/chain.js index c7dfe2ce86..910d228cf6 100644 --- a/apps/block_scout_web/assets/js/pages/chain.js +++ b/apps/block_scout_web/assets/js/pages/chain.js @@ -139,7 +139,7 @@ const elements = { chart = createMarketHistoryChart($el[0]) }, render ($el, state, oldState) { - if (oldState.availableSupply === state.availableSupply && oldState.marketHistoryData === state.marketHistoryData) return + if (!chart || (oldState.availableSupply === state.availableSupply && oldState.marketHistoryData === state.marketHistoryData)) return chart.update(state.availableSupply, state.marketHistoryData) } }, diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/chain/market_history_chart_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/chain/market_history_chart_controller.ex new file mode 100644 index 0000000000..4a498b8430 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/chain/market_history_chart_controller.ex @@ -0,0 +1,51 @@ +defmodule BlockScoutWeb.Chain.MarketHistoryChartController do + use BlockScoutWeb, :controller + + alias Explorer.{Chain, Market} + alias Explorer.ExchangeRates.Token + + def show(conn, _params) do + with true <- ajax?(conn) do + exchange_rate = Market.get_exchange_rate(Explorer.coin()) || Token.null() + + market_history_data = + 30 + |> Market.fetch_recent_history() + |> case do + [today | the_rest] -> [%{today | closing_price: exchange_rate.usd_value} | the_rest] + data -> data + end + |> encode_market_history_data() + + json(conn, %{ + history_data: market_history_data, + supply_data: available_supply(Chain.supply_for_days(30), exchange_rate) + }) + else + _ -> unprocessable_entity(conn) + end + end + + defp available_supply(:ok, exchange_rate) do + to_string(exchange_rate.available_supply || 0) + end + + defp available_supply({:ok, supply_for_days}, _exchange_rate) do + supply_for_days + |> Jason.encode() + |> case do + {:ok, data} -> data + _ -> [] + end + end + + defp encode_market_history_data(market_history_data) do + market_history_data + |> Enum.map(fn day -> Map.take(day, [:closing_price, :date]) end) + |> Jason.encode() + |> case do + {:ok, data} -> data + _ -> [] + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/chain_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/chain_controller.ex index 2a27bff4b6..ca16c28978 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/chain_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/chain_controller.ex @@ -13,20 +13,13 @@ defmodule BlockScoutWeb.ChainController do exchange_rate = Market.get_exchange_rate(Explorer.coin()) || Token.null() - market_history_data = - case Market.fetch_recent_history(30) do - [today | the_rest] -> [%{today | closing_price: exchange_rate.usd_value} | the_rest] - data -> data - end - render( conn, "show.html", address_count: Chain.count_addresses_with_balance_from_cache(), average_block_time: Chain.average_block_time(), exchange_rate: exchange_rate, - available_supply: available_supply(Chain.supply_for_days(30), exchange_rate), - market_history_data: market_history_data, + chart_data_path: market_history_chart_path(conn, :show), transaction_estimated_count: transaction_estimated_count, transactions_path: recent_transactions_path(conn, :index) ) @@ -88,17 +81,4 @@ defmodule BlockScoutWeb.ChainController do ) ) end - - defp available_supply(:ok, exchange_rate) do - to_string(exchange_rate.available_supply || 0) - end - - defp available_supply({:ok, supply_for_days}, _exchange_rate) do - supply_for_days - |> Jason.encode() - |> case do - {:ok, data} -> data - _ -> [] - end - end end diff --git a/apps/block_scout_web/lib/block_scout_web/router.ex b/apps/block_scout_web/lib/block_scout_web/router.ex index bd297e6c33..3a88147389 100644 --- a/apps/block_scout_web/lib/block_scout_web/router.ex +++ b/apps/block_scout_web/lib/block_scout_web/router.ex @@ -66,6 +66,8 @@ defmodule BlockScoutWeb.Router do resources("/", ChainController, only: [:show], singleton: true, as: :chain) + resources("/market_history_chart", Chain.MarketHistoryChartController, only: [:show], singleton: true) + resources "/blocks", BlockController, only: [:index, :show], param: "hash_or_number" do resources("/transactions", BlockTransactionController, only: [:index], as: :transaction) end diff --git a/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex index ad7c697f4c..9ac079c482 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex @@ -3,7 +3,17 @@
- +
+ + + + + <%= gettext("Loading chart") %>... +
+ +
diff --git a/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex b/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex index e328453b19..7f49d2d239 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/chain_view.ex @@ -2,14 +2,4 @@ defmodule BlockScoutWeb.ChainView do use BlockScoutWeb, :view alias BlockScoutWeb.LayoutView - - def encode_market_history_data(market_history_data) do - market_history_data - |> Enum.map(fn day -> Map.take(day, [:closing_price, :date]) end) - |> Jason.encode() - |> case do - {:ok, data} -> data - _ -> [] - end - end end diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index afe4821af4..21dbeaf767 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -118,7 +118,7 @@ msgid "All" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:27 +#: lib/block_scout_web/templates/chain/show.html.eex:37 msgid "Average block time" msgstr "" @@ -175,7 +175,7 @@ msgid "BlockScout provides analytics data, API, and Smart Contract tools for the msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:57 +#: lib/block_scout_web/templates/chain/show.html.eex:67 #: lib/block_scout_web/templates/layout/_topnav.html.eex:16 #: lib/block_scout_web/templates/layout/_topnav.html.eex:20 msgid "Blocks" @@ -540,7 +540,7 @@ msgid "Logs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:18 +#: lib/block_scout_web/templates/chain/show.html.eex:28 #: lib/block_scout_web/templates/layout/app.html.eex:49 #: lib/block_scout_web/views/address_view.ex:117 msgid "Market Cap" @@ -574,7 +574,7 @@ msgid "More internal transactions have come in" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:81 +#: lib/block_scout_web/templates/chain/show.html.eex:91 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:14 #: lib/block_scout_web/templates/transaction/index.html.eex:14 msgid "More transactions have come in" @@ -703,7 +703,7 @@ msgid "Position %{index}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:11 +#: lib/block_scout_web/templates/chain/show.html.eex:21 #: lib/block_scout_web/templates/layout/app.html.eex:50 msgid "Price" msgstr "" @@ -951,7 +951,7 @@ msgid "Total Supply" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:35 +#: lib/block_scout_web/templates/chain/show.html.eex:45 msgid "Total transactions" msgstr "" @@ -985,7 +985,7 @@ msgstr "" #: lib/block_scout_web/templates/block_transaction/index.html.eex:23 #: lib/block_scout_web/templates/block_transaction/index.html.eex:26 #: lib/block_scout_web/templates/block_transaction/index.html.eex:35 -#: lib/block_scout_web/templates/chain/show.html.eex:78 +#: lib/block_scout_web/templates/chain/show.html.eex:88 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 #: lib/block_scout_web/views/address_view.ex:253 msgid "Transactions" @@ -1060,12 +1060,12 @@ msgid "Verify & publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:56 +#: lib/block_scout_web/templates/chain/show.html.eex:66 msgid "View All Blocks →" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:77 +#: lib/block_scout_web/templates/chain/show.html.eex:87 msgid "View All Transactions →" msgstr "" @@ -1105,7 +1105,7 @@ msgid "WEI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:43 +#: lib/block_scout_web/templates/chain/show.html.eex:53 msgid "Wallet addresses" msgstr "" @@ -1189,8 +1189,8 @@ msgstr "" #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:19 #: lib/block_scout_web/templates/address_validation/index.html.eex:63 #: lib/block_scout_web/templates/address_validation/index.html.eex:82 -#: lib/block_scout_web/templates/chain/show.html.eex:69 -#: lib/block_scout_web/templates/chain/show.html.eex:95 +#: lib/block_scout_web/templates/chain/show.html.eex:79 +#: lib/block_scout_web/templates/chain/show.html.eex:105 #: lib/block_scout_web/templates/tokens/read_contract/index.html.eex:25 msgid "Loading..." msgstr "" @@ -1416,7 +1416,7 @@ msgstr "" #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 #: lib/block_scout_web/templates/address_transaction/index.html.eex:55 #: lib/block_scout_web/templates/address_validation/index.html.eex:70 -#: lib/block_scout_web/templates/chain/show.html.eex:61 +#: lib/block_scout_web/templates/chain/show.html.eex:71 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:23 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:23 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 @@ -1458,6 +1458,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:24 +#: lib/block_scout_web/templates/chain/show.html.eex:11 msgid "Loading chart" msgstr "" @@ -1468,6 +1469,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:27 +#: lib/block_scout_web/templates/chain/show.html.eex:14 msgid "There was a problem loading the chart." msgstr "" @@ -1537,6 +1539,6 @@ msgid "Emission Contract" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:87 +#: lib/block_scout_web/templates/chain/show.html.eex:97 msgid "Something went wrong, click to retry." msgstr "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index 41d0f4e0c2..85bdad66cb 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -118,7 +118,7 @@ msgid "All" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:27 +#: lib/block_scout_web/templates/chain/show.html.eex:37 msgid "Average block time" msgstr "" @@ -175,7 +175,7 @@ msgid "BlockScout provides analytics data, API, and Smart Contract tools for the msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:57 +#: lib/block_scout_web/templates/chain/show.html.eex:67 #: lib/block_scout_web/templates/layout/_topnav.html.eex:16 #: lib/block_scout_web/templates/layout/_topnav.html.eex:20 msgid "Blocks" @@ -540,7 +540,7 @@ msgid "Logs" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:18 +#: lib/block_scout_web/templates/chain/show.html.eex:28 #: lib/block_scout_web/templates/layout/app.html.eex:49 #: lib/block_scout_web/views/address_view.ex:117 msgid "Market Cap" @@ -574,7 +574,7 @@ msgid "More internal transactions have come in" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:81 +#: lib/block_scout_web/templates/chain/show.html.eex:91 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:14 #: lib/block_scout_web/templates/transaction/index.html.eex:14 msgid "More transactions have come in" @@ -703,7 +703,7 @@ msgid "Position %{index}" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:11 +#: lib/block_scout_web/templates/chain/show.html.eex:21 #: lib/block_scout_web/templates/layout/app.html.eex:50 msgid "Price" msgstr "" @@ -951,7 +951,7 @@ msgid "Total Supply" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:35 +#: lib/block_scout_web/templates/chain/show.html.eex:45 msgid "Total transactions" msgstr "" @@ -985,7 +985,7 @@ msgstr "" #: lib/block_scout_web/templates/block_transaction/index.html.eex:23 #: lib/block_scout_web/templates/block_transaction/index.html.eex:26 #: lib/block_scout_web/templates/block_transaction/index.html.eex:35 -#: lib/block_scout_web/templates/chain/show.html.eex:78 +#: lib/block_scout_web/templates/chain/show.html.eex:88 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 #: lib/block_scout_web/views/address_view.ex:253 msgid "Transactions" @@ -1060,12 +1060,12 @@ msgid "Verify & publish" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:56 +#: lib/block_scout_web/templates/chain/show.html.eex:66 msgid "View All Blocks →" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:77 +#: lib/block_scout_web/templates/chain/show.html.eex:87 msgid "View All Transactions →" msgstr "" @@ -1105,7 +1105,7 @@ msgid "WEI" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:43 +#: lib/block_scout_web/templates/chain/show.html.eex:53 msgid "Wallet addresses" msgstr "" @@ -1189,8 +1189,8 @@ msgstr "" #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:19 #: lib/block_scout_web/templates/address_validation/index.html.eex:63 #: lib/block_scout_web/templates/address_validation/index.html.eex:82 -#: lib/block_scout_web/templates/chain/show.html.eex:69 -#: lib/block_scout_web/templates/chain/show.html.eex:95 +#: lib/block_scout_web/templates/chain/show.html.eex:79 +#: lib/block_scout_web/templates/chain/show.html.eex:105 #: lib/block_scout_web/templates/tokens/read_contract/index.html.eex:25 msgid "Loading..." msgstr "" @@ -1416,7 +1416,7 @@ msgstr "" #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 #: lib/block_scout_web/templates/address_transaction/index.html.eex:55 #: lib/block_scout_web/templates/address_validation/index.html.eex:70 -#: lib/block_scout_web/templates/chain/show.html.eex:61 +#: lib/block_scout_web/templates/chain/show.html.eex:71 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:23 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:23 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 @@ -1458,6 +1458,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:24 +#: lib/block_scout_web/templates/chain/show.html.eex:11 msgid "Loading chart" msgstr "" @@ -1468,6 +1469,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:27 +#: lib/block_scout_web/templates/chain/show.html.eex:14 msgid "There was a problem loading the chart." msgstr "" @@ -1537,6 +1539,6 @@ msgid "Emission Contract" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/chain/show.html.eex:87 +#: lib/block_scout_web/templates/chain/show.html.eex:97 msgid "Something went wrong, click to retry." msgstr "" diff --git a/apps/block_scout_web/test/block_scout_web/controllers/chain/market_history_chart_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/chain/market_history_chart_controller_test.exs new file mode 100644 index 0000000000..e2958800fe --- /dev/null +++ b/apps/block_scout_web/test/block_scout_web/controllers/chain/market_history_chart_controller_test.exs @@ -0,0 +1,24 @@ +defmodule BlockScoutWeb.Chain.MarketHistoryChartControllerTest do + use BlockScoutWeb.ConnCase + + describe "GET show/2" do + test "returns error when not an ajax request" do + path = market_history_chart_path(BlockScoutWeb.Endpoint, :show) + + conn = get(build_conn(), path) + + assert conn.status == 422 + end + + test "returns ok when request is ajax" do + path = market_history_chart_path(BlockScoutWeb.Endpoint, :show) + + conn = + build_conn() + |> put_req_header("x-requested-with", "xmlhttprequest") + |> get(path) + + assert json_response(conn, 200) + end + end +end diff --git a/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs index e58db4c249..de589ff505 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs @@ -49,16 +49,6 @@ defmodule BlockScoutWeb.ChainControllerTest do refute(Enum.member?(response["blocks"], old_block)) end - test "returns market history data", %{conn: conn} do - today = Date.utc_today() - for day <- -40..0, do: insert(:market_history, date: Date.add(today, day)) - - conn = get(conn, "/") - - assert Map.has_key?(conn.assigns, :market_history_data) - assert length(conn.assigns.market_history_data) == 30 - end - test "displays miner primary address names" do miner_name = "POA Miner Pool" %{address: miner_address} = insert(:address_name, name: miner_name, primary: true) diff --git a/apps/block_scout_web/test/block_scout_web/views/chain_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/chain_view_test.exs deleted file mode 100644 index 87508724c7..0000000000 --- a/apps/block_scout_web/test/block_scout_web/views/chain_view_test.exs +++ /dev/null @@ -1,19 +0,0 @@ -defmodule BlockScoutWeb.ChainViewTest do - use BlockScoutWeb.ConnCase, async: true - - alias BlockScoutWeb.ChainView - - describe "encode_market_history_data/1" do - test "returns a JSON encoded market history data" do - market_history_data = [ - %Explorer.Market.MarketHistory{ - closing_price: Decimal.new("0.078"), - date: ~D[2018-08-20] - } - ] - - assert "[{\"closing_price\":\"0.078\",\"date\":\"2018-08-20\"}]" == - ChainView.encode_market_history_data(market_history_data) - end - end -end diff --git a/apps/explorer/lib/explorer/exchange_rates/source.ex b/apps/explorer/lib/explorer/exchange_rates/source.ex index 7401d27a0d..584f7bf147 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source.ex @@ -3,6 +3,7 @@ defmodule Explorer.ExchangeRates.Source do Behaviour for fetching exchange rates from external sources. """ + alias Explorer.ExchangeRates.Source.CoinMarketCap alias Explorer.ExchangeRates.Token alias HTTPoison.{Error, Response} @@ -11,6 +12,31 @@ defmodule Explorer.ExchangeRates.Source do """ @spec fetch_exchange_rates(module) :: {:ok, [Token.t()]} | {:error, any} def fetch_exchange_rates(source \\ exchange_rates_source()) do + if(source == CoinMarketCap) do + fetch_exchange_rates_from_paginable_source(source) + else + fetch_exchange_rates_request(source) + end + end + + defp fetch_exchange_rates_from_paginable_source(source, page \\ 1) do + case HTTPoison.get(source.source_url(page), headers()) do + {:ok, %Response{body: body, status_code: 200}} -> + cond do + body =~ Explorer.coin() -> {:ok, source.format_data(body)} + page == source.max_page_number -> {:error, "exchange rates not found for this network"} + true -> fetch_exchange_rates_from_paginable_source(source, page + 1) + end + + {:ok, %Response{body: body, status_code: status_code}} when status_code in 400..499 -> + {:error, decode_json(body)["error"]} + + {:error, %Error{reason: reason}} -> + {:error, reason} + end + end + + defp fetch_exchange_rates_request(source) do case HTTPoison.get(source.source_url(), headers()) do {:ok, %Response{body: body, status_code: 200}} -> {:ok, source.format_data(body)} @@ -43,6 +69,8 @@ defmodule Explorer.ExchangeRates.Source do def to_decimal(nil), do: nil + def to_decimal(%Decimal{} = value), do: value + def to_decimal(value) when is_float(value) do Decimal.from_float(value) end 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 568a9f36d1..4030eed06f 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 @@ -31,9 +31,15 @@ defmodule Explorer.ExchangeRates.Source.CoinMarketCap do @impl Source def source_url do - "#{base_url()}/v1/ticker/?limit=0" + source_url(1) end + def source_url(page) do + "#{base_url()}/v1/ticker/?start=#{page - 1}00" + end + + def max_page_number, do: 10 + defp base_url do config(:base_url) || "https://api.coinmarketcap.com" end