Sending USDC, or other ERC-20 tokens, is one of the most common actions taken by wallet users on Ethereum-based chains. This guide will walk you through how to format the transaction input data for these tokens, using USDC as an example.
To send USDC, you’ll need the contract address for USDC. The address is different for each network, so make sure you get the correct address for the network you’re targeting.
You can go to Circle’s website to look up the USDC address on both main networks and test networks.
USDC, and other ERC-20 tokens, are smart contracts. In order to send these tokens, your transaction needs to call the transfer function on the contract, which takes in two parameters:
to: The address of the recipient
value: The amount of tokens to send
When formatting the transaction input data, you must define the expected interface of the function you’re calling by providing an ABI. You can use helper packages like viem to provide the ABI and encode the function parameters.
Additionally, each ERC-20 token defines a decimals value, which is the number of decimal places for the token. For USDC, the decimals value is usually 6, but for most other ERC-20 tokens, it’s 18.
First, install the viem package if it is not installed yet.
You can send the transaction using the Privy API. Below are examples for React, React Native, and NodeJS; you can find other SDKs’ send transaction examples in the Send a transaction guide.
Copy
Ask AI
import { useSendTransaction } from '@privy-io/react-auth';const { sendTransaction } = useSendTransaction();const { hash } = await sendTransaction({to: usdcContractAddress,data: encodedData, // from the previous stepchainId: 8453, // Base's chainId})
Copy
Ask AI
import { useSendTransaction } from '@privy-io/react-auth';const { sendTransaction } = useSendTransaction();const { hash } = await sendTransaction({to: usdcContractAddress,data: encodedData, // from the previous stepchainId: 8453, // Base's chainId})
Copy
Ask AI
import {useEmbeddedEthereumWallet} from '@privy-io/expo';const {wallets} = useEmbeddedEthereumWallet();const wallet = wallets[0];const provider = await wallet.getProvider();const accounts = await provider.request({ method: 'eth_requestAccounts',});// Send transaction (will be signed and populated)const response = await provider.request({ method: 'eth_sendTransaction', params: [ { from: accounts[0], to: usdcContractAddress, data: encodedData, // from the previous step }, ],});
Copy
Ask AI
const usdcContractAddress = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; // on Baseconst {hash} = await privy.walletApi.ethereum.sendTransaction({walletId: 'insert-wallet-id',caip2: 'eip155:8453', // Base's caip2to: usdcContractAddress,data: encodedData // from the previous step})