okx-dex

v1.0.0

OKX DEX aggregator (v6). Get swap quotes, swap/approve tx data, tokens, and chains.

2· 1.9k·5 current·5 all-time

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for ricky321u/okx-dex.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "okx-dex" (ricky321u/okx-dex) from ClawHub.
Skill page: https://clawhub.ai/ricky321u/okx-dex
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Required binaries: curl, jq, python3
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install okx-dex

ClawHub CLI

Package manager switcher

npx clawhub@latest install okx-dex
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
The SKILL.md and scripts clearly implement an OKX DEX aggregator (requests to https://web3.okx.com, HMAC signing, swap/quote/approve endpoints), which is consistent with the declared purpose. However the registry metadata claims no required environment variables or primary credential while the runtime instructions require OKX API credentials — an inconsistency between declared metadata and actual capability.
!
Instruction Scope
The runtime instructions and provided test script confine network access to the OKX API base URL and only use curl/jq/python3, which is appropriate for the stated purpose. However there are multiple inconsistencies/bugs in the instructions: several Python signing snippets reference a different env var name (SECRET_KEY) than the documented OKX_SECRET_KEY, and some f-string usages rely on shell expansion in a way that is brittle. These mismatches could cause accidental misuse of the wrong environment variable or failed requests.
Install Mechanism
This is an instruction-only skill (no install spec that downloads/executes remote code). The only required binaries are curl, jq, and python3 — reasonable for the provided shell + python examples and lower risk than arbitrary downloads.
!
Credentials
The skill legitimately needs OKX_API_KEY, OKX_SECRET_KEY (secret), and OKX_PASSPHRASE to sign API calls, which is proportionate for a DEX aggregator. The problem: the registry metadata lists no required env vars / no primary credential, so the manifest underreports sensitive requirements. Also some code snippets refer to SECRET_KEY instead of OKX_SECRET_KEY, increasing the chance of misconfiguration or accidental use of a differently named secret.
!
Persistence & Privilege
The skill is flagged always: true which forces it to be included in every agent run. A DEX aggregator does not normally require permanent inclusion; 'always' increases the blast radius if the skill or its environment has issues. Autonomous invocation (disable-model-invocation: false) is the platform default and not itself flagged, but combined with always:true and the requirement for API secrets it raises additional risk.
What to consider before installing
This skill appears to implement a genuine OKX DEX API client, but there are important red flags you should address before installing: (1) The repository/registry metadata does NOT declare the three required secrets although SKILL.md and scripts do — verify the publisher and the provenance. (2) The SKILL.md contains inconsistent variable names (SECRET_KEY vs OKX_SECRET_KEY) and brittle signing snippets; test in a safe environment first. (3) The skill is configured 'always: true' which forces it into every agent session — remove or question this unless you need it always available. If you proceed, only provide API keys with minimal permissions, consider creating a dedicated OKX key you can revoke, and monitor/rotate keys after initial use. If the publisher cannot explain the metadata mismatches and justify always:true, treat the package as untrusted.

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

🧭 Clawdis
Binscurl, jq, python3
latestvk97byr9vf3xckdk2wqbqg7kyyh80kcy8
1.9kdownloads
2stars
1versions
Updated 1mo ago
v1.0.0
MIT-0

OKX DEX Aggregator 🧭

OKX Wallet DEX API provides aggregated swap quotes and transaction data across multiple chains (EVM + non‑EVM).

Environment Variables

VariableDescriptionRequired
OKX_API_KEYOKX API keyYes
OKX_SECRET_KEYOKX API secretYes
OKX_PASSPHRASEOKX API passphraseYes

API Base URL

https://web3.okx.com

Authentication (Required Headers)

All requests must include the following headers:

  • OK-ACCESS-KEY
  • OK-ACCESS-TIMESTAMP (UTC ISO time)
  • OK-ACCESS-PASSPHRASE
  • OK-ACCESS-SIGN (Base64(HMAC_SHA256(prehash, secret)))

Prehash string:

TIMESTAMP + METHOD + REQUEST_PATH_WITH_QUERY + BODY
  • For GET requests, BODY is empty and REQUEST_PATH_WITH_QUERY must include the query string.
  • For POST requests, BODY is the raw JSON string.

Get Supported Chains (Aggregator)

API_KEY="${OKX_API_KEY}"
SECRET_KEY="${OKX_SECRET_KEY}"
PASSPHRASE="${OKX_PASSPHRASE}"

TIMESTAMP=$(python3 - <<'PY'
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z'))
PY
)

METHOD="GET"
REQUEST_PATH="/api/v6/dex/aggregator/supported/chain"
QUERY="chainIndex=1"
PATH_WITH_QUERY="${REQUEST_PATH}?${QUERY}"

SIGN=$(python3 - <<PY
import hmac, hashlib, base64
import os
msg = f"${TIMESTAMP}${METHOD}${PATH_WITH_QUERY}"
secret = os.environ["SECRET_KEY"].encode()
print(base64.b64encode(hmac.new(secret, msg.encode(), hashlib.sha256).digest()).decode())
PY
)

curl -s "https://web3.okx.com${PATH_WITH_QUERY}" \
  -H "OK-ACCESS-KEY: ${API_KEY}" \
  -H "OK-ACCESS-TIMESTAMP: ${TIMESTAMP}" \
  -H "OK-ACCESS-PASSPHRASE: ${PASSPHRASE}" \
  -H "OK-ACCESS-SIGN: ${SIGN}" | jq '.'

Get Tokens

API_KEY="${OKX_API_KEY}"
SECRET_KEY="${OKX_SECRET_KEY}"
PASSPHRASE="${OKX_PASSPHRASE}"
CHAIN_INDEX="1"  # Ethereum

TIMESTAMP=$(python3 - <<'PY'
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z'))
PY
)

METHOD="GET"
REQUEST_PATH="/api/v6/dex/aggregator/all-tokens"
QUERY="chainIndex=${CHAIN_INDEX}"
PATH_WITH_QUERY="${REQUEST_PATH}?${QUERY}"

SIGN=$(python3 - <<PY
import hmac, hashlib, base64
import os
msg = f"${TIMESTAMP}${METHOD}${PATH_WITH_QUERY}"
secret = os.environ["SECRET_KEY"].encode()
print(base64.b64encode(hmac.new(secret, msg.encode(), hashlib.sha256).digest()).decode())
PY
)

curl -s "https://web3.okx.com${PATH_WITH_QUERY}" \
  -H "OK-ACCESS-KEY: ${API_KEY}" \
  -H "OK-ACCESS-TIMESTAMP: ${TIMESTAMP}" \
  -H "OK-ACCESS-PASSPHRASE: ${PASSPHRASE}" \
  -H "OK-ACCESS-SIGN: ${SIGN}" | jq '.data[:5]'

Get Swap Quote (Quote Only)

API_KEY="${OKX_API_KEY}"
SECRET_KEY="${OKX_SECRET_KEY}"
PASSPHRASE="${OKX_PASSPHRASE}"

CHAIN_INDEX="1"  # Ethereum
FROM_TOKEN="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"  # ETH (native)
TO_TOKEN="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"    # USDC
AMOUNT="1000000000000000000"  # 1 ETH in wei

TIMESTAMP=$(python3 - <<'PY'
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z'))
PY
)

METHOD="GET"
REQUEST_PATH="/api/v6/dex/aggregator/quote"
QUERY="chainIndex=${CHAIN_INDEX}&fromTokenAddress=${FROM_TOKEN}&toTokenAddress=${TO_TOKEN}&amount=${AMOUNT}&swapMode=exactIn"
PATH_WITH_QUERY="${REQUEST_PATH}?${QUERY}"

SIGN=$(python3 - <<PY
import hmac, hashlib, base64
import os
msg = f"${TIMESTAMP}${METHOD}${PATH_WITH_QUERY}"
secret = os.environ["SECRET_KEY"].encode()
print(base64.b64encode(hmac.new(secret, msg.encode(), hashlib.sha256).digest()).decode())
PY
)

curl -s "https://web3.okx.com${PATH_WITH_QUERY}" \
  -H "OK-ACCESS-KEY: ${API_KEY}" \
  -H "OK-ACCESS-TIMESTAMP: ${TIMESTAMP}" \
  -H "OK-ACCESS-PASSPHRASE: ${PASSPHRASE}" \
  -H "OK-ACCESS-SIGN: ${SIGN}" | jq '{
    fromTokenAmount: .data[0].fromTokenAmount,
    toTokenAmount: .data[0].toTokenAmount,
    tradeFee: .data[0].tradeFee,
    router: .data[0].router
  }'

