diff --git a/apps/explorer/config/test.exs b/apps/explorer/config/test.exs index 7f6d19ae82..9626facf30 100644 --- a/apps/explorer/config/test.exs +++ b/apps/explorer/config/test.exs @@ -27,6 +27,9 @@ if File.exists?(file = "test.secret.exs") do import_config file end +config :explorer, Explorer.ExchangeRates.Source.TransactionAndLog, + secondary_source: Explorer.ExchangeRates.Source.OneCoinSource + variant = if is_nil(System.get_env("ETHEREUM_JSONRPC_VARIANT")) do "parity" diff --git a/apps/explorer/lib/explorer/exchange_rates/source/transaction_and_log.ex b/apps/explorer/lib/explorer/exchange_rates/source/transaction_and_log.ex new file mode 100644 index 0000000000..3dd11f0355 --- /dev/null +++ b/apps/explorer/lib/explorer/exchange_rates/source/transaction_and_log.ex @@ -0,0 +1,50 @@ +defmodule Explorer.ExchangeRates.Source.TransactionAndLog do + @moduledoc """ + Adapter for calculating the market cap and total supply from logs and transactions + while still getting other info like price in dollars and bitcoin from a secondary source + """ + + alias Explorer.ExchangeRates.{Source, Token} + alias Explorer.Chain + + @behaviour Source + + @impl Source + def fetch_exchange_rates do + token_data = + secondary_source().fetch_exchange_rates() + |> elem(1) + |> Enum.find(fn token -> token.symbol == Explorer.coin() end) + |> build_struct + + {:ok, [token_data]} + end + + defp build_struct(original_token) do + %Token{ + available_supply: to_decimal(Chain.circulating_supply()), + btc_value: original_token.btc_value, + id: original_token.id, + last_updated: original_token.last_updated, + market_cap_usd: Decimal.mult(to_decimal(Chain.circulating_supply()), original_token.usd_value), + name: original_token.name, + symbol: original_token.symbol, + usd_value: original_token.usd_value, + volume_24h_usd: original_token.volume_24h_usd + } + end + + defp to_decimal(value) do + Decimal.new(value) + end + + @spec secondary_source() :: module() + defp secondary_source do + config(:secondary_source) || Explorer.ExchangeRates.Source.CoinMarketCap + end + + @spec config(atom()) :: term + defp config(key) do + Application.get_env(:explorer, __MODULE__, [])[key] + end +end diff --git a/apps/explorer/test/explorer/exchange_rates/source/transaction_and_log_test.exs b/apps/explorer/test/explorer/exchange_rates/source/transaction_and_log_test.exs new file mode 100644 index 0000000000..f5821ed2f4 --- /dev/null +++ b/apps/explorer/test/explorer/exchange_rates/source/transaction_and_log_test.exs @@ -0,0 +1,11 @@ +defmodule Explorer.ExchangeRates.Source.TransactionAndLogTest do + use Explorer.DataCase + alias Explorer.ExchangeRates.Source.TransactionAndLog + alias Explorer.ExchangeRates.Token + + describe "fetch_exchange_rates/1" do + test "bring a list with one %Token{}" do + assert {:ok, [%Token{}]} = TransactionAndLog.fetch_exchange_rates() + end + end +end diff --git a/apps/explorer/test/support/fakes/one_coin_source.ex b/apps/explorer/test/support/fakes/one_coin_source.ex new file mode 100644 index 0000000000..fc9781abe0 --- /dev/null +++ b/apps/explorer/test/support/fakes/one_coin_source.ex @@ -0,0 +1,25 @@ +defmodule Explorer.ExchangeRates.Source.OneCoinSource do + @moduledoc false + + alias Explorer.ExchangeRates.Source + alias Explorer.ExchangeRates.Token + + @behaviour Source + + @impl Source + def fetch_exchange_rates do + pseudo_token = %Token{ + available_supply: Decimal.new(10_000_000), + btc_value: Decimal.new(1), + id: "", + last_updated: Timex.now(), + name: "", + market_cap_usd: Decimal.new(10_000_000), + symbol: Explorer.coin(), + usd_value: Decimal.new(1), + volume_24h_usd: Decimal.new(1) + } + + {:ok, [pseudo_token]} + end +end