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
Added on

NPX Install

npx skill4agent add okx/onchainos-skills okx-dex-swap

OKX DEX Aggregator API

6 endpoints for multi-chain swap aggregation — quote, approve, and execute.
Base URL:
https://web3.okx.com
Base path:
/api/v6/dex/aggregator
Auth: HMAC-SHA256 signature, 4 headers required (
OK-ACCESS-KEY
,
OK-ACCESS-SIGN
,
OK-ACCESS-PASSPHRASE
,
OK-ACCESS-TIMESTAMP
)
Note: All aggregator endpoints are GET requests.

Authentication & Credentials

API Key Application: OKX Developer Portal
Read credentials from environment variables:
  • OKX_API_KEY
    → API key
  • OKX_SECRET_KEY
    → Secret key (system-generated)
  • OKX_PASSPHRASE
    → Passphrase (developer-supplied)
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:
{ "code": "0", "data": [...], "msg": "" }
.
code
=
"0"
means success.

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 & send

Common Chain IDs

ChainchainIndexChainchainIndex
Ethereum
1
Arbitrum
42161
BSC
56
Base
8453
Polygon
137
Solana
501

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
ChainNative Token Address
EVM (Ethereum, BSC, Polygon, Arbitrum, Base, etc.)
0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
Solana
11111111111111111111111111111111
Sui
0x2::sui::SUI
Tron
T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb
Ton
EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c
WARNING — Solana native SOL: The correct address is
11111111111111111111111111111111
(Solana system program). Do NOT use
So11111111111111111111111111111111111111112
(wSOL SPL token) — it is a different token and will cause swap failures (
custom program error: 0xb
).

Endpoint Index

#MethodPathDocs
1GET
/api/v6/dex/aggregator/supported/chain
dex-get-aggregator-supported-chains
2GET
/api/v6/dex/aggregator/get-liquidity
dex-get-liquidity
3GET
/api/v6/dex/aggregator/approve-transaction
dex-approve-transaction
4GET
/api/v6/dex/aggregator/quote
dex-get-quote
5GET
/api/v6/dex/aggregator/swap-instruction
dex-solana-swap-instruction
6GET
/api/v6/dex/aggregator/swap
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:
  • tokenContractAddress
    from step 1 →
    toTokenAddress
    in steps 3-4
  • SOL native address =
    "11111111111111111111111111111111"
    (Solana system program) →
    fromTokenAddress
    . Do NOT use
    So11111111111111111111111111111111111111112
    (wSOL) — see Native Token Addresses.
  • Amount
    1 SOL
    =
    "1000000000"
    (9 decimals) →
    amount
    param
  • balance
    from step 2 is UI units; swap needs minimal units → multiply by
    10^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) → swap

Swap 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 tx

Solana

1. GET /aggregator/quote               -> Get price and route
2. GET /aggregator/swap-instruction     -> Get serialized instruction
3. User signs & sends tx

Operation 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
    chainIndex
    -> ask which chain
  • Missing token addresses -> use
    okx-dex-token
    /market/token/search
    to resolve name → address
  • 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
    /quote
    , display estimated results
    • Expected output, gas estimate, price impact, routing path
    • Check
      isHoneyPot
      and
      taxRate
      — surface safety info to users
  • Confirmation phase: wait for user approval before proceeding
  • Approval phase (EVM only): check/execute approve if selling non-native token
  • Execution phase: call
    /swap
    (EVM) or
    /swap-instruction
    (Solana), return tx data for signing

Step 4: Suggest Next Steps

After displaying results, suggest 2-3 relevant follow-up actions based on the swap phase just completed:
Just completedSuggest
/aggregator/quote
(quote only, not yet confirmed)
1. Check wallet balance first →
okx-wallet-portfolio
2. View price chart before deciding →
okx-dex-market
3. Proceed with swap → continue approve + swap (this skill)
Swap executed successfully1. Verify updated balance →
okx-wallet-portfolio
2. Check price of the token just received →
okx-dex-market
3. Swap another token → new swap flow (this skill)
/aggregator/get-liquidity
1. Get a swap quote →
/aggregator/quote
(this skill)
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

ParamTypeRequiredDescription
chainIndex
StringNoFilter to a specific chain (e.g.,
"1"
)
Response:
FieldTypeDescription
data[].chainIndex
StringChain unique identifier (e.g., "1")
data[].chainName
StringChain name (e.g., "Ethereum")
data[].dexTokenApproveAddress
StringOKX DEX token approve contract address

2. GET /aggregator/get-liquidity

ParamTypeRequiredDescription
chainIndex
StringYesChain ID
Response:
FieldTypeDescription
data[].id
StringLiquidity pool ID
data[].name
StringPool name (e.g., "Uniswap V3")
data[].logo
StringPool logo URL

3. GET /aggregator/approve-transaction

