Skip to content

Commit

Permalink
Add logic to parse network name from URL (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pabl0cks authored Feb 19, 2024
1 parent f4d3b60 commit de4a698
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 43 deletions.
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

0 comments on commit de4a698

Please sign in to comment.