Overview

A swap is a transaction that exchanges one token for another.

In this guide, you will learn how to:

  • Estimate a swap price
  • Execute a swap with regular accounts (EOAs) or Smart Accounts

The Beta launch of our Swap API supports Ethereum and Base mainnet networks only - stay tuned for additional network support!

Price estimation

The SDK provides two methods for estimating swap prices:

MethodUse CaseFunction
Quick estimateUI displays, real-time rates, liquidity checks- getSwapPrice (Ts)
- get_swap_price (Py)
Swap quotePre-execution, approvals, custom handling- quoteSwap (Ts)
- quote_swap (Py)

CDP vs. external libraries

You can execute swaps using either:

  1. CDP Wallet Integration (Recommended for most use cases)

    • Use our managed wallet infrastructure
    • Automatic transaction signing and submission
    • Built-in security and compliance features
    • Smart Account support with gas sponsorship via paymasters
    • See the Wallet API v2 guide for details on setup and the Wallet API Swaps guide for more information on executing swaps
  2. External Library Integration (For custom infrastructure)

    • Use libraries like viem or web3.py
    • Full control over transaction signing
    • Support for custom wallet types (including Smart Accounts with additional setup)
    • Continue reading below for examples

Both options include built-in slippage protection to ensure your swap executes at a fair price, even in volatile market conditions. Gas fees are automatically calculated and optimized for the most cost-effective route.

Slippage

Slippage is the difference between the expected price of a trade and the actual price at which it executes.

Prerequisites

It is assumed you have:

Regular Accounts (EOAs)

1. Estimate a swap price

To begin, let’s walk through an example of how to estimate a swap price with a regular account (EOA).

getSwapPrice for Typescript and get_swap_price for Python provide estimates only and do not reserve funds. They are suitable for frequent price updates but may be less precise than creating a swap quote.

import { CdpClient } from "@coinbase/cdp-sdk";

const cdp = new CdpClient();

// Get price for swapping 1 WETH to USDC on Base
const swapPrice = await cdp.evm.getSwapPrice({
  fromToken: "0x4200000000000000000000000000000000000006",  // WETH
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",    // USDC
  fromAmount: BigInt("1000000000000000000"),  // 1 WETH (18 decimals)
  network: "base",
  taker: "0x1234567890123456789012345678901234567890"  // Your EOA address
});

if (swapPrice.liquidityAvailable) {
  console.log(`You'll receive: ${swapPrice.toAmount} USDC`);
  console.log(`Minimum after slippage: ${swapPrice.minToAmount} USDC`);
}

📖 Full examples: TypeScript | Python

2. Create a swap quote

Once you’re ready to commit to a swap, you can create a swap quote using the CDP API. This gives you the transaction data needed for execution as opposed to the quick price estimate that we demonstrated above.

Creating a swap quote may reserve funds onchain. This action is strictly rate-limited.

// Using a CDP account
const account = await cdp.evm.getOrCreateAccount({ name: "MyAccount" });

// Create a swap quote
const swapQuote = await account.quoteSwap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",    // USDC
  fromToken: "0x4200000000000000000000000000000000000006",  // WETH
  fromAmount: BigInt("1000000000000000000"),  // 1 WETH (18 decimals)
  slippageBps: 100,  // 1% slippage tolerance
});

if (swapQuote.liquidityAvailable) {
  console.log(`Expected output: ${swapQuote.toAmount} USDC`);
  console.log(`Minimum output: ${swapQuote.minToAmount} USDC`);
}

📖 Full examples: TypeScript | Python

3. Execute a swap

Now that we have a swap quote, we can execute it onchain. The easiest way to do this is by using CDP Wallets.

We also offer a smoother developer experience using our Wallet API. Read the Wallet API Swaps guide for more information.

// Execute the swap using the CDP account (recommended)
const { transactionHash } = await swapQuote.execute();

console.log(`Swap executed: ${transactionHash}`);

All-in-one swap

You can also create and execute a swap in a single call using account.swap():

// Create and execute swap in one call
const result = await account.swap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",    // USDC
  fromToken: "0x4200000000000000000000000000000000000006",  // WETH
  fromAmount: BigInt("1000000000000000000"),  // 1 WETH
  slippageBps: 100,  // 1% slippage tolerance
});

console.log(`Swap executed: ${result.transactionHash}`);
console.log(`Received: ${result.toAmount} USDC`);

📖 Full examples:

Smart Accounts

Smart Accounts provide additional features like gas sponsorship and batch operations. The key differences are:

  • Use the Smart Account address (not the owner’s EOA) as the taker
  • Transactions return userOpHash instead of transactionHash
  • Must wait for user operations to complete

