On Starknet, CCTP uses Cairo contracts and a combined
TokenMessengerMinterV2.
Before you integrate beyond these examples, read
CCTP Starknet contracts and interfaces.- Starknet to Arc
- Arc to Starknet
This quickstart demonstrates how to transfer USDC from Starknet Sepolia to Arc
Testnet using CCTP. You use
Then, update the When the transfer finishes, the console logs a completion message and the
relevant transaction hashes. Successful output looks similar to the following:Attestation polling can take several minutes depending on network conditions and
the finality threshold you chose. The script retries every 2 seconds with no
timeout, so allow the process to continue while Iris prepares the attestation.
starknet.js to approve and burn USDC
on Starknet, and viem to mint USDC on Arc Testnet. When
you finish, you will have executed a full burn-attest-mint flow.You should be comfortable using a terminal and Node.js. Familiarity with
Starknet account contracts and basic EVM usage helps you follow and adapt the
script. Examples use Arc Testnet as the destination, but you can use any
supported EVM blockchain.Prerequisites
Before you begin this tutorial, ensure you have:- Installed Node.js v22.6+
- Prepared a Starknet Sepolia account with the address and private key available
- Funded your account with testnet STRK from the Starknet faucet for transaction fees
- Funded your account with Starknet Sepolia USDC from the Circle Faucet
- Prepared an EVM wallet with the private key available for Arc Testnet
- Added the Arc Testnet network to your wallet (network details)
- Funded your wallet with Arc Testnet ETH for gas fees
Step 1: Set up the project
This step shows you how to prepare your project and environment.1.1. Set up your development environment
Create a new directory, initialize and set up a new Node.js project, and install the required dependencies:Shell
1.2. Initialize and configure the project
Create atsconfig.json file:tsconfig.json file:1.3. Configure environment variables
Open.env in your editor and add:EVM_PRIVATE_KEYis the private key for the EVM wallet used to receive USDC on Arc Testnet.STARKNET_PRIVATE_KEYis the private key for the Starknet Sepolia account used to sign the burn transaction.STARKNET_RPC_URLis optional. The script defaults to a public Starknet Sepolia RPC endpoint.
npm run start command loads variables from .env using Node.js native
env-file support.Step 2: Configure the script
Define the Starknet and Arc Testnet parameters, then configure the wallet clients for each chain.2.1. Define configuration constants
The script predefines the USDC and CCTP contract addresses, transfer amount, and CCTP domain IDs. ReplaceSTARKNET_ACCOUNT_ADDRESS with your Starknet Sepolia
account address. Starknet account addresses are not derived from the private key
alone, so you set the address as a constant.TypeScript
STARKNET_DOMAIN is the source domain used when requesting the attestation. The
destination domain for Arc Testnet is 26. Starknet Sepolia USDC uses 6 decimals,
so 1_000_000 represents 1 USDC.2.2. Set up wallet clients
The EVM clients connect to Arc Testnet withviem. The Starknet client uses
starknet.js with your account address and private key. The script loads the
contract ABI from the network with getClassAt.TypeScript
2.3. Format the Arc recipient for Starknet
deposit_for_burn accepts the mint recipient as a 32-byte felt. An EVM address
is left-padded with zeros to 32 bytes.TypeScript
Step 3: Implement the transfer logic
This step implements the core transfer logic: approve and burn on Starknet, poll for an attestation, then mint on Arc.3.1. Approve USDC on Starknet
Grant approval for theTokenMessengerMinterV2 contract to
withdraw USDC from your Starknet account. This allows the contract to burn USDC
when you initiate the transfer.TypeScript
3.2. Burn USDC on Starknet
Calldeposit_for_burn to burn USDC on Starknet. You specify the following
parameters:- Burn amount: The amount of USDC to burn in Starknet subunits (6 decimals)
- Destination domain: The target blockchain for minting USDC (26 for Arc Testnet)
- Mint recipient: The EVM wallet address that receives minted USDC on Arc, left-padded to 32 bytes
- Burn token: The Starknet Sepolia USDC address
- Destination caller: The zero address, allowing any caller to submit the receive transaction on Arc
- Max fee / finality threshold: This example uses Fast Transfer. For live fee values and allowance checks, see Get the fee for your transfer and Get the fast transfer allowance.
TypeScript
3.3. Retrieve attestation
Retrieve the attestation required to complete the CCTP transfer by calling Circle’s attestation API.- Call Circle’s
GET /v2/messagesAPI endpoint to retrieve the attestation. - Pass
STARKNET_DOMAINfor thesourceDomainpath parameter, using the CCTP domain for Starknet (25). - Pass the Starknet transaction hash returned by
burnUSDCastransactionHash.
TypeScript
3.4. Mint USDC on Arc
Call thereceiveMessage function
from the MessageTransmitterV2 contract
deployed on Arc Testnet.- Pass the signed attestation and message bytes as parameters.
- The contract verifies the attestation and mints USDC to the recipient encoded in the CCTP message.
TypeScript
Step 4: Full script
Create anindex.ts file in your project directory and paste the full script
following.index.ts
Step 5: Test the script
ReplaceSTARKNET_ACCOUNT_ADDRESS in index.ts with your Starknet Sepolia
account address, then run:Shell
Shell
Rate limit: The attestation service rate limit is 40 requests per second. If
you exceed this limit, the service blocks all API requests for the next five
minutes and returns an HTTP 429 (Too Many Requests) response.