diff --git a/CHANGELOG.md b/CHANGELOG.md index a1cfe747aa..c2715a9a12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### Features - [#3637](https://github.com/poanetwork/blockscout/pull/3637) - getsourcecode API endpoint: show data for unverified contract from verified contract with the same bytecode +- [#3631](https://github.com/poanetwork/blockscout/pull/3631) - Tokens search +- [#3631](https://github.com/poanetwork/blockscout/pull/3631) - BSC OMNI bridge support - [#3603](https://github.com/poanetwork/blockscout/pull/3603) - Display method output parameter name at contract read page - [#3597](https://github.com/poanetwork/blockscout/pull/3597) - Show APY for delegators in Staking DApp - [#3584](https://github.com/poanetwork/blockscout/pull/3584) - Token holders API endpoint @@ -20,6 +22,8 @@ - [#3577](https://github.com/poanetwork/blockscout/pull/3577) - Eliminate GraphiQL page XSS attack ### Chore +- [#3645](https://github.com/poanetwork/blockscout/pull/3645) - Change Twitter handle +- [#3644](https://github.com/poanetwork/blockscout/pull/3644) - Correct exchange rate for SURF.finance token - [#3618](https://github.com/poanetwork/blockscout/pull/3618) - Contracts verification up to 10 libraries - [#3616](https://github.com/poanetwork/blockscout/pull/3616) - POSDAO refactoring: use zero address instead of staker address for certain cases - [#3612](https://github.com/poanetwork/blockscout/pull/3612) - POSDAO refactoring: use 'getDelegatorPools' getter instead of 'getStakerPools' in Staking DApp diff --git a/apps/block_scout_web/assets/css/components/_dropdown.scss b/apps/block_scout_web/assets/css/components/_dropdown.scss index b15f6c5c4a..3fe3831dcc 100644 --- a/apps/block_scout_web/assets/css/components/_dropdown.scss +++ b/apps/block_scout_web/assets/css/components/_dropdown.scss @@ -40,6 +40,7 @@ $dropdown-menu-item-hover-background: rgba($secondary, 0.1) !default; font-size: 12px; padding: 10px 20px; transition: $transition-cont; + white-space: initial; & { &.active, diff --git a/apps/block_scout_web/assets/css/components/_form.scss b/apps/block_scout_web/assets/css/components/_form.scss index 0109e8c514..2a03bfb06e 100644 --- a/apps/block_scout_web/assets/css/components/_form.scss +++ b/apps/block_scout_web/assets/css/components/_form.scss @@ -112,3 +112,47 @@ $form-control-border-color-active: $primary !default; } } } + +.tokens-list-search-input-outer-container { + display: flex; + @include media-breakpoint-down(md) { + display: block; + } +} + +.tokens-list-search-input-container { + float: right; + margin-left: auto; + position: relative; + @include media-breakpoint-down(md) { + width: 100%; + margin-bottom: 20px; + } +} + +.tokens-list-search-input-container:before { + content: ""; + position: absolute; + left: 10px; + top: 0; + bottom: 10px; + @include media-breakpoint-down(md) { + bottom: 0px; + } + width: 20px; + background: url("data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2016%2017%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2217%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%237DD79F%22%20fill-rule%3D%22evenodd%22%20d%3D%22M15.713%2015.727a.982.982%200%200%201-1.388%200l-2.289-2.29C10.773%2014.403%209.213%2015%207.5%2015A7.5%207.5%200%201%201%2015%207.5c0%201.719-.602%203.284-1.575%204.55l2.288%202.288a.983.983%200%200%201%200%201.389zM7.5%202a5.5%205.5%200%201%200%200%2011%205.5%205.5%200%201%200%200-11z%22%2F%3E%0A%3C%2Fsvg%3E") center / contain no-repeat; +} + +.tokens-list-search-input-container.tokens:before { + bottom: 5px; +} + +.tokens-list-search-input { + height: 40px; + width: 300px; + @include media-breakpoint-down(md) { + width: 100%; + } + padding: 10px 10px 10px 35px; + outline: none; +} \ No newline at end of file diff --git a/apps/block_scout_web/assets/css/components/_label.scss b/apps/block_scout_web/assets/css/components/_label.scss index 970dadba8c..211b8fd87f 100644 --- a/apps/block_scout_web/assets/css/components/_label.scss +++ b/apps/block_scout_web/assets/css/components/_label.scss @@ -1,10 +1,12 @@ .bs-label { display: inline-block; - padding: 5px; + padding: 0 5px; background: #f5f6fa; color: #a3a9b5; border-radius: 5px; font-size: 10px; + height: 25px; + line-height: 25px; &.right { margin-left: auto; float: right; @@ -17,6 +19,22 @@ background: $secondary; color: #fff; } + &.destination-eth { + background: #253358; + color: #fff; + } + &.destination-bsc { + background: #e7b941; + color: #fff; + } + &.bridged { + background: #70aee3; + color: #fff; + } + &.validator { + background: $primary; + color: #fff; + } &.secondary { background: $secondary; color: #fff; diff --git a/apps/block_scout_web/assets/css/components/_tile.scss b/apps/block_scout_web/assets/css/components/_tile.scss index 4a1457bb71..0a64feaf87 100644 --- a/apps/block_scout_web/assets/css/components/_tile.scss +++ b/apps/block_scout_web/assets/css/components/_tile.scss @@ -578,3 +578,30 @@ $cube-quantity: 5; .dark-theme-applied .dark-block-loader { background-color: #313355; } + +.title-with-label { + display: inline-block; + vertical-align: middle; + margin-top: 3px; + @include media-breakpoint-down(sm) { + display: inline; + } +} + +.view-original-token-container { + margin-top: 15px; + font-size: 12px; +} + +.token-address-mobile { + @include media-breakpoint-down(sm) { + display: inline-block; + word-break: break-all; + } +} + +.bridged-tokens-buttons-mobile { + @include media-breakpoint-down(sm) { + margin-top: 0.5em; + } +} diff --git a/apps/block_scout_web/assets/css/theme/_dark-theme.scss b/apps/block_scout_web/assets/css/theme/_dark-theme.scss index 937c302b44..c4794e7c42 100644 --- a/apps/block_scout_web/assets/css/theme/_dark-theme.scss +++ b/apps/block_scout_web/assets/css/theme/_dark-theme.scss @@ -1029,7 +1029,8 @@ $dark-stakes-banned-background: #3e314c; color: #fff; } - .bs-label.omni { + .bs-label.omni, + .bs-label.destination-eth { background-color: $labels-dark; } diff --git a/apps/block_scout_web/assets/js/pages/token/search.js b/apps/block_scout_web/assets/js/pages/token/search.js new file mode 100644 index 0000000000..e4f16a43c6 --- /dev/null +++ b/apps/block_scout_web/assets/js/pages/token/search.js @@ -0,0 +1,50 @@ +import $ from 'jquery' +import omit from 'lodash/omit' +import humps from 'humps' +import { createAsyncLoadStore } from '../../lib/async_listing_load' +import '../address' + +const $searchInput = $('.tokens-list-search-input') + +export const initialState = { + isSearch: false +} + +export function reducer (state, action) { + switch (action.type) { + case 'PAGE_LOAD': + case 'ELEMENTS_LOAD': { + return Object.assign({}, state, omit(action, 'type')) + } + case 'START_SEARCH': { + return Object.assign({}, state, { pagesStack: [], isSearch: true }) + } + default: + return state + } +} + +if ($('[data-page="tokens"]').length) { + const store = createAsyncLoadStore(reducer, initialState, 'dataset.identifierLog') + + store.dispatch({ + type: 'PAGE_LOAD' + }) + + $searchInput.on('input', (event) => { + const value = $(event.target).val() + + const loc = window.location.pathname + + if (value.length >= 3 || value === '') { + $.ajax({ + url: `${loc}?type=JSON&filter=${value}`, + type: 'GET', + dataType: 'json', + contentType: 'application/json; charset=utf-8' + }).done(response => store.dispatch(Object.assign({ type: 'ITEMS_FETCHED' }, humps.camelizeKeys(response)))) + .fail(() => store.dispatch({ type: 'REQUEST_ERROR' })) + .always(() => store.dispatch({ type: 'FINISH_REQUEST' })) + } + }) +} diff --git a/apps/block_scout_web/assets/webpack.config.js b/apps/block_scout_web/assets/webpack.config.js index 12878d5ac3..0f52fa95bb 100644 --- a/apps/block_scout_web/assets/webpack.config.js +++ b/apps/block_scout_web/assets/webpack.config.js @@ -95,7 +95,8 @@ const appJs = 'try-api': './js/lib/try_api.js', 'try-eth-api': './js/lib/try_eth_api.js', 'async-listing-load': './js/lib/async_listing_load', - 'non-critical': './css/non-critical.scss' + 'non-critical': './css/non-critical.scss', + 'tokens': './js/pages/token/search.js' }, output: { filename: '[name].js', diff --git a/apps/block_scout_web/config/config.exs b/apps/block_scout_web/config/config.exs index 6ab54f6e8b..c865533fcb 100644 --- a/apps/block_scout_web/config/config.exs +++ b/apps/block_scout_web/config/config.exs @@ -35,7 +35,8 @@ config :block_scout_web, api_url: System.get_env("API_URL"), apps_menu: if(System.get_env("APPS_MENU", "false") == "true", do: true, else: false), external_apps: System.get_env("EXTERNAL_APPS"), - omni_bridge_mediator: System.get_env("OMNI_BRIDGE_MEDIATOR"), + eth_omni_bridge_mediator: System.get_env("ETH_OMNI_BRIDGE_MEDIATOR"), + bsc_omni_bridge_mediator: System.get_env("BSC_OMNI_BRIDGE_MEDIATOR"), amb_bridge_mediators: System.get_env("AMB_BRIDGE_MEDIATORS"), foreign_json_rpc: System.get_env("FOREIGN_JSON_RPC", ""), gas_price: System.get_env("GAS_PRICE", nil), diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/bridged_tokens_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/bridged_tokens_controller.ex index 7f5f34b470..4cdb7512b0 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/bridged_tokens_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/bridged_tokens_controller.ex @@ -7,11 +7,68 @@ defmodule BlockScoutWeb.BridgedTokensController do alias Explorer.Chain alias Phoenix.View + def show(conn, %{"type" => "JSON", "id" => "eth"} = params) do + get_items(conn, params, :eth) + end + + def show(conn, %{"type" => "JSON", "id" => "bsc"} = params) do + get_items(conn, params, :bsc) + end + + def show(conn, %{"id" => "eth"}) do + total_supply = Chain.total_supply() + + render(conn, "index.html", + current_path: current_path(conn), + total_supply: total_supply, + chain: "Ethereum", + chain_id: 1 + ) + end + + def show(conn, %{"id" => "bsc"}) do + total_supply = Chain.total_supply() + + render(conn, "index.html", + current_path: current_path(conn), + total_supply: total_supply, + chain: "Binance Smart Chain", + chain_id: 56 + ) + end + + def show(conn, _params) do + not_found(conn) + end + def index(conn, %{"type" => "JSON"} = params) do - tokens = + get_items(conn, params, :eth) + end + + def index(conn, _params) do + total_supply = Chain.total_supply() + + render(conn, "index.html", + current_path: current_path(conn), + total_supply: total_supply, + chain: "Ethereum", + chain_id: 1 + ) + end + + defp get_items(conn, params, destination) do + filter = + if Map.has_key?(params, "filter") do + Map.get(params, "filter") + else + nil + end + + paging_params = params |> paging_options() - |> Chain.list_top_bridged_tokens() + + tokens = Chain.list_top_bridged_tokens(destination, filter, paging_params) {tokens_page, next_page} = split_list_by_page(tokens) @@ -23,7 +80,8 @@ defmodule BlockScoutWeb.BridgedTokensController do next_page_params -> bridged_tokens_path( conn, - :index, + :show, + destination, Map.delete(next_page_params, "type") ) end @@ -59,13 +117,4 @@ defmodule BlockScoutWeb.BridgedTokensController do } ) end - - def index(conn, _params) do - total_supply = Chain.total_supply() - - render(conn, "index.html", - current_path: current_path(conn), - total_supply: total_supply - ) - end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/tokens_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/tokens_controller.ex index 905f7706b1..4756c67b42 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/tokens_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/tokens_controller.ex @@ -8,10 +8,18 @@ defmodule BlockScoutWeb.TokensController do alias Phoenix.View def index(conn, %{"type" => "JSON"} = params) do - tokens = + filter = + if Map.has_key?(params, "filter") do + Map.get(params, "filter") + else + nil + end + + paging_params = params |> paging_options() - |> Chain.list_top_tokens() + + tokens = Chain.list_top_tokens(filter, paging_params) {tokens_page, next_page} = split_list_by_page(tokens) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex index a6518b0d91..ff48bbe49d 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex @@ -26,7 +26,7 @@ <%= nil %> <% end %>