1. Estimate a swap price

When estimating prices for Smart Accounts, use the Smart Account address as the taker:

import { CdpClient } from "@coinbase/cdp-sdk";

const cdp = new CdpClient();

// First, create or get your Smart Account
const owner = await cdp.evm.getOrCreateAccount({ name: "OwnerAccount" });
const smartAccount = await cdp.evm.getOrCreateSmartAccount({ 
  name: "MySmartAccount",
  owner: owner
});

// Get price using the Smart Account address
const swapPrice = await cdp.evm.getSwapPrice({
  fromToken: "0x4200000000000000000000000000000000000006",  // WETH
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",    // USDC
  fromAmount: BigInt("1000000000000000000"),  // 1 WETH (18 decimals)
  network: "base",
  taker: smartAccount.address  // Smart Account address, not owner EOA
});

if (swapPrice.liquidityAvailable) {
  console.log(`You'll receive: ${swapPrice.toAmount} USDC`);
  console.log(`Minimum after slippage: ${swapPrice.minToAmount} USDC`);
}

📖 Full examples: TypeScript | Python

2. Create a swap quote

Once you’re ready to commit to a swap, you can create a swap quote using the CDP API. This gives you the transaction data needed for execution as opposed to the quick price estimate that we demonstrated above.

Creating a swap quote may reserve funds onchain. This action is strictly rate-limited.

// Create a swap quote with Smart Account
const swapQuote = await smartAccount.quoteSwap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",    // USDC
  fromToken: "0x4200000000000000000000000000000000000006",  // WETH
  fromAmount: BigInt("1000000000000000000"),  // 1 WETH (18 decimals)
  slippageBps: 100,  // 1% slippage tolerance
  // paymasterUrl: "https://your-paymaster.com" // Optional: sponsor gas fees
});

// Check if liquidity is available
if (swapQuote.liquidityAvailable) {
  console.log(`Expected output: ${swapQuote.toAmount} USDC`);
  console.log(`Minimum output: ${swapQuote.minToAmount} USDC`);
}

📖 Full examples: TypeScript | Python

3. Execute a swap

Now that we have a swap quote, we can execute it onchain. The easiest way to do this is by using CDP Wallets.

Executing swaps with Smart Accounts returns a user operation hash instead of a transaction hash. You must wait for the user operation to complete:

// Execute the swap using the Smart Account
const { userOpHash } = await swapQuote.execute();

console.log(`User operation submitted: ${userOpHash}`);

// Wait for the user operation to be mined
const receipt = await smartAccount.waitForUserOperation({
  userOpHash: userOpHash
});

if (receipt.status === "complete") {
  console.log(`Swap completed! Transaction: ${receipt.transactionHash}`);
} else {
  console.error(`User operation failed: ${receipt.status}`);
}


All-in-one swap

You can also create and execute a swap in a single call using smartAccount.swap():

// Create and execute swap in one call
const result = await smartAccount.swap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",    // USDC
  fromToken: "0x4200000000000000000000000000000000000006",  // WETH
  fromAmount: BigInt("1000000000000000000"),  // 1 WETH
  slippageBps: 100,  // 1% slippage tolerance
  // paymasterUrl: "https://your-paymaster.com" // Optional: sponsor gas
});

console.log(`User operation submitted: ${result.userOpHash}`);

// Wait for confirmation
const receipt = await smartAccount.waitForUserOperation({
  userOpHash: result.userOpHash
});

if (receipt.status === "complete") {
  console.log(`Swap completed! Transaction: ${receipt.transactionHash}`);
}

📖 Full examples:

Smart Account Benefits

  • Gas Sponsorship: Use paymasters to pay gas fees on behalf of users
  • Batch Operations: Combine multiple swaps or operations in one transaction
  • Account Abstraction: Enhanced UX with features like session keys and social recovery
  • Security: Multi-signature capabilities and spending limits

Using External Wallets

If you prefer to use your own wallet, signing infrastructure, and node for broadcasting transactions, you can use the core Swap APIs (like getSwapPrice and quoteSwap) without a CDP account.

📖 Full examples: TypeScript | Python

Custom Wallet Integration

If you’re using your own wallet infrastructure (e.g., viem, web3.py, etc.), you can execute swaps using the transaction data from the quote. For Smart Accounts with external wallets, additional ERC-4337 infrastructure setup is required.

  • Welcome: Read why Swap API is easier to use than traditional aggregator solutions.
  • API Reference: Explore the full CDP API v2 documentation.
  • Wallet API v2: Learn more about our new Wallet API, including account management and transaction signing.
  • USDC Rewards: Learn how to earn 4.1% rewards on USDC balances in your CDP wallets.