Track 8 · Capstones · lesson 4

Wallet portfolio tracker

90 min


A page that shows everything an address holds: ETH, a set of ERC-20s, and NFTs — read-only, no wallet required to view someone else's.

Scaffolding tier: signatures. Architecture and the shape of the data-fetching functions. No contract to write — this is a pure reading exercise, and reading well at scale is its own skill.

The build

Type an address (or connect a wallet), see its holdings. The whole thing runs on a public read provider — the point from track 6 that reads need no wallet.

Architecture

web/
  useHoldings.ts   // the data layer — the interesting part
  Portfolio.tsx    // presentation
  tokenList.ts     // the ERC-20s to check

The signatures — you fill the bodies

async function getEthBalance(address: Address): Promise<bigint>;
async function getTokenBalances(
  address: Address,
  tokens: Address[],
): Promise<{ token: Address; balance: bigint; symbol: string; decimals: number }[]>;
async function getNfts(address: Address): Promise<NftHolding[]>;

Where the skill is:

Acceptance criteria

Check

Why does this whole page work without connecting a wallet?

Choose one answer

Worth remembering

  • Capstone 4, signatures scaffolding: data-layer function shapes given, bodies yours.
  • A read-only portfolio for any address — no wallet needed to view.
  • Batch token reads with multicall; a read waterfall feels broken.
  • Format by each token's decimals, and handle empty and loading states as first-class.