Introduction
Circle’s Cross-Chain Transfer Protocol (CCTP) facilitates the transfer of USDC between distinct blockchains, providing a more streamlined experience. By integrating CCTP with Circle Wallets in your applications, you enable seamless USDC transactions across multiple chains. This reduces the need for users to manage separate wallets for different blockchains, potentially broadening your audience and providing increased liquidity and adaptability. It’s designed to provide users with a cohesive and efficient digital currency experience.Leverage Blockchain-Specific Attributes
Use blockchain-specific characteristics to optimize your user experience.
For instance, by bridging your ETH from Ethereum Mainnet to an Ethereum
Layer 2 rollup, such as Polygon, you gain access to lower transaction fees
while still enjoying the benefits of USDC.
Cross-Chain Swaps
Enable cross-chain swaps, allowing users to exchange digital assets that
reside on different chains. For example, users can swap AVAX for USDC on
Avalanche, route it to Polygon Mainnet, and further swap it for MATIC
token, expanding liquidity across multiple chains.
Cross-Chain Purchases
Facilitate cross-chain purchases with minimal effort. Users can utilize
USDC on Avalanche to buy an NFT on Uniswap on Ethereum, then list it for
sale on OpenSea. CCTP effortlessly routes the USDC from Avalanche to
Ethereum for the purchase.
Solve Fragmented Liquidity
Remove liquidity fragmentation barriers. If a user needs to send USDC to
an address on Avalanche but only holds USDC on Ethereum, the solution
becomes seamless. By bridging the USDC from Ethereum to Avalanche through
CCTP, users can transact across different blockchains.
Outcomes of this Interactive Quickstart Guide
By the conclusion of this interactive guide, you will learn how to facilitate a transfer of USDC across blockchains using a Circle Wallet. Specifically, the guide will demonstrate a scenario wherein a user conducts a USDC transfer leveraging the Cross-Chain Transfer Protocol, CCTP V1. You will follow step-by-step instructions to create and execute a USDC transfer from Sepolia, an Ethereum testnet, to Mumbai, the Polygon Testnet, via a Circle Wallet. This practical walkthrough is designed to equip you with the knowledge to implement CCTP V1 in your own applications. Completing a Cross-Blockchain Transfer: Step-By-Step Process1
Approve USDC Contract to Initiate Transfers
To utilize CCTP V1 effectively, it’s necessary to authorize the USDC
contract to conduct transfers on a user’s behalf. In this guide, we approve
only a small amount of USDC for demonstration. However, for operational
efficiency, you might want to approve a larger amount to minimize the
frequency of this action in a production environment.
2
Initiate the Burning of USDC
Following the user’s request to move USDC from Ethereum to Polygon,
leverage the provided tools to initiate burning the specified amount of
USDC from the Ethereum wallet created for this transaction.

3
Obtain Circle's Attestation
Circle monitors the burn event on the Ethereum blockchain and issues an
attestation. Retrieve this attestation using the relevant procedures,
which serves as the authorization required to mint the corresponding
USDC amount on the Polygon blockchain.

4
Trigger USDC Minting
Utilize the retrieved attestation to start the minting process. The
attestation confirms the amount of USDC to mint on the Polygon
blockchain, and the amount to allocate to the specified Polygon wallet.

Understanding Smart Contracts
Smart contracts are computer protocols that automate the execution of agreements, operating under a set of predefined conditions. Once deployed onto a blockchain, they follow an “if-then” logic to perform actions automatically when specific conditions are met. The immutable nature of blockchain ensures that the smart contract code cannot be changed once established, which reinforces their reliability as they always execute exactly as programmed. A smart contract typically consists of code that defines its operations, a data storage area, memory, and a unique public address that can be interacted with through its functions. For a comprehensive exploration of smart contracts, you are encouraged to read further on the dedicated resource.Exploring CCTP
CCTP serves as an integral tool in blockchain infrastructure to guarantee the secure and seamless transfer of USDC across various blockchain networks. By adopting CCTP, users can benefit from a protected and efficient means of transferring USDC between supported chains. To learn more about CCTP, see the CCTP Overview in the Circle Developer Documentation. To get started, create a Circle Developer Services account in the console.Prerequisites
Before you get started, ensure that you have:- Have a Developer Services account
- Created your API key
- Created a Developer-Controlled Wallet
Burn USDC
In the process of transferring USDC from Ethereum to Polygon, you need to give the TokenMessenger contract the necessary permissions to execute the USDC transfer on your behalf. In essence, you’re empowering the TokenMessenger contract to access and transfer the specified amount of USDC from your source wallet. For this, we use the Wallets contract execution API:| Term | Definition |
|---|---|
| contractAddress | You interact with the USDC contract on the source chain, so the contractAddress parameter of the request is 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238. |
| abiFunctionSignature | The function called on the USDC contract is approve(address spender, uint256 value). Calling approve allows the spender to spend value USDC on your behalf. This is necessary in the depositForBurn step later on.value is denominated in the smallest unit of USDC, which is a millionth of a dollar. In this case it’s approve(address,uint256) |
| abiParameters | In this case, address is the TokenMessenger contract’s address and value is 100000000 (100 USDC).In this case it’s [“0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5”, 100000000] |
| walletId | The wallet that performs the contract execution. This is the ID of the developer-controlled wallet you created earlier. |
| feeLevel | A dynamic blockchain fee level setting (LOW, MEDIUM, or HIGH) that will be used to pay gas for the transaction. HIGH is used for this transaction. |
| idempotencyKey | Universally unique identifier (UUID v4) idempotency key. This is automatically generated for you. |
| entitySecretCiphertext | A base64 string expression of the entity secret ciphertext. Refer to this helpful tool. |
⚠️ Approve USDC Sepolia from source wallet
⚠️ ADD CODE SNIPPET HERE
The second step of the process facilitates a burn of the specified amount of USDC on Ethereum Sepolia (the source chain) that you are looking to move to Polygon Mumbai (the destination chain).Mint and Burn are the terms used to refer to the creation and removal
of a token from a blockchain network. During the CCTP V1 transfer, tokens on
one blockchain are burnt, removing them from the total supply, before new
tokens are minted on the destination blockchain - effectively moving USDC
across chains.
| Term | Definition |
|---|---|
| contractAddress | You interact with the Token Messenger contract on the source chain, so the contractAddress parameter of the request is 0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5. |
| abiFunctionSignature | The function being called on the TokenMessenger contract is: depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken)This will be the abiFunctionSignature property of the request. In this case it’s depositForBurn(uint256,uint32,bytes32,address) |
| abiParameters | The abiParameters property defines the values to pass to the function. For the call to depositForBurn, they are amount, destinationDomain, mintRecipient and burnToken.
JavaScript Therefore, the complete abiParameters value is [1000000, 7, , “0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238”]. |
| walletId | The wallet that is performing the contract execution. This will be the ID of the developer-controlled wallet you created earlier. |
| feeLevel | A dynamic blockchain fee level setting (LOW, MEDIUM, or HIGH) that will be used to pay gas for the transaction. HIGH is used for this transaction. |
| idempotencyKey | Universally unique identifier (UUID v4) idempotency key. This is automatically generated for you. |
| entitySecretCiphertext | A base64 string expression of the entity secret ciphertext. Refer to this helpful tool. |
walletId, feeLevel, idempotencyKey, and EntitySecretCiphertext - were
automatically populated in the request.
⚠️ Deposit for Burn on Ethereum
⚠️ ADD CODE SNIPPET HERE
Validating the Burn of 1 USDC in your Developer Console
After initiating the burn of USDC through our API, you can check whether it was successful in our Developer Console.1
Login to the Developer Services Console
To begin the process of validating your burn of USDC, log in to the Web3
Services Console.
2
Navigate to the List of Wallets
Within the console, locate the Wallets page under Dev Controlled
Wallet. This page displays all of the wallets you created thus far. Open
the Wallets page.
3
Open the Wallet Details Screen
Find and click on the Ethereum Sepolia wallet from which you initiated the
USDC burn.
4
View Your Wallet Balance
On the wallet details screen, scroll down to the bottom to find the section
displaying your wallet balances. As you successfully created your Sepolia
Wallet, an initial deposit of 10 USDC was made. If you have successfully
burned 1 USDC, the total wallet balance should now reflect 9 USDC,
indicating the accurate deduction of the burned amount.

