Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add logic to parse network name from URL #65

Merged
merged 3 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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);
Expand All @@ -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 });
};
Expand Down Expand Up @@ -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,
Expand Down
97 changes: 57 additions & 40 deletions packages/nextjs/pages/[contractAddress]/[network].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,64 +29,81 @@ const ContractDetailPage = () => {
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(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 (
<>
Expand All @@ -106,7 +123,7 @@ const ContractDetailPage = () => {
<h2 className="text-2xl pt-2 flex items-end">{error}</h2>
<p className="break-all">
There was an error loading the contract <strong>{contractAddress}</strong> on{" "}
<strong>{getNetworkName(network)}</strong>.
<strong>{getNetworkName(chainId)}</strong>.
</p>
<p className="pb-2">Make sure the data is correct and you are connected to the right network.</p>

Expand Down
Loading