From cc348ef824003695518a5797c63fecffccf17cbb Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 18 Nov 2020 20:10:07 +0300 Subject: [PATCH] Price for bridged tokens --- CHANGELOG.md | 1 + .../address_token_balance/_tokens.html.eex | 2 +- .../views/address_token_balance_view.ex | 58 +++++++++++++++++++ .../block_scout_web/views/currency_helpers.ex | 2 +- .../block_scout_web/views/stakes_helpers.ex | 2 +- apps/block_scout_web/mix.exs | 4 +- .../address_read_contract_controller_test.exs | 1 + .../address_read_proxy_controller_test.exs | 1 + .../address_token_controller_test.exs | 1 + .../address_transaction_controller_test.exs | 1 + ...address_write_contract_controller_test.exs | 1 + .../address_write_proxy_controller_test.exs | 1 + .../views/address_token_balance_view_test.exs | 34 +++++++++++ apps/ethereum_jsonrpc/mix.exs | 2 +- apps/explorer/config/test.exs | 4 +- apps/explorer/lib/explorer/market/market.ex | 26 ++++++++- apps/explorer/mix.exs | 2 +- apps/indexer/mix.exs | 2 +- .../bound_interval_supervisor_test.exs | 1 + mix.exs | 3 +- mix.lock | 19 +++--- 21 files changed, 147 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e95df1cc9e..eb4f9ae193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#3462](https://github.com/poanetwork/blockscout/pull/3462) - Display price for bridged tokens ### Fixes diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex index 0fa96e73bd..e25a51a30a 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex @@ -3,7 +3,7 @@ <%= @type %> (<%= Enum.count(@token_balances)%>) - <%= for token_balance <- sort_by_name(@token_balances) do %> + <%= for token_balance <- sort_by_usd_value_and_name(@token_balances) do %>
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(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(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(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(usd_value1, usd_value2, sort_by_name) do + cond do + usd_value1 && usd_value2 && Decimal.cmp(usd_value1, usd_value2) == :gt -> + true + + usd_value1 && usd_value2 && Decimal.cmp(usd_value1, usd_value2) == :eq -> + sort_by_name + + true -> + sort_by_name + end + end + @doc """ Return the balance in usd corresponding to this token. Return nil if the usd_value of the token is not present. """ diff --git a/apps/block_scout_web/lib/block_scout_web/views/currency_helpers.ex b/apps/block_scout_web/lib/block_scout_web/views/currency_helpers.ex index 2bb4117951..8d497b4c0b 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/currency_helpers.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/currency_helpers.ex @@ -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 diff --git a/apps/block_scout_web/lib/block_scout_web/views/stakes_helpers.ex b/apps/block_scout_web/lib/block_scout_web/views/stakes_helpers.ex index 3b97d933f7..2528f5a75a 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/stakes_helpers.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/stakes_helpers.ex @@ -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 \\ []) diff --git a/apps/block_scout_web/mix.exs b/apps/block_scout_web/mix.exs index 67dbb9fa5a..c9190ae40b 100644 --- a/apps/block_scout_web/mix.exs +++ b/apps/block_scout_web/mix.exs @@ -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]}, diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs index 6cdc352587..e96e1fb6d5 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs @@ -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 diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_read_proxy_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_read_proxy_controller_test.exs index 3c37905cf9..5ee551deb4 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_read_proxy_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_read_proxy_controller_test.exs @@ -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 diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs index 046dc9ef50..0f025ea0f3 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs @@ -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 diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs index b402f7c29a..6e523f8b42 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs @@ -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 diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_write_contract_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_write_contract_controller_test.exs index 9356c474ea..2450d76f99 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_write_contract_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_write_contract_controller_test.exs @@ -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 diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_write_proxy_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_write_proxy_controller_test.exs index d4fc4917aa..de5db9d675 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_write_proxy_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_write_proxy_controller_test.exs @@ -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 diff --git a/apps/block_scout_web/test/block_scout_web/views/address_token_balance_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_token_balance_view_test.exs index aeb08e9e8c..ec2d6d1264 100644 --- a/apps/block_scout_web/test/block_scout_web/views/address_token_balance_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/address_token_balance_view_test.exs @@ -69,6 +69,40 @@ 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") |> Map.put(:usd_value, 2)) + token_balance_b = build(:token_balance, token: build(:token, name: "token") |> Map.put(:usd_value, 3)) + token_balance_c = build(:token_balance, token: build(:token, name: nil) |> Map.put(:usd_value, 2)) + token_balance_d = build(:token_balance, token: build(:token, name: "Atoken") |> Map.put(:usd_value, 1)) + token_balance_e = build(:token_balance, token: build(:token, name: "atoken") |> Map.put(:usd_value, nil)) + token_balance_f = build(:token_balance, token: build(:token, name: "Btoken") |> Map.put(:usd_value, nil)) + token_balance_g = build(:token_balance, token: build(:token, name: "Btoken") |> Map.put(:usd_value, 1)) + + 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 = diff --git a/apps/ethereum_jsonrpc/mix.exs b/apps/ethereum_jsonrpc/mix.exs index bcee381e6c..7eca2b71c0 100644 --- a/apps/ethereum_jsonrpc/mix.exs +++ b/apps/ethereum_jsonrpc/mix.exs @@ -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 diff --git a/apps/explorer/config/test.exs b/apps/explorer/config/test.exs index 281be01cc5..2a474ffbcb 100644 --- a/apps/explorer/config/test.exs +++ b/apps/explorer/config/test.exs @@ -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 diff --git a/apps/explorer/lib/explorer/market/market.ex b/apps/explorer/lib/explorer/market/market.ex index 24b15f5056..08fe8bdfb3 100644 --- a/apps/explorer/lib/explorer/market/market.ex +++ b/apps/explorer/lib/explorer/market/market.ex @@ -4,7 +4,7 @@ defmodule Explorer.Market do """ alias Explorer.Chain.Address.CurrentTokenBalance - alias Explorer.Chain.Hash + alias Explorer.Chain.{BridgedToken, Hash} alias Explorer.ExchangeRates.Token alias Explorer.Market.{MarketHistory, MarketHistoryCache} alias Explorer.{ExchangeRates, KnownTokens, Repo} @@ -56,7 +56,9 @@ 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) + fetch_token_usd_value? = matches_known_address || mainnet_bridged_token?(token) + + usd_value = fetch_token_usd_value(fetch_token_usd_value?, symbol) Map.put(token, :usd_value, usd_value) end @@ -71,6 +73,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 diff --git a/apps/explorer/mix.exs b/apps/explorer/mix.exs index 3108a1add2..44f36c439e 100644 --- a/apps/explorer/mix.exs +++ b/apps/explorer/mix.exs @@ -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"}, diff --git a/apps/indexer/mix.exs b/apps/indexer/mix.exs index 355330dbac..bf2b89d75e 100644 --- a/apps/indexer/mix.exs +++ b/apps/indexer/mix.exs @@ -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 diff --git a/apps/indexer/test/indexer/block/catchup/bound_interval_supervisor_test.exs b/apps/indexer/test/indexer/block/catchup/bound_interval_supervisor_test.exs index 556abf69bd..dca037a9cb 100644 --- a/apps/indexer/test/indexer/block/catchup/bound_interval_supervisor_test.exs +++ b/apps/indexer/test/indexer/block/catchup/bound_interval_supervisor_test.exs @@ -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 diff --git a/mix.exs b/mix.exs index e81884762b..3fcdb4ba6c 100644 --- a/mix.exs +++ b/mix.exs @@ -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 diff --git a/mix.lock b/mix.lock index 1aa51f4ac7..37bc6820ef 100644 --- a/mix.lock +++ b/mix.lock @@ -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"},