Quickstart: Transfer 10 USDC On-Chain

Use the USDC token contract and third-party tools to transfer 10 USDC from one blockchain wallet to another.

You can utilize USDC to move money near-instantly around the globe using decentralized protocols. This guide describes the steps to send 10 USDC between two wallets using the Ethereum Sepolia testnet network. To complete the steps in this guide, you use third-party tooling, such as Javascript libraries, node services, and wallets.

This guide provides the foundational knowledge you can build on to integrate USDC payment flows into your app or platform. You can adapt the sample code in this guide to serve as a framework for your development. Note that all API calls and transactions in this guide occur on a testnet environment. The tokens you use have no financial value.

After you validate and optimize your app in a testnet environment, you can migrate to a production or mainnet environment and create transactions that do transfer financial value using USDC.

Overview of USDC and its token contract

USDC is a stablecoin backed 1:1 to the U.S dollar and operates natively on many public blockchains. Like many digital currencies, USDC is powered by a token contract, which is a programmable piece of code that manages user balances autonomously across a decentralized network. As transactions occur, the token contract automatically updates the digital ledger, ensuring real-time tracking of funds. This mechanism allows individuals and businesses to send and receive dollars seamlessly, capitalizing on the transparency, security, and efficiency of blockchain technology. 

Before you get started

For this tutorial, you need the following apps, tools, and accounts:

  1. Circle Mint Sandbox Account: Get an account that provides access to testnet USDC. 

  2. MetaMask: A resource for creating wallets, which are devices for storing USDC on chain:

    1. Create two wallets, one for sending and one for receiving testnet USDC transactions on the Ethereum “Sepolia” testnet network. These will serve as the origin wallet (the one you’re sending USDC from) and the destination wallet (the one you’re sending to). Note the addresses for both. 
    2. Note the private key for the origin wallet. 
    3. Import the Ethereum Sepolia testnet USDC token contract into your origin wallet to enable it to read the token balance. The contract’s address is 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238

    To view the testnet USDC smart contracts for supported blockchains, see USDC on Test Networks.

  3. Infura: A node service for connecting to the blockchain and submitting your USDC transaction: 

    1. Create an API key for the Web3 API offering. 
    2. Note the Ethereum “Sepolia” testnet endpoint provided. 
  4. Node.js: Use the JavaScript runtime environment to run the code locally on your machine.

  5. Ethers.js: JavaScript library containing functions to call the USDC token contract and initiate transactions.

  6. Visual Studio: a lightweight, but powerful, source code editor available as a desktop app.

1. Set up a Circle Mint sandbox account

Set up a sandbox account so you can get testnet USDC tokens to use for testing.

  1. Visit Circle's sandbox signup page and click Sign Up.
  2. Log in to the sandbox account you create.
  3. Click APIs in the left pane, then click CREATE A KEY in the API Keys section.
  4. Provide a name for the key, then click CREATE KEY.
  5. Copy the key value and store it a location you can easily access. You use the key for steps later in this topic.

2. Obtain testnet USDC and native gas token

Use the Circle sample app to get testnet USDC to transfer, and testnet ETH to pay the gas (transaction fee) for the transaction.

  1. Configure the sample app to use you API key: 
    1. Navigate to sample-sandbox.circle.com 
    2. Click on the Settings cog wheel in the top-right corner.
    3. In the Your API Key field, paste the API key you created.
    4. Click on the menu (three horizontal bars) in the top-left corner, to display available API endpoints.
  2. Mint testnet USDC via simulated bank transfer in the Core Functionality set:
    1. Click POST /businessAccount/banks/wires
      1. Click PREFILL FORM to add a simulated bank account for testing.
      2. Click MAKE API CALL to simulate a request.
      3. Scroll down to display the response to the request, then copy the value for the id in the response. It should look similar to the following:
        "id": "d783e25e-e8b3-42eb-90b4-626f7a9580ce"
        This is the Account ID to use for the wire transfer.
    2. Click GET /businessAccount/banks/wires/{id}/instructions.
      1. In the Account ID field, paste the id value from the previous step.
      2. Click MAKE API CALL.
      3. From the Response section, copy and save the values for trackingRef and accountNumber
    3. Click POST /mocks/payments/wire.
      1. In the Tracking Ref field, paste the value for trackingRef from the previous step.
      2. In the Account Number field, paste the value for accountNumber from the previous step. 
      3. In the Amount field, enter 10.00.
      4. Click MAKE API CALL.
  3. Add recipient address from the Payouts API set: 
    1. Click POST /addressBook/recipients.
      1. In the Address field, enter your origin wallet address.
      2. In the Blockchain field, select ETH.
      3. In the Email field, enter your email address (as recipient).
      4. In the bns field, enter the nickname for your destination wallet.
      5. In the Nickname field, enter your user nickname.
      6. Click MAKE API CALL.
        Copy and store the ID from the response.
    2. Click GET addressBook/recipients/{id}.
      1. In the Recipient Id field, enter the ID from the previous step.
      2. Click MAKE API CALL.
        In the Response, confirm that the request successfully added the address.
  4. Perform a payout in USDC and native token (ETH) for gas fees from the Payouts API set:
    1. Click POST /payouts.
      1. In the Amount field, enter 10.00.
      2. Set the To Currency to USD.
      3. In the Destination field, enter the should be the recipient ID that corresponds to the destination wallet address.
      4. For Destination Type, select address_book.
      5. In the Beneficiary Email field, enter the email address of the recipient.
      6. Click MAKE API CALL.
      7. From the Response, copy the ID for the payout.
        Repeat these steps, but choose ETH for the To Currency field, to provide native tokens to cover gas fees for the transaction.
    2. Click GET /payouts/{id}.
      1. In the Payout Id field, enter the payout ID from the previous step.
      2. Click MAKE API CALL.
        View the Response to monitor the payout status. 

