okx-dex-swap
Original:🇺🇸 English
Translated
This skill should be used when the user asks to 'swap tokens', 'trade ETH for USDC', 'buy tokens', 'sell tokens', 'exchange crypto', 'convert tokens', 'swap SOL for USDC', 'get a swap quote', 'execute a trade', 'find the best swap route', 'cheapest way to swap', 'optimal swap', 'compare swap rates', or mentions swapping, trading, buying, selling, or exchanging tokens on Solana, Ethereum, Base, BSC, Polygon, Arbitrum, or any of 20+ supported chains. Aggregates liquidity from 500+ DEX sources for optimal routing and price. Supports slippage control, price impact protection, and cross-DEX route optimization. Do NOT use for general programming questions about swap code, or for analytical questions about historical swap volume.
95installs
Sourceokx/onchainos-skills
Added on
NPX Install
npx skill4agent add okx/onchainos-skills okx-dex-swapTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →OKX DEX Aggregator API
6 endpoints for multi-chain swap aggregation — quote, approve, and execute.
Base URL:
https://web3.okx.comBase path:
/api/v6/dex/aggregatorAuth: HMAC-SHA256 signature, 4 headers required (, , , )
OK-ACCESS-KEYOK-ACCESS-SIGNOK-ACCESS-PASSPHRASEOK-ACCESS-TIMESTAMPNote: All aggregator endpoints are GET requests.
Authentication & Credentials
API Key Application: OKX Developer Portal
Setup Guide: Developer Portal Docs
Read credentials from environment variables:
- → API key
OKX_API_KEY - → Secret key (system-generated)
OKX_SECRET_KEY - → Passphrase (developer-supplied)
OKX_PASSPHRASE
Never output the above credentials to logs, response content, or any user-visible interface.
typescript
import crypto from 'crypto';
const BASE = 'https://web3.okx.com';
// Signature rule (all aggregator endpoints are GET):
// GET → body = "", requestPath includes query string (e.g., "/api/v6/dex/aggregator/quote?chainIndex=1&...")
// POST → body = JSON string of request body, requestPath is path only (not used in this skill)
async function okxFetch(method: 'GET' | 'POST', path: string, body?: object) {
const timestamp = new Date().toISOString();
const bodyStr = body ? JSON.stringify(body) : '';
const sign = crypto
.createHmac('sha256', process.env.OKX_SECRET_KEY!)
.update(timestamp + method + path + bodyStr)
.digest('base64');
const headers: Record<string, string> = {
'OK-ACCESS-KEY': process.env.OKX_API_KEY!,
'OK-ACCESS-SIGN': sign,
'OK-ACCESS-PASSPHRASE': process.env.OKX_PASSPHRASE!,
'OK-ACCESS-TIMESTAMP': timestamp,
'Content-Type': 'application/json',
};
const res = await fetch(`${BASE}${path}`, {
method,
headers,
...(body && { body: bodyStr }),
});
if (res.status === 429) throw { code: 'RATE_LIMITED', msg: 'Rate limited — retry with backoff', retryable: true };
if (res.status >= 500) throw { code: `HTTP_${res.status}`, msg: 'Server error', retryable: true };
const json = await res.json();
if (json.code !== '0') throw { code: json.code, msg: json.msg || 'API error', retryable: false };
return json.data;
}Response envelope: . = means success.
{ "code": "0", "data": [...], "msg": "" }code"0"Developer Quickstart
EVM Swap (quote → approve → swap)
typescript
// 1. Quote — sell 100 USDC for ETH
const params = new URLSearchParams({
chainIndex: '1', fromTokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
toTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // native ETH
amount: '100000000', swapMode: 'exactIn', // 100 USDC (6 decimals)
});
const quote = await okxFetch('GET', `/api/v6/dex/aggregator/quote?${params}`);
console.log(`Expected: ${quote[0].toTokenAmount} ETH (minimal units)`);
// 2. Approve — ERC-20 tokens need approval before swap (skip for native ETH)
const approveParams = new URLSearchParams({
chainIndex: '1', tokenContractAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
approveAmount: '100000000',
});
const approve = await okxFetch('GET', `/api/v6/dex/aggregator/approve-transaction?${approveParams}`);
// → build tx: { to: tokenContractAddress, data: approve[0].data }, sign & send
// approve[0].dexContractAddress is the spender (already encoded in calldata), NOT the tx target
// 3. Swap
const swapParams = new URLSearchParams({
chainIndex: '1', fromTokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
toTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
amount: '100000000', slippagePercent: '1',
userWalletAddress: '0xYourWallet', swapMode: 'exactIn',
});
const swap = await okxFetch('GET', `/api/v6/dex/aggregator/swap?${swapParams}`);
// → sign & send swap[0].tx { from, to, data, value, gas }Solana Swap (swap-instruction)
typescript
const params = new URLSearchParams({
chainIndex: '501', fromTokenAddress: '11111111111111111111111111111111', // native SOL
toTokenAddress: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', // BONK
amount: '1000000000', slippagePercent: '1', userWalletAddress: 'YourSolanaWallet',
});
const result = await okxFetch('GET', `/api/v6/dex/aggregator/swap-instruction?${params}`);
// → result[0].instructionLists: assemble into VersionedTransaction, sign & sendCommon Chain IDs
| Chain | chainIndex | Chain | chainIndex |
|---|---|---|---|
| Ethereum | | Arbitrum | |
| BSC | | Base | |
| Polygon | | Solana | |
Native Token Addresses
CRITICAL: Each chain has a specific native token address for use in OKX DEX API. Using the wrong address (e.g., wSOL SPL token address instead of the Solana system program address) will cause swap transactions to fail. Reference: DEX Aggregation FAQ
| Chain | Native Token Address |
|---|---|
| EVM (Ethereum, BSC, Polygon, Arbitrum, Base, etc.) | |
| Solana | |
| Sui | |
| Tron | |
| Ton | |
WARNING — Solana native SOL: The correct address is(Solana system program). Do NOT use11111111111111111111111111111111(wSOL SPL token) — it is a different token and will cause swap failures (So11111111111111111111111111111111111111112).custom program error: 0xb
Endpoint Index
| # | Method | Path | Docs |
|---|---|---|---|
| 1 | GET | | dex-get-aggregator-supported-chains |
| 2 | GET | | dex-get-liquidity |
| 3 | GET | | dex-approve-transaction |
| 4 | GET | | dex-get-quote |
| 5 | GET | | dex-solana-swap-instruction |
| 6 | GET | | dex-swap |
Error Codes: DEX Error Codes
Cross-Skill Workflows
This skill is the execution endpoint of most user trading flows. It almost always needs input from other skills first.
Workflow A: Full Swap by Token Name (most common)
User: "Swap 1 SOL for BONK on Solana"
1. okx-dex-token /market/token/search?search=BONK&chains=501 → get BONK tokenContractAddress
↓ tokenContractAddress
2. okx-wallet-portfolio /balance/all-token-balances-by-address → verify SOL balance >= 1
↓ sufficient balance confirmed
3. okx-dex-swap /aggregator/quote → get quote (show expected output, gas, price impact)
↓ user confirms
4. okx-dex-swap /aggregator/swap-instruction → get serialized instruction (Solana)
5. User signs & sends tx (or use `okx-onchain-gateway` to broadcast via OKX nodes)Data handoff:
- from step 1 →
tokenContractAddressin steps 3-4toTokenAddress - SOL native address = (Solana system program) →
"11111111111111111111111111111111". Do NOT usefromTokenAddress(wSOL) — see Native Token Addresses.So11111111111111111111111111111111111111112 - Amount =
1 SOL(9 decimals) →"1000000000"paramamount - from step 2 is UI units; swap needs minimal units → multiply by
balance10^decimal
Workflow B: EVM Swap with Approval
User: "Swap 100 USDC for ETH on Ethereum"
1. okx-dex-token /market/token/search?search=USDC&chains=1 → get USDC address
2. okx-wallet-portfolio /balance/token-balances-by-address → verify USDC balance >= 100
3. okx-dex-swap /aggregator/quote → get quote
↓ check isHoneyPot, taxRate, priceImpactPercent
4. okx-dex-swap /aggregator/approve-transaction → get ERC-20 approval calldata
5. User signs & sends approval tx
6. okx-dex-swap /aggregator/swap → get swap calldata
7. User signs & sends swap tx (or use `okx-onchain-gateway` to broadcast via OKX nodes)Key: EVM tokens (not native ETH) require an approve step. Skip it if user is selling native ETH.
Workflow C: Compare Quote Then Execute
1. okx-dex-swap /aggregator/quote → get quote with route info
2. Display to user: expected output, gas, price impact, route
3. If price impact > 5% → warn user
4. If isHoneyPot = true → block trade, warn user
5. User confirms → proceed to approve (if EVM) → swapSwap Flow
EVM Chains (Ethereum, BSC, Arbitrum, Base, etc.)
1. GET /aggregator/quote -> Get price and route
2. GET /aggregator/approve-transaction -> Get approval calldata (if needed)
3. User signs & sends approval tx
4. GET /aggregator/swap -> Get swap calldata
5. User signs & sends swap txSolana
1. GET /aggregator/quote -> Get price and route
2. GET /aggregator/swap-instruction -> Get serialized instruction
3. User signs & sends txOperation Flow
Step 1: Identify Intent
- View a quote ->
GET /aggregator/quote - Execute a swap -> full swap flow (quote -> approve -> swap)
- List available DEXes ->
GET /aggregator/get-liquidity - Approve a token ->
GET /aggregator/approve-transaction
Step 2: Collect Parameters
- Missing -> ask which chain
chainIndex - Missing token addresses -> use
okx-dex-tokento resolve name → address/market/token/search - Missing amount -> ask user, remind to convert to minimal units
- Missing slippage -> suggest 1% default, 3-5% for volatile tokens
- Missing wallet address -> ask user
Step 3: Execute
- Quote phase: call , display estimated results
/quote- Expected output, gas estimate, price impact, routing path
- Check and
isHoneyPot— surface safety info to userstaxRate
- Confirmation phase: wait for user approval before proceeding
- Approval phase (EVM only): check/execute approve if selling non-native token
- Execution phase: call (EVM) or
/swap(Solana), return tx data for signing/swap-instruction
Step 4: Suggest Next Steps
After displaying results, suggest 2-3 relevant follow-up actions based on the swap phase just completed:
| Just completed | Suggest |
|---|---|
| 1. Check wallet balance first → |
| Swap executed successfully | 1. Verify updated balance → |
| 1. Get a swap quote → |
Present conversationally, e.g.: "Swap complete! Would you like to check your updated balance?" — never expose skill names or endpoint paths to the user.
API Reference
1. GET /aggregator/supported/chain
| Param | Type | Required | Description |
|---|---|---|---|
| String | No | Filter to a specific chain (e.g., |
Response:
| Field | Type | Description |
|---|---|---|
| String | Chain unique identifier (e.g., "1") |
| String | Chain name (e.g., "Ethereum") |
| String | OKX DEX token approve contract address |
2. GET /aggregator/get-liquidity
| Param | Type | Required | Description |
|---|---|---|---|
| String | Yes | Chain ID |
Response:
| Field | Type | Description |
|---|---|---|
| String | Liquidity pool ID |
| String | Pool name (e.g., "Uniswap V3") |
| String | Pool logo URL |
3. GET /aggregator/approve-transaction
| Param | Type | Required | Description |
|---|---|---|---|
| String | Yes | Chain ID |
| String | Yes | Token to approve |
| String | Yes | Amount in minimal units |
Response:
| Field | Type | Description |
|---|---|---|
| String | Approval calldata ( |
| String | DEX router address (the spender, already encoded in calldata). NOT the tx |
| String | Gas limit. May underestimate — use simulation or ×1.5 |
| String | Gas price in wei |
4. GET /aggregator/quote
| Param | Type | Required | Description |
|---|---|---|---|
| String | Yes | Chain ID |
| String | Yes | Amount in minimal units (sell amount if exactIn, buy amount if exactOut) |
| String | Yes | |
| String | Yes | Token to sell |
| String | Yes | Token to buy |
Optional params: , , (default 90%), (max 10 Solana, 3 others).
dexIdsdirectRoutepriceImpactProtectionPercentfeePercentResponse key fields: (output minimal units), , , (USD estimate), , , , / (each has , , , ). Full fields: see docs.
toTokenAmountfromTokenAmountestimateGasFeetradeFeepriceImpactPercentrouterdexRouterListfromTokentoTokenisHoneyPottaxRatedecimaltokenUnitPrice5. GET /aggregator/swap-instruction (Solana only)
| Param | Type | Required | Description |
|---|---|---|---|
| String | Yes | Must be |
| String | Yes | Amount in minimal units |
| String | Yes | Token to sell |
| String | Yes | Token to buy |
| String | Yes | User's wallet |
| String | Yes | 0 to <100 |
Optional params: , , , , , , .
autoSlippagecomputeUnitPricecomputeUnitLimitdexIdsswapReceiverAddressfeePercentpriceImpactProtectionPercentResponse key fields: (each has , , ), , (same as /quote), (, ), . Full fields: see docs.
instructionLists[]dataaccountsprogramIdaddressLookupTableAccountrouterResulttxminReceiveAmountslippagePercentwsolRentFee6. GET /aggregator/swap (EVM + Solana)
Note: This endpoint works for all chains including Solana.is a Solana-specific alternative that returns deserialized instructions instead of a serialized transaction./swap-instruction
| Param | Type | Required | Description |
|---|---|---|---|
| String | No | Chain ID. Technically optional but strongly recommended — always pass it. |
| String | Yes | Amount in minimal units |
| String | Yes | |
| String | Yes | Token to sell |
| String | Yes | Token to buy |
| String | Yes | 0-100 (EVM), 0-<100 (Solana) |
| String | Yes | User's wallet |
Optional params: (//), , , (Jito, 0.0000000001-2 SOL; use if is set), , , , , , (default 90%), (Boolean, combine approve+swap in one call), (used with ).
gasLevelaveragefastslowcomputeUnitPricecomputeUnitLimittips0computeUnitPricedexIdsautoSlippagemaxAutoSlippagePercentswapReceiverAddressfeePercentpriceImpactProtectionPercentapproveTransactionapproveAmountapproveTransactionResponse key fields: (same as /quote), — , , (hex-encoded for EVM, base58-encoded for Solana), , , (EIP-1559), , , , , . Full fields: see docs.
routerResulttxfromtodatagasgasPricemaxPriorityFeePerGasvalueminReceiveAmountmaxSpendAmountslippagePercentsignatureDataInput / Output Examples
User says: "Swap 100 USDC for ETH"
1. GET /api/v6/dex/aggregator/quote?chainIndex=1&fromTokenAddress=0xa0b8...&toTokenAddress=0xeeee...&amount=100000000&swapMode=exactIn
-> Display:
Expected output: 0.031 ETH
Gas fee: ~$2.50
Price impact: 0.05%
Route: USDC -> WETH -> ETH (Uniswap V3)
2. User confirms
3. GET /api/v6/dex/aggregator/approve-transaction?chainIndex=1&tokenContractAddress=0xa0b8...&approveAmount=100000000
-> Returns approval calldata and spender address
-> Build tx: { to: "0xa0b8..." (token contract), data: response.data } — sign & send
4. GET /api/v6/dex/aggregator/swap?chainIndex=1&...&slippagePercent=1&userWalletAddress=0x...
-> Returns tx: { from, to, data, gas, gasPrice, value, minReceiveAmount }
-> User signs and broadcastsUser says: "What DEXes are available on Ethereum?"
GET /api/v6/dex/aggregator/get-liquidity?chainIndex=1
-> Display: Uniswap V2, Uniswap V3, SushiSwap, Curve, Balancer, ... (80+ sources)Edge Cases
- High slippage (>5%): warn user, suggest splitting the trade or adjusting slippage
- Large price impact (>10%): strongly warn, suggest reducing amount
- Honeypot token: — block trade and warn user
isHoneyPot = true - Tax token: non-zero — display to user (e.g. 5% buy tax)
taxRate - Insufficient balance: use to check first, show current balance, suggest adjusting amount
okx-wallet-portfolio - exactOut not supported: only Ethereum/Base/BSC/Arbitrum — prompt user to use
exactIn - Solana chain: returns deserialized instructions (more control);
/swap-instructionalso works but returns a serialized transaction/swap - Solana native SOL address: Must use (system program), NOT
11111111111111111111111111111111(wSOL). Using wSOL address causesSo11111111111111111111111111111111111111112on-chain failures. See DEX Aggregation FAQ.custom program error: 0xb - 429 rate limit: exponential backoff with jitter. See Rate Limit & Fee Docs for tier-specific RPS limits (Trial: 1 RPS, Start-up: 2-50 RPS, Enterprise: custom).
- Cross-skill pipeline rate limit: when chaining calls across multiple skills (e.g., token search → balance check → swap), add 300-500ms delay between requests to avoid triggering rate limit (error code ).
50011 - Network error: retry once, then prompt user to try again later
- Request timeout: all API calls must set a 10-second timeout limit
Amount Display Rules
- Input/output amounts in UI units (,
1.5 ETH)3,200 USDC - Internal API params use minimal units (=
1 USDC,"1000000"=1 ETH)"1000000000000000000" - Gas fees in USD
- in both UI units and USD
minReceiveAmount - Price impact as percentage
Global Notes
- All endpoints are GET — no POST in the aggregator family
- Amounts must be in minimal units (wei/lamports)
- only on Ethereum(
exactOut)/Base(1)/BSC(8453)/Arbitrum(56)42161 - is Solana-only
/swap-instruction - Check and
isHoneyPot— surface safety info to userstaxRate - Solana referrer wallets require SOL deposit activation
- TON chain has limited commission pool support (excludes Stonfi V1)
- EVM contract addresses must be all lowercase
- For token search -> use
okx-dex-token - For market prices -> use
okx-dex-market - For balance queries -> use
okx-wallet-portfolio - For transaction broadcasting -> use
okx-onchain-gateway