Get Swap Transaction (Router Call Data)

Note: slippagePercent is required by the swap endpoint and is expressed as a decimal percentage (e.g., 0.01 = 1%).

API_KEY="${OKX_API_KEY}"
SECRET_KEY="${OKX_SECRET_KEY}"
PASSPHRASE="${OKX_PASSPHRASE}"

CHAIN_INDEX="1"  # Ethereum
FROM_TOKEN="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
TO_TOKEN="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
AMOUNT="1000000000000000000"  # 1 ETH in wei
slippagePercent="0.01"  # 1%
WALLET="<YOUR_WALLET_ADDRESS>"

TIMESTAMP=$(python3 - <<'PY'
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z'))
PY
)

METHOD="GET"
REQUEST_PATH="/api/v6/dex/aggregator/swap"
QUERY="chainIndex=${CHAIN_INDEX}&fromTokenAddress=${FROM_TOKEN}&toTokenAddress=${TO_TOKEN}&amount=${AMOUNT}&swapMode=exactIn&slippagePercent=${slippagePercent}&userWalletAddress=${WALLET}"
PATH_WITH_QUERY="${REQUEST_PATH}?${QUERY}"

SIGN=$(python3 - <<PY
import hmac, hashlib, base64
import os
msg = f"${TIMESTAMP}${METHOD}${PATH_WITH_QUERY}"
secret = os.environ["SECRET_KEY"].encode()
print(base64.b64encode(hmac.new(secret, msg.encode(), hashlib.sha256).digest()).decode())
PY
)

