> For the complete documentation index, see [llms.txt](https://docs.shredpay.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.shredpay.xyz/developers/agent-wallet/concepts/multi-chain.md).

# Multi-chain

One sub-wallet, one address, six chains. This page explains what that means in practice and where the asymmetries are.

## Supported chains

| Chain     |    ID | Native gas | Router |
| --------- | ----: | ---------- | :----: |
| Ethereum  |     1 | ETH        |    —   |
| Optimism  |    10 | ETH        |    —   |
| BNB Chain |    56 | BNB        |    —   |
| Polygon   |   137 | POL        |    —   |
| Base      |  8453 | ETH        |   Yes  |
| Arbitrum  | 42161 | ETH        |    —   |

The authoritative list is dynamic — query `GET /api/wallet/chains`. Any chain returned there is supported; the documentation above may lag.

## One address, many chains

EVM addresses are deterministic: the same private key produces the same address on every EVM chain. Your sub-wallet has one address that is valid everywhere. There is no per-chain provisioning step.

```http
GET /api/wallet/address
```

```json
{
  "addresses": {
    "evm": "0xA1b2C3d4e5F60718293A4B5c6d7E8f9012345678"
  },
  "sub_wallet_id": "sw_01HRZK..."
}
```

Funds on different chains are independent — sending USDC to your address on Ethereum does not make it appear on Base. Each balance is queried per chain.

## `has_router` matters

The Router contract powers ShredPay's sponsored-gas flows. **Sponsored operations only work on chains with `has_router: true`.** Today that's **Base** only; more chains are in the pipeline.

| Operation                        | Mainnet | Base | Arbitrum | Polygon | Optimism | BNB |
| -------------------------------- | :-----: | :--: | :------: | :-----: | :------: | :-: |
| `send_transaction`               |   yes   |  yes |    yes   |   yes   |    yes   | yes |
| `simulate_transaction`           |   yes   |  yes |    yes   |   yes   |    yes   | yes |
| `execute_swap`                   |    —    |  yes |     —    |    —    |     —    |  —  |
| `defi_deposit` / `defi_withdraw` |    —    |  yes |     —    |    —    |     —    |  —  |
| `gas_swap`                       |    —    |  yes |     —    |    —    |     —    |  —  |
| Read tools (`get_balance`, …)    |   yes   |  yes |    yes   |   yes   |    yes   | yes |

A sponsored call on a non-Router chain returns `400 ROUTER_NOT_AVAILABLE`. Either move the operation to Base, or use `send_transaction` and pay gas yourself.

## Per-chain key whitelisting

The `allowed_chains` array on an API key is checked first. If your bot only operates on Base, set `allowed_chains: [8453]` — every other chain returns `403 CHAIN_NOT_ALLOWED`, no matter what the agent tries. This is the cheapest defense against a confused agent moving funds on the wrong chain.

## Native gas per chain

If you intend to use `send_transaction` (the Agent-pays path), the sub-wallet needs the **right native token** on the **right chain**:

* Ethereum, Optimism, Base, Arbitrum → ETH
* BNB Chain → BNB
* Polygon → POL (formerly MATIC)

Use `GET /api/gas/estimate?chain_id=…` to see how much native gas a chain has. On Base you can self-fund through `POST /api/gas/swap`. On other chains you need to send native tokens to the address from outside.

## Practical advice

* **Default to Base.** Lowest fees, full Router support, sponsored gas. Build there first.
* **Use chain whitelists aggressively.** They cost nothing and prevent footguns.
* **Don't assume cross-chain liquidity.** If your strategy needs USDC on both Mainnet and Arbitrum, plan the bridge yourself — Agent Wallet does not auto-bridge.
* **Read `GET /api/wallet/chains` at startup.** Cache for a session, but re-poll occasionally so new chains light up automatically.
