Learn how to bridge USDC to Arc via CCTP with Bridge Kit
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.
In this tutorial, you’ll use
Circle’s Bridge Kit to
programmatically transfer USDC from an EVM chain (for example, Ethereum Sepolia)
or Solana Devnet to Arc Testnet with
Circle Dev-Controlled Wallets.
Create a .env file in the project directory with your Circle credentials,
replacing these placeholders with your own credentials:
CIRCLE_API_KEY: your API key should be either environment-prefixed (for example,
TEST_API_KEY:abc123:def456 or LIVE_API_KEY:xyz:uvw) or base64-encoded
strings.
CIRCLE_ENTITY_SECRET: your entity secret should be 64 lowercase alphanumeric
characters.
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.
Import the Wallets SDK and initialize the client using your API key and Entity
Secret. Dev-controlled wallets are created in a
wallet set,
which serves as the source from which individual wallet keys are derived.
Report incorrect code
Copy
Ask AI
import { initiateDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";const client = initiateDeveloperControlledWalletsClient({ apiKey: "<YOUR_API_KEY>", entitySecret: "<YOUR_ENTITY_SECRET>",});// Create a wallet setconst walletSetResponse = await client.createWalletSet({ name: "Wallet Set 1",});// Create a wallet on Arc Testnetconst walletsResponse = await client.createWallets({ blockchains: ["ARC-TESTNET", "SOL-DEVNET"], count: 1, walletSetId: walletSetResponse.data?.walletSet?.id ?? "",});
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.
You should now have two new Externally Owned Account (EOA) developer-controlled
wallets that you can also see from the
Circle Developer Console. The
API response will look similar to the following:
Obtain testnet USDC or EURC 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.
Create an index.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.
Report incorrect code
Copy
Ask AI
// Import Bridge Kit and its dependenciesimport { BridgeKit } from "@circle-fin/bridge-kit";import { createCircleWalletsAdapter } from "@circle-fin/adapter-circle-wallets";import { inspect } from "util";// Initialize the SDK and listen to eventsconst kit = new BridgeKit();kit.on("*", (payload) => { console.log("Event received:", payload);});const bridgeUSDC = async (): Promise<void> => { try { // Set up the Circle Wallets adapter instance, works for both ecosystems const adapter = createCircleWalletsAdapter({ apiKey: process.env.CIRCLE_API_KEY!, entitySecret: process.env.CIRCLE_ENTITY_SECRET!, }); console.log("---------------Starting Bridging---------------"); // Use the same adapter for the source and destination blockchains const result = await kit.bridge({ from: { adapter, chain: "Arbitrum_Sepolia" }, to: { adapter, chain: "Arc_Testnet" }, amount: "1.00", }); console.log("RESULT", inspect(result, false, null, true)); } catch (err) { console.log("ERROR", inspect(err, false, null, true)); }};void bridgeUSDC();
Save the index.ts file and run the script in your terminal:
Report incorrect code
Copy
Ask AI
npx tsx --env-file=.env index.ts
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.
After the script finishes, locate the returned steps 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: