Merge pull request #3462 from poanetwork/vb-price-for-bridged-tokens

Display price for bridged tokens
pull/3467/head
Victor Baranov 4 years ago committed by GitHub
commit 36d529ce07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex
  3. 64
      apps/block_scout_web/lib/block_scout_web/views/address_token_balance_view.ex
  4. 2
      apps/block_scout_web/lib/block_scout_web/views/currency_helpers.ex
  5. 2
      apps/block_scout_web/lib/block_scout_web/views/stakes_helpers.ex
  6. 4
      apps/block_scout_web/mix.exs
  7. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs
  8. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_read_proxy_controller_test.exs
  9. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs
  10. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs
  11. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_write_contract_controller_test.exs
  12. 1
      apps/block_scout_web/test/block_scout_web/controllers/address_write_proxy_controller_test.exs
  13. 68
      apps/block_scout_web/test/block_scout_web/views/address_token_balance_view_test.exs
  14. 2
      apps/ethereum_jsonrpc/mix.exs
  15. 4
      apps/explorer/config/test.exs
  16. 21
      apps/explorer/lib/explorer/chain/supply/token_bridge.ex
  17. 35
      apps/explorer/lib/explorer/market/market.ex
  18. 2
      apps/explorer/mix.exs
  19. 2
      apps/indexer/mix.exs
  20. 1
      apps/indexer/test/indexer/block/catchup/bound_interval_supervisor_test.exs
  21. 3
      mix.exs
  22. 19
      mix.lock

