The CDP SDK allows you to create wallets and send funds onchain within minutes. In this quickstart, you will learn how to create a wallet, fund it with testnet ETH, transfer funds between wallets, and trade assets.

See Securing a Wallet to learn how to protect your wallets.

What You’ll Learn

  • How to install the CDP SDK
  • How to create a Developer-Managed Wallet and view its default address
  • How to fund your wallet with testnet ETH
  • How to transfer funds between wallets
  • How to trade assets in a wallet

Requirements

Make sure that your developer environment satisfies all of the requirements before proceeding through the quickstart.

Node.js 18+

The Coinbase server-side SDK requires Node.js version 18 or higher and npm version 9.7.2 or higher. To view your currently installed versions of Node.js, run the following from the command-line:

node -v
npm -v

We recommend installing and managing Node.js and npm versions with nvm. See Installing and Updating in the nvm README for instructions on how to install nvm.

Once nvm has been installed, you can install and use the latest versions of Node.js and npm by running the following commands:

nvm install node # "node" is an alias for the latest version
nvm use node

Installation

Clone CDP SDK quickstart template

The CDP SDK provides a quickstart template to get started with the SDK. Clone the repository and navigate to the quickstart template directory:

git clone git@github.com:coinbase/coinbase-sdk-nodejs.git; cd coinbase-sdk-nodejs/quickstart-template

Install the dependencies:

npm install

The file index.js contains the code to perform your first transfer with the CDP SDK. Let’s break down the content of this file.

Creating a Wallet

The following instructions illustrate how to create a Developer-Managed (1-of-1) Wallet from scratch, using the CDP SDK.

  1. Create a CDP Secret API key
  2. Initialize the CDP SDK by passing your downloaded API key file
  3. Create a new Developer-Managed (1-of-1) wallet

This quickstart creates wallets on Base Sepolia testnet. You can create wallets across various EVM networks, including Base, Ethereum L1, and Polygon.

Initialize the SDK by passing your API key information:

index.js
import { Coinbase, Wallet } from "@coinbase/coinbase-sdk";

const apiKeyName = "Copy your secret API key name here."
const apiKeyPrivateKey = "Copy your secret API key's private key here."

Coinbase.configure(apiKeyName, apiKeyPrivateKey)

Another way to initialize the SDK is by sourcing the API key from the JSON file that contains your secret API key, downloaded from the CDP portal:

index.js
let coinbase = Coinbase.configureFromJson({ filePath: '~/Downloads/cdp_api_key.json' });

Now create a wallet:

index.js
// Create a new Wallet
let wallet = await Wallet.create();
console.log(`Wallet successfully created: `, wallet.toString());

// Wallets are not saved locally by default. Refer to the Wallets concept for more information.

Wallets are initialized with a single default Address, accessible via getDefaultAddress:

index.js
let address = await wallet.getDefaultAddress();
console.log(`Default address for the wallet: `, address.toString());

In a production environment, we recommend turning on IP Whitelisting and using the 2-of-2 Coinbase-Managed Wallet for additional security.

The wallet created should be persisted to avoid losing access to it. Refer to Persisting a wallet section for more information.

Importing a Wallet

The following instructions illustrate how to bring your own wallet into the CDP ecosystem, as a Developer-Managed (1-of-1) Wallet, using the CDP SDK.

  1. Create a CDP Secret API key
  2. Initialize the CDP SDK by passing your downloaded API key file
  3. Create a new Developer-Managed (1-of-1) wallet using your BIP-39 mnemonic seed phrase

This quickstart creates wallets on Base Sepolia testnet. You can create wallets across various EVM networks, including Base, Ethereum L1, and Polygon.

Initialize the SDK by passing your API key information:

index.js
import { Coinbase, Wallet } from "@coinbase/coinbase-sdk";

const apiKeyName = "Copy your secret API key name here."
const apiKeyPrivateKey = "Copy your secret API key's private key here."

Coinbase.configure(apiKeyName, apiKeyPrivateKey)

Another way to initialize the SDK is by sourcing the API key from the JSON file that contains your secret API key, downloaded from the CDP portal:

index.js
let coinbase = Coinbase.configureFromJson({ filePath: '~/Downloads/cdp_api_key.json' });

Now import your wallet:

index.js
// Import your Wallet into CDP using your BIP-39 mnemonic seed phrase.
// NOTE 1: For security reasons, we recommend storing your seed phrase in an environment variable.
// NOTE 2: Your wallet's seed and seed phrase will not leave your device.
let wallet = await Wallet.import({ mnemonicPhrase: process.env.MNEMONIC_PHRASE });
console.log(`Wallet successfully created: `, wallet.toString());

// Wallets are not saved locally by default. Refer to the Wallets concept for more information.

Wallets are initialized with a single default Address, accessible via getDefaultAddress:

index.js
let address = await wallet.getDefaultAddress();
console.log(`Default address for the wallet: `, address.toString());

In a production environment, we recommend turning on IP Whitelisting and using the 2-of-2 Coinbase-Managed Wallet for additional security.

Once initialized, your imported wallet should be stored as a Wallet data object, for easy re-instantiation. Refer to Persisting a wallet section for more information.

Funding a Wallet

Wallets do not have funds on them to start. For Base Sepolia and Ethereum Sepolia testnets, we provide a faucet method to fund your wallet with testnet ETH.

const faucetTransaction = await wallet.faucet();

// Wait for transaction to land on-chain.
await faucetTransaction.wait();

console.log(`Faucet transaction completed successfully: `, faucetTransaction.toString());

Transferring Funds

Now that your faucet transaction has successfully completed, you can send the funds in your wallet to another wallet. The code below creates another wallet, and sends testnet ETH from the first wallet to the second:

Creating multiple transactions simultaneously can lead to failures.

All transfers, excluding gasless transfers, do not support concurrent transactions. We recommend running sequential calls and waiting for the previous transaction to confirm before continuing.

See Processing multiple transfers for same address as an example. If you need more assistance, reach out to us on Discord in #wallet-api.

let anotherWallet = await Wallet.create();
console.log(`Second Wallet successfully created: `, anotherWallet.toString());

const transfer = await wallet.createTransfer({
amount: 0.00001,
assetId: Coinbase.assets.Eth,
destination: anotherWallet,
});

// Wait for the transfer to settle.
await transfer.wait()

// Check if the transfer successfully completed on-chain.
if (transfer.getStatus() === 'complete') {
console.log(`Transfer successfully completed: `, transfer.toString());
} else {
console.error('Transfer failed on-chain: ', transfer.toString());
}

See Transfers for more information.

You can create your wallet, fund it with testnet tokens and perform your first transfer by running the following command:

npm start

Trading Assets

On base-mainnet you can trade between different assets from your wallet. Since trading is only supported on mainnet wallets, wallet should be funded with real assets before trading. The code below creates a wallet and trades some ETH to USDC and then all of the USDC to WETH:

Refer to trade.js for a complete example of trading assets.

trade_assets.js
import { Coinbase, Wallet } from "@coinbase/coinbase-sdk";

let coinbase = Coinbase.configureFromJson({ filePath: '~/Downloads/cdp_api_key.json' });

// Create a Wallet on base-mainnet to trade assets with.
let wallet = await Wallet.create({ networkId: Coinbase.networks.BaseMainnet });

// Fund the Wallet's default Address with ETH from an external source.
// Trade 0.00001 ETH to USDC.
let trade = await wallet.createTrade({
  amount: 0.00001,
  fromAssetId: Coinbase.assets.Eth,
  toAssetId: Coinbase.assets.Usdc
});

await trade.wait();

if (trade.getStatus() === 'complete') {
  console.log(`Trade successfully completed: `, trade.toString());
} else {
  console.log(`Trade failed on-chain: `, trade.toString());
}

// Trade the wallet's full balance of USDC to WETH.
let trade2 = await wallet.createTrade({
  amount: wallet.getBalance(Coinbase.assets.Usdc),
  fromAssetId: Coinbase.assets.Usdc,
  toAssetId: Coinbase.assets.Weth,
});

await trade2.wait();

if (trade2.getStatus() === "complete") {
  console.log(`Trade successfully completed: `, trade2.toString());
} else {
  console.log(`Trade failed on-chain: `, trade2.toString());
}

See Trades for more information.

The Developer-Managed Wallets created in the above quickstart are not persisted. We recommend Coinbase-Managed Wallets in production environments.