curl -s "https://web3.okx.com${PATH_WITH_QUERY}" \
  -H "OK-ACCESS-KEY: ${API_KEY}" \
  -H "OK-ACCESS-TIMESTAMP: ${TIMESTAMP}" \
  -H "OK-ACCESS-PASSPHRASE: ${PASSPHRASE}" \
  -H "OK-ACCESS-SIGN: ${SIGN}" | jq '{
    tx: .data[0].tx,
    router: .data[0].routerResult.router,
    priceImpactPercent: .data[0].routerResult.priceImpactPercent,
    dexRouterList: (.data[0].routerResult.dexRouterList // [])
  }'

Get Approval Transaction (EVM)

Note: Some responses may omit to/value. If to is null, use the chain's dexTokenApproveAddress from the Supported Chains response as the target.

API_KEY="${OKX_API_KEY}"
SECRET_KEY="${OKX_SECRET_KEY}"
PASSPHRASE="${OKX_PASSPHRASE}"

CHAIN_INDEX="1"  # Ethereum
TOKEN_ADDRESS="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"  # USDC
AMOUNT="1000000000"  # 1,000,000 USDC (6 decimals)

TIMESTAMP=$(python3 - <<'PY'
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z'))
PY
)

METHOD="GET"
REQUEST_PATH="/api/v6/dex/aggregator/approve-transaction"
QUERY="chainIndex=${CHAIN_INDEX}&tokenContractAddress=${TOKEN_ADDRESS}&approveAmount=${AMOUNT}"
PATH_WITH_QUERY="${REQUEST_PATH}?${QUERY}"

SIGN=$(python3 - <<PY
import hmac, hashlib, base64
import os
msg = f"${TIMESTAMP}${METHOD}${PATH_WITH_QUERY}"
secret = os.environ["SECRET_KEY"].encode()
print(base64.b64encode(hmac.new(secret, msg.encode(), hashlib.sha256).digest()).decode())
PY
)