@ -1,6 +1,7 @@
## Current
### Features
- [#3462](https://github.com/poanetwork/blockscout/pull/3462) - Display price for bridged tokens
### Fixes

@ -3,7 +3,7 @@
<%= @type %> (<span data-number-of-tokens-by-type="<%= @type %>"><%= Enum.count(@token_balances)%></span>)
</h6>
<%= for token_balance <- sort_by_name(@token_balances) do %>
<%= for token_balance <- sort_by_usd_value_and_name(@token_balances) do %>
<div
class="border-bottom"
data-dropdown-token-balance-test

@ -20,6 +20,70 @@ defmodule BlockScoutWeb.AddressTokenBalanceView do
Enum.sort_by(named, &String.downcase(&1.token.name)) ++ unnamed
end
@doc """
Sorts the given list of tokens by usd_value of token in descending order and alphabetically order considering nil values in the bottom of
the list.
"""
def sort_by_usd_value_and_name(token_balances) do
token_balances
|> Enum.sort(fn token_balance1, token_balance2 ->
usd_value1 = token_balance1.token.usd_value
usd_value2 = token_balance2.token.usd_value
token_name1 = token_balance1.token.name
token_name2 = token_balance2.token.name
sort_by_name = sort_2_tokens_by_name(token_name1, token_name2)
sort_2_tokens_by_value_desc_and_name(token_balance1, token_balance2, usd_value1, usd_value2, sort_by_name)
end)
end
defp sort_2_tokens_by_name(token_name1, token_name2) do
cond do
token_name1 && token_name2 ->
String.downcase(token_name1) <= String.downcase(token_name2)
token_name1 && is_nil(token_name2) ->
true
is_nil(token_name1) && token_name2 ->
false
true ->
true
end
end
defp sort_2_tokens_by_value_desc_and_name(token_balance1, token_balance2, usd_value1, usd_value2, sort_by_name)
when not is_nil(usd_value1) and not is_nil(usd_value2) do
case Decimal.cmp(balance_in_usd(token_balance1), balance_in_usd(token_balance2)) do
:gt ->
true
:eq ->
sort_by_name
:lt ->
false
end
end
defp sort_2_tokens_by_value_desc_and_name(_token_balance1, _token_balance2, usd_value1, usd_value2, _sort_by_name)
when not is_nil(usd_value1) and is_nil(usd_value2) do
true
end
defp sort_2_tokens_by_value_desc_and_name(_token_balance1, _token_balance2, usd_value1, usd_value2, _sort_by_name)
when is_nil(usd_value1) and not is_nil(usd_value2) do
false
end
defp sort_2_tokens_by_value_desc_and_name(_token_balance1, _token_balance2, usd_value1, usd_value2, sort_by_name)
when is_nil(usd_value1) and is_nil(usd_value2) do
sort_by_name
end
@doc """
Return the balance in usd corresponding to this token. Return nil if the usd_value of the token is not present.
"""

@ -77,6 +77,6 @@ defmodule BlockScoutWeb.CurrencyHelpers do
def divide_decimals(%{sign: sign, coef: coef, exp: exp}, decimals) do
sign
|> Decimal.new(coef, exp - Decimal.to_integer(decimals))
|> Decimal.reduce()
|> Decimal.normalize()
end
end

@ -46,7 +46,7 @@ defmodule BlockScoutWeb.StakesHelpers do
amount.sign
|> Decimal.new(amount.coef, amount.exp - decimals)
|> Decimal.reduce()
|> Decimal.normalize()
end
def format_token_amount(amount, token, options \\ [])

@ -83,7 +83,7 @@ defmodule BlockScoutWeb.Mixfile do
{:cldr_utils, "~> 2.3"},
{:ex_machina, "~> 2.1", only: [:test]},
# Code coverage
{:excoveralls, "~> 0.13.1"},
{:excoveralls, "~> 0.13.3"},
{:explorer, in_umbrella: true},
{:exvcr, "~> 0.10", only: :test},
# HTML CSS selectors for Phoenix controller tests
@ -100,7 +100,7 @@ defmodule BlockScoutWeb.Mixfile do
{:math, "~> 0.3.0"},
{:mock, "~> 0.3.0", only: [:test], runtime: false},
{:number, "~> 1.0.1"},
{:phoenix, "== 1.5.4"},
{:phoenix, "== 1.5.6"},
{:phoenix_ecto, "~> 4.1"},
{:phoenix_html, "~> 2.10"},
{:phoenix_live_reload, "~> 1.2", only: [:dev]},

@ -1,5 +1,6 @@
defmodule BlockScoutWeb.AddressReadContractControllerTest do
use BlockScoutWeb.ConnCase, async: true
use ExUnit.Case, async: false
alias Explorer.ExchangeRates.Token
alias Explorer.Chain.Address

@ -1,5 +1,6 @@
defmodule BlockScoutWeb.AddressReadProxyControllerTest do
use BlockScoutWeb.ConnCase, async: true
use ExUnit.Case, async: false
alias Explorer.ExchangeRates.Token
alias Explorer.Chain.Address

@ -1,5 +1,6 @@
defmodule BlockScoutWeb.AddressTokenControllerTest do
use BlockScoutWeb.ConnCase, async: true
use ExUnit.Case, async: false
import BlockScoutWeb.WebRouter.Helpers, only: [address_token_path: 3]
import Mox

@ -1,5 +1,6 @@
defmodule BlockScoutWeb.AddressTransactionControllerTest do
use BlockScoutWeb.ConnCase, async: true
use ExUnit.Case, async: false
import BlockScoutWeb.WebRouter.Helpers, only: [address_transaction_path: 3, address_transaction_path: 4]
import Mox

@ -1,5 +1,6 @@
defmodule BlockScoutWeb.AddressWriteContractControllerTest do
use BlockScoutWeb.ConnCase, async: true
use ExUnit.Case, async: false
alias Explorer.ExchangeRates.Token
alias Explorer.Chain.Address

@ -1,5 +1,6 @@
defmodule BlockScoutWeb.AddressWriteProxyControllerTest do
use BlockScoutWeb.ConnCase, async: true
use ExUnit.Case, async: false
alias Explorer.ExchangeRates.Token
alias Explorer.Chain.Address

@ -69,6 +69,74 @@ defmodule BlockScoutWeb.AddressTokenBalanceViewTest do
end
end
describe "sort_by_usd_value_and_name/1" do
test "sorts the given tokens by its name and usd_value" do
token_balance_a =
build(:token_balance,
token: build(:token, name: "token name", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(2)),
value: Decimal.new(100_500)
)
token_balance_b =
build(:token_balance,
token: build(:token, name: "token", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(3.45)),
value: Decimal.new(100_500)
)
token_balance_c =
build(:token_balance,
token: build(:token, name: nil, decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(2)),
value: Decimal.new(100_500)
)
token_balance_d =
build(:token_balance,
token: build(:token, name: "Atoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(1)),
value: Decimal.new(100_500)
)
token_balance_e =
build(:token_balance,
token: build(:token, name: "atoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, nil),
value: Decimal.new(100_500)
)
token_balance_f =
build(:token_balance,
token: build(:token, name: "Btoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, nil),
value: Decimal.new(100_500)
)
token_balance_g =
build(:token_balance,
token: build(:token, name: "Btoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(1)),
value: Decimal.new(100_500)
)
token_balances = [
token_balance_a,
token_balance_b,
token_balance_c,
token_balance_d,
token_balance_e,
token_balance_f,
token_balance_g
]
expected = [
token_balance_b,
token_balance_a,
token_balance_c,
token_balance_d,
token_balance_g,
token_balance_e,
token_balance_f
]
assert AddressTokenBalanceView.sort_by_usd_value_and_name(token_balances) == expected
end
end
describe "balance_in_usd/1" do
test "return balance in usd" do
token =

@ -68,7 +68,7 @@ defmodule EthereumJsonrpc.MixProject do
# Static Type Checking
{:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false},
# Code coverage
{:excoveralls, "~> 0.13.1"},
{:excoveralls, "~> 0.13.3"},
# JSONRPC HTTP Post calls
{:httpoison, "~> 1.6"},
# Decode/Encode JSON for JSONRPC

@ -9,7 +9,9 @@ config :explorer, Explorer.Repo,
hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox,
# Default of `5_000` was too low for `BlockFetcher` test
ownership_timeout: :timer.minutes(1)
ownership_timeout: :timer.minutes(1),
timeout: :timer.seconds(60),
queue_target: 1000
config :explorer, Explorer.ExchangeRates, enabled: false, store: :ets

@ -196,7 +196,9 @@ defmodule Explorer.Chain.Supply.TokenBridge do
def get_current_price_for_bridged_token(symbol) when is_nil(symbol), do: nil
def get_current_price_for_bridged_token(symbol) do
case Source.fetch_exchange_rates_for_token(symbol) do
bridged_token_symbol_for_price_fetching = bridged_token_symbol_mapping_to_get_price(symbol)
case Source.fetch_exchange_rates_for_token(bridged_token_symbol_for_price_fetching) do
{:ok, [rates]} ->
rates.usd_value
@ -222,14 +224,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do
bridged_mainnet_tokens_with_supply =
bridged_mainnet_tokens_list
|> Enum.map(fn {bridged_token_hash, bridged_token_symbol} ->
bridged_token_symbol_corrected =
case bridged_token_symbol do
"POA20" -> "POA"
"yDAI+yUSDC+yUSDT+yTUSD" -> "yCurve"
symbol -> symbol
end
bridged_token_price = Bridge.fetch_token_price(bridged_token_symbol_corrected)
bridged_token_price = Bridge.fetch_token_price(bridged_token_symbol)
query =
from(t in Token,
@ -274,4 +269,12 @@ defmodule Explorer.Chain.Supply.TokenBridge do
omni_bridge_market_cap
end
defp bridged_token_symbol_mapping_to_get_price(symbol) do
case symbol do
"POA20" -> "POA"
"yDAI+yUSDC+yUSDT+yTUSD" -> "yCurve"
symbol -> symbol
end
end
end

@ -4,7 +4,8 @@ defmodule Explorer.Market do
"""
alias Explorer.Chain.Address.CurrentTokenBalance
alias Explorer.Chain.Hash
alias Explorer.Chain.{BridgedToken, Hash}
alias Explorer.Chain.Supply.TokenBridge
alias Explorer.ExchangeRates.Token
alias Explorer.Market.{MarketHistory, MarketHistoryCache}
alias Explorer.{ExchangeRates, KnownTokens, Repo}
@ -56,7 +57,17 @@ defmodule Explorer.Market do
matches_known_address = known_address && known_address == token.contract_address_hash
usd_value = fetch_token_usd_value(matches_known_address, symbol)
usd_value =
cond do
matches_known_address ->
fetch_token_usd_value(matches_known_address, symbol)
mainnet_bridged_token?(token) ->
TokenBridge.get_current_price_for_bridged_token(symbol)
true ->
nil
end
Map.put(token, :usd_value, usd_value)
end
@ -71,6 +82,26 @@ defmodule Explorer.Market do
Enum.map(tokens, &add_price/1)
end
defp mainnet_bridged_token?(token) do
bridged_prop = Map.get(token, :bridged) || nil
if bridged_prop do
bridged_token = Repo.get_by(BridgedToken, home_token_contract_address_hash: token.contract_address_hash)
if bridged_token do
if bridged_token.foreign_chain_id do
if Decimal.cmp(bridged_token.foreign_chain_id, Decimal.new(1)) == :eq, do: true, else: false
else
false
end
else
false
end
else
false
end
end
defp fetch_token_usd_value(true, symbol) do
case get_exchange_rate(symbol) do
%{usd_value: usd_value} -> usd_value

@ -82,7 +82,7 @@ defmodule Explorer.Mixfile do
# Data factory for testing
{:ex_machina, "~> 2.3", only: [:test]},
# Code coverage
{:excoveralls, "~> 0.13.1"},
{:excoveralls, "~> 0.13.3"},
{:exvcr, "~> 0.10", only: :test},
{:httpoison, "~> 1.6"},
{:jason, "~> 1.0"},

@ -51,7 +51,7 @@ defmodule Indexer.MixProject do
# RLP encoding
{:ex_rlp, "~> 0.5.2"},
# Code coverage
{:excoveralls, "~> 0.13.1"},
{:excoveralls, "~> 0.13.3"},
# Importing to database
{:explorer, in_umbrella: true},
# libsecp2561k1 crypto functions

@ -7,6 +7,7 @@ defmodule Indexer.Block.Catchup.BoundIntervalSupervisorTest do
import EthereumJSONRPC, only: [integer_to_quantity: 1]
alias Explorer.Chain.Block
alias Explorer.Repo
alias Indexer.BoundInterval
alias Indexer.Block.Catchup

@ -72,10 +72,11 @@ defmodule BlockScout.Mixfile do
# and cannot be accessed from applications inside the apps folder
defp deps do
[
{:mox, "== 0.5.1"},
# Documentation
{:ex_doc, "~> 0.19.0", only: [:dev]},
# Code coverage
{:excoveralls, "~> 0.13.1"},
{:excoveralls, "~> 0.13.3"},
{:number, "~> 1.0.1"}
]
end

@ -19,12 +19,13 @@
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
"cors_plug": {:hex, :cors_plug, "2.0.0", "238ddb479f92b38f6dc1ae44b8d81f0387f9519101a6da442d543ab70ee0e482", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "118162367ef41448c9742ced8c8bc33ae2857d958d6b997e1db26402dd8c6f37"},
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
"cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
"credo": {:hex, :credo, "1.4.0", "92339d4cbadd1e88b5ee43d427b639b68a11071b6f73854e33638e30a0ea11f5", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1fd3b70dce216574ce3c18bdf510b57e7c4c85c2ec9cad4bff854abaf7e58658"},
"csv": {:hex, :csv, "2.3.1", "9ce11eff5a74a07baf3787b2b19dd798724d29a9c3a492a41df39f6af686da0e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm", "86626e1c89a4ad9a96d0d9c638f9e88c2346b89b4ba1611988594ebe72b5d5ee"},
"dataloader": {:hex, :dataloader, "1.0.7", "58351b335673cf40601429bfed6c11fece6ce7ad169b2ac0f0fe83e716587391", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "12bf66478e4a5085d09dc96932d058c206ee8c219cc7691d12a40dc35c8cefaa"},
"db_connection": {:hex, :db_connection, "2.2.2", "3bbca41b199e1598245b716248964926303b5d4609ff065125ce98bcd368939e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "642af240d8a8affb93b4ba5a6fcd2bbcbdc327e1a524b825d383711536f8070c"},
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
"db_connection": {:hex, :db_connection, "2.3.0", "d56ef906956a37959bcb385704fc04035f4f43c0f560dd23e00740daf8028c49", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "dcc082b8f723de9a630451b49fdbd7a59b065c4b38176fb147aaf773574d4520"},
"decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"},
"decorator": {:hex, :decorator, "1.3.0", "6203dbd6e4e519a21a079e2a74e50fddaf03e80be22711b92eb4cd410173abea", [:mix], [], "hexpm", "1fde31b23897e529b44d72d798489e1c6d45936f106812a8df80180779afafb4"},
"deep_merge": {:hex, :deep_merge, "0.2.0", "c1050fa2edf4848b9f556fba1b75afc66608a4219659e3311d9c9427b5b680b3", [:mix], [], "hexpm", "e3bf435a54ed27b0ba3a01eb117ae017988804e136edcbe8a6a14c310daa966e"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"},
@ -44,7 +45,7 @@
"ex_rlp": {:hex, :ex_rlp, "0.5.2", "7f4ce7bd55e543c054ce6d49629b01e9833c3462e3d547952be89865f39f2c58", [:mix], [], "hexpm", "1b8b8f72f8399ace4e096b99c653cba8c52dc6db17b6b410771c0f088774db82"},
"ex_utils": {:hex, :ex_utils, "0.1.7", "2c133e0bcdc49a858cf8dacf893308ebc05bc5fba501dc3d2935e65365ec0bf3", [:mix], [], "hexpm", "66d4fe75285948f2d1e69c2a5ddd651c398c813574f8d36a9eef11dc20356ef6"},
"exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm", "1222419f706e01bfa1095aec9acf6421367dcfab798a6f67c54cf784733cd6b5"},
"excoveralls": {:hex, :excoveralls, "0.13.1", "b9f1697f7c9e0cfe15d1a1d737fb169c398803ffcbc57e672aa007e9fd42864c", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "b4bb550e045def1b4d531a37fb766cbbe1307f7628bf8f0414168b3f52021cce"},
"excoveralls": {:hex, :excoveralls, "0.13.3", "edc5f69218f84c2bf61b3609a22ddf1cec0fbf7d1ba79e59f4c16d42ea4347ed", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cc26f48d2f68666380b83d8aafda0fffc65dafcc8d8650358e0b61f6a99b1154"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"},
"exth_crypto": {:hex, :exth_crypto, "0.1.6", "8e636a9bcb75d8e32451be96e547a495121ed2178d078db294edb0f81f7cf2e8", [:mix], [{:binary, "~> 0.0.4", [hex: :binary, repo: "hexpm", optional: false]}, {:keccakf1600, "~> 2.0.0", [hex: :keccakf1600_orig, repo: "hexpm", optional: false]}, {:libsecp256k1, "~> 0.1.9", [hex: :libsecp256k1, repo: "hexpm", optional: false]}], "hexpm", "45d6faf4b889f8fc526deba059e0c7947423784ab1e7fa85be8db4c46cf4416b"},
"exvcr": {:hex, :exvcr, "0.10.1", "cb266e5cc0d4fef12572ce6673d13f97aa3c302911010d64d51cee0690f566d1", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "643cb18909d93b42d7be6fca7c9737284024a7200f9cb81dc4b3666afd840ede"},
@ -57,7 +58,7 @@
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm", "3e3d7156a272950373ce5a4018b1490bea26676f8d6a7d409f6fac8568b8cb9a"},
"httpoison": {:hex, :httpoison, "1.6.2", "ace7c8d3a361cebccbed19c283c349b3d26991eff73a1eaaa8abae2e3c8089b6", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "aa2c74bd271af34239a3948779612f87df2422c2fdcfdbcec28d9c105f0773fe"},
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
"jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"},
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"},
"junit_formatter": {:hex, :junit_formatter, "3.0.1", "4ed76a50886717a6d683a978cec775abdcb88d9d51cfddd3d8fbf8e6af4625da", [:mix], [], "hexpm", "55ba8f459c0d2568bb6ca7c44f1b1384194773fce4d8bc99454fa40320664af9"},
"keccakf1600": {:hex, :keccakf1600_orig, "2.0.0", "0a7217ddb3ee8220d449bbf7575ec39d4e967099f220a91e3dfca4dbaef91963", [:rebar3], [], "hexpm", "bdbbb02d67bea35605f95d4e3de48203347374e414da7945c4f2f7fd13ffe632"},
@ -69,7 +70,7 @@
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
"memento": {:hex, :memento, "0.3.1", "b2909390820550d8b90b68ec96f9e15ff8a45a28b6f97fa4a62ef50e87c2f9d9", [:mix], [], "hexpm", "ff8fc66255d21dcd539c5d77a0b5458715bf3efec91b389dd06017bbb4e2e916"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mime": {:hex, :mime, "1.4.0", "5066f14944b470286146047d2f73518cf5cca82f8e4815cf35d196b58cf07c47", [:mix], [], "hexpm", "75fa42c4228ea9a23f70f123c74ba7cece6a03b1fd474fe13f6a7a85c6ea4ff6"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mix_erlang_tasks": {:hex, :mix_erlang_tasks, "0.1.0", "36819fec60b80689eb1380938675af215565a89320a9e29c72c70d97512e4649", [:mix], [], "hexpm", "95d2839c422c482a70c08a8702da8242f86b773f8ab6e8602a4eb72da8da04ed"},
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm", "b93e2b1e564bdbadfecc297277f9e6d0902da645b417d6c9210f6038ac63489a"},
@ -82,15 +83,15 @@
"optimal": {:hex, :optimal, "0.3.6", "46bbf52fbbbd238cda81e02560caa84f93a53c75620f1fe19e81e4ae7b07d1dd", [:mix], [], "hexpm", "1a06ea6a653120226b35b283a1cd10039550f2c566edcdec22b29316d73640fd"},
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm", "639b2e8749e11b87b9eb42f2ad325d161c170b39b288ac8d04c4f31f8f0823eb"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"phoenix": {:hex, :phoenix, "1.5.4", "0fca9ce7e960f9498d6315e41fcd0c80bfa6fbeb5fa3255b830c67fdfb7e703f", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4e516d131fde87b568abd62e1b14aa07ba7d5edfd230bab4e25cc9dedbb39135"},
"phoenix": {:hex, :phoenix, "1.5.6", "8298cdb4e0f943242ba8410780a6a69cbbe972fef199b341a36898dd751bdd66", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0dc4d39af1306b6aa5122729b0a95ca779e42c708c6fe7abbb3d336d5379e956"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.1.0", "a044d0756d0464c5a541b4a0bf4bcaf89bffcaf92468862408290682c73ae50d", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c5e666a341ff104d0399d8f0e4ff094559b2fde13a5985d4cb5023b2c2ac558b"},
"phoenix_form_awesomplete": {:hex, :phoenix_form_awesomplete, "0.1.5", "d09aade160b584e3428e1e095645482396f17bddda4f566f1118f12d2598d11c", [:mix], [{:phoenix_html, "~> 2.10", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "acef2dbc638b5bcad92c11e41eb2b55d71f2596741a2f936717b8472196456ec"},
"phoenix_html": {:hex, :phoenix_html, "2.14.2", "b8a3899a72050f3f48a36430da507dd99caf0ac2d06c77529b1646964f3d563e", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "58061c8dfd25da5df1ea0ca47c972f161beb6c875cd293917045b92ffe1bf617"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.4", "940c0344b1d66a2e46eef02af3a70e0c5bb45a4db0bf47917add271b76cd3914", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "38f9308357dea4cc77f247e216da99fcb0224e05ada1469167520bed4cb8cccd"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
"plug": {:hex, :plug, "1.10.3", "c9cebe917637d8db0e759039cc106adca069874e1a9034fd6e3fdd427fd3c283", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "01f9037a2a1de1d633b5a881101e6a444bcabb1d386ca1e00bb273a1f1d9d939"},
"plug_cowboy": {:hex, :plug_cowboy, "2.3.0", "149a50e05cb73c12aad6506a371cd75750c0b19a32f81866e1a323dda9e0e99d", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bc595a1870cef13f9c1e03df56d96804db7f702175e4ccacdb8fc75c02a7b97e"},
"plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"},
"plug": {:hex, :plug, "1.11.0", "f17217525597628298998bc3baed9f8ea1fa3f1160aa9871aee6df47a6e4d38e", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2d9c633f0499f9dc5c2fd069161af4e2e7756890b81adcbb2ceaa074e8308876"},
"plug_cowboy": {:hex, :plug_cowboy, "2.4.1", "779ba386c0915027f22e14a48919a9545714f849505fa15af2631a0d298abf0f", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d72113b6dff7b37a7d9b2a5b68892808e3a9a752f2bf7e503240945385b70507"},
"plug_crypto": {:hex, :plug_crypto, "1.2.0", "1cb20793aa63a6c619dd18bb33d7a3aa94818e5fd39ad357051a67f26dfa2df6", [:mix], [], "hexpm", "a48b538ae8bf381ffac344520755f3007cc10bd8e90b240af98ea29b69683fc2"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "4737ce62a31747b4c63c12b20c62307e51bb4fcd730ca0c32c280991e0606c90"},

Loading…
Cancel
Save