- <%= address_title(@address) %> <%= gettext "Details" %> +
<%= address_title(@address) %> <%= gettext "Details" %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/_tile.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/_tile.html.eex index 1ddaf92a8b..6c520ac946 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/_tile.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/_tile.html.eex @@ -30,9 +30,13 @@ <% end %> - <%= if @bridged_token.type do %> + <%= if @bridged_token && @bridged_token.type do %>
<%= String.upcase(@bridged_token.type) %>
<% end %> + <%= if @bridged_token && @bridged_token.foreign_chain_id do %> + <% tag = Chain.chain_id_display_name(@bridged_token.foreign_chain_id) %> +
<%= String.upcase(tag) %>
+ <% end %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/index.html.eex index 891a95ac01..5757a5dd07 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/index.html.eex @@ -1,7 +1,13 @@ -
+
-

<%= gettext "Bridged Tokens" %>

+
+ <% tag = Chain.chain_id_display_name(@chain_id) %> +

<%= gettext "Bridged Tokens from " %><%= @chain %>
<%= String.upcase(tag) %>

+ +

List of the tokens bridged through OmniBridge OMNI and Arbitrary Message Bridge AMB extensions

@@ -45,5 +51,5 @@ <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
- +
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/form/_tag.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/form/_tag.html.eex new file mode 100644 index 0000000000..54f032df05 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/templates/form/_tag.html.eex @@ -0,0 +1,3 @@ +
"> + <%= @text %> +
\ No newline at end of file diff --git a/apps/block_scout_web/lib/block_scout_web/templates/layout/_footer.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/layout/_footer.html.eex index c82bb8b1cf..e972d44a11 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/layout/_footer.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/layout/_footer.html.eex @@ -22,7 +22,7 @@ - + diff --git a/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex index 537aa6d55c..3e196dac10 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex @@ -78,7 +78,7 @@ <%= gettext("Accounts") %> <% end %> - <%= if Application.get_env(:block_scout_web, :omni_bridge_mediator) && Application.get_env(:block_scout_web, :omni_bridge_mediator) != "" do %> + <%= if Chain.bridged_tokens_enabled?() do %>
-
- <%= if Map.has_key?(@token, :custom_metadata) do %> + <%= if Map.has_key?(@token, :custom_metadata) do %> +
<%= @token.custom_metadata %> - <% end %> -
+
+ <% end %> <% end %>

