Overview
This guide will walk you through executing a token swap on Base blockchain. By the end, you’ll have a working example that:
- Initializes the OKX DEX SDK client
- Gets a real-time price quote
- Executes a token swap
- Tracks the transaction status
Make sure you’ve completed the Installation guide before proceeding.
Quick Setup
Let’s execute a swap from ETH to USDC on Base in three steps.
Initialize the SDK Client
First, import the SDK and set up your client with API credentials:import { OKXDexClient } from '@okx-dex/okx-dex-sdk';
import { createEVMWallet } from '@okx-dex/okx-dex-sdk/core/evm-wallet';
import { ethers } from 'ethers';
import 'dotenv/config';
// Create EVM wallet instance
const provider = new ethers.JsonRpcProvider(process.env.EVM_RPC_URL!);
const wallet = createEVMWallet(process.env.EVM_PRIVATE_KEY!, provider);
// Initialize the client
const client = new OKXDexClient({
apiKey: process.env.OKX_API_KEY!,
secretKey: process.env.OKX_SECRET_KEY!,
apiPassphrase: process.env.OKX_API_PASSPHRASE!,
projectId: process.env.OKX_PROJECT_ID!,
evm: {
wallet: wallet
}
});
Ensure your .env file contains all required credentials as shown in the Installation guide. Get a Price Quote
Before executing a swap, get a quote to see the expected output and price impact:// Define token addresses on Base
const TOKENS = {
ETH: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // Native ETH
USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' // USDC on Base
};
async function getSwapQuote() {
const quote = await client.dex.getQuote({
chainIndex: '8453', // Base Chain
fromTokenAddress: TOKENS.ETH,
toTokenAddress: TOKENS.USDC,
amount: '100000000000000000', // 0.1 ETH in wei
slippagePercent: '0.5' // 0.5% slippage
});
console.log('Quote Details:');
console.log(`Rate: 1 ${quote.data[0].fromToken.tokenSymbol} = ${quote.data[0].toTokenAmount} ${quote.data[0].toToken.tokenSymbol}`);
console.log(`Price Impact: ${quote.data[0].priceImpactPercentage}%`);
return quote;
}
The amount parameter should be in the token’s base units (wei for ETH). Use parseFloat(amount) * Math.pow(10, decimals) to convert.
Execute the Swap
Once you’re satisfied with the quote, execute the swap:async function executeSwap() {
try {
const swap = await client.dex.executeSwap({
chainIndex: '8453', // Base Chain
fromTokenAddress: TOKENS.ETH,
toTokenAddress: TOKENS.USDC,
amount: '100000000000000000', // 0.1 ETH
slippagePercent: '0.5', // 0.5% slippage
userWalletAddress: wallet.address
});
console.log('\nSwap completed successfully!');
console.log('Transaction ID:', swap.transactionId);
console.log('Explorer URL:', swap.explorerUrl);
if (swap.details) {
console.log(`Input: ${swap.details.fromToken.amount} ${swap.details.fromToken.symbol}`);
console.log(`Output: ${swap.details.toToken.amount} ${swap.details.toToken.symbol}`);
}
} catch (error: any) {
console.error('Swap failed:', error.message);
}
}
// Run the swap
executeSwap();
Complete Working Example
Here’s the full code from the SDK’s example directory:
import { createEVMWallet } from '@okx-dex/okx-dex-sdk/core/evm-wallet';
import { OKXDexClient } from '@okx-dex/okx-dex-sdk';
import 'dotenv/config';
import { ethers } from 'ethers';
// Token addresses on Base
const TOKENS = {
NATIVE: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
} as const;
const provider = new ethers.JsonRpcProvider(process.env.EVM_RPC_URL!);
const wallet = createEVMWallet(process.env.EVM_PRIVATE_KEY!, provider);
async function main() {
// Initialize client
const client = new OKXDexClient({
apiKey: process.env.OKX_API_KEY!,
secretKey: process.env.OKX_SECRET_KEY!,
apiPassphrase: process.env.OKX_API_PASSPHRASE!,
projectId: process.env.OKX_PROJECT_ID!,
evm: {
wallet: wallet
}
});
const amount = '0.1'; // 0.1 ETH
const DECIMALS = 18;
const rawAmount = (parseFloat(amount) * Math.pow(10, DECIMALS)).toString();
// Get quote
const quote = await client.dex.getQuote({
chainIndex: '8453',
fromTokenAddress: TOKENS.NATIVE,
toTokenAddress: TOKENS.USDC,
amount: rawAmount,
slippagePercent: '0.5'
});
console.log('Quote:', `${quote.data[0].fromToken.tokenSymbol} → ${quote.data[0].toToken.tokenSymbol}`);
console.log(`Expected output: ${quote.data[0].toTokenAmount} USDC`);
// Execute swap
const result = await client.dex.executeSwap({
chainIndex: '8453',
fromTokenAddress: TOKENS.NATIVE,
toTokenAddress: TOKENS.USDC,
amount: rawAmount,
slippagePercent: '0.5',
userWalletAddress: wallet.address
});
console.log('\nSwap completed!');
console.log('Transaction:', result.transactionId);
console.log('Explorer:', result.explorerUrl);
}
main();
Understanding Token Approvals (ERC-20 Only)
When swapping ERC-20 tokens on EVM chains, you need to approve the DEX router to spend your tokens. This is not needed for native tokens like ETH.
// Only needed when swapping FROM an ERC-20 token (not native ETH)
const approval = await client.dex.executeApproval({
chainIndex: '8453',
tokenContractAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
approveAmount: '1000000000' // Amount to approve (1000 USDC with 6 decimals)
});
console.log('Approval tx:', approval.transactionHash);
The SDK automatically checks existing allowances. If sufficient approval already exists, it will skip the approval step.
Token Addresses by Chain
Here are common token addresses for supported chains:
Base (8453)
Ethereum (1)
Solana (501)
Sui (784)
const BASE_TOKENS = {
ETH: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
WETH: '0x4200000000000000000000000000000000000006'
};
const ETH_TOKENS = {
ETH: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
};
const SOLANA_TOKENS = {
SOL: 'So11111111111111111111111111111111111111112',
USDC: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
USDT: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'
};
const SUI_TOKENS = {
SUI: '0x2::sui::SUI',
USDC: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC'
};
Use client.dex.getTokens(chainId) to fetch all available tokens for a specific chain.
Error Handling
Always wrap your swap logic in try-catch blocks to handle errors gracefully:
try {
const swap = await client.dex.executeSwap({
chainIndex: '8453',
fromTokenAddress: TOKENS.ETH,
toTokenAddress: TOKENS.USDC,
amount: '100000000000000000',
slippagePercent: '0.5',
userWalletAddress: wallet.address
});
console.log('Success:', swap.transactionId);
} catch (error: any) {
// Handle specific error cases
if (error?.status === 429) {
console.log('Rate limited, try again later');
} else if (error.message?.includes('Insufficient liquidity')) {
console.log('Not enough liquidity for this trade');
} else if (error.message?.includes('Insufficient balance')) {
console.log('Wallet balance too low');
} else if (error.message?.includes('Slippage too high')) {
console.log('Price impact exceeds slippage tolerance');
} else {
console.error('Swap failed:', error.message);
}
}
| Error | Cause | Solution |
|---|
Insufficient liquidity | Not enough liquidity for trade size | Reduce amount or try different route |
Insufficient balance | Wallet doesn’t have enough tokens | Check wallet balance and fund |
Slippage too high | Price moved beyond tolerance | Increase slippage or reduce amount |
Rate limited (429) | Too many API requests | Implement retry logic with backoff |
Invalid token address | Token not supported on chain | Verify token address for the chain |
Testing Your Integration
Before going to production, test with small amounts:
Start with testnet
Use testnet RPC URLs and test tokens first:# Base Sepolia testnet
EVM_RPC_URL=https://sepolia.base.org
Use minimal amounts
When testing on mainnet, start with very small amounts:const amount = '10000000000000000'; // 0.01 ETH
Monitor transactions
Always check the explorer URL to verify transaction success:console.log('View on explorer:', swap.explorerUrl);
Next Steps
Now that you’ve executed your first swap, explore more features:
API Reference
Explore all available methods and parameters
Advanced Features
Learn about gas estimation, simulation, and MEV protection
Supported Chains
View all supported blockchain networks
Error Handling
Implement robust error handling and retry logic