This guide demonstrates how to execute token swaps on Solana using the OKX DEX SDK. The SDK supports both simplified swap execution and instruction-based swaps for advanced use cases.
Prerequisites
OKX API credentials
Solana wallet with a private key
Access to a Solana RPC endpoint
SOL for transaction fees
Setup
Install Dependencies
Install the required packages: npm install @okx-dex/sdk @solana/web3.js dotenv
Configure Environment
Set up your environment variables: OKX_API_KEY = your_api_key
OKX_SECRET_KEY = your_secret_key
OKX_API_PASSPHRASE = your_passphrase
OKX_PROJECT_ID = your_project_id
SOLANA_PRIVATE_KEY = your_wallet_private_key
SOLANA_WALLET_ADDRESS = your_wallet_address
SOLANA_RPC_URL = https://api.mainnet-beta.solana.com
Initialize the Client
Create a Solana wallet and initialize the OKX client: import { OKXDexClient } from '@okx-dex/sdk' ;
import { Connection } from '@solana/web3.js' ;
import { createWallet } from '@okx-dex/sdk/core/wallet' ;
import 'dotenv/config' ;
const connection = new Connection ( process . env . SOLANA_RPC_URL ! );
const wallet = createWallet ( process . env . SOLANA_PRIVATE_KEY ! , connection );
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 ! ,
solana: {
wallet: wallet ,
computeUnits: 300000 , // Optional: set compute units
maxRetries: 3 // Optional: retry failed transactions
}
});
Getting a Quote
Fetch a quote to preview swap rates and routes:
const quote = await client . dex . getQuote ({
chainIndex: '501' , // Solana mainnet
fromTokenAddress: 'So11111111111111111111111111111111111111112' , // SOL (wrapped)
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' , // USDC
amount: '10000000000' , // 10 SOL (9 decimals)
slippagePercent: '0.5' ,
dexIds: '277' , // Optional: specific DEX (Jupiter = 277)
directRoute: true , // Optional: prefer direct routes
feePercent: '5' // Optional: fee percentage
});
console . log ( 'Quote:' , JSON . stringify ( quote , null , 2 ));
Solana uses 9 decimals for SOL. For example, 1 SOL = 1000000000 lamports.
Common Token Addresses
Token Address Decimals SOL (Native) 111111111111111111111111111111119 SOL (Wrapped) So111111111111111111111111111111111111111129 USDC EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v6 USDT Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB6 BONK DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB2635
Executing a Swap
The SDK provides two methods for executing swaps on Solana.
Standard Swap
Instruction-Based Swap
Use the simplified executeSwap method for most use cases: // Get token information first
const quote = await client . dex . getQuote ({
chainIndex: '501' ,
fromTokenAddress: '11111111111111111111111111111111' ,
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' ,
amount: '100000000' ,
slippagePercent: '0.005'
});
const tokenInfo = {
fromToken: {
symbol: quote . data [ 0 ]. fromToken . tokenSymbol ,
decimals: parseInt ( quote . data [ 0 ]. fromToken . decimal ),
price: quote . data [ 0 ]. fromToken . tokenUnitPrice
},
toToken: {
symbol: quote . data [ 0 ]. toToken . tokenSymbol ,
decimals: parseInt ( quote . data [ 0 ]. toToken . decimal ),
price: quote . data [ 0 ]. toToken . tokenUnitPrice
}
};
// Convert amount to base units
const amount = '0.1' ; // 0.1 SOL
const rawAmount = (
parseFloat ( amount ) * Math . pow ( 10 , tokenInfo . fromToken . decimals )
). toString ();
console . log ( 'Swap Details:' );
console . log ( `From: ${ tokenInfo . fromToken . symbol } ` );
console . log ( `To: ${ tokenInfo . toToken . symbol } ` );
console . log ( `Amount: ${ amount } ${ tokenInfo . fromToken . symbol } ` );
console . log ( `Amount in base units: ${ rawAmount } ` );
// Execute the swap
const result = await client . dex . executeSwap ({
chainIndex: '501' ,
fromTokenAddress: '11111111111111111111111111111111' ,
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' ,
amount: rawAmount ,
slippagePercent: '0.005' ,
userWalletAddress: wallet . publicKey . toString ()
});
console . log ( 'Swap completed!' );
console . log ( 'Transaction ID:' , result . transactionId );
console . log ( 'Explorer URL:' , result . explorerUrl );
if ( result . details ) {
console . log ( ' \n Details:' );
console . log ( `Input: ${ result . details . fromToken . amount } ${ result . details . fromToken . symbol } ` );
console . log ( `Output: ${ result . details . toToken . amount } ${ result . details . toToken . symbol } ` );
if ( result . details . priceImpact ) {
console . log ( `Price Impact: ${ result . details . priceImpact } %` );
}
}
For advanced use cases where you need to compose transactions: // Step 1: Get swap instructions
const instructionData = await client . dex . getSolanaSwapInstruction ({
chainIndex: '501' ,
fromTokenAddress: '11111111111111111111111111111111' , // SOL
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' , // USDC
amount: '10000000' , // 0.01 SOL
userWalletAddress: wallet . publicKey . toString (),
slippagePercent: '0.1'
});
console . log ( 'Instruction response:' , instructionData );
if ( ! instructionData . data ) {
throw new Error ( 'No instruction data received' );
}
// Check the routing information
const routerName = instructionData . data ?. routerResult ?. dexRouterList ?.[ 0 ]?. dexProtocol ?. dexName ;
const instructionCount = instructionData . data ?. instructionLists ?. length ?? 0 ;
console . log ( 'Router:' , routerName );
console . log ( 'Instructions:' , instructionCount );
// Step 2: Execute the swap using the instructions
const result = await client . dex . executeSolanaSwapInstructions ({
chainIndex: '501' ,
fromTokenAddress: '11111111111111111111111111111111' ,
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' ,
amount: '10000000' ,
userWalletAddress: wallet . publicKey . toString (),
slippagePercent: '0.01'
});
console . log ( 'Swap completed!' );
console . log ( 'Transaction Result:' , result );
The instruction-based method is useful when you need to:
Combine swaps with other Solana instructions
Implement custom transaction logic
Build complex multi-step transactions
Solana-Specific Configuration
When initializing the client, you can configure Solana-specific parameters:
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 ! ,
solana: {
wallet: wallet ,
computeUnits: 300000 , // Compute units for transaction
maxRetries: 3 , // Retry attempts for failed transactions
confirmationTimeout: 60000 // Timeout for confirmation (ms)
}
});
Parameter Details
Parameter Description Default computeUnitsMaximum compute units for the transaction 200000 maxRetriesNumber of retry attempts for failed transactions 1 confirmationTimeoutMilliseconds to wait for transaction confirmation 30000
Quote Parameters
Solana swaps support additional parameters for routing optimization:
const quote = await client . dex . getQuote ({
chainIndex: '501' ,
fromTokenAddress: 'So11111111111111111111111111111111111111112' ,
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' ,
amount: '1000000000' ,
slippagePercent: '0.5' ,
// Optional Solana-specific parameters
dexIds: '277' , // Specify DEX (277 = Jupiter)
directRoute: true , // Prefer direct routes (fewer hops)
feePercent: '5' // Fee percentage for referral
});
Complete Example
Here’s a full working example:
import { OKXDexClient } from '@okx-dex/sdk' ;
import { Connection } from '@solana/web3.js' ;
import { createWallet } from '@okx-dex/sdk/core/wallet' ;
import 'dotenv/config' ;
async function swapSolanaTokens () {
// Initialize connection and wallet
const connection = new Connection ( process . env . SOLANA_RPC_URL ! );
const wallet = createWallet ( process . env . SOLANA_PRIVATE_KEY ! , connection );
// Create 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 ! ,
solana: {
wallet: wallet ,
computeUnits: 300000 ,
maxRetries: 3
}
});
try {
// Execute swap: 0.1 SOL to USDC
const result = await client . dex . executeSwap ({
chainIndex: '501' ,
fromTokenAddress: '11111111111111111111111111111111' ,
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' ,
amount: '100000000' , // 0.1 SOL
slippagePercent: '0.005' ,
userWalletAddress: wallet . publicKey . toString ()
});
console . log ( '✅ Swap successful!' );
console . log ( 'Transaction:' , result . transactionId );
console . log ( 'Explorer:' , result . explorerUrl );
} catch ( error ) {
console . error ( '❌ Swap failed:' , error . message );
}
}
swapSolanaTokens ();
Best Practices
Use Appropriate Slippage Set 0.5-1% slippage for most tokens, higher for illiquid tokens
Set Compute Units Increase compute units for complex swaps to avoid failures
Handle Retries Configure maxRetries for better transaction success rates
Monitor Network Check Solana network congestion before large swaps
Error Handling
try {
const result = await client . dex . executeSwap ({
chainIndex: '501' ,
fromTokenAddress: '11111111111111111111111111111111' ,
toTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' ,
amount: '100000000' ,
slippagePercent: '0.01' ,
userWalletAddress: wallet . publicKey . toString ()
});
} catch ( error ) {
if ( error . message . includes ( 'insufficient' )) {
console . error ( 'Insufficient SOL balance' );
} else if ( error . message . includes ( 'slippage' )) {
console . error ( 'Price moved beyond slippage tolerance' );
} else if ( error . message . includes ( 'timeout' )) {
console . error ( 'Transaction confirmation timeout' );
} else {
console . error ( 'Swap failed:' , error . message );
}
}
Next Steps
Sui Swaps Learn how to execute swaps on Sui
API Reference View complete API documentation