curl -s "https://web3.okx.com${PATH_WITH_QUERY}" \
  -H "OK-ACCESS-KEY: ${API_KEY}" \
  -H "OK-ACCESS-TIMESTAMP: ${TIMESTAMP}" \
  -H "OK-ACCESS-PASSPHRASE: ${PASSPHRASE}" \
  -H "OK-ACCESS-SIGN: ${SIGN}" | jq '{
    data: .data[0].data,
    dexContractAddress: .data[0].dexContractAddress,
    gasLimit: .data[0].gasLimit,
    gasPrice: .data[0].gasPrice
  }'

Get Approval Transaction (EVM) with to from Supported Chains

API_KEY="${OKX_API_KEY}"
PASSPHRASE="${OKX_PASSPHRASE}"

CHAIN_INDEX="1"  # Ethereum
TOKEN_ADDRESS="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"  # USDC
AMOUNT="1000000000"  # 1,000,000 USDC (6 decimals)

TIMESTAMP=$(python3 - <<'PY'
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z'))
PY
)

METHOD="GET"
REQUEST_PATH="/api/v6/dex/aggregator/supported/chain"
QUERY="chainIndex=${CHAIN_INDEX}"
PATH_WITH_QUERY="${REQUEST_PATH}?${QUERY}"

SIGN=$(python3 - <<PY
import hmac, hashlib, base64
import os
msg = f"${TIMESTAMP}${METHOD}${PATH_WITH_QUERY}"
secret = os.environ["OKX_SECRET_KEY"].encode()
print(base64.b64encode(hmac.new(secret, msg.encode(), hashlib.sha256).digest()).decode())
PY
)

APPROVE_TO=$(curl -s "https://web3.okx.com${PATH_WITH_QUERY}" \
  -H "OK-ACCESS-KEY: ${API_KEY}" \
  -H "OK-ACCESS-TIMESTAMP: ${TIMESTAMP}" \
  -H "OK-ACCESS-PASSPHRASE: ${PASSPHRASE}" \
  -H "OK-ACCESS-SIGN: ${SIGN}" | jq -r '.data[0].dexTokenApproveAddress')

TIMESTAMP=$(python3 - <<'PY'
from datetime import datetime, timezone
print(datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z'))
PY
)

METHOD="GET"
REQUEST_PATH="/api/v6/dex/aggregator/approve-transaction"
QUERY="chainIndex=${CHAIN_INDEX}&tokenContractAddress=${TOKEN_ADDRESS}&approveAmount=${AMOUNT}"
PATH_WITH_QUERY="${REQUEST_PATH}?${QUERY}"

SIGN=$(python3 - <<PY
import hmac, hashlib, base64
import os
msg = f"${TIMESTAMP}${METHOD}${PATH_WITH_QUERY}"
secret = os.environ["OKX_SECRET_KEY"].encode()
print(base64.b64encode(hmac.new(secret, msg.encode(), hashlib.sha256).digest()).decode())
PY
)

curl -s "https://web3.okx.com${PATH_WITH_QUERY}" \
  -H "OK-ACCESS-KEY: ${API_KEY}" \
  -H "OK-ACCESS-TIMESTAMP: ${TIMESTAMP}" \
  -H "OK-ACCESS-PASSPHRASE: ${PASSPHRASE}" \
  -H "OK-ACCESS-SIGN: ${SIGN}" | jq --arg to "${APPROVE_TO}" '{
    data: .data[0].data,
    dexContractAddress: (.data[0].dexContractAddress // $to),
    gasLimit: .data[0].gasLimit,
    gasPrice: .data[0].gasPrice
  }'

Safety Rules

  1. ALWAYS display swap details before execution.
  2. WARN if price impact is high or priceImpactProtectionPercent is exceeded.
  3. CHECK token allowance (EVM) before swap execution.
  4. VERIFY slippage settings (slippagePercent).
  5. For approve responses, if to is null, use dexTokenApproveAddress for the chain.
  6. NEVER execute without explicit user confirmation.

Links

Comments

Loading comments...