Read balances
useBalance for EVM wallets, or query your own RPC for every other platform and for full control.
useBalance: the built-in path
useBalance(wallet, options) takes a connected wallet, from useWallet() or
useSelectedWallet(platform), and returns a typed lifecycle state plus
refetch:
import { useBalance, useSelectedWallet } from "@usebutr/react";
const wallet = useSelectedWallet("evm");
const balance = useBalance(wallet);
const text =
balance.status === "success"
? `${balance.data.formatted} ${balance.data.symbol}`
: balance.status === "loading"
? "…"
: balance.status === "error"
? balance.error.message
: "—";With no wallet (undefined) it stays "idle". Both options are optional:
| Option | Default | Meaning |
|---|---|---|
account | the wallet's active account | which exposed account to read |
token | the native asset | an ERC-20 contract address |
const usdc = useBalance(wallet, { token: USDC_ADDRESS });balance.data is a Balance:
type Balance = {
decimals: number; // 18 for ETH, or the token's decimals
formatted: string; // human-readable, trailing zeros trimmed
symbol: string; // "ETH", or the token's symbol
value: bigint; // raw integer amount
};refetch() reads again, for example after a transaction lands. The hook also
refetches when the wallet, account, or token changes.
Only EVM adapters define getBalance: they read through the wallet's own provider
(eth_getBalance, or balanceOf for a token). butr ships no RPC for Solana, Sui, Bitcoin, or
Polkadot, and a Ledger has none either, so for those wallets useBalance stays "idle". Query
your own RPC for them. The native balance is labelled "ETH" on every EVM chain.
To call it without the hook, check for the method first:
if (wallet.connector.getBalance) {
const balance = await wallet.connector.getBalance({ account: wallet.account, token: USDC });
}Querying RPC yourself
For every other platform, and for full control on EVM (custom RPC, caching, token lists), read through your chain library. butr stays out of the way:
// viem: its own public client, not the wallet's RPC
const wei = await publicClient.getBalance({ address: account });
const eth = `${formatEther(wei)} ETH`;
// gill / @solana/kit
const { value } = await rpc.getBalance(addr).send();
const sol = `${Number(value) / 1_000_000_000} SOL`;For a reactive Solana read that auto-fetches and watches, framework-kit's
useBalance works against a butr-managed wallet; see the
framework-kit integration.
Source: useBalance usage in apps/demo-vite/src/app.tsx; manual RPC reads in
apps/demo-with-viem/src/app.tsx, apps/demo-with-gill/src/app.tsx, and
apps/demo-with-solana-kit/src/app.tsx; framework-kit's useBalance in
apps/demo-with-solana-framework-kit/src/app.tsx.