diff --git a/CHANGELOG.md b/CHANGELOG.md index 4648f5300c..6d74f174f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#3278](https://github.com/poanetwork/blockscout/pull/3278) - Support of fetching of NFT tokens metadata from IPFS - [#3273](https://github.com/poanetwork/blockscout/pull/3273) - Update token metadata at burn/mint events - [#3268](https://github.com/poanetwork/blockscout/pull/3268) - Token total supply on-demand fetcher - [#3261](https://github.com/poanetwork/blockscout/pull/3261) - Bridged tokens table diff --git a/apps/explorer/lib/explorer/token/instance_metadata_retriever.ex b/apps/explorer/lib/explorer/token/instance_metadata_retriever.ex index ad5ada3ced..0dac1c66ed 100644 --- a/apps/explorer/lib/explorer/token/instance_metadata_retriever.ex +++ b/apps/explorer/lib/explorer/token/instance_metadata_retriever.ex @@ -8,6 +8,8 @@ defmodule Explorer.Token.InstanceMetadataRetriever do alias Explorer.SmartContract.Reader alias HTTPoison.{Error, Response} + @token_uri "c87b56dd" + @abi [ %{ "type" => "function", @@ -38,7 +40,7 @@ defmodule Explorer.Token.InstanceMetadataRetriever do def fetch_metadata(contract_address_hash, token_id) do # c87b56dd = keccak256(tokenURI(uint256)) - contract_functions = %{"c87b56dd" => [token_id]} + contract_functions = %{@token_uri => [token_id]} contract_address_hash |> query_contract(contract_functions) @@ -49,26 +51,26 @@ defmodule Explorer.Token.InstanceMetadataRetriever do Reader.query_contract(contract_address_hash, @abi, contract_functions) end - def fetch_json(%{"c87b56dd" => {:ok, [""]}}) do + def fetch_json(%{@token_uri => {:ok, [""]}}) do {:ok, %{error: @no_uri_error}} end - def fetch_json(%{"c87b56dd" => {:error, "(-32015) VM execution error."}}) do + def fetch_json(%{@token_uri => {:error, "(-32015) VM execution error."}}) do {:ok, %{error: @no_uri_error}} end - def fetch_json(%{"c87b56dd" => {:ok, ["http://" <> _ = token_uri]}}) do + def fetch_json(%{@token_uri => {:ok, ["http://" <> _ = token_uri]}}) do fetch_metadata(token_uri) end - def fetch_json(%{"c87b56dd" => {:ok, ["https://" <> _ = token_uri]}}) do + def fetch_json(%{@token_uri => {:ok, ["https://" <> _ = token_uri]}}) do fetch_metadata(token_uri) end - def fetch_json(%{"c87b56dd" => {:ok, ["data:application/json," <> json]}}) do + def fetch_json(%{@token_uri => {:ok, ["data:application/json," <> json]}}) do decoded_json = URI.decode(json) - fetch_json(%{"c87b56dd" => {:ok, [decoded_json]}}) + fetch_json(%{@token_uri => {:ok, [decoded_json]}}) rescue e -> Logger.debug(["Unknown metadata format #{inspect(json)}. error #{inspect(e)}"], @@ -78,7 +80,12 @@ defmodule Explorer.Token.InstanceMetadataRetriever do {:error, json} end - def fetch_json(%{"c87b56dd" => {:ok, [json]}}) do + def fetch_json(%{@token_uri => {:ok, ["ipfs://ipfs/" <> ipfs_uid]}}) do + ipfs_url = "https://ipfs.io/ipfs/" <> ipfs_uid + fetch_metadata(ipfs_url) + end + + def fetch_json(%{@token_uri => {:ok, [json]}}) do {:ok, json} = decode_json(json) check_type(json)