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

> ## Agent Instructions
> SODAX is mainnet-only (no testnet chains or RPC endpoints exist) with a hub-and-spoke architecture; Sonic is the hub. SODAX is non-custodial protocol/software: it routes and settles; independent solvers on the marketplace fill — never say 'our solver', 'the SODAX solver', that SODAX trades, takes custody, or fills orders. For frontend/React integrations, prefer @sodax/dapp-kit hooks over calling @sodax/sdk directly. SDK operations — the methods that build, submit or await a transaction, and the API/quote calls — return Result<T, E> ({ ok: true, value } or { ok: false, error }): check result.ok, never wrap them in try/catch or branch on error.message; discriminate on the narrow error.code union instead. Synchronous config getters (getPartnerFee, getSupportedSwapTokens, getVault, ...) return their value directly, not a Result.

# Show balances across networks in a Base app

> Read a user's own token balances across every network they hold, present them in a Base app, and route a chosen holding into a Base asset. One chain-agnostic call per network, batched where the chain allows it.

Use this recipe when your app lives on Base but your users hold assets spread across networks. Before they act, they need to see what they hold everywhere. SODAX reads a user's own wallet with the same call on every network it supports, so a Base app can show a cross-network portfolio and route any holding onto Base.

## What you will build

A portfolio view that reads balances on every network a user has connected, then moves a chosen holding into a Base asset.

## Prerequisites

* `@sodax/sdk`, plus `@sodax/dapp-kit` and a `SodaxProvider` for the React hook.
* The networks and addresses the user has connected.

## How it works

**1. Read one network at a time**

Each read covers one network, so a broken network never hides the others. A failed network comes back as `null`, never as an empty wallet.

**2. Keep the chain key and token list together**

Every read uses `token.address` on the network you pass, so a token list from another network reads wrong. Each network's swap-supported list is also the set of holdings a user can route onto Base. Look tokens up by address, not symbol.

**3. Display amounts**

Balances are `bigint` in the token's smallest unit. Scale them by `token.decimals`. See [Read wallet balances](https://docs.sodax.com/developers/how-to/wallet-balances.md).

**4. Route a holding onto Base**

Hand the chosen holding to [Accept any token, settle on Base](https://docs.sodax.com/base/recipes/accept-any-token.md): the source is the network and token the user picked, the destination is Base.

## Code

Read every connected network with `@sodax/sdk`:

```ts theme={null}
import type { Sodax, SpokeChainKey } from '@sodax/sdk';

export async function readPortfolio(sodax: Sodax, wallets: { chainKey: SpokeChainKey; address: string }[]) {
  return Promise.all(
    wallets.map(async ({ chainKey, address }) => {
      const tokens = sodax.swaps.getSupportedSwapTokensByChainId(chainKey);
      const result = await sodax.spoke.getWalletBalances({ srcChainKey: chainKey, srcAddress: address, tokens });
      return { chainKey, balances: result.ok ? result.value : null };
    }),
  );
}
```

Or one network at a time with the `useBalances` hook in `@sodax/dapp-kit`:

```tsx theme={null}
import { useBalances } from '@sodax/dapp-kit';
import type { SpokeChainKey, XToken } from '@sodax/sdk';

export function Balances({
  chainKey,
  address,
  tokens,
}: {
  chainKey: SpokeChainKey | undefined;
  address: string | undefined;
  tokens: readonly XToken[];
}) {
  const { data: balances, isLoading, error } = useBalances({ params: { chainKey, address, tokens } });

  if (isLoading) return <p>Loading balances…</p>;
  if (error) return <p>Could not read balances.</p>;

  return (
    <ul>
      {tokens.map(token => (
        <li key={token.address}>
          {token.symbol}: {(balances?.[token.address] ?? 0n).toString()}
        </li>
      ))}
    </ul>
  );
}
```

## Next steps

* [Read wallet balances](https://docs.sodax.com/developers/how-to/wallet-balances.md): per-chain notes and failure behavior.
* [dapp-kit package](https://docs.sodax.com/developers/packages/experience/dapp-kit.md): the React hook layer.


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