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.

Prerequisites

  • Node.js 18+ installed
  • A wallet with a private key for Base Sepolia
  • Base Sepolia ETH for gas fees (get from CDP Faucet)
  • Base Sepolia CBTUSD tokens (get from CDP Faucet)
  • 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.

1. Create tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true
  }
}

2. Install dependencies

npm install ethers
npm install --save-dev ts-node typescript @types/node

3. Set environment variables

export PRIVATE_KEY="your-wallet-private-key"
export RPC_URL="https://sepolia.base.org"
Never commit your private key to source control. Use environment variables or a secrets manager. For production, use CDP Server Wallet v2 for secure key management.

4. Create your script

transfer.ts
import { ethers } from "ethers";

const TOKEN_ADDRESS = "0x57AB1EFE59b1C7b36b1Dc9315B4782bCcBb83721"; // CBTUSD on Base Sepolia

const ERC20_ABI = [
  "function balanceOf(address account) view returns (uint256)",
  "function decimals() view returns (uint8)",
  "function transfer(address to, uint256 amount) returns (bool)",
];

async function main() {
  const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
  const signer   = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
  const token    = new ethers.Contract(TOKEN_ADDRESS, ERC20_ABI, signer);

  const decimals = await token.decimals();
  const balance  = await token.balanceOf(signer.address);
  console.log("Balance:", ethers.formatUnits(balance, decimals));

  // Transfer 1 token to yourself as a smoke test
  const amount = ethers.parseUnits("1", decimals);
  const tx     = await token.transfer(signer.address, amount);
  const receipt = await tx.wait();
  console.log("Transfer confirmed:", receipt.hash);
}

main()
  .then(() => process.exit(0))
  .catch((err) => { console.error(err.message); process.exit(1); });

5. Run your script

npx ts-node transfer.ts
Running into issues? See the Troubleshooting guide for common errors and solutions.

What’s next?

Examples

Memos, permit, gasless transfers, and more

Reference

Full function and program reference

Key Addresses

Contract and mint addresses

Overview

Learn about Custom Stablecoins