Overview
Swap any ERC-20 token pair with a simple API that handles price discovery, routing, Permit2 signing, and transaction submission. The SDK provides two levels of abstraction:- React hooks (
@coinbase/cdp-hooks) — reactive state management with automatic on-chain confirmation tracking - Core functions (
@coinbase/cdp-core) — framework-agnostic async functions for vanilla JS/TS apps
Any ERC-20 Pair
Swap between any supported tokens using contract addresses
Price Discovery
Get indicative prices with fee and slippage estimates before executing
Smart Account Support
Works with both EOAs and ERC-4337 Smart Accounts
Gas Sponsorship
Built-in Paymaster support for gasless Smart Account swaps
Get an indicative price
Before executing a swap, fetch a non-binding price estimate. This is a read-only operation that does not modify any on-chain state.- React hooks
- Vanilla JS
The You can disable automatic fetching by passing
useGetSwapPrice hook automatically fetches when all required parameters are present and the user is signed in. It uses a stale-while-revalidate strategy: when the token pair or network changes, previous data is cleared; when only the amount, slippage, or account changes, previous data is preserved while the new price loads.enabled: false:Price result
When liquidity is available, the response includestoAmount (expected output), minToAmount (minimum after slippage), swap fees, estimated totalNetworkFee, and preflight issues. See GetSwapPriceResult for the full type.
When liquidity is not available, the response omits these values altogether. See SwapUnavailableResult for the full type.
Execute a swap
Execute a swap to submit the transaction on-chain. The CDP Swap API atomically quotes, signs the Permit2 permit, simulates, and submits the transaction.- React hooks
- Vanilla JS
The
useSwap hook tracks the full lifecycle: submission, on-chain confirmation, and errors. For EOA accounts it waits for a transaction receipt; for Smart Accounts it polls the user operation until completion.Swap result
The result is a discriminated union based on account type:"evm-eoa" results include a transactionHash, while "evm-smart" results include a userOpHash. Both include the resolved token addresses, amounts, fees, and network fee estimate. See ExecuteSwapResult for the full type.
When using the
useSwap hook, the data object is enriched with confirmation details: receipt for EOA transactions, and transactionHash / receipts / userOperation for Smart Accounts. These values are populated once the operation completes on-chain.Token approvals
Swaps use Permit2 for token transfers. The CDP Swap API signs the per-swap Permit2 permit automatically, but thefromToken must have an ERC-20 approval to the Permit2 contract.
Use
getSwapPrice / useGetSwapPrice to check before executing — if issues.allowance is non-null, the taker needs to approve issues.allowance.spender (the Permit2 contract) for at least fromAmount. Approving a larger amount avoids re-approving on every swap.Gas sponsorship
For Smart Account users, you can sponsor gas fees to enable gasless swaps. PassuseCdpPaymaster: true to use the CDP Paymaster on Base, or provide a custom paymasterUrl for any ERC-7677-compatible paymaster. These options are ignored for EOA accounts.
Account selection
By default, the SDK auto-selects the taker account using the following heuristics:| Configuration | Result |
|---|---|
| 1 Smart Account + 1 EOA | Prefers the Smart Account (EOA is typically just a signer) |
| 1 EOA only (no Smart Accounts) | Uses the EOA |
| Multiple accounts | Error: must specify account |
account explicitly to choose which address to swap from.
Supported networks
| Network | Value |
|---|---|
| Base | base |
| Ethereum | ethereum |
| Arbitrum | arbitrum |
| Optimism | optimism |
| Polygon | polygon |
Swaps are currently supported on mainnet networks only; testnet support is not available. See
EvmSwapsNetwork for the canonical list.Error handling
Swap-specific failures throw aSwapError with a typed code (see SwapErrorCode for all values). Input validation errors (invalid addresses, non-positive amounts, invalid slippage) throw an InputValidationError before any API call is made.
When using
useSwap, check the returned error value instead of a try/catch. The same instanceof SwapError check applies.FAQ
How do I specify token addresses?
How do I specify token addresses?
What units should fromAmount be in?
What units should fromAmount be in?
fromAmount must be a positive integer string in atomic units (the smallest denomination of the token). For example, USDC has 6 decimals, so 1 USDC = "1000000". WETH has 18 decimals, so 0.1 WETH = "100000000000000000".What does slippageBps control?
What does slippageBps control?
slippageBps sets the maximum acceptable price impact in basis points (1 bps = 0.01%). The default is 100 (1%), applied by the API when omitted. If the price moves beyond this threshold between the quote and execution, the transaction will revert to protect the user.Are testnets supported?
Are testnets supported?
Swaps are currently available on mainnet networks only (Base, Ethereum, Arbitrum, Optimism, Polygon). Testnet support is not yet available.
Can I swap the native gas token (ETH, POL)?
Can I swap the native gas token (ETH, POL)?
Yes. Use the sentinel address
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE as fromToken or toToken to represent the chain’s native token (ETH on Ethereum/Base/Arbitrum/Optimism, POL on Polygon). No Permit2 approval is needed for native tokens.Does the SDK handle token approvals?
Does the SDK handle token approvals?
The CDP Swap API handles the per-swap Permit2 signature automatically. However, the
fromToken must have an ERC-20 approval to the Permit2 contract. See Token approvals for details.What's the difference between useSwap and executeSwap?
What's the difference between useSwap and executeSwap?
executeSwap (core) returns a Promise that resolves with the swap result (transaction hash or user op hash) as soon as it’s submitted. useSwap (hooks) additionally tracks on-chain confirmation — status stays "pending" until the transaction receipt (EOA) or user operation (Smart Account) is confirmed, then moves to "success".Full example
Reference
@coinbase/cdp-core
| Resource | Description |
|---|---|
getSwapPrice | Get an indicative price |
executeSwap | Execute a swap |
GetSwapPriceOptions | Parameters for price requests |
GetSwapPriceResult | Price response when liquidity is available |
SwapUnavailableResult | Price response when no route exists |
ExecuteSwapOptions | Parameters for swap execution |
ExecuteSwapResult | Swap result type (EOA / Smart Account) |
SwapError | Typed error class for swap failures |
@coinbase/cdp-hooks
| Resource | Description |
|---|---|
useGetSwapPrice | Reactive price fetching |
useSwap | Execute and track a swap |
UseGetSwapPriceOptions | Options for useGetSwapPrice |
UseGetSwapPriceReturnType | Return type of useGetSwapPrice |
UseSwapReturnType | Return type of useSwap |
SwapTransactionData | Hook swap result (EOA / Smart Account) |
What to read next
USDC Send
Send USDC with a simple, unified API across all account types
Smart Accounts
Learn about EVM Smart Accounts and gas abstraction
React Hooks Reference
Explore all available React hooks for embedded wallets
Trade API
Onchain swaps for trading bots, DeFi apps, and server-side integrations