Warning: Directly transferring USDC to the Gateway Wallet contract with a standard ERC-20 transfer will result in loss of that USDC. You must use one of the deposit methods on the wallet contract to get a unified USDC balance.
Circle Gateway allows you to establish a unified USDC balance consisting of USDC stored on multiple source chains. Once established, you can transfer this balance instantly to any destination chain.
This guide demonstrates how to establish a unified USDC balance by depositing USDC into the Gateway Wallet contract. You can perform this action on multiple chains to establish a chain-abstracted balance.
Before you begin, ensure that you've:
Installed Node.js and npm on your development machine
Created a testnet wallet on Ethereum Sepolia and have the private key available
Funded your testnet wallet with USDC and native tokens
Created a new Node project and have the following dependencies installed:
viem
dotenv
You've set up a .env
file with the following variables:
PRIVATE_KEY=<your_private_key>
Follow these steps to establish a unified USDC balance. Note that this example demonstrates how to deposit USDC on a single chain (Ethereum Sepolia). Repeat these steps on other chains to add to your balance.
Create a new file called index.js
in the root of your project, and add the
following code to it. This code calls the approve()
method on the USDC
contract to allow the Gateway Wallet contract to transfer USDC from your wallet.
import "dotenv/config";
import { createPublicClient, getContract, http, erc20Abi } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import * as chains from "viem/chains";
// Partial ABI for the functions needed on the Gateway wallet
const gatewayWalletAbi = [
{
type: "function",
name: "deposit",
inputs: [
{
name: "token",
type: "address",
internalType: "address",
},
{
name: "value",
type: "uint256",
internalType: "uint256",
},
],
outputs: [],
stateMutability: "nonpayable",
},
];
// Contract addresses on Ethereum Sepolia
const gatewayWalletAddress = "0x0077777d7EBA4688BDeF3E311b846F25870A19B9";
const usdcAddress = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238";
const DEPOSIT_AMOUNT = 10_000000n; // 10 USDC
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const client = createPublicClient({
chain: chains["sepolia"],
account,
transport: http(),
});
const usdc = getContract({ address: usdcAddress, abi: erc20Abi, client });
const gatewayWallet = getContract({
address: gatewayWalletAddress,
abi: gatewayWalletAbi,
client,
});
const approvalTx = await usdc.write.approve([
gatewayWallet.address,
DEPOSIT_AMOUNT,
]);
await client.waitForTransactionReceipt({ hash: approvalTx });
Add the following code to the index.js
file to call the deposit()
method on
the Gateway Wallet contract. Note that you must use the deposit()
method and
not the standard transfer on the USDC contract.
Warning: Directly transferring USDC to the Gateway Wallet contract with a standard ERC-20 transfer will result in loss of that USDC. You must use one of the deposit methods on the wallet contract to get a unified USDC balance.
const depositTx = await gatewayWallet.write.deposit([
usdc.address,
DEPOSIT_AMOUNT,
]);
Once you have added the code to your index.js
file, run it with the following
command:
node index.js
Wait for the required number of block confirmations. Once the deposit transaction is final, your unified balance to reflects the amount from Ethereum Sepolia. If you have balances on other chains, the total balance is the sum of all the USDC from deposit transactions across all supported chains that have reached finality.