From de4a6983fafedd400d10dcc5a4f0b1781ec7160d Mon Sep 17 00:00:00 2001 From: Pablo Alayeto <55535804+Pabl0cks@users.noreply.github.com> Date: Mon, 19 Feb 2024 12:39:43 +0100 Subject: [PATCH] Add logic to parse network name from URL (#65) --- .../scaffold-eth/Contract/ContractUI.tsx | 8 +- .../pages/[contractAddress]/[network].tsx | 97 +++++++++++-------- 2 files changed, 62 insertions(+), 43 deletions(-) diff --git a/packages/nextjs/components/scaffold-eth/Contract/ContractUI.tsx b/packages/nextjs/components/scaffold-eth/Contract/ContractUI.tsx index 739e5fcc..088c47f5 100644 --- a/packages/nextjs/components/scaffold-eth/Contract/ContractUI.tsx +++ b/packages/nextjs/components/scaffold-eth/Contract/ContractUI.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo, useReducer, useState } from "react"; -import router from "next/router"; +import { useRouter } from "next/router"; import { ContractReadMethods } from "./ContractReadMethods"; import { ContractVariables } from "./ContractVariables"; import { ContractWriteMethods } from "./ContractWriteMethods"; @@ -28,6 +28,8 @@ export const ContractUI = ({ className = "", initialContractData }: ContractUIPr const mainChainId = useAbiNinjaState(state => state.mainChainId); const mainNetwork = mainNetworks.find(network => network.id === mainChainId); const networkColor = useNetworkColor(mainNetwork); + const router = useRouter(); + const { network } = router.query as { network?: string }; const updateUrlWithSelectedMethods = (selectedMethods: string[]) => { const currentQuery = new URLSearchParams(window.location.search); @@ -36,7 +38,7 @@ export const ContractUI = ({ className = "", initialContractData }: ContractUIPr } else { currentQuery.delete("methods"); } - const newPath = `/${initialContractData.address}/${mainChainId}`; + const newPath = `/${initialContractData.address}/${network}`; router.push({ pathname: newPath, query: currentQuery.toString() }, undefined, { shallow: true }); }; @@ -83,7 +85,7 @@ export const ContractUI = ({ className = "", initialContractData }: ContractUIPr method => method.type === "function" && "name" in method && selectedMethodNames.includes(method.name), ) as AbiFunction[]; // Cast it to AbiFunction[] setAbi(selectedMethods); - }, [initialContractData.abi]); + }, [initialContractData.abi, router?.query?.methods]); const { data: contractNameData, isLoading: isContractNameLoading } = useContractRead({ address: initialContractData.address, diff --git a/packages/nextjs/pages/[contractAddress]/[network].tsx b/packages/nextjs/pages/[contractAddress]/[network].tsx index ffe5a3b4..b3b4beb9 100644 --- a/packages/nextjs/pages/[contractAddress]/[network].tsx +++ b/packages/nextjs/pages/[contractAddress]/[network].tsx @@ -29,64 +29,81 @@ const ContractDetailPage = () => { const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const contractName = contractData.address; - const { contractAbi: storedAbi, setMainChainId } = useAbiNinjaState(state => ({ + const { + contractAbi: storedAbi, + setMainChainId, + chainId, + } = useAbiNinjaState(state => ({ contractAbi: state.contractAbi, setMainChainId: state.setMainChainId, + chainId: state.mainChainId, })); - const getNetworkName = (chainId: string) => { - const chain = Object.values(chains).find(chain => chain.id === parseInt(chainId)); + const getNetworkName = (chainId: number) => { + const chain = Object.values(chains).find(chain => chain.id === chainId); return chain ? chain.name : "Unknown Network"; }; useEffect(() => { if (network) { - setMainChainId(parseInt(network)); - } - }, [network, setMainChainId]); + let normalizedNetwork = network.toLowerCase(); + if (normalizedNetwork === "ethereum" || normalizedNetwork === "mainnet") { + normalizedNetwork = "homestead"; // chain.network for mainnet in viem/chains + } - useEffect(() => { - const fetchContractAbi = async () => { - setIsLoading(true); + const chain = Object.values(chains).find(chain => chain.network === normalizedNetwork); - if (storedAbi && storedAbi.length > 0) { - setContractData({ abi: storedAbi, address: contractAddress }); - setError(null); - setIsLoading(false); - return; + let parsedNetworkId = 1; + if (chain) { + parsedNetworkId = chain.id; + } else { + parsedNetworkId = parseInt(network); } - try { - const abi = await fetchContractABIFromAnyABI(contractAddress, parseInt(network)); - if (!abi) throw new Error("Got empty or undefined ABI from AnyABI"); - setContractData({ abi, address: contractAddress }); - setError(null); - } catch (error) { - console.error("Error fetching ABI from AnyABI: ", error); - console.log("Trying to fetch ABI from Etherscan..."); + setMainChainId(parsedNetworkId); + + const fetchContractAbi = async () => { + setIsLoading(true); + + if (storedAbi && storedAbi.length > 0) { + setContractData({ abi: storedAbi, address: contractAddress }); + setError(null); + setIsLoading(false); + return; + } + try { - const abiString = await fetchContractABIFromEtherscan(contractAddress, parseInt(network)); - const parsedAbi = JSON.parse(abiString); - setContractData({ abi: parsedAbi, address: contractAddress }); + const abi = await fetchContractABIFromAnyABI(contractAddress, parsedNetworkId); + if (!abi) throw new Error("Got empty or undefined ABI from AnyABI"); + setContractData({ abi, address: contractAddress }); setError(null); - } catch (etherscanError: any) { - console.error("Error fetching ABI from Etherscan: ", etherscanError); - setError(etherscanError.message || "Error occurred while fetching ABI"); + } catch (error: any) { + console.error("Error fetching ABI from AnyABI: ", error); + console.log("Trying to fetch ABI from Etherscan..."); + try { + const abiString = await fetchContractABIFromEtherscan(contractAddress, parsedNetworkId); + const parsedAbi = JSON.parse(abiString); + setContractData({ abi: parsedAbi, address: contractAddress }); + setError(null); + } catch (etherscanError: any) { + console.error("Error fetching ABI from Etherscan: ", etherscanError); + setError(etherscanError.message || "Error occurred while fetching ABI"); + } + } finally { + setIsLoading(false); } - } finally { - setIsLoading(false); - } - }; + }; - if (contractAddress && network) { - if (isAddress(contractAddress)) { - fetchContractAbi(); - } else { - setIsLoading(false); - setError("Please enter a valid address"); + if (contractAddress && network) { + if (isAddress(contractAddress)) { + fetchContractAbi(); + } else { + setIsLoading(false); + setError("Please enter a valid address"); + } } } - }, [contractAddress, network, storedAbi]); + }, [contractAddress, network, storedAbi, setMainChainId]); return ( <> @@ -106,7 +123,7 @@ const ContractDetailPage = () => {

{error}

There was an error loading the contract {contractAddress} on{" "} - {getNetworkName(network)}. + {getNetworkName(chainId)}.

Make sure the data is correct and you are connected to the right network.