> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# `useEthereumWalletAssets`

:::info
**Ethereum only.** Import from `@openfort/react/ethereum`.
:::

Returns native and ERC-20 assets for the connected Ethereum address using ERC-7811 via Openfort's authenticated RPC proxy.

:::warning
Fetches [default assets](https://www.openfort.io/docs/configuration/default-assets) plus any assets defined in [wallet configuration](https://www.openfort.io/docs/products/embedded-wallet/react/wallet/assets#1-configure-tracked-tokens) or passed as options.
:::

## Usage

```tsx
import { useEthereumWalletAssets } from '@openfort/react/ethereum';
import { formatUnits } from 'viem';

function WalletAssets() {
  const { data: assets, isLoading, error } = useEthereumWalletAssets();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {assets?.map((asset) => (
        <li key={asset.address}>
          {formatUnits(asset.balance, asset.metadata?.decimals ?? 18)} {asset.metadata?.symbol}
        </li>
      ))}
    </ul>
  );
}
```

## Return type

The hook returns the full TanStack Query result, including fields such as `isPending`, `isFetching`, `status`, and `refetch`. Openfort overrides `data` to be `null` before the first result, normalizes `error` to `OpenfortError`, and adds `isIdle` for a query gated by missing wallet or chain state. The result is discriminated by the `multiChain` option:

```ts
type UseEthereumWalletAssetsResult =
  | (WalletAssetsReturnBase & { multiChain: true; data: readonly MultiChainAsset[] | null })
  | (WalletAssetsReturnBase & { multiChain: false; data: readonly Asset[] | null })

type WalletAssetsReturnBase = {
  isIdle: boolean  // True when wallet not connected or chain not available
  error: OpenfortError | undefined
  // Plus all remaining TanStack Query result fields.
}

// Asset is a discriminated union by `type`
type Asset = {
  type: 'native'
  address?: 'native'
  balance: bigint
  metadata?: {
    decimals?: number
    symbol: string
    name?: never
    fiat: { value: number; currency: string }
  }
  raw?: NativeAsset
} | {
  type: 'erc20'
  address: Hex  // e.g. `0x${string}`
  balance: bigint
  metadata: {
    decimals?: number
    symbol: string
    name: string
    fiat?: { value: number; currency: string }
  }
  raw?: Erc20Asset
} | {
  type: 'spl'
  address: string
  balance: bigint
  metadata: {
    decimals: number
    symbol: string
    name: string
    fiat?: { value: number; currency: string }
  }
}

type MultiChainAsset = Asset & {
  chainId: number
}
```

`Asset` is shared with the SDK UI and includes an `spl` variant, but this Ethereum hook returns `native` and `erc20` assets.

## Parameters

```ts
type UseEthereumWalletAssetsOptions = {
  assets?: Record<number, Hex[]>  // Additional assets to track per chain
  multiChain?: boolean            // When true, fetches across all configured chains
  staleTime?: number              // Cache duration in ms (default: 30000)
}

// assets format: { [chainId: number]: Hex[] }
// Example USDC on mainnet: { 1: ['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'] }
```
