Cross-Chain Transfer Protocol
(CCTP) is a
permissionless onchain utility that facilitates USDC transfers securely
between supported blockchains via native burning and minting. For more info,
visit the CCTP docs.
Prerequisites
Before you begin, make sure you have:- Installed Node.js v22+
- A Circle Developer Console account
- An API key created in the Console:
Keys → Create a key → API key → Standard Key - Your Entity Secret registered
Step 1: Set up your project
In this step, you prepare your project and environment.1.1. Create a new project
Create a new directory, navigate to it and initialize a new project.1.2. Initialize and configure the project
This command creates atsconfig.json file:
Shell
tsconfig.json file:
Shell
1.3 Configure environment variables
Create a.env file in the project directory with your Circle credentials and
wallet addresses, replacing these placeholders with your own credentials:
CIRCLE_API_KEY: your API key should be either environment-prefixed (for example,TEST_API_KEY:abc123:def456orLIVE_API_KEY:xyz:uvw) or base64-encoded strings.YOUR_ENTITY_SECRET: your entity secret should be 64 lowercase alphanumeric characters.YOUR_EVM_WALLET_ADDRESSandYOUR_SOLANA_WALLET_ADDRESSare the wallet addresses you control through Circle Wallets. You can fetch the addresses from the Circle Developer Console or the list wallets endpoint. If you don’t have dev-controlled wallets, you will create them in Step 2.
Shell
Step 2: Set up your wallets
In this step, you create two dev-controlled wallets and fund one of them with testnet tokens to make the transfer. If you already have funded dev-controlled wallets, skip to Step 3.2.1. Create wallets
Install the Circle Wallets SDK. It is also possible to call the API directly if you can’t use the SDK in your project.If you are calling the API directly, you’ll need
to make two requests: one to create the wallet set; one to create the wallet.Be sure to replace the
Entity Secret ciphertext
and the idempotency key in your request. If you are using the SDKs, this is
automatically taken care of for you.
2.2. Fund a wallet with testnet tokens
Obtain testnet USDC from the Circle Faucet and native tokens from the Console Faucet to pay gas fees. You’ll need a funded balance to execute transactions using your dev-controlled wallet.2.3. Check the wallet’s balance
You can check your wallets’ balance from the Developer Console or programmatically by making a request to GET /wallets/{id}/balances with the specified wallet ID.Step 3: Bridge USDC
In this step, you set up your script, execute the bridge transfer, and check the result.3.1. Create the script
Create anindex.ts file in the project directory and add the following code.
This code sets up your script and transfers 1 USDC from your chosen chain to Arc
Testnet. It also listens to
bridge events
that occur during the transfer lifecycle.
3.2. Run the script
Save theindex.ts file and run the script in your terminal:
For blockchains other than Arc, you will need native tokens to pay for gas.
The approve and burn steps require gas fees in the native token of the
source chain, while the mint step requires gas fees in the native token of
the destination chain.
3.3. Verify the transfer
After the script finishes, locate the returnedsteps array in the terminal
output. Each transaction step includes an explorerUrl field. Use that URL to
verify that the USDC amount matches the amount you transferred.
The following example shows how all four steps (Approve, Burn, Fetch
Attestation, Mint) might look like in the terminal output. The values shown are
for demonstration purposes only and don’t represent a real transaction:
Summary
After completing this tutorial, you’ve successfully:- Created dev-controlled wallets
- Funded your wallet with testnet USDC
- Bridged USDC from one chain to another