-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Exchange rates CoinMarketCap source module
- Loading branch information
Showing
11 changed files
with
224 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
180 changes: 180 additions & 0 deletions
180
apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
defmodule Explorer.ExchangeRates.Source.CoinMarketCap do | ||
@moduledoc """ | ||
Adapter for fetching exchange rates from https://coinmarketcap.com/api/ | ||
""" | ||
|
||
alias Explorer.{Chain, ExchangeRates} | ||
alias Explorer.ExchangeRates.{Source, Token} | ||
|
||
import Source, only: [to_decimal: 1] | ||
|
||
@behaviour Source | ||
|
||
@impl Source | ||
def format_data(%{"data" => _} = json_data) do | ||
market_data = json_data["data"] | ||
token_properties = get_token_properties(market_data) | ||
|
||
last_updated = get_last_updated(token_properties) | ||
current_price = get_current_price(token_properties) | ||
|
||
id = token_properties && token_properties["id"] | ||
btc_value = get_btc_value(id, token_properties) | ||
|
||
circulating_supply_data = get_circulating_supply(token_properties) | ||
|
||
total_supply_data = get_total_supply(token_properties) | ||
|
||
market_cap_data_usd = get_market_cap_data_usd(token_properties) | ||
|
||
total_volume_data_usd = get_total_volume_data_usd(token_properties) | ||
|
||
[ | ||
%Token{ | ||
available_supply: to_decimal(circulating_supply_data), | ||
total_supply: to_decimal(total_supply_data) || to_decimal(circulating_supply_data), | ||
btc_value: btc_value, | ||
id: id, | ||
last_updated: last_updated, | ||
market_cap_usd: to_decimal(market_cap_data_usd), | ||
name: token_properties && token_properties["name"], | ||
symbol: token_properties && String.upcase(token_properties["symbol"]), | ||
usd_value: current_price, | ||
volume_24h_usd: to_decimal(total_volume_data_usd) | ||
} | ||
] | ||
end | ||
|
||
@impl Source | ||
def format_data(_), do: [] | ||
|
||
defp api_key do | ||
Application.get_env(:explorer, ExchangeRates)[:coinmarketcap_api_key] | ||
end | ||
|
||
defp get_token_properties(market_data) do | ||
token_values_list = | ||
market_data | ||
|> Map.values() | ||
|
||
if Enum.count(token_values_list) > 0 do | ||
token_values = token_values_list |> Enum.at(0) | ||
|
||
if Enum.count(token_values) > 0 do | ||
token_values |> Enum.at(0) | ||
else | ||
%{} | ||
end | ||
else | ||
%{} | ||
end | ||
end | ||
|
||
defp get_circulating_supply(token_properties) do | ||
token_properties && token_properties["circulating_supply"] | ||
end | ||
|
||
defp get_total_supply(token_properties) do | ||
token_properties && token_properties["total_supply"] | ||
end | ||
|
||
defp get_market_cap_data_usd(token_properties) do | ||
token_properties && token_properties["quote"] && | ||
token_properties["quote"]["USD"] && | ||
token_properties["quote"]["USD"]["market_cap"] | ||
end | ||
|
||
defp get_total_volume_data_usd(token_properties) do | ||
token_properties && token_properties["quote"] && | ||
token_properties["quote"]["USD"] && | ||
token_properties["quote"]["USD"]["volume_24h"] | ||
end | ||
|
||
defp get_last_updated(token_properties) do | ||
last_updated_data = token_properties && token_properties["last_updated"] | ||
|
||
if last_updated_data do | ||
{:ok, last_updated, 0} = DateTime.from_iso8601(last_updated_data) | ||
last_updated | ||
else | ||
nil | ||
end | ||
end | ||
|
||
defp get_current_price(token_properties) do | ||
if token_properties && token_properties["quote"] && token_properties["quote"]["USD"] && | ||
token_properties["quote"]["USD"]["price"] do | ||
to_decimal(token_properties["quote"]["USD"]["price"]) | ||
else | ||
1 | ||
end | ||
end | ||
|
||
defp get_btc_value(id, token_properties) do | ||
case get_btc_price() do | ||
{:ok, price} -> | ||
btc_price = to_decimal(price) | ||
current_price = get_current_price(token_properties) | ||
|
||
if id != "btc" && current_price && btc_price do | ||
Decimal.div(current_price, btc_price) | ||
else | ||
1 | ||
end | ||
|
||
_ -> | ||
1 | ||
end | ||
end | ||
|
||
@impl Source | ||
def source_url do | ||
coin = Explorer.coin() | ||
symbol = if coin, do: String.upcase(Explorer.coin()), else: nil | ||
|
||
if symbol, do: "#{base_url()}/cryptocurrency/quotes/latest?symbol=#{symbol}&CMC_PRO_API_KEY=#{api_key()}", else: nil | ||
end | ||
|
||
@impl Source | ||
def source_url(input) do | ||
case Chain.Hash.Address.cast(input) do | ||
{:ok, _} -> | ||
# todo: find symbol by contract address hash | ||
nil | ||
|
||
_ -> | ||
symbol = if input, do: input |> String.upcase(), else: nil | ||
|
||
if symbol, | ||
do: "#{base_url()}/cryptocurrency/quotes/latest?symbol=#{symbol}&CMC_PRO_API_KEY=#{api_key()}", | ||
else: nil | ||
end | ||
end | ||
|
||
defp base_url do | ||
config(:base_url) || "https://pro-api.coinmarketcap.com/v2" | ||
end | ||
|
||
defp get_btc_price(currency \\ "usd") do | ||
url = "#{base_url()}/cryptocurrency/quotes/latest?symbol=BTC&CMC_PRO_API_KEY=#{api_key()}" | ||
|
||
case Source.http_request(url) do | ||
{:ok, data} = resp -> | ||
if is_map(data) do | ||
current_price = data["rates"][currency]["value"] | ||
|
||
{:ok, current_price} | ||
else | ||
resp | ||
end | ||
|
||
resp -> | ||
resp | ||
end | ||
end | ||
|
||
@spec config(atom()) :: term | ||
defp config(key) do | ||
Application.get_env(:explorer, __MODULE__, [])[key] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters