Merge pull request #1558 from poanetwork/ab-search-by-token-name

allow searching by token symbol
pull/1579/head
Victor Baranov 6 years ago committed by GitHub
commit f890d9076c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      apps/block_scout_web/lib/block_scout_web/chain.ex
  2. 2
      apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
  3. 10
      apps/block_scout_web/priv/gettext/default.pot
  4. 10
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  5. 14
      apps/block_scout_web/test/block_scout_web/chain_test.exs
  6. 16
      apps/explorer/lib/explorer/chain.ex
  7. 7
      apps/explorer/priv/repo/migrations/20190313085740_add_index_symobl_in_tokens.exs
  8. 15
      apps/explorer/test/explorer/chain_test.exs

@ -11,7 +11,8 @@ defmodule BlockScoutWeb.Chain do
number_to_block: 1, number_to_block: 1,
string_to_address_hash: 1, string_to_address_hash: 1,
string_to_block_hash: 1, string_to_block_hash: 1,
string_to_transaction_hash: 1 string_to_transaction_hash: 1,
token_contract_address_from_token_name: 1
] ]
alias Explorer.Chain.Block.Reward alias Explorer.Chain.Block.Reward
@ -67,10 +68,10 @@ defmodule BlockScoutWeb.Chain do
end end
end end
def from_param(formatted_number) when is_binary(formatted_number) do def from_param(string) when is_binary(string) do
case param_to_block_number(formatted_number) do case param_to_block_number(string) do
{:ok, number} -> number_to_block(number) {:ok, number} -> number_to_block(number)
{:error, :invalid} -> {:error, :not_found} _ -> token_address_from_name(string)
end end
end end
@ -159,6 +160,13 @@ defmodule BlockScoutWeb.Chain do
end end
end end
defp token_address_from_name(name) do
case token_contract_address_from_token_name(name) do
{:ok, hash} -> find_or_insert_address_from_hash(hash)
_ -> {:error, :not_found}
end
end
defp paging_params({%Reward{block: %{number: number}}, _}) do defp paging_params({%Reward{block: %{number: number}}, _}) do
%{"block_number" => number, "index" => 0} %{"block_number" => number, "index" => 0}
end end

@ -80,7 +80,7 @@
<div class="search-form d-lg-flex d-inline-block"> <div class="search-form d-lg-flex d-inline-block">
<%= form_for @conn, chain_path(@conn, :search), [class: "form-inline my-2 my-lg-0", method: :get, enforce_utf8: false], fn f -> %> <%= form_for @conn, chain_path(@conn, :search), [class: "form-inline my-2 my-lg-0", method: :get, enforce_utf8: false], fn f -> %>
<div class="input-group"> <div class="input-group">
<%= search_input f, :q, class: 'form-control mr-auto', placeholder: gettext("Search by address, transaction hash, or block number"), "aria-describedby": "search-icon", "aria-label": gettext("Search"), "data-test": "search_input" %> <%= search_input f, :q, class: 'form-control mr-auto', placeholder: gettext("Search by address, token symbol name, transaction hash, or block number"), "aria-describedby": "search-icon", "aria-label": gettext("Search"), "data-test": "search_input" %>
<div class="input-group-append"> <div class="input-group-append">
<button class="input-group-text" id="search-icon"> <button class="input-group-text" id="search-icon">
<%= render BlockScoutWeb.IconsView, "_search_icon.html" %> <%= render BlockScoutWeb.IconsView, "_search_icon.html" %>

@ -733,11 +733,6 @@ msgstr ""
msgid "Search" msgid "Search"
msgstr "" msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:83
msgid "Search by address, transaction hash, or block number"
msgstr ""
#, elixir-format #, elixir-format
#: #:
#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:28 #: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:28
@ -1701,3 +1696,8 @@ msgstr ""
#: lib/block_scout_web/templates/address/overview.html.eex:83 #: lib/block_scout_web/templates/address/overview.html.eex:83
msgid "Error: Could not determine contract creator." msgid "Error: Could not determine contract creator."
msgstr "" msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:83
msgid "Search by address, token symbol name, transaction hash, or block number"
msgstr ""

@ -733,11 +733,6 @@ msgstr ""
msgid "Search" msgid "Search"
msgstr "" msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:83
msgid "Search by address, transaction hash, or block number"
msgstr ""
#, elixir-format #, elixir-format
#: #:
#: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:28 #: lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex:28
@ -1701,3 +1696,8 @@ msgstr ""
#: lib/block_scout_web/templates/address/overview.html.eex:83 #: lib/block_scout_web/templates/address/overview.html.eex:83
msgid "Error: Could not determine contract creator." msgid "Error: Could not determine contract creator."
msgstr "" msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:83
msgid "Search by address, token symbol name, transaction hash, or block number"
msgstr ""

@ -44,6 +44,20 @@ defmodule BlockScoutWeb.ChainTest do
assert {:ok, %Address{hash: ^hash}} = address |> Phoenix.Param.to_param() |> Chain.from_param() assert {:ok, %Address{hash: ^hash}} = address |> Phoenix.Param.to_param() |> Chain.from_param()
end end
test "finds a token by its name" do
name = "AYR"
insert(:token, symbol: name)
assert {:ok, %Address{}} = name |> Chain.from_param()
end
test "finds a token by its name even if lowercase name was passed" do
name = "ayr"
insert(:token, symbol: String.upcase(name))
assert {:ok, %Address{}} = name |> Chain.from_param()
end
test "returns {:error, :not_found} when garbage is passed in" do test "returns {:error, :not_found} when garbage is passed in" do
assert {:error, :not_found} = Chain.from_param("any ol' thing") assert {:error, :not_found} = Chain.from_param("any ol' thing")
end end

@ -656,6 +656,22 @@ defmodule Explorer.Chain do
end end
end end
@spec token_contract_address_from_token_name(String.t()) :: {:ok, Hash.Address.t()} | {:error, :not_found}
def token_contract_address_from_token_name(name) when is_binary(name) do
query =
from(token in Token,
where: ilike(token.symbol, ^name),
select: token.contract_address_hash
)
query
|> Repo.one()
|> case do
nil -> {:error, :not_found}
hash -> {:ok, hash}
end
end
@doc """ @doc """
Converts `t:Explorer.Chain.Address.t/0` `hash` to the `t:Explorer.Chain.Address.t/0` with that `hash`. Converts `t:Explorer.Chain.Address.t/0` `hash` to the `t:Explorer.Chain.Address.t/0` with that `hash`.

@ -0,0 +1,7 @@
defmodule Explorer.Repo.Migrations.AddIndexSymoblInTokens do
use Ecto.Migration
def change do
create(index(:tokens, [:symbol]))
end
end

@ -855,6 +855,21 @@ defmodule Explorer.ChainTest do
end end
end end
describe "token_contract_address_from_token_name/1" do
test "return not found if token doesn't exist" do
name = "AYR"
assert {:error, :not_found} = Chain.token_contract_address_from_token_name(name)
end
test "return the correct token if it exists" do
name = "AYR"
insert(:token, symbol: name)
assert {:ok, _} = Chain.token_contract_address_from_token_name(name)
end
end
describe "find_or_insert_address_from_hash/1" do describe "find_or_insert_address_from_hash/1" do
test "returns an address if it already exists" do test "returns an address if it already exists" do
address = insert(:address) address = insert(:address)

Loading…
Cancel
Save