This quickstart walks you through how to use App Kit’s Swap and
Bridge capabilities to swap tokens on the same blockchain.
The example in this quickstart swaps USDT for USDC on Ethereum, but you can use
other
supported tokens or blockchains.
Because the Swap capability is only available on mainnet, this quickstart uses
mainnet chains and requires real funds.
Prerequisites
Before you begin, ensure that you’ve:
- Installed Node.js v22+.
- Created an Ethereum wallet using a wallet provider such as
MetaMask and funded it with USDT and ETH tokens.
- Obtained a (free) kit key
from the Circle Console.
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 and install App Kit and its dependencies:
# Set up your directory and initialize a Node.js project
mkdir app-kit-quickstart-swap
cd app-kit-quickstart-swap
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 swap and want a lighter install than the full App Kit? Install the
standalone swap package instead: @circle-fin/swap-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:
Then, add your credentials. Replace YOUR_PRIVATE_KEY with the private key for
your Ethereum wallet and YOUR_KIT_KEY with the kit key from the Circle
Console:
PRIVATE_KEY=YOUR_PRIVATE_KEY
KIT_KEY=YOUR_KIT_KEY
Edit .env files in your IDE or editor so credentials are not leaked to your
shell history.
This step shows you how to set up your script, execute a swap from USDT to USDC
on Ethereum, and check the result.
2.1. Create the script
Create an index.ts file in the project directory and add the following code.
This code swaps 1.00 USDT for USDC on Ethereum:
Using other tokens
or a different blockchain? Change
the tokenIn, tokenOut, and chain values in kit.swap() and use an adapter
for that chain.
// 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 swapUSDTtoUSDC = async (): Promise<void> => {
try {
// Initialize the adapter
const adapter = createViemAdapterFromPrivateKey({
privateKey: process.env.PRIVATE_KEY as string,
});
console.log("---------------Starting Swapping---------------");
const result = await kit.swap({
from: { adapter, chain: "Ethereum" }, // Adapter and blockchain for the swap
tokenIn: "USDT", // Token to swap
tokenOut: "USDC", // Token to receive
amountIn: "1.00", // Amount of tokenIn to swap (human-readable)
config: {
kitKey: process.env.KIT_KEY as string, // Your kit key from the Circle Console
},
});
console.log("RESULT", inspect(result, false, null, true));
} catch (err) {
console.log("ERROR", inspect(err, false, null, true));
}
};
void swapUSDTtoUSDC();
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 the
amount matches how much USDC was received.
The following code is an example of how the result of a successful swap might
look in the terminal output. The values are used in this example only and are
not a real transaction:
{
tokenIn: 'USDT',
tokenOut: 'USDC',
chain: {
type: 'evm',
chain: 'Ethereum',
name: 'Ethereum',
title: 'Ethereum Mainnet',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
chainId: 1,
isTestnet: false,
explorerUrl: 'https://etherscan.io/tx/{hash}',
rpcEndpoints: [ 'https://eth.merkle.io', 'https://ethereum.publicnode.com' ],
eurcAddress: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
usdcAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
usdtAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7',
cctp: {
domain: 0,
contracts: {
v1: {
type: 'split',
tokenMessenger: '0xbd3fa81b58ba92a82136038b25adec7066af3155',
messageTransmitter: '0x0a992d191deec32afe36203ad87d7d289a738f81',
confirmations: 65
},
v2: {
type: 'split',
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
confirmations: 65,
fastConfirmations: 2
}
}
},
kitContracts: {
bridge: '0xB3FA262d0fB521cc93bE83d87b322b8A23DAf3F0',
adapter: '0x7FB8c7260b63934d8da38aF902f87ae6e284a845'
}
},
amountIn: '1.00',
amountOut: '0.99',
fromAddress: '0x1234123412341234123412341234123412341234',
toAddress: '0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd',
txHash: '0x78abb6a896e6b166925cae122b6ab2a6abd49ba23cbbd4749c99d5cccf205897',
explorerUrl: 'https://etherscan.io/tx/0x78abb6a896e6b166925cae122b6ab2a6abd49ba23cbbd4749c99d5cccf205897',
fees: [ { token: 'USDT', amount: '0.001', type: 'provider' } ],
config: {
kitKey: 'KIT_KEY:fdd99fdbdb3c87b9b3f7b29d6cc17b6e:cc8777b4e419eb6dda9f0de932cf0bb8',
}
}
Next steps