Loading...
Loading...
Build USDC bridging with Circle Bridge Kit SDK and Crosschain Transfer Protocol (CCTP). Supports bridging USDC between EVM chains, between EVM chains and Solana, and between any two chains on Circle Wallets (i.e Developer-Controlled Wallets or Programmable wallets). Use when: bridge USDC, setting up Bridge Kit adapters (Viem, Ethers, Solana Kit, Circle Wallets), handling bridge events, collecting custom fees, configuring transfer speed, or using the Forwarding Service. Triggers on: Bridge Kit, bridge USDC, crosschain transfer, CCTP, move USDC between chains, @circle-fin/bridge-kit, adapter-viem, adapter-ethers, adapter-solana-kit, forwarding service, bridge routes.
npx skill4agent add circlefin/skills bridge-stablecoinkit.bridge()npm install @circle-fin/bridge-kit @circle-fin/adapter-viem-v2npm install @circle-fin/adapter-solana-kitnpm install @circle-fin/adapter-circle-walletsPRIVATE_KEY= # EVM wallet private key (hex, 0x-prefixed)
EVM_PRIVATE_KEY= # EVM private key (when also using Solana)
SOLANA_PRIVATE_KEY= # Solana wallet private key (base58)
CIRCLE_API_KEY= # Circle API key (for Circle Wallets adapter)
CIRCLE_ENTITY_SECRET= # Entity secret (for Circle Wallets adapter)
EVM_WALLET_ADDRESS= # Developer-controlled EVM wallet address
SOLANA_WALLET_ADDRESS= # Developer-controlled Solana wallet addressimport { BridgeKit } from "@circle-fin/bridge-kit";
const kit = new BridgeKit();approveburnfetchAttestationmintcreateViemAdapterFromPrivateKeycreateSolanaKitAdapterFromPrivateKeycreateCircleWalletsAdapteruseForwarder: true"Arc_Testnet""Base_Sepolia""Solana_Devnet"kit.bridge()references/adapter-private-key.mdreferences/adapter-circle-wallets.mdreferences/adapter-wagmi.md{
"amount": "25.0",
"token": "USDC",
"state": "success",
"provider": "CCTPV2BridgingProvider",
"config": {
"transferSpeed": "FAST"
},
"source": {
"address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"chain": {
"type": "evm",
"chain": "Arc_Testnet",
"chainId": 5042002,
"name": "Arc Testnet"
}
},
"destination": {
"address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"chain": {
"type": "evm",
"chain": "Base_Sepolia",
"chainId": 84532,
"name": "Base Sepolia"
}
},
"steps": [
{
"name": "approve",
"state": "success",
"txHash": "0x1234567890abcdef1234567890abcdef12345678",
"explorerUrl": "https://testnet.arcscan.app/tx/0x1234..."
},
{
"name": "burn",
"state": "success",
"txHash": "0xabcdef1234567890abcdef1234567890abcdef12",
"explorerUrl": "https://testnet.arcscan.app/tx/0xabcdef..."
},
{
"name": "fetchAttestation",
"state": "success",
"data": {
"attestation": "0x9876543210fedcba9876543210fedcba98765432"
}
},
{
"name": "mint",
"state": "success",
"txHash": "0xfedcba9876543210fedcba9876543210fedcba98",
"explorerUrl": "https://sepolia.basescan.org/tx/0xfedcba..."
}
]
}useForwarder: trueconst result = await kit.bridge({
from: { adapter, chain: "Ethereum_Sepolia" },
to: {
adapter,
chain: "Arc_Testnet",
useForwarder: true,
},
amount: "1",
});const result = await kit.bridge({
from: { adapter, chain: "Ethereum_Sepolia" },
to: {
recipientAddress: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
chain: "Arc_Testnet",
useForwarder: true,
},
amount: "1",
});kit.on("approve", (payload) => {
console.log("Approval completed:", payload.values.txHash);
});
kit.on("burn", (payload) => {
console.log("Burn completed:", payload.values.txHash);
});
kit.on("fetchAttestation", (payload) => {
console.log("Attestation completed:", payload.values.data.attestation);
});
kit.on("mint", (payload) => {
console.log("Mint completed:", payload.values.txHash);
});
kit.on("*", (payload) => {
console.log("Event received:", payload);
});result.stateresult.stepsconst result = await kit.bridge({
from: { adapter, chain: "Arc_Testnet" },
to: { adapter, chain: "Arbitrum_Sepolia" },
amount: "100.00",
});
if (result.state === "error") {
const failedStep = result.steps.find((step) => step.state === "error");
console.log(`Failed at: ${failedStep?.name}`);
console.log(`Error: ${failedStep?.error}`);
const completedSteps = result.steps.filter(
(step) => step.state === "success",
);
completedSteps.forEach((step) => {
console.log(`${step.name}: ${step.txHash}`);
});
}kit.retry()approveburnfetchAttestationconst result = await kit.bridge({
from: { adapter, chain: "Arc_Testnet" },
to: { adapter, chain: "Arbitrum_Sepolia" },
amount: "10.00",
});
if (result.state === "error") {
const retryResult = await kit.retry(result, {
from: adapter,
to: adapter,
});
console.log("Retry result:", retryResult.state);
}.gitignore.env*kit.bridge()result.steps"Arc_Testnet""Base_Sepolia"use-gateway