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

# Getting Multichain Token Balances

> [!NOTE]
>
> **Recommended default.** `getMultichainTokenBalances` is the most general
> balance fetcher: it batches token balances across any combination of
> chains, networks, and addresses in a single API call. Use it unless you
> specifically only need one chain ([`getTokenBalances`](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-token-balances))
> or the native gas balance ([`getNativeBalance`](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-native-balance)).

You can get token balances across multiple chains and networks by calling the `getMultichainTokenBalances` function. This fetches cryptocurrency and token balances for wallet addresses across different chains, networks, and addresses specified in the request. Each token in the response includes `marketValue` (USD value) and `price` (USD per unit), so you can render a USD-denominated portfolio without a separate price feed.

## Usage

> [tab] JavaScript
>
> ```javascript theme={"system"}
> import { getMultichainTokenBalances } from '@dynamic-labs-sdk/client';
>
> const chainBalances = await getMultichainTokenBalances({
>   balanceRequest: {
>     filterSpamTokens: true,
>     balanceRequests: [
>       {
>         address: '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0',
>         chain: 'EVM',
>         networkIds: [1, 137, 56], // Ethereum, Polygon, BNB
>         whitelistedContracts: ['0x...'], // Optional: contracts to not filter out
>       },
>       {
>         address: 'CKEAuq1E7hUcrjDcu1xP6nax3YBvEhhq7qaCzDUkPNer',
>         chain: 'SOL',
>         networkIds: [101], // Solana mainnet
>       },
>     ],
>   },
> });
> ```

> [tab] React
>
> ```tsx theme={"system"}
> import { useGetMultichainTokenBalances } from '@dynamic-labs-sdk/react-hooks';
> import { useMemo } from 'react';
>
> function MultichainBalances({ evmAddress, solanaAddress }) {
>   // Memoize so the request (and the hook's cache key) only changes when an address does.
>   const balanceRequest = useMemo(
>     () =>
>       evmAddress
>         ? {
>             filterSpamTokens: true,
>             balanceRequests: [
>               { address: evmAddress, chain: 'EVM' as const, networkIds: [1, 137] },
>               ...(solanaAddress
>                 ? [{ address: solanaAddress, chain: 'SOL' as const, networkIds: [101] }]
>                 : []),
>             ],
>           }
>         : undefined,
>     [evmAddress, solanaAddress],
>   );
>
>   // Stays disabled until `balanceRequest` is defined, then re-fetches when it changes.
>   const { data: balances } = useGetMultichainTokenBalances({ balanceRequest });
>
>   return <pre>{JSON.stringify(balances ?? [], null, 2)}</pre>;
> }
> ```

## Parameters

| Parameter | Type | Description |
| - | - | - |
| `balanceRequest` | `MultichainAccountBalancesRequest` | The balance request configuration |
| `client` | `DynamicClient` | Optional. Only required when using multiple Dynamic clients |

### MultichainAccountBalancesRequest

| Parameter | Type | Required | Description |
| - | - | - | - |
| `filterSpamTokens` | Boolean | No | Filter out spam tokens (default: `true`) |
| `balanceRequests` | Array | Yes | Array of balance request objects |

### Balance Request Object

| Parameter | Type | Required | Description |
| - | - | - | - |
| `address` | String | Yes | The wallet address |
| `chain` | `ChainEnum` | Yes | Chain type (`EVM`, `SOL`, `BTC`, etc.) |
| `networkIds` | Array\<Number> | Yes | Array of network IDs to query |
| `whitelistedContracts` | Array\<String> | No | Contract addresses to not filter out |

> [!NOTE]
>
> For BTC, pass a single network ID matching the network the address belongs to: `1` for mainnet, `2` for testnet, or `3` for signet. Only the first network ID is used for a BTC balance lookup, and a mismatch returns an empty balance set. Testnet and signet share the same address format, so pass the ID for the network you intend to query.

## Response

Returns `Promise<MultichainAccountBalanceResponse['chainBalances']>`, an array of chain balance objects organized by chain and network.

```json theme={"system"}
[
  {
    "chain": "EVM",
    "networks": [
      {
        "networkId": 1,
        "balances": [
          {
            "address": "0x9de16c805a3227b9b92e39a446f9d56cf59fe640",
            "balance": 7877386.999999999,
            "decimals": 18,
            "id": null,
            "isNative": false,
            "liquidityPoolSizeUsd": 35339.28,
            "logoURI": "https://...",
            "marketValue": 0.05,
            "name": "TokenName",
            "networkId": 1,
            "price": 6.83e-9,
            "rawBalance": 7.877387e+24,
            "rawBalanceString": "7877387000000000000000000",
            "symbol": "TKN"
          }
        ]
      }
    ],
    "walletAddress": "0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0"
  }
]
```

## Computing total portfolio USD

Sum `marketValue` across every token to get the total portfolio value in USD:

```javascript theme={"system"}
const totalUsd = chainBalances
  .flatMap((chain) => chain.networks)
  .flatMap((network) => network.balances ?? [])
  .reduce((sum, token) => sum + (token.marketValue ?? 0), 0);
```

## Related functions

* [Getting Token Balances](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-token-balances.md) - Single-network token balance variant
* [Getting Native Balance](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-native-balance.md) - Native gas balance only, via RPC
* [Getting Wallet Accounts](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-wallet-accounts.md)
* [Getting Active Network](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-active-network.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.