ParamTypeRequiredDescription
chainIndex
StringYesChain ID
tokenContractAddress
StringYesToken to approve
approveAmount
StringYesAmount in minimal units
Response:
FieldTypeDescription
data[].data
StringApproval calldata (
approve(dexContractAddress, amount)
)
data[].dexContractAddress
StringDEX router address (the spender, already encoded in calldata). NOT the tx
to
— send tx to the token contract
data[].gasLimit
StringGas limit. May underestimate — use simulation or ×1.5
data[].gasPrice
StringGas price in wei

4. GET /aggregator/quote

ParamTypeRequiredDescription
chainIndex
StringYesChain ID
amount
StringYesAmount in minimal units (sell amount if exactIn, buy amount if exactOut)
swapMode
StringYes
exactIn
(default) or
exactOut
fromTokenAddress
StringYesToken to sell
toTokenAddress
StringYesToken to buy
Optional params:
dexIds
,
directRoute
,
priceImpactProtectionPercent
(default 90%),
feePercent
(max 10 Solana, 3 others).
Response key fields:
toTokenAmount
(output minimal units),
fromTokenAmount
,
estimateGasFee
,
tradeFee
(USD estimate),
priceImpactPercent
,
router
,
dexRouterList
,
fromToken
/
toToken
(each has
isHoneyPot
,
taxRate
,
decimal
,
tokenUnitPrice
). Full fields: see docs.

5. GET /aggregator/swap-instruction (Solana only)

ParamTypeRequiredDescription
chainIndex
StringYesMust be
"501"
(Solana)
amount
StringYesAmount in minimal units
fromTokenAddress
StringYesToken to sell
toTokenAddress
StringYesToken to buy
userWalletAddress
StringYesUser's wallet
slippagePercent
StringYes0 to <100
Optional params:
autoSlippage
,
computeUnitPrice
,
computeUnitLimit
,
dexIds
,
swapReceiverAddress
,
feePercent
,
priceImpactProtectionPercent
.
Response key fields:
instructionLists[]
(each has
data
,
accounts
,
programId
),
addressLookupTableAccount
,
routerResult
(same as /quote),
tx
(
minReceiveAmount
,
slippagePercent
),
wsolRentFee
. Full fields: see docs.

6. GET /aggregator/swap (EVM + Solana)

Note: This endpoint works for all chains including Solana.
/swap-instruction
is a Solana-specific alternative that returns deserialized instructions instead of a serialized transaction.
ParamTypeRequiredDescription
chainIndex
StringNoChain ID. Technically optional but strongly recommended — always pass it.
amount
StringYesAmount in minimal units
swapMode
StringYes
exactIn
(default) or
exactOut
fromTokenAddress
StringYesToken to sell
toTokenAddress
StringYesToken to buy
slippagePercent
StringYes0-100 (EVM), 0-<100 (Solana)
userWalletAddress
StringYesUser's wallet
Optional params:
gasLevel
(
average
/
fast
/
slow
),
computeUnitPrice
,
computeUnitLimit
,
tips
(Jito, 0.0000000001-2 SOL; use
0
if
computeUnitPrice
is set),
dexIds
,
autoSlippage
,
maxAutoSlippagePercent
,
swapReceiverAddress
,
feePercent
,
priceImpactProtectionPercent
(default 90%),
approveTransaction
(Boolean, combine approve+swap in one call),
approveAmount
(used with
approveTransaction
).
Response key fields:
routerResult
(same as /quote),
tx
from
,
to
,
data
(hex-encoded for EVM, base58-encoded for Solana),
gas
,
gasPrice
,
maxPriorityFeePerGas
(EIP-1559),
value
,
minReceiveAmount
,
maxSpendAmount
,
slippagePercent
,
signatureData
. Full fields: see docs.

Input / 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 broadcasts
User 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:
    isHoneyPot = true
    — block trade and warn user
  • Tax token:
    taxRate
    non-zero — display to user (e.g. 5% buy tax)
  • Insufficient balance: use
    okx-wallet-portfolio
    to check first, show current balance, suggest adjusting amount
  • exactOut not supported: only Ethereum/Base/BSC/Arbitrum — prompt user to use
    exactIn
  • Solana chain:
    /swap-instruction
    returns deserialized instructions (more control);
    /swap
    also works but returns a serialized transaction
  • Solana native SOL address: Must use
    11111111111111111111111111111111
    (system program), NOT
    So11111111111111111111111111111111111111112
    (wSOL). Using wSOL address causes
    custom program error: 0xb
    on-chain failures. See DEX Aggregation FAQ.
  • 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
  • minReceiveAmount
    in both UI units and USD
  • Price impact as percentage

Global Notes

  • All endpoints are GET — no POST in the aggregator family
  • Amounts must be in minimal units (wei/lamports)
  • exactOut
    only on Ethereum(
    1
    )/Base(
    8453
    )/BSC(
    56
    )/Arbitrum(
    42161
    )
  • /swap-instruction
    is Solana-only
  • Check
    isHoneyPot
    and
    taxRate
    — surface safety info to users
  • 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