-

<%= Address.checksum(@token.contract_address_hash) %>

+

<%= Address.checksum(@token.contract_address_hash) %>

diff --git a/apps/block_scout_web/lib/block_scout_web/views/bridged_tokens_view.ex b/apps/block_scout_web/lib/block_scout_web/views/bridged_tokens_view.ex index 1af950b205..04d9d2096a 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/bridged_tokens_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/bridged_tokens_view.ex @@ -1,6 +1,7 @@ defmodule BlockScoutWeb.BridgedTokensView do use BlockScoutWeb, :view + alias Explorer.Chain alias Explorer.Chain.Token @owl_token_amb "0x0905Ab807F8FD040255F0cF8fa14756c1D824931" diff --git a/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex b/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex index 6b295332e3..aa6922899c 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex @@ -106,6 +106,9 @@ defmodule BlockScoutWeb.Tokens.OverviewView do 1 -> @etherscan_token_link + 56 -> + "https://bscscan.com/token/" + _ -> @etherscan_token_link end diff --git a/apps/block_scout_web/lib/block_scout_web/views/tokens_view.ex b/apps/block_scout_web/lib/block_scout_web/views/tokens_view.ex index bde196fa85..aafc4de64a 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/tokens_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/tokens_view.ex @@ -1,17 +1,12 @@ defmodule BlockScoutWeb.TokensView do use BlockScoutWeb, :view + alias Explorer.Chain alias Explorer.Chain.Token def decimals?(%Token{decimals: nil}), do: false def decimals?(%Token{decimals: _}), do: true - def bridged_tokens_enabled? do - omni_bridge_mediator = Application.get_env(:block_scout_web, :omni_bridge_mediator) - - omni_bridge_mediator && omni_bridge_mediator !== "" - end - def token_display_name(%Token{name: nil, symbol: nil}), do: "" def token_display_name(%Token{name: "", symbol: ""}), do: "" diff --git a/apps/block_scout_web/lib/block_scout_web/web_router.ex b/apps/block_scout_web/lib/block_scout_web/web_router.ex index 91360fe475..0db15bd1c5 100644 --- a/apps/block_scout_web/lib/block_scout_web/web_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/web_router.ex @@ -79,7 +79,7 @@ defmodule BlockScoutWeb.WebRouter do resources("/tokens", TokensController, only: [:index]) - resources("/bridged-tokens", BridgedTokensController, only: [:index]) + resources("/bridged-tokens", BridgedTokensController, only: [:index, :show]) resources "/address", AddressController, only: [:show] do resources("/transactions", AddressTransactionController, only: [:index], as: :transaction) diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 51f1716f3b..62d8911c72 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -107,7 +107,7 @@ msgid "API for the %{subnetwork} - BlockScout" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:119 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:124 msgid "APIs" msgstr "" @@ -405,8 +405,8 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:34 #: lib/block_scout_web/templates/address/overview.html.eex:38 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:32 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:36 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:38 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:42 msgid "Copy Address" msgstr "" @@ -624,7 +624,7 @@ msgid "Error: Could not determine contract creator." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:133 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:138 msgid "Eth RPC" msgstr "" @@ -725,7 +725,7 @@ msgid "Github" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:123 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:128 msgid "GraphQL" msgstr "" @@ -861,7 +861,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:10 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:26 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:32 msgid "Token Details" msgstr "" @@ -1181,8 +1181,8 @@ msgstr "" #: lib/block_scout_web/templates/address/overview.html.eex:158 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:51 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:107 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:52 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:137 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:58 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:140 msgid "QR Code" msgstr "" @@ -1192,7 +1192,7 @@ msgid "Query" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:128 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:133 msgid "RPC" msgstr "" @@ -1250,13 +1250,13 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_logs/index.html.eex:14 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:210 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:254 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:215 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:259 msgid "Search" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:204 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:209 msgid "Search by address, token symbol name, transaction hash, or block number" msgstr "" @@ -1291,7 +1291,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:55 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:52 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:53 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:59 msgid "Show QR Code" msgstr "" @@ -1453,7 +1453,7 @@ msgid "Topics" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:107 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:110 msgid "Total Supply" msgstr "" @@ -1610,7 +1610,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:16 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:20 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:87 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:90 msgid "View Contract" msgstr "" @@ -1725,8 +1725,8 @@ msgstr "" #: lib/block_scout_web/templates/address/overview.html.eex:167 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:108 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:116 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:138 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:146 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:141 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:149 msgid "Close" msgstr "" @@ -1743,7 +1743,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:76 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:98 msgid "Decimals" msgstr "" @@ -1861,7 +1861,7 @@ msgstr "" #: lib/block_scout_web/templates/address_token/index.html.eex:8 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:11 #: lib/block_scout_web/templates/layout/_topnav.html.eex:87 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:108 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:113 #: lib/block_scout_web/templates/tokens/index.html.eex:4 #: lib/block_scout_web/views/address_view.ex:343 msgid "Tokens" @@ -1942,7 +1942,7 @@ msgid "Write Proxy" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:147 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:152 msgid "Apps" msgstr "" @@ -1952,7 +1952,7 @@ msgid "Copy Raw Trace" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:208 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:213 msgid "Search by address, token symbol, name, transaction hash, or block number" msgstr "" @@ -1976,16 +1976,6 @@ msgstr "" msgid "page" msgstr "" -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:96 -msgid "Bridged" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/bridged_tokens/index.html.eex:4 -msgid "Bridged Tokens" -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/address/_custom_view_df_title.html.eex:9 #: lib/block_scout_web/templates/address/_custom_view_df_title.html.eex:13 @@ -2609,7 +2599,7 @@ msgid "validator" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:149 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:154 msgid "Stakes" msgstr "" @@ -2620,12 +2610,12 @@ msgid "Contract is not verified. However, we found a verified contract with the msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:155 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:160 msgid "Staking" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:247 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:252 msgid "Press / and focus will be moved to the search field" msgstr "" @@ -2686,3 +2676,18 @@ msgstr "" #: lib/block_scout_web/templates/stakes/_table.html.eex:39 msgid "Approximate Current Annual Percentage Yield. If you see N/A, please wait for a few blocks (APY cannot be calculated at the very beginning of a staking epoch)." msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/bridged_tokens/index.html.eex:6 +msgid "Bridged Tokens from " +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_topnav.html.eex:96 +msgid "Bridged from Ethereum" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_topnav.html.eex:101 +msgid "Bridged from BSC" +msgstr "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index 51f1716f3b..62d8911c72 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -107,7 +107,7 @@ msgid "API for the %{subnetwork} - BlockScout" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:119 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:124 msgid "APIs" msgstr "" @@ -405,8 +405,8 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:34 #: lib/block_scout_web/templates/address/overview.html.eex:38 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:32 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:36 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:38 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:42 msgid "Copy Address" msgstr "" @@ -624,7 +624,7 @@ msgid "Error: Could not determine contract creator." msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:133 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:138 msgid "Eth RPC" msgstr "" @@ -725,7 +725,7 @@ msgid "Github" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:123 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:128 msgid "GraphQL" msgstr "" @@ -861,7 +861,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:10 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:26 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:32 msgid "Token Details" msgstr "" @@ -1181,8 +1181,8 @@ msgstr "" #: lib/block_scout_web/templates/address/overview.html.eex:158 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:51 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:107 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:52 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:137 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:58 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:140 msgid "QR Code" msgstr "" @@ -1192,7 +1192,7 @@ msgid "Query" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:128 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:133 msgid "RPC" msgstr "" @@ -1250,13 +1250,13 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_logs/index.html.eex:14 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:210 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:254 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:215 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:259 msgid "Search" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:204 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:209 msgid "Search by address, token symbol name, transaction hash, or block number" msgstr "" @@ -1291,7 +1291,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:55 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:52 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:53 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:59 msgid "Show QR Code" msgstr "" @@ -1453,7 +1453,7 @@ msgid "Topics" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:107 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:110 msgid "Total Supply" msgstr "" @@ -1610,7 +1610,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:16 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:20 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:87 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:90 msgid "View Contract" msgstr "" @@ -1725,8 +1725,8 @@ msgstr "" #: lib/block_scout_web/templates/address/overview.html.eex:167 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:108 #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:116 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:138 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:146 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:141 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:149 msgid "Close" msgstr "" @@ -1743,7 +1743,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:76 -#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95 +#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:98 msgid "Decimals" msgstr "" @@ -1861,7 +1861,7 @@ msgstr "" #: lib/block_scout_web/templates/address_token/index.html.eex:8 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:11 #: lib/block_scout_web/templates/layout/_topnav.html.eex:87 -#: lib/block_scout_web/templates/layout/_topnav.html.eex:108 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:113 #: lib/block_scout_web/templates/tokens/index.html.eex:4 #: lib/block_scout_web/views/address_view.ex:343 msgid "Tokens" @@ -1942,7 +1942,7 @@ msgid "Write Proxy" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:147 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:152 msgid "Apps" msgstr "" @@ -1952,7 +1952,7 @@ msgid "Copy Raw Trace" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:208 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:213 msgid "Search by address, token symbol, name, transaction hash, or block number" msgstr "" @@ -1976,16 +1976,6 @@ msgstr "" msgid "page" msgstr "" -#, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:96 -msgid "Bridged" -msgstr "" - -#, elixir-format -#: lib/block_scout_web/templates/bridged_tokens/index.html.eex:4 -msgid "Bridged Tokens" -msgstr "" - #, elixir-format #: lib/block_scout_web/templates/address/_custom_view_df_title.html.eex:9 #: lib/block_scout_web/templates/address/_custom_view_df_title.html.eex:13 @@ -2609,7 +2599,7 @@ msgid "validator" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:149 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:154 msgid "Stakes" msgstr "" @@ -2620,12 +2610,12 @@ msgid "Contract is not verified. However, we found a verified contract with the msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:155 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:160 msgid "Staking" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/layout/_topnav.html.eex:247 +#: lib/block_scout_web/templates/layout/_topnav.html.eex:252 msgid "Press / and focus will be moved to the search field" msgstr "" @@ -2686,3 +2676,18 @@ msgstr "" #: lib/block_scout_web/templates/stakes/_table.html.eex:39 msgid "Approximate Current Annual Percentage Yield. If you see N/A, please wait for a few blocks (APY cannot be calculated at the very beginning of a staking epoch)." msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/bridged_tokens/index.html.eex:6 +msgid "Bridged Tokens from " +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_topnav.html.eex:96 +msgid "Bridged from Ethereum" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/layout/_topnav.html.eex:101 +msgid "Bridged from BSC" +msgstr "" diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 848f254ae7..0c94b735ff 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -1822,21 +1822,23 @@ defmodule Explorer.Chain do Lists the top `t:Explorer.Chain.Token.t/0`'s'. """ - @spec list_top_tokens :: [{Token.t(), non_neg_integer()}] - def list_top_tokens(options \\ []) do + @spec list_top_tokens(String.t()) :: [{Token.t(), non_neg_integer()}] + def list_top_tokens(filter, options \\ []) do paging_options = Keyword.get(options, :paging_options, @default_paging_options) - fetch_top_tokens(paging_options) + fetch_top_tokens(filter, paging_options) end - @spec list_top_bridged_tokens :: [{Token.t(), non_neg_integer()}] - def list_top_bridged_tokens(options \\ []) do + @spec list_top_bridged_tokens(atom(), String.t(), [paging_options | necessity_by_association_option]) :: [ + {Token.t(), non_neg_integer()} + ] + def list_top_bridged_tokens(destination, filter, options \\ []) do paging_options = Keyword.get(options, :paging_options, @default_paging_options) - fetch_top_bridged_tokens(paging_options) + fetch_top_bridged_tokens(destination, paging_options, filter) end - defp fetch_top_tokens(paging_options) do + defp fetch_top_tokens(filter, paging_options) do base_query = from(t in Token, where: t.total_supply > ^0, @@ -1844,21 +1846,35 @@ defmodule Explorer.Chain do preload: [:contract_address] ) - base_query - |> page_tokens(paging_options) - |> limit(^paging_options.page_size) + base_query_with_paging = + base_query + |> page_tokens(paging_options) + |> limit(^paging_options.page_size) + + query = + if filter && filter !== "" do + base_query_with_paging + |> where(fragment("to_tsvector('english', symbol || ' ' || name ) @@ to_tsquery(?)", ^filter)) + else + base_query_with_paging + end + + query |> Repo.all() end - defp fetch_top_bridged_tokens(paging_options) do + defp fetch_top_bridged_tokens(destination, paging_options, filter) do + chain_id = translate_destination_to_chain_id(destination) + bridged_tokens_query = from(bt in BridgedToken, - select: bt + select: bt, + where: bt.foreign_chain_id == ^chain_id ) base_query = from(t in Token, - left_join: bt in subquery(bridged_tokens_query), + right_join: bt in subquery(bridged_tokens_query), on: t.contract_address_hash == bt.home_token_contract_address_hash, where: t.total_supply > ^0, where: t.bridged, @@ -1867,12 +1883,31 @@ defmodule Explorer.Chain do preload: [:contract_address] ) - base_query - |> page_tokens(paging_options) - |> limit(^paging_options.page_size) + base_query_with_paging = + base_query + |> page_tokens(paging_options) + |> limit(^paging_options.page_size) + + query = + if filter && filter !== "" do + base_query_with_paging + |> where(fragment("to_tsvector('english', symbol || ' ' || name ) @@ to_tsquery(?)", ^filter)) + else + base_query_with_paging + end + + query |> Repo.all() end + defp translate_destination_to_chain_id(destination) do + case destination do + :eth -> 1 + :bsc -> 56 + _ -> 1 + end + end + @doc """ Calls `reducer` on a stream of `t:Explorer.Chain.Block.t/0` without `t:Explorer.Chain.Block.Reward.t/0`. """ @@ -3843,7 +3878,17 @@ defmodule Explorer.Chain do set_token_bridged_status(token_address_hash, false) created_from_int_tx && created_from_int_tx_success -> - extract_omni_bridged_token_metadata_wrapper(token_address_hash, created_from_int_tx_success) + extract_omni_bridged_token_metadata_wrapper( + token_address_hash, + created_from_int_tx_success, + :eth_omni_bridge_mediator + ) + + extract_omni_bridged_token_metadata_wrapper( + token_address_hash, + created_from_int_tx_success, + :bsc_omni_bridge_mediator + ) true -> :ok @@ -3853,8 +3898,8 @@ defmodule Explorer.Chain do :ok end - defp extract_omni_bridged_token_metadata_wrapper(token_address_hash, created_from_int_tx_success) do - omni_bridge_mediator = Application.get_env(:block_scout_web, :omni_bridge_mediator) + defp extract_omni_bridged_token_metadata_wrapper(token_address_hash, created_from_int_tx_success, mediator) do + omni_bridge_mediator = Application.get_env(:block_scout_web, mediator) %{transaction_hash: transaction_hash} = created_from_int_tx_success if omni_bridge_mediator && omni_bridge_mediator !== "" do @@ -5746,4 +5791,42 @@ defmodule Explorer.Chain do |> limit(1) |> Repo.one() end + + def bridged_tokens_enabled? do + eth_omni_bridge_mediator = Application.get_env(:block_scout_web, :eth_omni_bridge_mediator) + bsc_omni_bridge_mediator = Application.get_env(:block_scout_web, :bsc_omni_bridge_mediator) + + (eth_omni_bridge_mediator && eth_omni_bridge_mediator !== "") || + (bsc_omni_bridge_mediator && bsc_omni_bridge_mediator !== "") + end + + def bridged_tokens_eth_enabled? do + eth_omni_bridge_mediator = Application.get_env(:block_scout_web, :eth_omni_bridge_mediator) + + eth_omni_bridge_mediator && eth_omni_bridge_mediator !== "" + end + + def bridged_tokens_bsc_enabled? do + bsc_omni_bridge_mediator = Application.get_env(:block_scout_web, :bsc_omni_bridge_mediator) + + bsc_omni_bridge_mediator && bsc_omni_bridge_mediator !== "" + end + + def chain_id_display_name(nil), do: "" + + def chain_id_display_name(chain_id) do + chain_id_int = + if is_integer(chain_id) do + chain_id + else + chain_id + |> Decimal.to_integer() + end + + case chain_id_int do + 1 -> "eth" + 56 -> "bsc" + _ -> "" + end + end end diff --git a/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex b/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex index a178ab5883..7c138fd1a9 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex @@ -182,6 +182,7 @@ defmodule Explorer.ExchangeRates.Source.CoinGecko do defp bridged_token_symbol_to_id_mapping_to_get_price(symbol) do case symbol do "UNI" -> "uniswap" + "SURF" -> "surf-finance" _symbol -> nil end end diff --git a/apps/indexer/lib/indexer/supervisor.ex b/apps/indexer/lib/indexer/supervisor.ex index cea90d8b47..12ebf8b7ab 100644 --- a/apps/indexer/lib/indexer/supervisor.ex +++ b/apps/indexer/lib/indexer/supervisor.ex @@ -5,6 +5,7 @@ defmodule Indexer.Supervisor do use Supervisor + alias Explorer.Chain alias Indexer.{Block, PendingOpsCleaner, SetAmbBridgedMetadataForTokens, SetOmniBridgedMetadataForTokens} alias Indexer.Block.{Catchup, Realtime} @@ -129,10 +130,8 @@ defmodule Indexer.Supervisor do {PendingOpsCleaner, [[], []]} ] - omni_bridge_mediator = Application.get_env(:block_scout_web, :omni_bridge_mediator) - extended_fetchers = - if omni_bridge_mediator && omni_bridge_mediator !== "" do + if Chain.bridged_tokens_enabled?() do [{SetOmniBridgedMetadataForTokens, [[], []]} | basic_fetchers] else basic_fetchers