diff --git a/apps/extension/src/core/util/getErc20ContractData.ts b/apps/extension/src/core/util/getErc20ContractData.ts index 9ee6690e4c..338815a56f 100644 --- a/apps/extension/src/core/util/getErc20ContractData.ts +++ b/apps/extension/src/core/util/getErc20ContractData.ts @@ -1,26 +1,64 @@ -import { Client, getContract, parseAbi } from "viem" +import { + Abi, + Client, + ContractFunctionExecutionError, + getContract, + hexToString, + parseAbi, +} from "viem" -const ABI_ERC20 = [ - "function symbol() view returns (string)", - "function decimals() view returns (uint8)", -] as const +const DECIMALS_ABI_METHOD = "function decimals() view returns (uint8)" +const ABI_ERC20 = ["function symbol() view returns (string)", DECIMALS_ABI_METHOD] as const const PARSED_ABI_ERC20 = parseAbi(ABI_ERC20) +const ABI_ERC20_BYTES_SYMBOL = [ + "function symbol() view returns (bytes32)", + DECIMALS_ABI_METHOD, +] as const + +const PARSED_ABI_ERC20_BYTES_SYMBOL = parseAbi(ABI_ERC20_BYTES_SYMBOL) + export type Erc20ContractData = { symbol: string decimals: number } +const getErc20Contract = + (client: Client, contractAddress: `0x${string}`) => + (abi: TAbi) => + getContract({ + address: contractAddress, + abi, + publicClient: client, + }) + export const getErc20ContractData = async ( client: Client, contractAddress: `0x${string}` ): Promise => { - const contract = getContract({ - address: contractAddress, - abi: PARSED_ABI_ERC20, - publicClient: client, - }) - const [symbol, decimals] = await Promise.all([contract.read.symbol(), contract.read.decimals()]) + const getEr20ContractFn = getErc20Contract(client, contractAddress) + + try { + const contract = getEr20ContractFn(PARSED_ABI_ERC20) + + // eslint-disable-next-line no-var + var [symbol, decimals] = await Promise.all([contract.read.symbol(), contract.read.decimals()]) + } catch (e) { + if (e instanceof ContractFunctionExecutionError) { + // try to perform the contract read with bytes32 symbol + const contract = getEr20ContractFn(PARSED_ABI_ERC20_BYTES_SYMBOL) + + // eslint-disable-next-line no-var + var [bytesSymbol, decimals] = await Promise.all([ + contract.read.symbol(), + contract.read.decimals(), + ]) + symbol = hexToString(bytesSymbol) + } else { + throw e + } + } + return { symbol, decimals } } diff --git a/apps/extension/src/ui/apps/dashboard/routes/Tokens/AddCustomTokenPage.tsx b/apps/extension/src/ui/apps/dashboard/routes/Tokens/AddCustomTokenPage.tsx index d9adb1ecd3..f43a52a118 100644 --- a/apps/extension/src/ui/apps/dashboard/routes/Tokens/AddCustomTokenPage.tsx +++ b/apps/extension/src/ui/apps/dashboard/routes/Tokens/AddCustomTokenPage.tsx @@ -116,10 +116,11 @@ export const AddCustomTokenPage = () => { ) const addressErrorMessage = useMemo(() => { - // error code may be filled by ethers provider + // error code may be filled by viem provider const error = tokenInfoError as Error & { code?: string } + if (error?.code === "NETWORK_ERROR") return t("Failed to connect") - else if (error) return t("Invalid address") + else if (error) return t("Not a valid token address") else return undefined }, [t, tokenInfoError])