> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Balances for All Wallets

> Use getMultichainTokenBalances to fetch token holdings across every connected wallet in a single API call.

When a user connects multiple wallets — for example, an EVM and a Solana account, or several EVM networks — you almost always want to display each balance side by side. The right tool for this is [`getMultichainTokenBalances`](/javascript/reference/wallets/get-multichain-token-balances): it batches **every chain, every network, and every address** into a single API call, so you avoid the N×M round-trip explosion of looping `getTokenBalances` (or `getNativeBalance`) over each wallet.

## Why getMultichainTokenBalances

`getMultichainTokenBalances` accepts a list of `balanceRequests`. Each entry says: *for this address on this chain, get the balances on these networks*. The API fans out, dedups, and returns a single grouped result.

```ts theme={"system"}
{
  balanceRequest: {
    filterSpamTokens: true,
    balanceRequests: [
      { address: '0xabc…', chain: 'EVM', networkIds: [1, 137, 56] },
      { address: 'CKEAuq…', chain: 'SOL', networkIds: [101] },
    ],
  }
}
```

Each balance row in the response carries `isNative`, `symbol`, `price`, `decimals`, `rawBalance`, etc. — so a portfolio view never needs a second call for token metadata or prices. Use `filterSpamTokens: true` to drop airdrop spam server-side, and `whitelistedContracts` per request entry to pin specific tokens you care about.

## Building the request from connected wallets

Group the user's connected `walletAccounts` by chain, then collect the network IDs each address should query. `getWalletAccounts` is the source of truth — it includes both verified and unverified accounts, so filter on `walletAccount.verifiedCredentialId` if you only want verified ones.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    import {
      getWalletAccounts,
      getMultichainTokenBalances,
    } from '@dynamic-labs-sdk/client';

    // Customize per-app: which networks you care about for each chain
    const NETWORKS_BY_CHAIN = {
      EVM: [1, 137, 56, 8453], // Ethereum, Polygon, BNB, Base
      SOL: [101],
      BTC: [0],
    };

    export const getAllBalances = async () => {
      const walletAccounts = getWalletAccounts();

      // Group addresses by chain (you may have several EVM accounts)
      const byChain = walletAccounts.reduce((acc, walletAccount) => {
        const networkIds = NETWORKS_BY_CHAIN[walletAccount.chain];
        if (!networkIds) return acc;

        acc.push({
          address: walletAccount.address,
          chain: walletAccount.chain,
          networkIds,
        });
        return acc;
      }, []);

      if (byChain.length === 0) return [];

      const chainBalances = await getMultichainTokenBalances({
        balanceRequest: {
          filterSpamTokens: true,
          balanceRequests: byChain,
        },
      });

      return chainBalances;
    };
    ```
  </Tab>

  <Tab title="React">
    `useGetWalletAccounts` re-renders whenever accounts are added or removed, so the request rebuilds — and `useGetMultichainTokenBalances` re-fetches — automatically when the user connects or disconnects a wallet.

    ```tsx theme={"system"}
    import {
      useGetMultichainTokenBalances,
      useGetWalletAccounts,
    } from '@dynamic-labs-sdk/react-hooks';
    import { useMemo } from 'react';

    const NETWORKS_BY_CHAIN: Record<string, number[]> = {
      EVM: [1, 137, 56, 8453],
      SOL: [101],
    };

    export function AllWalletBalances() {
      const { data: walletAccounts = [] } = useGetWalletAccounts();

      const balanceRequest = useMemo(() => {
        const balanceRequests = walletAccounts
          .filter((walletAccount) => NETWORKS_BY_CHAIN[walletAccount.chain])
          .map((walletAccount) => ({
            address: walletAccount.address,
            chain: walletAccount.chain,
            networkIds: NETWORKS_BY_CHAIN[walletAccount.chain],
          }));

        // Keep the hook disabled until there is at least one account to query.
        return balanceRequests.length === 0
          ? undefined
          : { filterSpamTokens: true, balanceRequests };
      }, [walletAccounts]);

      const { data: balances } = useGetMultichainTokenBalances({ balanceRequest });

      return <pre>{JSON.stringify(balances ?? [], null, 2)}</pre>;
    }
    ```
  </Tab>
</Tabs>

## Reading the response

The response is grouped by chain → network → balance rows. Each row carries the metadata you need to render a portfolio cell without a second fetch.

```ts theme={"system"}
[
  {
    chain: 'EVM',
    walletAddress: '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0',
    networks: [
      {
        networkId: 1,
        balances: [
          {
            symbol: 'ETH',
            isNative: true,
            balance: 0.42,
            rawBalance: 4.2e17,
            decimals: 18,
            price: 3200.55,
            marketValue: 1344.23,
            logoURI: 'https://…',
          },
          {
            symbol: 'USDC',
            isNative: false,
            address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
            balance: 250.0,
            rawBalance: 2.5e8,
            decimals: 6,
            price: 1.0,
            marketValue: 250.0,
            logoURI: 'https://…',
          },
        ],
      },
    ],
  },
]
```

Common ways to slice it for the UI:

```ts theme={"system"}
// Flatten into a single list of "wallet × chain × network × token" rows
const tokenRows = chainBalances.flatMap((chainBalance) =>
  chainBalance.networks.flatMap((network) =>
    network.balances.map((tokenBalance) => ({
      walletAddress: chainBalance.walletAddress,
      chain: chainBalance.chain,
      networkId: network.networkId,
      ...tokenBalance,
    }))
  )
);