3. Install Ethers.js library to enable API calls

Run the following command to install Ethers.js:

npm install ethers

4. Customize the sample JavaScript code with input variables

In Visual Studio Code, create a new JavaScript file named send10.js. Copy the following code sample and paste it into the send10.js file:

const { ethers } = require('ethers');

// 1. Input the Sepolia RPC endpoint
const rpcEndpoint = '<RPC_ENDPOINT_URL>'; // Insert the INFURA Network Endpoint

// 2. Initialize the Ethers.js provider
const provider = new ethers.JsonRpcProvider(rpcEndpoint);

// 3. Input USDC token contract address for Ethereum Sepolia
const tokenAddress = '<USDC_TOKEN_CONTRACT>'; // USDC TokenAddress

// 4. Define the USDC token contract ABI
const minTokenAbi = [
  {
    inputs: [
      { internalType: 'address', name: 'to', type: 'address' },
      { internalType: 'uint256', name: 'value', type: 'uint256' },
    ],
    name: 'transfer',
    outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
    name: 'balanceOf',
    outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'decimals',
    outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }],
    stateMutability: 'view',
    type: 'function',
  },
];

// 5. Create a new contract instance
const contract = new ethers.Contract(tokenAddress, minTokenAbi, provider);

// 6. Input the addresses and the private key; specify number of tokens to send
const senderAddress = '<SENDER_WALLET_ADDRESS>';
const recipientAddress = '<RECIPIENT_WALLET_ADDRESS>';
const senderPrivateKey = '<SENDER_WALLET_PRIVATE_KEY>';

const usdcAmount = 1.0;

async function main() {
  // 7. Check the number of decimals for the USDC token
  const decimals = await contract.decimals();

  // 8. Check the balance of the sender's address
  const balance = await contract.balanceOf(senderAddress);
  console.log('Sender USDC balance:', ethers.formatUnits(balance, decimals));

  // 9. Calculate the actual amount in the smallest unit
  const value = ethers.parseUnits(usdcAmount.toString(), decimals);

  // 10. Create the transaction
  const tx = await contract.connect(new ethers.Wallet(senderPrivateKey, provider)).transfer(recipientAddress, value);

  // 11. Wait for the transaction to be mined and log the transaction hash
  const receipt = await tx.wait();
  console.log('Tx Hash:', receipt);
}

main().catch((error) => {
  console.error('Error:', error);
  process.exit(1);
});

Customize Code

To customize the code for this guide, replace the following variable values: 

  • Under comment // 2 replace <RPC_ENDPOINT_URL> with the INFURA endpoint.
  • Under comment // 4, replace <USDC_TOKEN_CONTRACT> with the token contract address: 0x07865c6E87B9F70255377e024ace6630C1Eaa37F.
  • Under comment // 6:
    • Replace <SENDER_WALLET_ADDRESS> with the origin wallet address.
    • Replace <RECIPIENT_WALLET_ADDRESS> with the destination wallet address.
    • Replace <SENDER_WALLET_PRIVATE_KEY> with the origin wallet’s private key.
    • Update the value for usdcAmount to the number of USDC to send. For this example, 10.

Save the Javascript file.

5. Execute JavaScript code to initiate USDC transfer

In Terminal, enter the following command to execute the code and transfer USDC. 

// Type node <FILENAME>.js to run code
node send10.js

Check the status of your USDC transaction by visiting the Sepolia testnet block explorer:

Paste the transactionHash value from your terminal log into the search bar. Under Status, “Success” means the transaction successfully settled. 

Congratulations! Completing this quickstart guide for USDC has equipped you with the essential skills of programmable money.

You can adapt the script provided in this guide to enable real-world transactions and empower your own app development. Now, you can apply this newfound knowledge to create frictionless financial experiences, empowering users with seamless, secure global transactions.