Skip to main content

Addresses and decimals

Overview

USDC is a digital dollar, also known as a stablecoin, issued by Circle. It runs on many of the world’s leading blockchains. USDC is designed to represent US dollars on the internet. It is backed 100% by highly liquid cash and cash-equivalent assets, so it is always redeemable 1:1 for USD. It is commonly used for payments, trading, and on-ramps and off-ramps in dApps. On Sei, you can transfer USDC like any standard ERC-20 token. This guide shows how to build a standalone index.js script with viem and Node.js. The script checks your USDC balance and sends a test transfer to another address. The sample is a minimal, generic ERC-20 flow that uses USDC as the example token.

Prerequisites

  • Node.js v18 or later, with "type": "module" in package.json
  • viem and dotenv installed
  • A Sei wallet that holds USDC and SEI (for gas) on your selected network. The default network is Sei Testnet.
  • To get USDC on Sei Testnet, use the Circle Faucet. You can also use the Circle CCTP v2 sample application to transfer USDC cross-chain to your Sei wallet.
  • A private key and a recipient address, stored in a .env file
  • Optional: set SEI_NETWORK=testnet|mainnet (defaults to testnet)

Project setup

Follow these steps to set up your project and environment:
  • To initialize a Node.js project and install the dependencies, create a project folder. Then run these commands in it:
  • Prepare environment variables: In the project root, create a file named .env. Add your private key and the recipient address to it:
  • Create the script file: Create an index.js file in the project directory. You build this script step by step in the next section. Make sure that your Node.js environment can handle ES module imports, because the code uses import syntax.

Script breakdown

Open index.js in your editor. Then add these script sections. An explanation follows each one: 1. Import modules and define chain and token constants: First, import the required functions from viem. Then set up constants for the Sei networks (Sei Testnet and Sei Mainnet) and the USDC token contract. The constants include the chain ID, RPC URL, token address, decimals, and a minimal ABI for the balanceOf and transfer functions of the USDC contract. The ABI has only the function signatures that the script needs:
2. Load environment variables and validate input: Next, load and validate the private key and the recipient address from the environment. The script checks that the variables exist and that the recipient address looks valid. Then it normalizes the private key string:
This code makes sure that the script has the necessary inputs. If the private key or the recipient address is missing or malformed, the script logs an error and exits. If the private key does not start with “0x”, the script adds the prefix, because viem expects a 0x-prefixed key. After this step, PRIVATE_KEY is a clean hex string, and RECIPIENT is a validated address. 3. Initialize viem clients: Use the chain config and the credentials to create two clients. The public client reads blockchain data. The wallet client writes to the chain by signing transactions. Also derive an account object from the private key:
  • privateKeyToAccount converts the hex private key into an account object. The object includes the corresponding address and other account properties.
  • createPublicClient connects to the RPC endpoint of the selected Sei network for read-only calls. It does not need a private key.
  • createWalletClient uses your account and the RPC endpoint to send transactions.
The script can now interact with the selected Sei network. publicClient calls eth_call for contract reads, and walletClient signs and sends transactions from your account. 4. Main transfer logic: Finally, write an asynchronous function that performs the USDC transfer. The function checks the sender’s USDC balance and makes sure that it is sufficient. Then it calls the transfer function of the USDC contract. The function also logs the transfer details and handles errors:
  • The script uses publicClient.readContract to call balanceOf(address) on the USDC contract and get the sender’s token balance.
  • formatUnits converts the balance from the smallest units (6 decimals for USDC) into a human-readable number. This example sets the amount to 10 USDC. You can change this value. The script compares the amount to the current balance. If the balance is not sufficient, the script logs an error and exits.
  • If the balance is sufficient, the script uses parseUnits to convert 10 USDC into the raw token amount (10 * 10^6, because USDC has 6 decimals).
    Then walletClient.writeContract calls the transfer(to, amount) function of the USDC contract. This sends a transaction from your account to transfer the tokens. On success, it returns a transaction hash. The script logs the hash and a URL where you can view the transaction on the Sei block explorer.
  • If an error occurs, such as an RPC issue or a transaction failure, the try/catch block logs “Transfer failed” with the error message. The script ends with process.exit(0), which stops the process after the async function completes.

Run the script

When index.js is complete, you can run the script from your terminal:
If the transfer succeeds, the output looks like this, with your own addresses and values:
You should see “Transfer successful!” and a transaction hash. To view the transaction details on Seiscan, you can copy the explorer URL into a browser. For more information, see the Circle Developer Docs.

Important notes

  • Testnet only: Sei Testnet USDC has no real value. Do not use Sei Mainnet keys, and do not expect real funds.
  • Security: Store private keys in .env. Never commit secrets. Follow best practices for key management.
  • Gas: You need a small amount of SEI on Sei Testnet to pay for gas.
  • Lightweight ABI: The script uses only balanceOf and transfer. These functions are enough for simple transfers.
  • viem behavior: readContract handles reads, and writeContract handles writes. The script adds the 0x prefix to the private key automatically.