Skip to main content
Get up and running with your custom stablecoin. This guide walks through reading a balance and sending your first transfer. The onchain source code is available at coinbase/custom-stablecoin.
A custom stablecoin is a standard token — an ERC-20 on EVM networks and an SPL token on Solana. That means you read balances and move funds with the same libraries, wallets, and explorers you’d use for any token. There is nothing custom-stablecoin-specific in the code below, so anything you already know about ERC-20 or SPL transfers applies directly.
Select your environment first. This guide covers both EVM and Solana. Choose your network in the tabs below — the prerequisites, dependencies, and code differ for each, so follow a single tab end to end.

Prerequisites

  • Node.js 18+ installed
  • A wallet with a private key for Base Sepolia
  • Base Sepolia ETH to pay for gas (get from CDP Faucet) — every transfer, including the self-transfer below, is an onchain transaction that costs gas
  • A CBTUSD balance to transfer (see How do I get testnet CBTUSD? below)
  • Basic familiarity with TypeScript
This quickstart uses CBTUSD, a test custom stablecoin already deployed on Base Sepolia. Your production stablecoin address is provided during onboarding.
On testnet, you have two ways to get CBTUSD:
  1. Request CBTUSD directly from the CDP Faucet.
  2. Get USDC from the CDP Faucet and swap it 1:1 for CBTUSD using the Stableswapper quickstart. There is no added Coinbase fee for the swap — you only pay network gas.
Either way, make sure you also have Base Sepolia ETH for gas. Once you hold CBTUSD, you can pick up below.In production, you acquire your own custom stablecoin the same way — swap USDC for it via Stableswapper, or through Coinbase Retail, Exchange, and Prime. Issuance itself is managed by Coinbase as part of onboarding.

1. Create tsconfig.json

2. Install dependencies

We use ethers here, but any EVM library (viem, web3.js) works the same way — the stablecoin is a plain ERC-20.

3. Set environment variables

RPC_URL is the Base Sepolia endpoint your script reads from and submits transactions to. The public endpoint above is fine for testing; for production traffic, use a dedicated Base node or RPC provider to avoid rate limits.
Never commit your private key to source control. Use environment variables or a secrets manager. For production, use CDP Non-custodial Wallets for secure key management.

4. Create your script

The script below reads your CBTUSD balance and then sends a small transfer. It will:
  • Connect to Base Sepolia and load your wallet from PRIVATE_KEY
  • Read the token’s decimals so amounts display in human-readable units
  • Print your current CBTUSD balance
  • Transfer 1 CBTUSD to your own address as a smoke test
Why transfer to yourself? A self-transfer exercises the full signing-and-broadcasting path — proving your wallet, RPC, and the token contract all work together — without needing a second wallet and without changing your net balance. You still need to hold at least 1 CBTUSD (the contract checks your balance) and you still pay gas in ETH.
transfer.ts

5. Run your script

You should see output similar to:
Paste the transaction hash into Base Sepolia explorer to view the transfer onchain.
Going to production? The only changes are configuration, not code: point RPC_URL at Base Mainnet, fund the wallet with real ETH for gas, and set TOKEN_ADDRESS to your stablecoin’s address from onboarding.
Running into issues? See the Troubleshooting guide for common errors and solutions.

Examples

Memos, permit, gasless transfers, and more

Reference

Full function and program reference

Key Addresses

Contract and mint addresses

Overview

Learn about Custom Stablecoins