// Sum marketValue for a portfolio total
const portfolioTotalUsd = tokenRows.reduce(
  (sum, tokenRow) => sum + (tokenRow.marketValue ?? 0),
  0
);

// Group by token symbol for a "holdings" view
const balanceBySymbol = tokenRows.reduce<Record<string, number>>(
  (accumulator, tokenRow) => {
    accumulator[tokenRow.symbol] =
      (accumulator[tokenRow.symbol] ?? 0) + tokenRow.balance;
    return accumulator;
  },
  {}
);
```

## Patterns

### Pin specific tokens per chain

When you only care about a stablecoin or a handful of governance tokens, pass `whitelistedContracts` per request entry. The API skips the rest, response stays small.

```ts theme={"system"}
await getMultichainTokenBalances({
  balanceRequest: {
    filterSpamTokens: true,
    balanceRequests: [
      {
        address: walletAccount.address,
        chain: 'EVM',
        networkIds: [1, 137],
        whitelistedContracts: [
          '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC mainnet
          '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', // USDC polygon
        ],
      },
    ],
  },
});
```

### Disable spam filtering for power-user views

`filterSpamTokens: false` returns the raw set, including airdrop spam. Use this on a "see all tokens" toggle, not in the default view.

### Refresh on `walletAccountsChanged`

`useGetWalletAccounts` already covers this in React. For vanilla apps, subscribe via `onEvent`:

```ts theme={"system"}
import { onEvent } from '@dynamic-labs-sdk/client';

onEvent({
  event: 'walletAccountsChanged',
  listener: () => {
    getAllBalances().then(render);
  },
});
```

## When NOT to use it

* You only need the native gas balance — use [`getNativeBalance`](/javascript/reference/wallets/get-native-balance) for an RPC-direct read.
* You have a single wallet on a single chain (one or more networks of that chain) and prefer the simpler call shape — use [`getTokenBalances`](/javascript/reference/wallets/get-token-balances).

## Related functions

* [Getting Multichain Token Balances](/javascript/reference/wallets/get-multichain-token-balances) — full parameter reference
* [Getting Wallet Accounts](/javascript/reference/wallets/get-wallet-accounts)
* [Getting Token Balances](/javascript/reference/wallets/get-token-balances) — token balances for a single chain (one or more networks)
* [Getting Native Balance](/javascript/reference/wallets/get-native-balance) — native gas balance only
