UNPKG

@nomicfoundation/hardhat-viem

Version:
98 lines (82 loc) 2.39 kB
import type { EthereumProvider } from "hardhat/types"; import type { Chain } from "viem"; import type { TestClientMode } from "../types"; import memoize from "lodash.memoize"; import { UnknownDevelopmentNetworkError, NetworkNotFoundError, MultipleMatchingNetworksError, } from "./errors"; export async function getChain(provider: EthereumProvider): Promise<Chain> { const chains: Record<string, Chain> = require("viem/chains"); const chainId = await getChainId(provider); if (isDevelopmentNetwork(chainId)) { if (await isHardhatNetwork(provider)) { return chains.hardhat; } else if (await isFoundryNetwork(provider)) { return chains.foundry; } else { throw new UnknownDevelopmentNetworkError(); } } const matchingChains = Object.values(chains).filter( ({ id }) => id === chainId ); if (matchingChains.length === 0) { if (await isHardhatNetwork(provider)) { return { ...chains.hardhat, id: chainId, }; } else if (await isFoundryNetwork(provider)) { return { ...chains.foundry, id: chainId, }; } else { throw new NetworkNotFoundError(chainId); } } if (matchingChains.length > 1) { throw new MultipleMatchingNetworksError(chainId); } return matchingChains[0]; } export function isDevelopmentNetwork(chainId: number) { return chainId === 31337; } export async function getMode( provider: EthereumProvider ): Promise<TestClientMode> { if (await isHardhatNetwork(provider)) { return "hardhat"; } else if (await isFoundryNetwork(provider)) { return "anvil"; } else { throw new UnknownDevelopmentNetworkError(); } } const getChainId = memoize(async (provider: EthereumProvider) => Number(await provider.send("eth_chainId")) ); const isHardhatNetwork = memoize(async (provider: EthereumProvider) => detectNetworkByMethodName(provider, NetworkMethod.HARDHAT_METADATA) ); const isFoundryNetwork = memoize(async (provider: EthereumProvider) => detectNetworkByMethodName(provider, NetworkMethod.ANVIL_NODE_INFO) ); enum NetworkMethod { HARDHAT_METADATA = "hardhat_metadata", ANVIL_NODE_INFO = "anvil_nodeInfo", } async function detectNetworkByMethodName( provider: EthereumProvider, methodName: string ) { try { await provider.send(methodName); return true; } catch { return false; } }