输入/搜索内容
内置函数
结构体
内置变量与常量
通用约定
交易所
能力矩阵
中心化交易所
去中心化交易所
Hyperliquid
Lighter
edgeX
Aster
Aevo
Pendle
WOOFi Pro
Uniswap / PancakeSwap
Aerodrome / Velodrome
KyberSwap
1inch
EVM DEX通用指令
Jupiter
OKX DEX
DEX策略示例
预测市场
证券与期货
链上与自定义接入

通过OKX DEX聚合器接口在链上兑换代币,钱包由配置的助记词派生(EVM链、Tron、Solana、TON、Aptos、SUI、Starknet)。只支持同一条链上的市价兑换;行情、K线、成交、代币列表来自OKX DEX的行情接口。接口凭据默认使用平台内置的项目凭据,也可以用exchange.IO("config", ...)换成自己的OKX API凭据(在OKX开发者平台 https://web3.okx.com/onchainos/dev-portal 申请,各字段来源见该指令说明)。钱包每条链固定使用助记词的第一个账户(EVM链为m/44'/60'/0'/0/0),不支持选择账户序号或导入私钥。

名称与配置

exchange.GetName():OKX_DEX(现货);别名:OKX Web3、欧易DEX。

配置项必填说明
助记词是钱包助记词(BIP39,12或24个单词,不支持私钥),各链钱包地址由它派生,每条链只用第一个账户(派生路径见注意事项)。OKX API凭据不在这里填写,见exchange.IO("config", ...)。

交易对与合约代码

交易对示例:1:ETH_USD、501:SOL_USD、1:ETH_1:USDC

品种代码写作<链>:<代币>_USD(例如1:ETH_USD、501:SOL_USD),用于行情、K线、成交;下单(兑换)使用双边写法<链>:<代币>_<链>:<代币>,例如1:ETH_1:USDC,两边必须是同一条链。链可以写OKX的链号(chainIndex)或链名(ETH、SOL、TRX、APT、SUI、TON、STRK等,其它别名可用regChain注册)。

代币可以写代币名或合约地址(如1:0xa0b8..._USD)。代币名区分大小写(OKX把BAX与BAx当作两个代币)。同一条链上名字相同的多个合约(例如GALA的新旧合约)不出现在代币列表中,也不能按名字使用,需要写合约地址或用regToken把名字绑定到某个地址。

专属IO指令
指令参数说明返回值
configstring(JSON)设置OKX API凭据,字段ApiKey、SecretKey、Passphrase、Project缺一不可。(详见表下)成功返回true。
keystring运行时更换钱包助记词(12或24个单词),解析失败时保留原钱包。成功返回true。
address[chainIndex]获取钱包在某条链上的地址(链可写链号或链名),不传时为以太坊(1)。—
addresses—导出钱包在全部链上的地址。以链号为键、地址为值的对象。
slippage[number]无参数时读取,带参数时设置兑换滑点(百分比,大于0且不超过50,默认0.5)。读取时返回当前值(字符串,如"0.5"),设置成功返回true。
gasLevel[string]无参数时读取,带参数时设置Gas档位:average(默认)、fast、slow。读取时返回当前值,设置成功返回true。
gasMultiplier[number]无参数时读取,带参数时设置EVM交易gas上限的倍数(≥1,默认1.5)。读取时返回当前值,设置成功返回true。
allChainBalance[bool]无参数时读取,带参数时设置exchange.GetAssets()是否查询全部链的余额(默认只查以太坊),开启后exchange.GetAccount()的Equity也按全部链计。(详见表下)读取时返回当前值,设置成功返回true。
rpc[chain[, url]]查询或设置各链的自定义RPC地址,chain须写链号(如1、501),写链名不生效:无参数返回全部,只传链返回该链的地址(未设置时为空字符串),url为空字符串时删除。(详见表下)设置或删除成功返回true。
regChainchainId, alias注册链别名,之后可以在品种代码中用别名代替链号。别名不区分大小写,不能含_、:,最长20个字符。成功返回true。
regTokenchainId, alias, address把代币名绑定到某条链上的合约地址(chainId须写链号),绑定的名字优先于OKX代币表,按名字使用时不区分大小写;名字规则同regChain。成功返回true。
quotesymbol, amount只读报价预览(双边品种代码,例如1:USDC_1:ETH,两边须同链),amount是第一个代币(花费)的数量,滑点用slippage的设置;不构造链上交易。{toAmount, fromAmount, priceImpact, estimateGasFee, routerList, info}:toAmount、fromAmount为按精度换算后的代币数量(数字);priceImpact(价格影响,百分比)与estimateGasFee是OKX给的字符串;routerList为路由数组(每项有dexProtocol.dexName、dexProtocol.percent等);info是OKX报价接口原始数据的JSON字符串。
allowancesymbol[, spender]查询钱包对spender的ERC-20授权额度(品种代码第一个代币,也可以只写<链>:<代币>如1:USDC),不传spender时使用OKX DEX的授权合约。(详见表下)额度(最小单位的十进制字符串)。
approvesymbol[, amount]ERC-20授权(品种代码第一个代币,也可以只写<链>:<代币>;只支持EVM链),amount按代币数量计(自动按精度换算),不传时为最大额度;等待交易上链(最多60秒)。交易哈希。
signTxtx, chainIndex只签名不广播。(详见表下)签名后的交易(字符串)。
broadcastsignedTx, chainIndex广播已签名的交易。{txHash, orderId}
marketSupportedChains—只读查询行情接口支持的链。—
balanceSupportedChains—只读查询余额接口支持的链。—
swapSupportedChains—只读查询兑换接口支持的链。OKX接口的原始数组,每项有chainIndex、chainName、dexTokenApproveAddress(授权合约)。
broadcastSupportedChains—只读查询广播接口支持的链。—
tokenSearchchains, search按名称或地址搜索代币(chains为逗号分隔的链号),返回OKX接口的原始数据。数组,每项有chainIndex、tokenSymbol、tokenName、tokenContractAddress、decimal、price、liquidity等(都是字符串)。
allTokenschainIndex列出某条链上可兑换的全部代币,返回OKX接口的原始数据。数组,每项有tokenSymbol、tokenName、tokenContractAddress、decimals等。

表中长说明的其余部分:

  • config:不设置时使用平台内置的项目凭据(所有用户共用一份限频额度,查询频繁时容易遇到HTTP 429)。

凭据在OKX开发者平台申请:https://web3.okx.com/onchainos/dev-portal (旧地址/build/dev-portal已失效)。登录后先创建项目,再在项目下创建API Key:Project是项目的Project ID;ApiKey与SecretKey是创建API Key时生成的API Key和Secret Key(Secret Key只在创建时显示一次);Passphrase是创建API Key时自己设置的口令。这里的SecretKey是OKX API的密钥,与配置中填写的钱包助记词无关。

  • allChainBalance:全链查询按钱包地址分组(EVM链共用一个地址,每次最多50条链,其它链各查一次),相邻两次请求间隔1秒以免触发限频,因此一次查询要十几秒(exchange.GetAccount()另查估值,请求数翻倍);不要高频轮询。
  • rpc:EVM链查询授权额度(allowance与下单前的自动检查)必须配置RPC,OKX的nonce接口失败时也用它兜底;Solana、Tron、SUI、TON签名时查询链上状态,未配置时使用各链的公共节点。Unichain(130)已预置官方RPC。
  • allowance:只适用于EVM链,需要先用exchange.IO("rpc", 链号, url)配置该链的RPC;原生币没有授权,报错。
  • signTx:tx为交易JSON(字符串或对象),chainIndex可写链号或链名。EVM链的交易要有to、data、gas(或gasLimit),可选value、gasPrice、maxPriorityFeePerGas(与OKX兑换接口返回的tx相同):nonce自动查询,gas上限乘以gasMultiplier,没有gasPrice时经该链的RPC查询。

通用指令api、base、currency见exchange.IO。

常用用法
兑换前预览报价(只读,不发交易)
javascript
function main() { // 以太坊(链号1)上花100 USDC能换多少ETH var q = exchange.IO("quote", "1:USDC_1:ETH", 100) if (!q) { Log("报价失败:", GetLastError()) return } Log("花费:", q.fromAmount, "USDC", "得到:", q.toAmount, "ETH") Log("价格:", q.fromAmount / q.toAmount, "价格影响(%):", q.priceImpact, "预估gas:", q.estimateGasFee) for (var i = 0; i < q.routerList.length; i++) { var p = q.routerList[i].dexProtocol Log("路由:", p.dexName, p.percent + "%") } var info = JSON.parse(q.info) // OKX报价接口的原始数据 Log("交易费(美元):", info.tradeFee) }
配置RPC、检查授权额度后市价兑换,再查询兑换结果
javascript
function main() { // 查授权额度、下单前自动授权都要该链的RPC(第一个参数写链号) exchange.IO("rpc", 1, "https://ethereum-rpc.publicnode.com") exchange.IO("slippage", 1) // 滑点1% exchange.IO("gasLevel", "fast") var allowance = exchange.IO("allowance", "1:USDC") // 最小单位的十进制字符串 Log("USDC授权额度:", allowance) if (Number(allowance) < 20e6) { // USDC精度6位 // 只授权100 USDC(不传数量为无限额度),等交易上链后返回交易哈希 Log("授权交易:", exchange.IO("approve", "1:USDC", 100)) } // 买入时数量是花费的第二个代币:花20 USDC买ETH var id = exchange.CreateOrder("1:ETH_1:USDC", "buy", -1, 20) if (!id) { Log("兑换失败:", GetLastError()) return } for (var i = 0; i < 20; i++) { var o = exchange.GetOrder(id) if (o && o.Status != ORDER_STATE_PENDING) { Log("状态:", o.Status, "买到ETH:", o.DealAmount, "均价:", o.AvgPrice) break } Sleep(3000) } }
搜索代币,把名字绑定到合约地址,并注册链别名
javascript
function main() { // 在Base(链号8453)上搜索USDC,返回OKX接口的原始数据 var rows = exchange.IO("tokenSearch", "8453", "USDC") if (!rows || rows.length == 0) { Log("没有搜到:", GetLastError()) return } for (var i = 0; i < rows.length; i++) { var r = rows[i] Log(r.chainIndex, r.tokenSymbol, r.tokenName, r.tokenContractAddress) } var all = exchange.IO("allTokens", "8453") // Base上可兑换的全部代币 Log("可兑换代币数:", all.length, "第一个:", all[0].tokenSymbol) // 链别名:之后可以写MYBASE:USDC_USD(别名不区分大小写) exchange.IO("regChain", 8453, "mybase") // 把名字USDC绑定到搜到的第一个合约,优先于OKX代币表 exchange.IO("regToken", 8453, "USDC", rows[0].tokenContractAddress) var q = exchange.IO("quote", "MYBASE:USDC_MYBASE:ETH", 10) Log("10 USDC可换ETH:", q ? q.toAmount : GetLastError()) }
查看钱包在各链的地址、各接口支持的链与全链余额
javascript
function main() { Log("以太坊地址:", exchange.IO("address"), "Solana地址:", exchange.IO("address", "SOL")) var addrs = exchange.IO("addresses") // {链号: 地址} Log("Base地址:", addrs["8453"], "Tron地址:", addrs["195"]) var chains = exchange.IO("swapSupportedChains") for (var i = 0; i < chains.length; i++) { Log("可兑换:", chains[i].chainIndex, chains[i].chainName) } Log("行情接口支持", exchange.IO("marketSupportedChains").length, "条链,", "余额接口", exchange.IO("balanceSupportedChains").length, "条,", "广播接口", exchange.IO("broadcastSupportedChains").length, "条") // GetAssets默认只查以太坊;改为查全部链(一次十几秒,不要高频轮询) exchange.IO("allChainBalance", true) var assets = exchange.GetAssets() for (var j = 0; assets && j < assets.length; j++) { Log(assets[j].Currency, assets[j].Amount) } }
用OKX兑换接口取交易数据,自己签名后广播
javascript
function main() { var chain = "1" var wallet = exchange.IO("address", chain) // 花1 USDC换ETH的交易数据(数量写最小单位);花ERC-20前要先授权,见上面的示例 var r = exchange.IO("api", "GET", "/api/v6/dex/aggregator/swap", { chainIndex: chain, amount: "1000000", fromTokenAddress: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", toTokenAddress: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", slippagePercent: "0.5", userWalletAddress: wallet }) if (!r || r.code != "0") { Log("取交易失败:", r ? r.msg : GetLastError()) return } // tx有to、data、value、gas、gasPrice等;签名时自动取nonce,gas上限乘以gasMultiplier var signed = exchange.IO("signTx", r.data[0].tx, chain) if (!signed) { Log("签名失败:", GetLastError()) return } var res = exchange.IO("broadcast", signed, chain) Log("交易哈希:", res.txHash, "OKX订单号:", res.orderId) }

函数支持差异

不支持(调用时报错并返回空值):exchange.GetDepth、exchange.GetOrders、exchange.GetHistoryOrders、exchange.CancelOrder、exchange.ModifyOrder、exchange.CreateConditionOrder、exchange.ModifyConditionOrder、exchange.CancelConditionOrder、exchange.GetConditionOrder、exchange.GetConditionOrders、exchange.GetHistoryConditionOrders。

以回退方式支持:

  • exchange.GetRecords:原生周期为1分钟、3分钟、5分钟、15分钟、30分钟、1小时、2小时、4小时、6小时、12小时、1天、3天、1周、1月、3月;其它周期由托管者合成。

注意事项
  • 只支持市价单(price为-1),限价单报错;不支持跨链兑换。卖出时amount是品种代码第一个代币的数量,买入时是第二个代币(花费)的数量。订单ID为<品种代码>,<交易哈希>,用exchange.GetOrder()查询兑换结果。
  • 下单附加参数原样传给OKX DEX的兑换接口(例如slippagePercent覆盖本单滑点);Solana上的兑换不带gasLevel,改为自动设置computeUnitPrice、computeUnitLimit,也可以在附加参数中指定。
  • EVM链上花费ERC-20代币(非原生币)的兑换,下单前自动检查授权额度,不足时先发送无限额度的授权交易并等待上链;检查额度需要该链的RPC,没有用exchange.IO("rpc", 链号, url)配置时下单报错。
  • exchange.GetOrder()按交易哈希查询OKX的兑换记录,数量按订单ID中品种代码的第一个代币(基础币)统一口径,买卖一致:换到基础币的是买单、花出基础币的是卖单(Type);Amount是花出的代币数量(买单是花费的计价币,同下单时的amount);DealAmount是成交的基础币数量(买单为买到的、卖单为卖出的);AvgPrice是计价币÷基础币。DealAmount与AvgPrice只在兑换成功后给出,失败或未完成时为0;交易尚未被索引时状态为未完成。
  • Solana上OKX的兑换记录不给到账代币的数量,exchange.GetOrder()改从链上交易读取(钱包在这笔交易前后的余额差,节点为exchange.IO("rpc", "501", url)设置的,缺省公共主网节点);节点还没索引到这笔交易时按挂单中报,下次轮询再取。
  • 请求OKX接口遇到限频(HTTP 429,错误码50011)时自动等待1、2、4秒重试,最多3次,仍失败才报错。
  • 链上没有订单簿和挂单:exchange.GetDepth()、exchange.GetOrders()、exchange.CancelOrder()等函数报错并返回空值。
  • exchange.GetTickers()返回以太坊(链号1)上24小时成交量排行榜中的代币,不是全部代币;exchange.GetMarkets()列出以太坊上可兑换的代币(同一条链上重名的代币不列出)。
  • exchange.GetAssets()默认只查询以太坊上的余额,资产名写作链名:代币名(OKX没有给出代币名的资产用合约地址代替代币名);用exchange.IO("allChainBalance", true)查询全部链。exchange.GetAccount()查询当前交易对两边代币所在的链,按链号和合约地址取Stocks(左边代币)与Balance(右边代币,计价为USD时为0),交易对写链号、链名或合约地址都可以。
  • 钱包只能用助记词派生,每条链固定使用第一个账户,不支持选择账户序号或导入私钥。EVM链(以太坊、BSC、Base、Arbitrum等共用一个地址)为m/44'/60'/0'/0/0,即MetaMask等钱包中该助记词的第1个账户,第2个及以后的账户无法使用。其它链:ETC m/44'/61'/0'/0/0;Tron m/44'/195'/0'/0/0;Bitcoin m/86'/0'/0'/0/0(Taproot地址bc1p…);Litecoin m/49'/2'/0'/0/0(P2SH-SegWit);Dogecoin m/44'/3'/0'/0/0、Dash m/44'/5'/0'/0/0、Bitcoin Cash m/44'/145'/0'/0/0;Osmosis m/44'/118'/0'/0/0;Stacks m/44'/5757'/0'/0/0;Solana m/44'/501'/0'/0';Aptos m/44'/637'/0'/0'/0';SUI m/44'/784'/0'/0'/0';TON m/44'/607'/0'(W5R1钱包合约地址);Starknet以EVM私钥为种子再按m/44'/9004'/0'/0/0派生。可以用exchange.IO("address", 链)核对地址。