diff --git a/CHANGELOG.md b/CHANGELOG.md index b50a716de3..5a8d2a43aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#2825](https://github.com/poanetwork/blockscout/pull/2825) - separate token transfers and transactions - [#2787](https://github.com/poanetwork/blockscout/pull/2787) - async fetching of address counters - [#2791](https://github.com/poanetwork/blockscout/pull/2791) - add ipc client - [#2449](https://github.com/poanetwork/blockscout/pull/2449) - add ability to send notification events through postgres notify @@ -8,6 +9,7 @@ ### Fixes - [#2854](https://github.com/poanetwork/blockscout/pull/2854) - Fix all npm vulnerabilities +- [#2851](https://github.com/poanetwork/blockscout/pull/2851) - Fix paths for front assets - [#2843](https://github.com/poanetwork/blockscout/pull/2843) - fix realtime fetcher small skips feature - [#2841](https://github.com/poanetwork/blockscout/pull/2841) - LUKSO dashboard height fix - [#2837](https://github.com/poanetwork/blockscout/pull/2837) - fix txlist ordering issue @@ -101,6 +103,7 @@ fixed menu hovers in dark mode desktop view - [#2724](https://github.com/poanetwork/blockscout/pull/2724) - fix ci by commenting a line in hackney library - [#2708](https://github.com/poanetwork/blockscout/pull/2708) - add log index to logs view - [#2723](https://github.com/poanetwork/blockscout/pull/2723) - get rid of ex_json_schema warnings +- [#2740](https://github.com/poanetwork/blockscout/pull/2740) - add verify contract rpc doc ## 2.0.4-beta diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex index 6c0899624a..af7a4c93f4 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex @@ -8,7 +8,20 @@ defmodule BlockScoutWeb.AddressTokenTransferController do alias Phoenix.View import BlockScoutWeb.Chain, - only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1] + only: [current_filter: 1, next_page_params: 3, paging_options: 1, split_list_by_page: 1] + + @transaction_necessity_by_association [ + necessity_by_association: %{ + [created_contract_address: :names] => :optional, + [from_address: :names] => :optional, + [to_address: :names] => :optional, + [token_transfers: :token] => :optional, + [token_transfers: :to_address] => :optional, + [token_transfers: :from_address] => :optional, + [token_transfers: :token_contract_address] => :optional, + :block => :required + } + ] def index( conn, @@ -93,4 +106,86 @@ defmodule BlockScoutWeb.AddressTokenTransferController do not_found(conn) end end + + def index( + conn, + %{ + "address_id" => address_hash_string, + "type" => "JSON" + } = params + ) do + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), + {:ok, address} <- Chain.hash_to_address(address_hash) do + options = + @transaction_necessity_by_association + |> Keyword.merge(paging_options(params)) + |> Keyword.merge(current_filter(params)) + + transactions = + Chain.address_hash_to_token_transfers( + address_hash, + options + ) + + {transactions_paginated, next_page} = split_list_by_page(transactions) + + next_page_path = + case next_page_params(next_page, transactions_paginated, params) do + nil -> + nil + + next_page_params -> + address_token_transfers_path( + conn, + :index, + address_hash_string, + Map.delete(next_page_params, "type") + ) + end + + transfers_json = + Enum.map(transactions_paginated, fn transaction -> + View.render_to_string( + TransactionView, + "_tile.html", + conn: conn, + transaction: transaction, + current_address: address + ) + end) + + json(conn, %{items: transfers_json, next_page_path: next_page_path}) + else + :error -> + unprocessable_entity(conn) + + {:error, :not_found} -> + not_found(conn) + end + end + + def index( + conn, + %{"address_id" => address_hash_string} = params + ) do + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), + {:ok, address} <- Chain.hash_to_address(address_hash) do + render( + conn, + "index.html", + address: address, + coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), + exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), + filter: params["filter"], + current_path: current_path(conn), + counters_path: address_path(conn, :address_counters, %{"id" => to_string(address_hash)}) + ) + else + :error -> + unprocessable_entity(conn) + + {:error, :not_found} -> + not_found(conn) + end + end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex index b79800a464..2bac5acdb2 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex @@ -19,10 +19,6 @@ defmodule BlockScoutWeb.AddressTransactionController do [created_contract_address: :names] => :optional, [from_address: :names] => :optional, [to_address: :names] => :optional, - [token_transfers: :token] => :optional, - [token_transfers: :to_address] => :optional, - [token_transfers: :from_address] => :optional, - [token_transfers: :token_contract_address] => :optional, :block => :required } ] diff --git a/apps/block_scout_web/lib/block_scout_web/etherscan.ex b/apps/block_scout_web/lib/block_scout_web/etherscan.ex index cedc6d77ad..eadaf0fff5 100644 --- a/apps/block_scout_web/lib/block_scout_web/etherscan.ex +++ b/apps/block_scout_web/lib/block_scout_web/etherscan.ex @@ -1946,7 +1946,24 @@ defmodule BlockScoutWeb.Etherscan do @contract_verify_action %{ name: "verify", - description: "Verify a contract with its source code and contract creation information.", + description: """ + Verify a contract with its source code and contract creation information. +
+
+

curl POST example:

+
+
+
+
+
+ curl -d '{"addressHash":"0xd6984e092b51337032cf0300c7291e4839be37e1","compilerVersion":"v0.5.4+commit.9549d8ff", + "contractSourceCode":"pragma solidity ^0.5.4;\n","name":"Test","optimization":false}' + -H "Content-Type: application/json" -X POST "https://blockscout.com/eth/kovan/api?module=contract&action=verify" + +
+
+
+ """, required_params: [ %{ key: "addressHash", diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex index f484a9ac8a..b615035ac4 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex @@ -4,6 +4,12 @@ class: "card-tab #{tab_status("transactions", @conn.request_path)}", to: address_transaction_path(@conn, :index, @address.hash) ) %> + <%= link( + gettext("Token Transfers"), + class: "card-tab #{tab_status("token_transfers", @conn.request_path)}", + "data-test": "token_transfers_tab_link", + to: address_token_transfers_path(@conn, :index, @address.hash) + ) %> <%= link( gettext("Tokens"), class: "card-tab #{tab_status("tokens", @conn.request_path)}", diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex index c974ff549a..5296512291 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex @@ -2,7 +2,7 @@
<%= link( - to: address_token_transfers_path(@conn, :index, @address.hash, @token.contract_address_hash), + to: address_token_transfers_path(@conn, :index, to_string(@address.hash), to_string(@token.contract_address_hash)), class: "tile-title-lg", "data-test": "token_transfers_#{@token.contract_address_hash}" ) do %> 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 1366a83a0a..0fa96e73bd 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 @@ -11,7 +11,7 @@ data-token-symbol="<%= token_balance.token.symbol %>" > <%= link( - to: token_path(@conn, :show, token_balance.token.contract_address_hash), + to: token_path(@conn, :show, to_string(token_balance.token.contract_address_hash)), class: "dropdown-item" ) do %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex index 738d70883d..a24338c3ab 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex @@ -5,9 +5,54 @@
<%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %>
+ + <%= if assigns[:token] do %>

<%= gettext "Tokens" %> / <%= token_name(@token) %>

+ <% end %> + + <%= if !assigns[:token] do %> +
+

<%= gettext "Transactions" %>

+ +
+ <% end %> <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", 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/layout/_topnav.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex index f835177a50..61e28903d0 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 @@ -1,7 +1,7 @@ - - - - +" as="style" onload="this.rel='stylesheet'"> + + +