- "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { formatUnits } from \"viem\"\nimport { useContractRead } from \"wagmi\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Skeleton } from \"@/registry/default/ui/skeleton\"\n\nconst erc20TotalSupplyAbi = [\n {\n inputs: [],\n name: \"totalSupply\",\n outputs: [{ internalType: \"uint256\", name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const\n\nconst erc20DecimalsAbi = [\n {\n inputs: [],\n name: \"decimals\",\n outputs: [\n {\n internalType: \"uint8\",\n name: \"\",\n type: \"uint8\",\n },\n ],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const\n\nfunction trimFormattedBalance(balance: string | undefined, decimals = 4) {\n if (!balance) {\n return \"0\"\n }\n const [integer, decimal] = balance.split(\".\")\n if (!decimal) return integer\n\n const trimmedDecimal = decimal.slice(0, decimals)\n return `${integer}.${trimmedDecimal}`\n}\n\nconst ErrorMessage = ({ error }: { error: Error | null }) => {\n return (\n <div className={cn(\"break-words text-sm font-medium text-red-500\")}>\n {error?.message ?? \"Error while fetching ERC20 data\"}\n </div>\n )\n}\n\nexport type Erc20TotalSupplyProps = React.HTMLAttributes<HTMLSpanElement> & {\n address: `0x${string}`\n chainId?: number\n formatDecimals?: number\n}\n\nconst Erc20TotalSupply = React.forwardRef<\n HTMLSpanElement,\n Erc20TotalSupplyProps\n>(({ chainId, address, formatDecimals = 4, ...props }, ref) => {\n const {\n data: totalSupply,\n isLoading: isLoadingTotalSupply,\n isError: isErrorTotalSupply,\n error: errorTotalSupply,\n } = useContractRead({\n address,\n abi: erc20TotalSupplyAbi,\n functionName: \"totalSupply\",\n chainId,\n })\n\n const {\n data: decimals,\n isLoading: isLoadingDecimals,\n isError: isErrorDecimals,\n error: errorDecimals,\n } = useContractRead({\n address,\n abi: erc20DecimalsAbi,\n functionName: \"decimals\",\n chainId,\n })\n\n if (isLoadingTotalSupply || isLoadingDecimals) {\n return <Skeleton className=\"h-6 w-12\" {...props} />\n }\n\n if (isErrorTotalSupply || isErrorDecimals) {\n return <ErrorMessage error={errorTotalSupply ?? errorDecimals} />\n }\n\n if (totalSupply === undefined || decimals === undefined) {\n return null\n }\n\n return (\n <span ref={ref} {...props}>\n {trimFormattedBalance(formatUnits(totalSupply, decimals), formatDecimals)}\n </span>\n )\n})\n\nErc20TotalSupply.displayName = \"Erc20TotalSupply\"\n\nexport { Erc20TotalSupply }\n"
0 commit comments