This guide will show you how to create a faucet request and claim testnet funds within minutes.

You will:

  • Create a wallet and a faucet request for each supported token standard
  • Claim testnet funds onchain
  • Return faucet transaction information and verify wallet balance(s)

Prerequisites

It is assumed you have:

At this point, you should have initialized the CDP SDK with your API key before proceeding.

UI (CDP Portal)

While the CDP Faucets API allows for programmatic faucet requests, you can also use the CDP Portal UI with a wallet address to claim funds in-browser.

Assuming you completed the prerequisites, navigate to Faucets.

  1. Select a Network (either Base Sepolia, Ethereum Sepolia, or Solana Devnet).
  2. Select a Token (either ETH, USDC, EURC, cbBTC, or SOL).
  3. Enter a wallet address and click the Claim button.

Continue reading to programmatically claim testnet funds.

Programmatically

The majority of this quickstart will focus on claiming faucet funds using a new wallet created using our Wallet API.

If you’d like to use your own wallet, skip to Step 4: Use an external address.

1. Create a wallet

To create a wallet, use the following snippet:

// Create a wallet on Base Sepolia (default)
let wallet = await Wallet.create();

Wallets are created for Base Sepolia by default. Change the network by passing in a network identifier:

let wallet = Wallet.create({ networkId: Coinbase.networks.EthereumSepolia });

2. Claim ETH from faucet

Continue reading to create an ETH faucet request.

ETH claim limits are capped at 1000 claims per every 24 hours at 0.0001 ETH per claim.

This is an example where the created wallet is not persisted by default. For more details, see the Wallet API documentation.

// Create a faucet request and return the transaction */
const faucetTransaction = await wallet.faucet();

// Wait for the faucet transaction to land onchain */
await faucetTransaction.wait();

console.log(`Faucet transaction successfully completed: ${faucetTransaction}`);
console.log("Transaction hash:", faucetTransaction.getTransactionHash());

// Check wallet balance 
console.log("Wallet balance after ETH faucet request:", await wallet.listBalances());

After running this example, you should see output similar to the following:

Faucet transaction successfully completed: Coinbase::FaucetTransaction{transaction_hash: '0xd2ef7e373f99cc7deafa4e214c1cdac533d1a9b743106b62a33daebd05fb2b37', transaction_link: 'https://sepolia.basescan.org/tx/0xd2ef7e373f99cc7deafa4e214c1cdac533d1a9b743106b62a33daebd05fb2b37'}
Transaction hash: 0xd2ef7e373f99cc7deafa4e214c1cdac533d1a9b743106b62a33daebd05fb2b37
Wallet balance after ETH faucet request: BalanceMap(1) [Map] { 'eth' => 0.0001 }

3. Claim ERC-20 token from faucet

Continue reading to create a request for (and claim) ERC-20 funds from a faucet.

ERC-20 claim limits are capped every 24 hours dependent on token symbol.

After creating your wallet, request a faucet similar to above, this time passing in a supported Asset ID.

// Create a faucet request and return the transaction
const faucetTransactionUSDC = await wallet.faucet("usdc");
const faucetTransactionCBBTC = await wallet.faucet("cbbtc");    
// Wait for the faucet transaction to land onchain
await faucetTransactionUSDC.wait();
await faucetTransactionCBBTC.wait();

console.log("\nFaucet Transactions successfully completed:")
console.log(`USDC transaction: ${faucetTransactionUSDC}`);
console.log("Transaction hash:", faucetTransactionUSDC.getTransactionHash());

console.log(`cbBTC transaction: ${faucetTransactionCBBTC}`);
console.log("Transaction hash:", faucetTransactionCBBTC.getTransactionHash());

// Check wallet balances
console.log("Wallet balance after ERC-20 faucet request:", await wallet.listBalances());

After running this example, you should see output similar to the following:

Faucet Transactions successfully completed:
USDC transaction: Coinbase::FaucetTransaction{transaction_hash: '0xc52f4578e487d12ff92b44fa3d9a21b6dfca772e05df5f0b723f2751178fe289', transaction_link: 'https://sepolia.basescan.org/tx/0xc52f4578e487d12ff92b44fa3d9a21b6dfca772e05df5f0b723f2751178fe289'}
Transaction hash: 0xc52f4578e487d12ff92b44fa3d9a21b6dfca772e05df5f0b723f2751178fe289
cbBTC transaction: Coinbase::FaucetTransaction{transaction_hash: '0xdec3164e59ae53d616dbdebabf8bfac914a619160edd0344dca8d758d09491c0', transaction_link: 'https://sepolia.basescan.org/tx/0xdec3164e59ae53d616dbdebabf8bfac914a619160edd0344dca8d758d09491c0'}
Transaction hash: 0xdec3164e59ae53d616dbdebabf8bfac914a619160edd0344dca8d758d09491c0
Wallet balance after ERC20 faucet request: BalanceMap(2) [Map] { 'cbbtc' => 0.0001, 'usdc' => 1 }

4. Use an external address (optional)

You can also bring your own wallet to claim faucet funds. Try the following to use an external address.

First, use your address to create an external address object, then wait for the faucet request to land onchain.

// Create external address object for your wallet
let externalAddress = new ExternalAddress("base-sepolia", "0x...");

// Check wallet balance
console.log("ETH balance before request:", await externalAddress.getBalance("eth"));

// Create faucet request and wait for it to land onchain
const faucetTransactionExternal = await externalAddress.faucet("eth");
faucetTransactionExternal.wait();

Your transaction may take some time to complete. You can monitor it by checking its status:

while (true) {
  const status = await faucetTransactionExternal.getStatus();
  console.log("Current Transaction Status:", status);

  // Check if complete
  if (status === "complete") {
      console.log("\nFaucet Transaction successfully completed:");
      console.log(faucetTransactionExternal);
      break;
  }

  // Wait for 30 seconds before rechecking
  console.log("Transaction is not yet complete...");
  await new Promise(resolve => setTimeout(resolve, 30000)); 
}

// Check balance 
console.log("ETH balance after claim:", await externalAddress.getBalance("eth"));

After running this example, you should see output similar to the following:

ETH balance before request: 0.0013
Current Transaction Status: pending
Transaction is not yet complete...
Current Transaction Status: complete

Faucet Transaction successfully completed:
FaucetTransaction {
  model: {
    transaction: {
      from_address_id: '',
      network_id: 'base-sepolia',
      status: 'complete',
      to_address_id: '0xF73C0009bE9337C00651A0Cdd05051dA204418c3',
      transaction_hash: '0xde2142cb2de6841b26160d2cff5ceb5acdaf4de30cbd58d4b607ab07a3e0bae5',
      transaction_link: 'https://sepolia.basescan.org/tx/0xde2142cb2de6841b26160d2cff5ceb5acdaf4de30cbd58d4b607ab07a3e0bae5',
      unsigned_payload: ''
    },
    transaction_hash: '0xde2142cb2de6841b26160d2cff5ceb5acdaf4de30cbd58d4b607ab07a3e0bae5',
    transaction_link: 'https://sepolia.basescan.org/tx/0xde2142cb2de6841b26160d2cff5ceb5acdaf4de30cbd58d4b607ab07a3e0bae5'
  },
  _transaction: Transaction {
    model: {
      from_address_id: '',
      network_id: 'base-sepolia',
      status: 'complete',
      to_address_id: '0xF73C0009bE9337C00651A0Cdd05051dA204418c3',
      transaction_hash: '0xde2142cb2de6841b26160d2cff5ceb5acdaf4de30cbd58d4b607ab07a3e0bae5',
      transaction_link: 'https://sepolia.basescan.org/tx/0xde2142cb2de6841b26160d2cff5ceb5acdaf4de30cbd58d4b607ab07a3e0bae5',
      unsigned_payload: ''
    }
  }
}
ETH balance after claim: 0.0014

Video: Watch and learn

Watch this video for a walkthrough of using faucets in CDP Portal: