Skip to main content

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.
1

Initialize the SDK Client

First, import the SDK and set up your client with API credentials:
swap.ts
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.
2

Get a Price Quote

Before executing a swap, get a quote to see the expected output and price impact:
swap.ts
// 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.
3

Execute the Swap

Once you’re satisfied with the quote, execute the swap:
swap.ts
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:
const BASE_TOKENS = {
  ETH: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
  USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  WETH: '0x4200000000000000000000000000000000000006'
};
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);
  }
}
ErrorCauseSolution
Insufficient liquidityNot enough liquidity for trade sizeReduce amount or try different route
Insufficient balanceWallet doesn’t have enough tokensCheck wallet balance and fund
Slippage too highPrice moved beyond toleranceIncrease slippage or reduce amount
Rate limited (429)Too many API requestsImplement retry logic with backoff
Invalid token addressToken not supported on chainVerify token address for the chain

Testing Your Integration

Before going to production, test with small amounts:
1

Start with testnet

Use testnet RPC URLs and test tokens first:
# Base Sepolia testnet
EVM_RPC_URL=https://sepolia.base.org
2

Use minimal amounts

When testing on mainnet, start with very small amounts:
const amount = '10000000000000000'; // 0.01 ETH
3

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

Build docs developers (and LLMs) love