Track 6 · dApps & frontend · lesson 2

Reading state with viem

11 min


You have been using viem all along — the Forge's tests are written in it. Now you point it at a real network instead of the in-browser chain.

viem is a TypeScript library for talking to Ethereum: type-safe, small, and the current default for new projects. The functions you met in the Forge — readContract, getBalance — are the same ones you use against mainnet. Only the transport changes.

A public client

import { createPublicClient, http, formatEther } from "viem";
import { mainnet } from "viem/chains";

const client = createPublicClient({
  chain: mainnet,
  transport: http("https://rpc.example.com"),
});

const balance = await client.getBalance({ address: "0xf39f…2266" });
console.log(formatEther(balance), "ETH");   // wei -> a human number

formatEther turns the raw wei integer into a readable decimal — the display step from track 5, applied. Its opposite, parseEther("1.5"), turns a human number back into wei for sending.

Reading a contract

const symbol = await client.readContract({
  address: tokenAddress,
  abi: erc20Abi,
  functionName: "symbol",
});

const balance = await client.readContract({
  address: tokenAddress,
  abi: erc20Abi,
  functionName: "balanceOf",
  args: [userAddress],
});

The abi is how viem knows how to encode the call and decode the answer — the exact role it played in the Forge's test runner. Reads cost no gas and need no wallet.

Predict

A token reports `balanceOf` as 1000000000 with decimals of 6. What should the UI show?

Choose one answer

Multicall

Reading twenty balances as twenty separate requests is slow. viem's multicall batches them into one RPC round-trip:

const results = await client.multicall({
  contracts: addresses.map((a) => ({
    address: token, abi: erc20Abi, functionName: "balanceOf", args: [a],
  })),
});

One request, twenty answers. This is the difference between a portfolio page that loads instantly and one that spinners for five seconds.

Check

What does the `abi` give viem when reading a contract?

Choose one answer

Worth remembering

  • viem is the same library the Forge uses; only the transport changes when you point it at a real network.
  • A public client reads without a wallet or gas.
  • `formatEther`/`formatUnits` convert wei to human numbers; `parseEther` goes back.
  • Always format token amounts by the token's own `decimals`, never a hardcoded divisor.
  • `multicall` batches many reads into one request.