Bridge USDC between two EVM-compatible blockchains using the Viem adapter. The
examples use Ethereum Sepolia and Arc Testnet, but you can use any
supported EVM chains as the source
or destination.Prerequisites
Before you begin, ensure that you have:Step 1. Set up the project
1.1. Set up your development environment
Create a new directory and install App Kit and its dependencies:# Set up your directory and initialize a Node.js project
mkdir app-kit-quickstart-bridge-evm
cd app-kit-quickstart-bridge-evm
npm init -y
# Install App Kit and tools
npm install @circle-fin/app-kit @circle-fin/adapter-viem-v2 viem typescript tsx
Only need to bridge and want a lighter install than the full App Kit? Install
the standalone bridge package instead: @circle-fin/bridge-kit
This step is optional. It helps prevent missing types in your IDE or editor.
Create a tsconfig.json file:Then, update the tsconfig.json file:cat <<'EOF' > tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"types": ["node"]
}
}
EOF
Create an .env file in the project directory:Add your wallet private key. Replace YOUR_PRIVATE_KEY with the private key
from your Ethereum Sepolia (or any EVM) wallet:PRIVATE_KEY=YOUR_PRIVATE_KEY
Edit .env files in your IDE or editor so credentials are not leaked to your
shell history.
Step 2. Bridge USDC
2.1. Create the script
Create an index.ts file in the project directory and add the following code.
This code sets up your script and bridges 1.00 USDC from Ethereum Sepolia to Arc
Testnet:Using other EVM chains? Change the chain values in kit.bridge() and ensure
your source wallet has USDC and both wallets have native tokens.
// Import App Kit and its dependencies
import { AppKit } from "@circle-fin/app-kit";
import { createViemAdapterFromPrivateKey } from "@circle-fin/adapter-viem-v2";
import { inspect } from "util";
// Initialize the SDK
const kit = new AppKit();
const bridgeUSDC = async (): Promise<void> => {
try {
// Initialize the adapter which lets you bridge tokens from your wallet on any EVM-compatible chain
const adapter = createViemAdapterFromPrivateKey({
privateKey: process.env.PRIVATE_KEY as string,
});
console.log("---------------Starting Bridging---------------");
// Use the same adapter for the source and destination blockchains
const result = await kit.bridge({
from: { adapter, chain: "Ethereum_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();
2.2. Run the script
Save the index.ts file and run the script in your terminal:npx tsx --env-file=.env index.ts
2.3. Verify the transaction
After the script finishes, find the returned steps array in the terminal
output. Each transaction step includes an explorerUrl. Use that link to verify
that the token amount matches the amount you bridged.The following code is an example of how an approve step might look in the
terminal output. The values are used in this example only and are not a real
transaction:steps: [
{
name: "approve",
state: "success",
txHash: "0xdeadbeefcafebabe1234567890abcdef1234567890abcdef1234567890abcd",
data: {
txHash:
"0xdeadbeefcafebabe1234567890abcdef1234567890abcdef1234567890abcd",
status: "success",
cumulativeGasUsed: 17138643n,
gasUsed: 38617n,
blockNumber: 8778959n,
blockHash:
"0xbeadfacefeed1234567890abcdef1234567890abcdef1234567890abcdef12",
transactionIndex: 173,
effectiveGasPrice: 1037232n,
explorerUrl:
"https://testnet.arcscan.app/tx/0xdeadbeefcafebabe1234567890abcdef1234567890abcdef1234567890abcd",
},
},
];
Bridge USDC between Solana and an EVM-compatible blockchain using the Solana and
Viem adapters. The examples use Solana Devnet and Arc Testnet, but you can use
Solana and any supported EVM chain
as the source or destination.Prerequisites
Before you begin, ensure that you have:
- Installed Node.js v22+.
- Created a Solana Devnet wallet and an
Arc Testnet
wallet using a wallet provider such as MetaMask.
- Funded your wallets with testnet tokens:
Step 1. Set up the project
1.1. Set up your development environment
Create a new directory and install App Kit and its dependencies:# Set up your directory and initialize the project
mkdir app-kit-quickstart-bridge-solana-evm
cd app-kit-quickstart-bridge-solana-evm
npm init -y
# Install App Kit and tools (Solana + EVM adapters)
npm install @circle-fin/app-kit @circle-fin/adapter-viem-v2 @circle-fin/adapter-solana-kit @solana/kit @solana/web3.js viem typescript tsx
Only need to bridge and want a lighter install than the full App Kit? Install
the standalone bridge package instead: @circle-fin/bridge-kit
This step is optional. It helps prevent missing types in your IDE or editor.
Create a tsconfig.json file:Then, update the tsconfig.json file:cat <<'EOF' > tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"types": ["node"]
}
}
EOF
Create an .env file in the project directory:Add your wallet private keys. Replace YOUR_SOLANA_PRIVATE_KEY with your Solana
wallet private key and YOUR_ARC_TESTNET_PRIVATE_KEY with your Arc Testnet
(EVM) wallet private key:SOLANA_PRIVATE_KEY=YOUR_SOLANA_PRIVATE_KEY
EVM_PRIVATE_KEY=YOUR_ARC_TESTNET_PRIVATE_KEY
Edit .env files in your IDE or editor so credentials are not leaked to your
shell history.
Step 2. Bridge USDC
2.1. Create the script
Create an index.ts file in the project directory and add the following code.
This code sets up your script and bridges 1.00 USDC from Solana Devnet to Arc
Testnet:Using a different EVM chain or Solana as the destination? Change the chain
values in kit.bridge() and ensure your source wallet has USDC and both wallets
have native tokens.
// Import App Kit and dependencies
import { AppKit } from "@circle-fin/app-kit";
import { createViemAdapterFromPrivateKey } from "@circle-fin/adapter-viem-v2";
import { createSolanaKitAdapterFromPrivateKey } from "@circle-fin/adapter-solana-kit";
import { inspect } from "util";
const kit = new AppKit();
const bridgeUSDC = async (): Promise<void> => {
try {
const solanaAdapter = createSolanaKitAdapterFromPrivateKey({
privateKey: process.env.SOLANA_PRIVATE_KEY as string,
});
const evmAdapter = createViemAdapterFromPrivateKey({
privateKey: process.env.EVM_PRIVATE_KEY as string,
});
console.log("---------------Starting Bridging---------------");
const result = await kit.bridge({
from: { adapter: solanaAdapter, chain: "Solana_Devnet" },
to: { adapter: evmAdapter, 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();
2.2. Run the script
Save the index.ts file and run the script in your terminal:npx tsx --env-file=.env index.ts
2.3. Verify the transaction
After the script finishes, find the returned steps array in the terminal
output. Each transaction step includes an explorerUrl. Use that link to verify
that the token amount matches the amount you bridged.The following code is an example of how a burn step might look in the terminal
output. The values are used in this example only and are not a real transaction:steps: [
{
name: "burn",
state: "success",
txHash: "5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm",
data: {
txHash:
"5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm",
status: "success",
blockNumber: 312456789n,
blockHash: "HxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNK",
transactionIndex: 0,
gasUsed: 25000n,
cumulativeGasUsed: 0n,
effectiveGasPrice: 5000n,
explorerUrl:
"https://solscan.io/tx/5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm?cluster=devnet",
},
},
];
Bridge USDC between blockchains using the Circle Wallets adapter. The examples
use Solana Devnet and Arc Testnet, but you can use any blockchain the Circle
Wallets adapter supports as the
source or destination.Prerequisites
Before you begin, ensure that you have:Step 1. Set up the project
1.1. Set up your development environment
Create a new directory and install App Kit with the Circle Wallets adapter and
supporting tools:# Set up your directory and initialize the project
mkdir app-kit-quickstart-bridge-circle-wallets-adapter
cd app-kit-quickstart-bridge-circle-wallets-adapter
npm init -y
# Install App Kit, Circle Wallets adapter, and tools
npm install @circle-fin/app-kit @circle-fin/adapter-circle-wallets typescript tsx
Only need to bridge and want a lighter install than the full App Kit? Install
the standalone bridge package instead: @circle-fin/bridge-kit
This step is optional. It helps prevent missing types in your IDE or editor.
Create a tsconfig.json file:Then, update the tsconfig.json file:cat <<'EOF' > tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"types": ["node"]
}
}
EOF
Create an .env file in the project directory:Add your credentials. Replace YOUR_API_KEY with your Circle Developer API key,
YOUR_ENTITY_SECRET with your entity secret (64 lowercase alphanumeric
characters), and YOUR_EVM_WALLET_ADDRESS and YOUR_SOLANA_WALLET_ADDRESS with
the wallet addresses you control through Circle Wallets. You can fetch the
addresses from the
Circle Developer Console
or the
list wallets
endpoint:CIRCLE_API_KEY=YOUR_API_KEY
CIRCLE_ENTITY_SECRET=YOUR_ENTITY_SECRET
EVM_WALLET_ADDRESS=YOUR_EVM_WALLET_ADDRESS
SOLANA_WALLET_ADDRESS=YOUR_SOLANA_WALLET_ADDRESS
Edit .env files in your IDE or editor so credentials are not leaked to your
shell history.
Step 2. Bridge USDC
2.1. Create the script
Create an index.ts file in the project directory and add the following code.
This code sets up your script and bridges 1.00 USDC from Solana Devnet to Arc
Testnet.Using a different blockchain as the source or destination? Change the chain
values in kit.bridge() and ensure your source wallet has USDC and both wallets
have native tokens.
// Import App Kit and the Circle Wallets adapter
import { AppKit } from "@circle-fin/app-kit";
import { createCircleWalletsAdapter } from "@circle-fin/adapter-circle-wallets";
import { inspect } from "util";
// Initialize the SDK
const kit = new AppKit();
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: "Solana_Devnet",
address: process.env.SOLANA_WALLET_ADDRESS!, // Solana address (developer-controlled)
},
to: {
adapter, // Use the same adapter instance
chain: "Arc_Testnet",
address: process.env.EVM_WALLET_ADDRESS!, // EVM address (developer-controlled)
},
amount: "1.00",
});
console.log("RESULT", inspect(result, false, null, true));
} catch (err) {
console.log("ERROR", inspect(err, false, null, true));
}
};
void bridgeUSDC();
2.2. Run the script
Save the index.ts file and run the script in your terminal:npx tsx --env-file=.env index.ts
2.3. Verify the transaction
After the script finishes, find the returned steps array in the terminal
output. Each transaction step includes an explorerUrl. Use that link to verify
that the token amount matches the amount you bridged.The following code is an example of how a burn step might look in the terminal
output. The values are used in this example only and are not a real transaction:steps: [
{
name: "burn",
state: "success",
txHash: "5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm",
data: {
txHash:
"5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm",
status: "success",
blockNumber: 312456789n,
blockHash: "HxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNK",
transactionIndex: 0,
gasUsed: 25000n,
cumulativeGasUsed: 0n,
effectiveGasPrice: 5000n,
explorerUrl:
"https://solscan.io/tx/5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKSNc7WLyFTmgL5RFGujWNqEbUBdNKRkHmx7ZRQR3FVhdEwxKHm?cluster=devnet",
},
},
];