> ## 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.

# Migrate from CCTP V1 (Legacy) to V2

> Complete migration guide for developers upgrading CCTP integrations

This guide provides a summary of the breaking changes when migrating from
Cross-Chain Transfer Protocol (CCTP) V1 to V2. CCTP V2 introduces enhancements
including Fast Transfer, Hooks features, and improved API endpoints, but
requires updating your integration due to breaking changes.

<Important>
  **Important**: CCTP V2 isn't backward compatible with V1. It uses separate
  contracts, APIs, and transfer speeds. It also introduces new blockchain support,
  while deprecating some chains. Plan for a complete integration update rather
  than incremental changes.

  Failure to migrate will eventually result in loss of crosschain capabilities for
  your integration.
</Important>

The [Bridge](https://docs.arc.io/app-kit/bridge) capability in Arc App Kits can
help simplify your migration to CCTP V2. See the
[Migrating with App Kits](#migrating-with-app-kits) section for more
information.

## V1 deprecation

Circle is deprecating CCTP V1 to focus on the newer version, which is upgradable
and provides a faster, more secure, and more robust crosschain experience across
a wider network of blockchains.

### Naming changes

CCTP V2 is now referred to as CCTP (except in this document). The V1 version of
CCTP is now CCTP V1 (Legacy).

### Deprecation timeline

CCTP V1 (Legacy) deprecation begins October 31, 2026 and completes on December
1, 2026, in favor of CCTP V2. CCTP V2 contracts are available on all CCTP V1
chains except for Noble and Sui. Sui will be supported by V2 before the
deprecation begins.

### Access to funds

You will not lose access to funds during the V1 phase out. All pending
redemptions will remain available as CCTP V1 (legacy) begins its phase out.
Circle will maintain minter allowances greater than the total of pending
attestations, ensuring every redemption can be processed before V1 contracts are
fully paused.

The deprecation process is designed to wind down activity gradually, message
limits will tighten over time until no new burns can be initiated, bringing
transfer volume to zero before contracts are fully paused.

### Additional resources

In addition to this guide and [Arc App Kits](https://docs.arc.io/app-kit), you
can contact the Circle team on the
[BuildOnCircle Discord](https://discord.com/invite/buildoncircle) for questions
and migration support.

## Summary of breaking changes

The latest version of CCTP introduces architectural changes that make it
incompatible with V1 integrations. You must update your implementation to use
the new contracts, APIs, and transfer speeds. Additionally, the overall flow of
the protocol has been streamlined, which means you need to update your
integration to use the new functions.

* Contracts are deployed at
  [different addresses](/cctp/references/contract-addresses) than V1 contracts.
  You should update your integration to point to the new contract addresses.
* [Contract interfaces](/cctp/references/contract-interfaces) have changed.
  Importantly, the
  [`depositForBurn` function](/cctp/references/contract-interfaces#depositforburn)
  now takes additional parameters. You should update your integration to use the
  new ABIs and contract calls.
* CCTP now allows you to specify a transfer speed. The `finalityThreshold`
  parameter specifies whether the transfer should be a
  [Fast Transfer](/cctp/concepts/finality-and-block-confirmations#fast-transfer-attestation-times)
  or a
  [Standard Transfer](/cctp/concepts/finality-and-block-confirmations#standard-transfer-attestation-times).
* You no longer need to extract the message from the onchain transaction to
  fetch an attestation. Instead, you can call the new
  `/v2/messages/{sourceDomainId}` endpoint with the transaction hash to get the
  message and attestation in a single call.
* API endpoints have changed. The new `/v2/` endpoints have different functions
  than the old `/v1/` endpoints. You should update your integration to use the
  new endpoints. Review the
  [CCTP API reference](/api-reference/cctp/all/get-public-keys-v2) for details
  on the changes to the CCTP offchain API.
* [Fees](/cctp/concepts/fees) have been introduced. Fast Transfer has a variable
  fee based on the source chain. You should update your integration to account
  for the new fees.

## Migrating with App Kits

[Arc App Kits](https://docs.arc.io/app-kit) provides a simplified migration path
by abstracting routine setup steps and standardizing bridging flows. This
enables you to integrate bridging operations with minimal code.

### Benefits of using App Kits to bridge

* **No contract management**: App Kits handles contract addresses, ABIs, and
  function calls for you.
* **No attestation polling**: Automatically retrieves attestations without
  manual API calls.
* **Built-in CCTP features**: Access Fast Transfer and other capabilities
  through simple configuration.
* **Type-safe interface**: Compatible with `viem` and `ethers` for safer
  development.
* **Fee collection**: Optionally collect fees from transfers to monetize your
  application.

### Example migration

Replace manual contract calls and API polling with a single method:

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";
import { createViemAdapterFromPrivateKey } from "@circle-fin/adapter-viem-v2";

// Initialize the App Kit SDK
const kit = new AppKit();

// Create adapter for your wallet
const adapter = createAdapterFromPrivateKey({
  privateKey: process.env.PRIVATE_KEY as string,
});

// Transfer USDC with Fast Transfer
const result = await kit.bridge({
  from: { adapter, chain: "Ethereum" },
  to: { adapter, chain: "Base" },
  amount: "100",
  config: {
    transferSpeed: "FAST", // Use Fast Transfer
    maxFee: "5000000", // Max 5 USDC fee (optional)
  },
});

// Result includes transaction details and explorer URLs
console.log("Transfer complete:", result.steps);
```

For more information, see the [Bridge](https://docs.arc.io/app-kit/bridge)
capability in Arc App Kits.

## Changes to smart contracts

CCTP uses new smart contracts with different names, addresses, and interfaces.
You must update your integration to use the new contracts and their new function
signatures.

### Contract name and address changes

All legacy contracts have V2 equivalents deployed at new addresses:

| Legacy contract | V2 contract | Documentation |
| - | - | - |
| `TokenMessenger` | `TokenMessengerV2` | [V2 Interface](/cctp/evm-smart-contracts#tokenmessengerv2) |
| `MessageTransmitter` | `MessageTransmitterV2` | [V2 Interface](/cctp/evm-smart-contracts#messagetransmitterv2) |
| `TokenMinter` | `TokenMinterV2` | [V2 Addresses](/cctp/evm-smart-contracts#tokenminterv2-mainnet) |
| `Message` | `MessageV2` | [V2 Addresses](/cctp/evm-smart-contracts#messagev2-mainnet) |

<Important>
  **Important**: V2 contracts are deployed at different addresses than V1
  contracts. See the
  [CCTP Contract Addresses](/cctp/evm-smart-contracts#mainnet-contract-addresses)
  for the complete list of mainnet and testnet addresses.
</Important>

### `TokenMessengerV2` changes

**Modified functions:**

* `depositForBurn()` now requires three additional parameters:
  * `destinationCaller` (bytes32) - Address that can call `receiveMessage` on
    destination
  * `maxFee` (uint256) - Maximum fee for Fast Transfer in units of burn token
  * `minFinalityThreshold` (uint32) - Minimum finality level (1000 for Fast,
    2000 for Standard)

**New functions:**

* `depositForBurnWithHook()` - Enables custom logic execution on destination
  chain using hook data
* `getMinFeeAmount()` - Calculates minimum fee for Standard Transfer (on
  supported chains only)

**Removed functions:**

* `depositForBurnWithCaller()` - Use `destinationCaller` parameter in
  `depositForBurn()` instead
* `replaceDepositForBurn()` - No V2 equivalent available

### Contract source code

Full contract source code is available on GitHub:

* [CCTP EVM Contracts](https://github.com/circlefin/evm-cctp-contracts) - Main
  repository
* [Contract ABIs](https://github.com/circlefin/evm-cctp-contracts/tree/master/docs/abis/cctp/v2) -
  Interface definitions

## API migration guide

CCTP streamlines the API workflow by combining message retrieval and attestation
into single calls, while introducing new endpoints for features like Fast
Transfer monitoring and re-attestation.

### Workflow changes

The API eliminates the need to extract the message emitted by the onchain
transaction:

**Legacy workflow:**

1. Get the transaction receipt from the onchain transaction
2. Find the MessageSent event in the transaction receipt
3. Hash the message bytes emitted by the MessageSent event
4. Call `/v1/attestations/{messageHash}` to get an attestation

**V2 workflow:**

1. Call `/v2/messages/{sourceDomainId}` with transaction hash or nonce to get
   message, attestation, and decoded data

#### Legacy workflow example

```javascript theme={null}
import { createPublicClient, http } from "viem";
import { sepolia } from "viem/chains";

// V1 requires multiple steps to extract message and get attestation
const burnTxHash = "0x1234..."; // Transaction hash from depositForBurn

// Step 1: Get the transaction receipt from the onchain transaction
const client = createPublicClient({
  chain: sepolia,
  transport: http(),
});
const transactionReceipt = await client.getTransactionReceipt({
  hash: burnTxHash,
});

// Step 2: Find the MessageSent event in the transaction receipt
const eventTopic = keccak256(toBytes("MessageSent(bytes)"));
const log = transactionReceipt.logs.find((l) => l.topics[0] === eventTopic);
const messageBytes = decodeAbiParameters([{ type: "bytes" }], log.data)[0];

// Step 3: Hash the message bytes emitted by the MessageSent event
const messageHash = keccak256(messageBytes);

// Step 4: Call attestation API with the message hash
let attestationResponse = { status: "pending" };
while (attestationResponse.status !== "complete") {
  const response = await fetch(
    `https://iris-api-sandbox.circle.com/attestations/${messageHash}`,
  );
  attestationResponse = await response.json();
  await new Promise((r) => setTimeout(r, 2000));
}

const attestation = attestationResponse.attestation;

// Now you can use messageBytes and attestation to call receiveMessage
```

#### V2 workflow example

```javascript theme={null}
// V2 gets message and attestation in a single call
const sourceDomainId = 0; // Ethereum mainnet
const transactionHash = "0x1234...";

// Single step: Get message, attestation, and decoded data
const response = await fetch(
  `https://iris-api.circle.com/v2/messages/${sourceDomainId}?transactionHash=${transactionHash}`,
);
const data = await response.json();

// All data available in single response
const message = data.messages[0].message;
const attestation = data.messages[0].attestation;
const decodedMessage = data.messages[0].decodedMessage;

// Now you can use message and attestation to call receiveMessage
// You can also access decoded fields without manual parsing
console.log(`Amount: ${decodedMessage.decodedMessageBody.amount}`);
console.log(`Recipient: ${decodedMessage.decodedMessageBody.mintRecipient}`);
```

### Endpoint migration mapping

| Legacy endpoint | V2 replacement | Migration notes |
| - | - | - |
| `GET /v1/attestations/{messageHash}` | `GET /v2/messages/{sourceDomainId}?transactionHash={hash}` | Combined into messages endpoint with enhanced response |
| `GET /v1/messages/{sourceDomainId}/{transactionHash}` | `GET /v2/messages/{sourceDomainId}?transactionHash={hash}` | Enhanced with decoded data and attestation |
| `GET /v1/publicKeys` | `GET /v2/publicKeys` | Multi-version support, backward compatible |

### New V2-only endpoints

V2 introduces additional endpoints for advanced features:

| Endpoint | Purpose | Use case |
| - | - | - |
| `POST /v2/reattest/{nonce}` | Re-attest messages for edge cases | Handle expired Fast Transfer burns or finality changes |
| `GET /v2/fastBurn/USDC/allowance` | Monitor Fast Transfer allowance | Check remaining Fast Transfer capacity in real-time |
| `GET /v2/burn/USDC/fees/{sourceDomainId}/{destDomainId}` | Get current transfer fees | Calculate fees before initiating transfers |

### Message data changes

V2 message responses now include the decoded message data and attestation:

#### V1 messages response

```json theme={null}
{
  "messages": [
    {
      "attestation": "0xdc485fb2f9a8f68c871f4ca7386dee9086ff9d4387756990c9c4b9280338325252866861f9495dce3128cd524d525c44e8e7b731dedd3098a618dcc19c45be1e1c",
      "message": "0x00000000000000050000000300000000000194c2...",
      "eventNonce": "9682"
    }
  ]
}
```

#### V2 messages response

```json theme={null}
{
  "messages": [
    {
      "message": "0x00000000000000050000000300000000000194c2...",
      "eventNonce": "9682",
      "attestation": "0x6edd90f4a0ad0212fd9fbbd5058a25aa8ee10ce77e4fc143567bbe73fb6e164f384a3e14d350c8a4fc50b781177297e03c16b304e8d7656391df0f59a75a271f1b",
      "decodedMessage": {
        "sourceDomain": "7",
        "destinationDomain": "5",
        "nonce": "569",
        "sender": "0xca9142d0b9804ef5e239d3bc1c7aa0d1c74e7350",
        "recipient": "0xb7317b4EFEa194a22bEB42506065D3772C2E95EF",
        "destinationCaller": "0xf2Edb1Ad445C6abb1260049AcDDCA9E84D7D8aaA",
        "messageBody": "0x00000000000000050000000300000000000194c2...",
        "decodedMessageBody": {
          "burnToken": "0x4Bc078D75390C0f5CCc3e7f59Ae2159557C5eb85",
          "mintRecipient": "0xb7317b4EFEa194a22bEB42506065D3772C2E95EF",
          "amount": "5000",
          "messageSender": "0xca9142d0b9804ef5e239d3bc1c7aa0d1c74e7350"
        }
      },
      "cctpVersion": 2,
      "status": "complete"
    }
  ]
}
```

<Note>
  On Stellar, USDC precision and address encoding differ from other CCTP-supported
  blockchains. For inbound transfers, use
  [`CctpForwarder`](/cctp/references/stellar#use-cctpforwarder-for-stellar-recipients)
  so funds reach the correct recipient. See
  [CCTP on Stellar](/cctp/references/stellar).
</Note>