Approve Burn
As a result of interacting with the TokenMessenger contract, Circle generates a unique ID for the transaction. Starting with the returned transaction ID, you call Circle’s Attestation service to fetch an attestation that the burn took place. This attestation proves that the USDC was removed from circulation on the source chain.The transactionId returned is a unique transaction ID generated by Circle. It
is distinct from the unique identifier that is used to track the transaction
on the blockchain - known as the transaction hash.
transactionHash, retrieve the logs of the
depositForBurn transaction, and use Circle’s Attestation API to fetch the
attestation signature. The steps have been broken down for you here, but you can
use the following “Try It Out” component to run all of these steps together.
1
Fetching the Deposit Transaction Object from the Wallets API
Call the Wallets API to fetch the transaction object for the
depositForBurn transaction. Make a GET request using the provided code and the transaction ID. Retrieve the transaction object from the response data.- SDK
- Go
- NodeJS
- Java
- JavaScript
- Kotlin
- PHP
- Python
- Ruby
- Shell
- Swift
2
3
Fetch Attestation Signature from Circle's Iris API
Retrieve the attestation signature from Circle’s Iris API using the
messageHash obtained in the previous step. Use the provided code inside a loop to query the API until the attestation status is “complete”. Access the attestation signature from the response.JavaScript
The attestation service is rate-limited. Please limit your requests to less
than 10 per second.
Message hash refers to the cryptographic value that represents the specific
message related to the USDC burn transaction. It serves as a fingerprint of
the transaction and helps ensure its integrity and authenticity. The message
hash plays a crucial role in verifying and validating the burn transaction on
the source blockchain, allowing participants to track and confirm the
successful burning of tokens. As a developer, you will need to generate the
message hash using the Keccak-256 hash of the bytes emitted by the
MessageSent event, as shown previously.⚠️ Fetch Attestation
⚠️ ADD CODE SNIPPET HERE
Mint USDC
To mint USDC on the destination blockchain, we’re using themessageBytes from
the depositForBurn event and the attestation signature
(attestationResponse.attestation). We’re fetching both from Circle’s
attestation services and calling the receiveMessage function on the Message
Transmitter contract in the destination blockchain network.
Using the Wallets smart contract execution API:
| Term | Definition |
|---|---|
| contractAddress | You interact with the Message Transmitter contract on the destination chain, so the contractAddress parameter of the request is 0x7865fAfC2db2093669d92c0F33AeEF291086BEFD |
| abiFunctionSignature | The function being called on the Message Transmitter contract is: receiveMessage(bytes message, ,bytes attestation)This is the abiFunctionSignature property of the request receiveMessage(bytes,bytes) |
| abiParameters | For the call to receiveMessage, the abiParameters are
|
| walletId | The wallet that is performing the contract execution. This will be the ID of the developer-controlled wallet you created earlier. |
| feeLevel | A dynamic blockchain fee level setting (LOW, MEDIUM, or HIGH) that will be used to pay gas for the transaction. HIGH is used for this transaction. |
| idempotencyKey | Universally unique identifier (UUID v4) idempotency key. This is automatically generated for you. |
| entitySecretCiphertext | A base64 string expression of the entity secret ciphertext. Refer to this helpful tool. |
⚠️ Mint on Polygon
⚠️ ADD CODE SNIPPET HERE
This returns atransactionId after you submit the receiveMessage request.
You can use this transactionId to look up the status and details of the final
transaction.
⚠️ Check transaction
⚠️ ADD CODE SNIPPET HERE
Congratulations on your Progress!
Throughout this process, you’ve successfully:Set up a Developer-Controlled Wallet
You successfully established a developer-controlled wallet using the
Programmable Wallet system. This wallet gives you full control and
flexibility over your users’ wallets, ensuring a secure and frictionless
experience.
Interacted with USDC and CCTP V1 Contracts
Using your newly created wallet, you seamlessly interacted with the USDC
and CCTP V1 contracts. This enabled you to initiate and monitor USDC
transfers, ensuring transparency and control over the process.
Completed USDC Mint on Mumbai
To finalize the USDC minting process on the Mumbai testnet, you called
Circle’s attestation service. This step ensures the successful creation
and verification of USDC tokens on Matic.
Stay connected & Explore more
Your journey with us doesn’t stop here. There’s so much more to discover und dive into:Dive into our documentation
Your comprehensive resource for understanding our web3 tools,
technologies, and best practices.
Join our Discord server
Engage, ask, share, and collaborate. Become an integral part of our
vibrant developer community.
Sample Apps
Get hands-on with real-world use cases, or gain inspiration for your next
big project.
Start building with our SDKs
Explore our server and client-side SDKs to start building.