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

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# Unified wallet addressing on EVM blockchains

> How Circle Wallets share the same address across supported EVM blockchains, and how to add or recover wallets.

Circle Wallets on EVM share the same address across every
[supported EVM blockchain](/wallets/supported-blockchains). Your users see one
address for their tokens across the ecosystem, you avoid parallel address
bookkeeping per blockchain, and if a user accidentally deposits to an EVM
blockchain you don't support, you can still sign a transaction to move the funds
out.

This is automatic for user-controlled wallets and configurable for
developer-controlled wallets.

## How it works

An EVM address is derived from a public key through hierarchical deterministic
(HD) derivation rooted in a user's identity. Two wallets derived under the same
identity produce the same public key, and therefore the same address on every
EVM blockchain.

Circle groups wallets by identity so they share a key: through a JWT for
user-controlled wallets, and through a
[wallet set](/wallets/dev-controlled/entity-secret-management#wallet-set) plus a
`refId` for developer-controlled wallets.

## User-controlled wallets

Call
[`POST /user/wallets`](/api-reference/wallets/user-controlled-wallets/create-user-wallet)
with the user's JWT and an array of the EVM blockchains you want wallets on:

```json theme={null}
{
  "idempotencyKey": "YOUR_IDEMPOTENCY_KEY",
  "blockchains": ["ARB", "ETH", "MATIC"],
  "accountType": "EOA"
}
```

Every wallet returned shares the same address. To add a new EVM blockchain later
for the same user, call the endpoint again with the additional blockchain and
the same JWT.

## Developer-controlled wallets

Group wallets under a shared `walletSetId` and `refId`. The `refId` typically
maps to a user ID in your system.

### Create wallets with a shared address

Call
[POST /wallets](/api-reference/wallets/developer-controlled-wallets/create-wallet)
with a `walletSetId`, an array of EVM `blockchains`, and an array of `refIds`:

```json theme={null}
{
  "walletSetId": "YOUR_WALLET_SET_ID",
  "blockchains": ["ARB", "ETH", "MATIC"],
  "refIds": ["YOUR_USER_ID"]
}
```

Every wallet in the response that shares a `refId` produces the same address.
Retrieve the wallets with
[`GET /wallets`](/api-reference/wallets/developer-controlled-wallets/get-wallets).

### Add a supported blockchain

To add a new EVM blockchain to a user's existing set of wallets, call
[`PUT /wallets/{id}/blockchains/{blockchain}`](/api-reference/wallets/developer-controlled-wallets/derive-wallet)
with the `walletId` of any of the user's existing EVM wallets. Circle derives a
wallet on the new blockchain at the same address.

### Recover tokens from unsupported blockchains

If a user accidentally deposits tokens to an EVM blockchain Circle doesn't
support, you can still access the funds by signing a raw transaction with the
generic `EVM` blockchain. For background on how Circle's signing APIs work, see
[Signing APIs](/wallets/signing-apis).

<Steps>
  <Step title="Create a wallet on the generic EVM blockchain">
    Create a wallet with `blockchain: "EVM"` under the same `walletSetId` and
    `refId`. Circle derives a wallet at the user's address.

    ```json theme={null}
    {
      "walletSetId": "YOUR_WALLET_SET_ID",
      "blockchains": ["EVM"],
      "refIds": ["YOUR_USER_ID"]
    }
    ```
  </Step>

  <Step title="Sign a raw transaction to move the assets">
    Use [Sign
    transaction](/api-reference/wallets/developer-controlled-wallets/sign-transaction)
    to sign a raw transaction that moves the assets.
  </Step>

  <Step title="Broadcast the signed transaction">
    Broadcast the signed transaction to the blockchain yourself. Circle doesn't
    broadcast on unsupported blockchains.
  </Step>
</Steps>

<Warning>
  For unsupported EVM blockchains, Circle only signs the transaction. You are
  responsible for constructing a valid raw transaction and broadcasting it.
</Warning>

## Address indexes

Wallets in a wallet set are derived by index. On EVM, a single index maps to the
same address on every EVM blockchain the wallet is created on. Index assignment
behavior for `POST /wallets`:

* Single-blockchain call, no existing wallets: index starts at `0x1`.
* Multi-blockchain call: uses the latest available index across the group.
* Single-blockchain call with existing wallets on that blockchain: increments
  the index on that blockchain.
* New blockchain with no existing wallets on it: starts at `0x1`.

For example, seven consecutive `POST /wallets` calls produce the following
indexes:

| Step | Ethereum | Polygon PoS | Arbitrum |
| - | - | - | - |
| 1 | `0x1` | | |
| 2 | `0x2` | | |
| 3 | `0x3` | `0x3` | |
| 4 | | `0x4` | |
| 5 | | | `0x1` |
| 6 | | | `0x2` |
| 7 | `0x5` | `0x5` | `0x5` |

Empty cells are gaps. To fill a gap and derive a wallet at an existing address
on a new blockchain, use
[`PUT /wallets/{id}/blockchains/{blockchain}`](/api-reference/wallets/developer-controlled-wallets/derive-wallet).

<Note>
  Don't create a unique `walletSetId` per user. [Wallet
  sets](/wallets/dev-controlled/entity-secret-management#wallet-set) are
  organizational boundaries for scaling (for example, one set per tenant or
  product line), not per-user containers.
</Note>
