Skip to content

Commit

Permalink
feat: API endpoint to re-fetch token instance metadata (blockscout#10097
Browse files Browse the repository at this point in the history
)

* feat: Re-fetch token instance metadata

* Partially process review comments

* Process reviewer comments. Part 2

* Process reviewer comments. Part 3

* Process reviewer comments. Part 4

* Fix events

* Add test

* Remove :token preload

* fix formatting

* Fix tests

* Remove unused aliases

* Add reCAPTCHA for token instance re-fetch API endpoint

* Check event on websocket at /api/v2/tokens/{address_hash}/instances/{token_id}/refetch-metadata endpoint
  • Loading branch information
vbaranov authored Jun 13, 2024
1 parent c31f937 commit 4297704
Show file tree
Hide file tree
Showing 76 changed files with 950 additions and 178 deletions.
5 changes: 3 additions & 2 deletions apps/block_scout_web/.sobelow-conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
format: "compact",
ignore: ["Config.Headers", "Config.CSWH", "XSS.SendResp", "XSS.Raw"],
ignore_files: [
"apps/block_scout_web/lib/block_scout_web/smart_contracts_api_v2_router.ex",
"apps/block_scout_web/lib/block_scout_web/utils_api_v2_router.ex"
"apps/block_scout_web/lib/block_scout_web/routers/smart_contracts_api_v2_router.ex",
"apps/block_scout_web/lib/block_scout_web/routers/tokens_api_v2_router.ex",
"apps/block_scout_web/lib/block_scout_web/routers/utils_api_v2_router.ex"
]
]
4 changes: 2 additions & 2 deletions apps/block_scout_web/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ config :prometheus, BlockScoutWeb.Prometheus.PhoenixInstrumenter,

config :spandex_phoenix, tracer: BlockScoutWeb.Tracer

config :block_scout_web, BlockScoutWeb.ApiRouter,
config :block_scout_web, BlockScoutWeb.Routers.ApiRouter,
writing_enabled: !ConfigHelper.parse_bool_env_var("API_V1_WRITE_METHODS_DISABLED"),
reading_enabled: !ConfigHelper.parse_bool_env_var("API_V1_READ_METHODS_DISABLED")

config :block_scout_web, BlockScoutWeb.WebRouter, enabled: !ConfigHelper.parse_bool_env_var("DISABLE_WEBAPP")
config :block_scout_web, BlockScoutWeb.Routers.WebRouter, enabled: !ConfigHelper.parse_bool_env_var("DISABLE_WEBAPP")

config :block_scout_web, BlockScoutWeb.CSPHeader,
mixpanel_url: System.get_env("MIXPANEL_URL", "https://api-js.mixpanel.com"),
Expand Down
6 changes: 3 additions & 3 deletions apps/block_scout_web/lib/block_scout_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ defmodule BlockScoutWeb do

import BlockScoutWeb.Controller
import BlockScoutWeb.Router.Helpers
import BlockScoutWeb.WebRouter.Helpers, except: [static_path: 2]
import BlockScoutWeb.Routers.WebRouter.Helpers, except: [static_path: 2]
import BlockScoutWeb.Gettext
import BlockScoutWeb.ErrorHelper
import BlockScoutWeb.Routers.AccountRouter.Helpers, except: [static_path: 2]
import Plug.Conn

alias BlockScoutWeb.AdminRouter.Helpers, as: AdminRoutes
alias BlockScoutWeb.Routers.AdminRouter.Helpers, as: AdminRoutes
end
end

Expand Down Expand Up @@ -61,7 +61,7 @@ defmodule BlockScoutWeb do

import Explorer.Chain.CurrencyHelper, only: [divide_decimals: 2]

import BlockScoutWeb.WebRouter.Helpers, except: [static_path: 2]
import BlockScoutWeb.Routers.WebRouter.Helpers, except: [static_path: 2]
end
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule BlockScoutWeb.TokenInstanceChannel do
@moduledoc """
Establishes pub/sub channel for live updates of token instances events.
"""
use BlockScoutWeb, :channel

intercept(["fetched_token_instance_metadata"])

def join("fetched_token_instance_metadata", _params, socket) do
{:ok, %{}, socket}
end

def join("token_instances:" <> _token_contract_address_hash, _params, socket) do
{:ok, %{}, socket}
end

def handle_out(
"fetched_token_instance_metadata",
res,
%Phoenix.Socket{handler: BlockScoutWeb.UserSocketV2} = socket
) do
push(socket, "fetched_token_instance_metadata", res)

{:noreply, socket}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defmodule BlockScoutWeb.UserSocket do
channel("rewards:*", BlockScoutWeb.RewardChannel)
channel("transactions:*", BlockScoutWeb.TransactionChannel)
channel("tokens:*", BlockScoutWeb.TokenChannel)
channel("token_instances:*", BlockScoutWeb.TokenInstanceChannel)

def connect(%{"locale" => locale}, socket) do
{:ok, assign(socket, :locale, locale)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule BlockScoutWeb.UserSocketV2 do
channel("rewards:*", BlockScoutWeb.RewardChannel)
channel("transactions:*", BlockScoutWeb.TransactionChannel)
channel("tokens:*", BlockScoutWeb.TokenChannel)
channel("token_instances:*", BlockScoutWeb.TokenInstanceChannel)
channel("zkevm_batches:*", BlockScoutWeb.PolygonZkevmConfirmedBatchChannel)

def connect(_params, socket) do
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule BlockScoutWeb.Admin.SetupController do
use BlockScoutWeb, :controller

import BlockScoutWeb.AdminRouter.Helpers
import BlockScoutWeb.Routers.AdminRouter.Helpers

alias BlockScoutWeb.Endpoint
alias Explorer.Accounts.User.Registration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ defmodule BlockScoutWeb.API.RPC.RPCTranslator do
end

defp action_accessed?(action, write_actions) do
conf = Application.get_env(:block_scout_web, BlockScoutWeb.ApiRouter)
conf = Application.get_env(:block_scout_web, BlockScoutWeb.Routers.ApiRouter)

if action in write_actions do
conf[:writing_enabled] || {:error, :no_action}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ defmodule BlockScoutWeb.API.V2.CSVExportController do
def export_token_holders(conn, %{"address_hash_param" => address_hash_string} = params) do
with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)},
{:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params),
{:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)},
{:recaptcha, true} <-
{:recaptcha,
Application.get_env(:block_scout_web, :recaptcha)[:is_disabled] ||
CSVHelper.captcha_helper().recaptcha_passed?(params["recaptcha_response"])} do
CSVHelper.captcha_helper().recaptcha_passed?(params["recaptcha_response"])},
{:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)} do
token_holders = Chain.fetch_token_holders_from_token_hash_for_csv(address_hash, @options)

token_holders
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ defmodule BlockScoutWeb.API.V2.FallbackController do
alias BlockScoutWeb.API.V2.ApiView
alias Ecto.Changeset

@verification_failed "API v2 smart-contract verification failed"
@invalid_parameters "Invalid parameter(s)"
@invalid_address_hash "Invalid address hash"
@invalid_hash "Invalid hash"
Expand Down Expand Up @@ -36,7 +35,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:format, _params}) do
Logger.error(fn ->
["#{@verification_failed}: #{@invalid_parameters}"]
["#{@invalid_parameters}"]
end)

conn
Expand All @@ -47,7 +46,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:format_address, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@invalid_address_hash}"]
["#{@invalid_address_hash}"]
end)

conn
Expand All @@ -58,7 +57,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:format_url, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@invalid_url}"]
["#{@invalid_url}"]
end)

conn
Expand All @@ -69,7 +68,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:not_found, _, :empty_items_with_next_page_params}) do
Logger.error(fn ->
["#{@verification_failed}: :empty_items_with_next_page_params"]
[":empty_items_with_next_page_params"]
end)

conn
Expand All @@ -78,7 +77,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:not_found, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@not_found}"]
["#{@not_found}"]
end)

conn
Expand All @@ -89,7 +88,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:contract_interaction_disabled, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@contract_interaction_disabled}"]
["#{@contract_interaction_disabled}"]
end)

conn
Expand All @@ -100,7 +99,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:error, {:invalid, :hash}}) do
Logger.error(fn ->
["#{@verification_failed}: #{@invalid_hash}"]
["#{@invalid_hash}"]
end)

conn
Expand All @@ -111,7 +110,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:error, {:invalid, :number}}) do
Logger.error(fn ->
["#{@verification_failed}: #{@invalid_number}"]
["#{@invalid_number}"]
end)

conn
Expand All @@ -122,7 +121,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:error, :not_found}) do
Logger.error(fn ->
["#{@verification_failed}: :not_found"]
[":not_found"]
end)

conn
Expand All @@ -138,7 +137,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:restricted_access, true}) do
Logger.error(fn ->
["#{@verification_failed}: #{@restricted_access}"]
["#{@restricted_access}"]
end)

conn
Expand All @@ -149,7 +148,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:already_verified, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@already_verified}"]
["#{@already_verified}"]
end)

conn
Expand All @@ -159,7 +158,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:no_json_file, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@json_not_found}"]
["#{@json_not_found}"]
end)

conn
Expand All @@ -169,7 +168,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:file_error, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@error_while_reading_json}"]
["#{@error_while_reading_json}"]
end)

conn
Expand All @@ -179,7 +178,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:libs_format, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@error_in_libraries}"]
["#{@error_in_libraries}"]
end)

conn
Expand All @@ -189,7 +188,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:lost_consensus, {:ok, block}}) do
Logger.error(fn ->
["#{@verification_failed}: #{@block_lost_consensus}"]
["#{@block_lost_consensus}"]
end)

conn
Expand All @@ -199,7 +198,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:lost_consensus, {:error, :not_found}}) do
Logger.error(fn ->
["#{@verification_failed}: #{@block_lost_consensus}"]
["#{@block_lost_consensus}"]
end)

conn
Expand All @@ -208,7 +207,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:recaptcha, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@invalid_captcha_resp}"]
["#{@invalid_captcha_resp}"]
end)

conn
Expand All @@ -219,7 +218,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:auth, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@unauthorized}"]
["#{@unauthorized}"]
end)

conn
Expand All @@ -230,7 +229,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:sensitive_endpoints_api_key, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@not_configured_api_key}"]
["#{@not_configured_api_key}"]
end)

conn
Expand All @@ -241,7 +240,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do

def call(conn, {:api_key, _}) do
Logger.error(fn ->
["#{@verification_failed}: #{@wrong_api_key}"]
["#{@wrong_api_key}"]
end)

conn
Expand Down
Loading

0 comments on commit 4297704

Please sign in to comment.