Skip to main content

What you will learn

  • Which EVM chains Clavion supports and how to configure RPC endpoints
  • How the RPC resolution logic determines single-chain vs. multi-chain mode
  • How chain selection works via TxIntent
  • DEX router addresses per chain
  • How to add support for a new chain

Supported chains

Additional EVM chains can be added by configuring an RPC URL and updating the policy config.

RPC configuration

Single-chain setup

For a single chain, set one RPC URL:
A single URL creates a plain ViemRpcClient. All operations target this one chain.

Multi-chain setup

For multiple chains, set multiple RPC URLs:
Multiple URLs create an RpcRouter that dispatches calls per chain ID.

Resolution logic

The RPC resolution process runs at startup via parseRpcEnv() in packages/core/src/rpc/parse-rpc-env.ts:
1

Scan environment variables

Find all variables matching the pattern ISCL_RPC_URL_{digits}.
2

Apply BASE_RPC_URL fallback

If BASE_RPC_URL is set and ISCL_RPC_URL_8453 is not, map BASE_RPC_URL to chain 8453.
3

Determine client type

  • One URL found — plain ViemRpcClient
  • Multiple URLs foundRpcRouter (dispatches per chain)
  • No URLs found — preflight and broadcast disabled (build-only mode)
ISCL_RPC_URL_8453 always takes priority over BASE_RPC_URL. If both are set, the ISCL_RPC_URL_8453 value is used.

How chain selection works

Every operation is scoped to a chain via the TxIntent.chain.chainId field:
This chain ID drives all downstream routing:
  • Transaction builders select chain-specific contract addresses (e.g., Uniswap V3 router per chain)
  • Preflight simulation uses the chain-scoped RPC for eth_call and estimateGas
  • Signing uses the chain-scoped RPC for nonce, gas fees, and broadcast
  • Balance lookups accept an optional ?chainId=N query parameter:
If no RPC is configured for the requested chain, the endpoint returns 502 no_rpc_client.

DEX router addresses

Uniswap V3 routers

Base uses a different Uniswap V3 router address than the other chains. Make sure you use the correct address for your target chain.

1inch AggregationRouterV6

Same address on all supported chains:
The 1inch router requires the ONEINCH_API_KEY environment variable. When not set, 1inch intents silently fall back to Uniswap V3.

Policy configuration for multi-chain

allowedChains

The allowedChains field in PolicyConfig controls which chains are permitted:
A TxIntent targeting a chain not in this list is denied with: "Chain N not in allowed chains [...]".

Token and contract allowlists

Allowlists are not chain-scoped in PolicyConfig v1. The same token address may exist on multiple chains (e.g., USDC has different addresses per chain). Include all relevant addresses:
USDC has a different contract address on each chain. When configuring multi-chain, make sure to include the USDC address for every chain you support.

Adding a new chain

1

Configure RPC

Set ISCL_RPC_URL_{chainId} with a valid RPC endpoint for the new chain.
2

Update policy

Add the chain ID to allowedChains in your PolicyConfig.
3

Add router addresses (for swaps)

If Uniswap V3 is deployed on the chain, add its router address to UNISWAP_V3_ROUTERS in packages/core/src/tx/builders/swap-builder.ts. The 1inch router address is the same on all chains.
4

Add token addresses

Add chain-specific token addresses to your allowlists.
No code changes are required for basic transfers and approvals — only RPC configuration and policy updates.

Troubleshooting

Cause: No ISCL_RPC_URL_{N} environment variable set for the requested chain.Fix: Add ISCL_RPC_URL_{N}=https://your-rpc-provider/... to your environment.
Cause: PolicyConfig allowedChains does not include the requested chain ID.Fix: Update your policy config to include the chain ID in allowedChains.
Cause: Same as preflight — no RPC configured for that chain.Fix: Add the appropriate ISCL_RPC_URL_{N} variable.
Verify all of the following:
  1. ISCL_RPC_URL_{B} is set and the URL is valid
  2. Chain B is in allowedChains
  3. For swaps: the router address is configured for chain B
  4. Token addresses in allowlists exist on chain B (addresses differ per chain)

Next steps