Addresses and Decimals
- Testnet (atlantic-2) USDC:
0x4fCF1784B31630811181f670Aea7A7bEF803eaED - Mainnet (pacific-1) USDC:
0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392 - Decimals:
6
Overview
USDC is a digital dollar issued by Circle, also known as a stablecoin, running on many of the world’s leading blockchains. Designed to represent US dollars on the internet, USDC is backed 100% by highly liquid cash and cash-equivalent assets so that it’s always redeemable 1:1 for USD. It is commonly used for payments, trading, and on/off-ramps in web3 apps. On the Sei, USDC can be transferred like any standard ERC-20 token — enabling fast, secure, and programmable digital dollar transactions. This guide walks you through building a standalone index.js script using Viem and Node.js to check your USDC balance and send a test transfer to another address. The sample is a minimal, generic ERC‑20 flow using USDC as the example token.Prerequisites
- Node.js v18+ with “type”: “module” in package.json
- viem and dotenv installed
- Sei wallet with USDC and SEI for gas on your selected network (default: testnet).
- To get testnet USDC on Sei, use the Circle Faucet or use Circle’s CCTP v2 Sample application to transfer USDC cross-chain to your Sei wallet.
- Private key and recipient address stored in a .env file
- Optional: set
SEI_NETWORK=testnet|mainnet(defaults totestnet)
Project Setup
Follow these steps to set up your project and environment:- Initialize a Node.js project and install dependencies: create a project folder and run:
- Prepare environment variables: In the project root, create a file named .env and add your private key and recipient address:
- Create the script file: Create an index.js file in the project directory. We will build this script step by step in the next section. Ensure that your Node environment can handle ES module imports (the code uses import syntax).
Script Breakdown
Open index.js in your editor and add the following sections. Each part of the script is explained below: 1. Import Modules and Define Chain/Token Constants: First, import required functions from Viem and set up constants for Sei networks (testnet and mainnet) and the USDC token contract. This includes chain ID, RPC URL, token address, decimals, and a minimal ABI for the USDC contract’s balanceOf and transfer functions (just the function signatures we need):- privateKeyToAccount converts the hex private key into an account object (with the corresponding address, etc.).
- createPublicClient connects to the selected Sei network RPC for read-only calls (no private key needed).
- createWalletClient uses our account and the RPC to allow sending transactions.
- The script uses publicClient.readContract to call the USDC contract’s balanceOf(address) and get the sender’s token balance.
- We format the balance from smallest units (6 decimals for USDC) into a human-readable number with formatUnits. The amount is set to 10 USDC in this example – you can adjust this value. We compare the desired amount to the current balance; if insufficient, it logs an error and exits.
-
If the balance is adequate, we use parseUnits to convert 10 USDC into the raw token amount (10 * 10^6, since USDC has 6 decimals).
Then walletClient.writeContract calls the USDC contract’s transfer(to, amount) function. This sends a transaction from our account to transfer the tokens. On success, it returns a transaction hash, which we log alongside a URL to view the transaction on the Sei block explorer. - Errors in the try/catch (for example, RPC issues or a transaction failure) will log “Transfer failed” with the error message. The script ends with process.exit(0) to terminate after completing the async function.
Run the Script
With index.js completed, you can run the script from your terminal:Important Notes
- Testnet Only: Sei testnet USDC has no real value. Don’t use mainnet keys or expect real funds.
- Security: Store private keys in
.env; never commit secrets. Use best practices for key management. - Gas Fees: You’ll need a small amount of testnet SEI to cover gas.
- Lightweight ABI: Only
balanceOfandtransferare used — enough for simple transfers. - Viem Behavior:
readContractandwriteContracthandle reads/writes. The private key is auto-prefixed with0x.