输入/搜索内容
内置函数
结构体
内置变量与常量
通用约定
交易所

连接Solana链上的Jupiter聚合器,把兑换映射为现货交易函数。一个交易所对象对应一个Solana钱包:报价和兑换交易由Jupiter Swap API生成(它在Solana上的众多DEX和做市商之间拆单选路),托管者用配置的私钥签名后经Solana节点广播。不填Jupiter API Key时使用免费的lite-api.jup.ag,填写后使用api.jup.ag;注意:填写API Key后,计价币为USDC、USDT的原生限价单与定投默认改用Jupiter Trigger V2,资金要存入Jupiter托管的vault(不再留在链上自己的订单账户);要保持非托管的v1,在策略开头调用exchange.IO("trigger.api", "v1")。见下文「限价单」「定投」。

同一个交易所对象还提供Meteora DLMM、Raydium CLMM与Orca Whirlpools池子的集中流动性(exchange.IO("lp.*", ...),见下文「集中流动性」):交易由连接器自己构造、签名并经Solana节点广播,指令与返回字段对齐Uniswap交易所对象的LP指令。

pump.fun打新(exchange.IO("pump.*", ...),见下文「Pump.fun打新」):在链上发现刚创建的币,直接在pump.fun的联合曲线上报价、买卖(连接器自己构造、模拟、签名交易),币毕业迁到PumpSwap后自动改走Jupiter兑换。新币风险极高,见该节的风险说明。

名称与配置

exchange.GetName():Jupiter(现货)。

配置项必填默认值说明
钱包私钥是—Solana钱包私钥:Phantom、Solflare导出的base58字符串,或solana-keygen生成的JSON字节数组。
节点地址否https://api.mainnet-beta.solana.com,https://solana-rpc.publicnode.comSolana RPC节点,多个用逗号分隔,某个节点出错时自动换下一个。默认为官方公共节点和publicnode。
Jupiter API Key否—可选。(详见表下)
流动性来源否—可选。(详见表下)

表中长说明的其余部分:

  • Jupiter API Key:不填时使用免费的lite-api.jup.ag;填写后使用api.jup.ag,请求速率可按套餐提高(见exchange.IO("rps", ...)),并且计价币为USDC、USDT的原生限价单与定投默认改用Jupiter Trigger V2(资金存入Jupiter托管的vault,见「限价单」「定投」;要保持非托管的v1,调用exchange.IO("trigger.api", "v1"))。API Key在Jupiter开发者平台申请;设置了接口权限的Key要包含Trigger。
  • 流动性来源:只经过这些流动性来源兑换,例如pump(pump.fun的bonding curve与PumpSwap)、meteora、raydium、orca,或Jupiter的来源名;不填表示全部来源。运行中可用exchange.IO("dexes", ...)修改。

交易对与合约代码

交易对示例:SOL_USDC、JUP_USDC、BONK_SOL

SOL为原生币,兑换时自动包装、解包。内置代币:SOL、USDC、USDT、JUP、BONK、WIF、JTO、PYTH、RAY、JitoSOL、mSOL、JupSOL、TRUMP、PENGU、POPCAT。其它代币有三种写法:直接写代币名,按Jupiter代币列表中经过认证、名称完全一致的代币识别(同名的多个认证代币时报错);直接写mint地址;或者先用exchange.IO("token", ...)登记。交易对不转大写(mint地址与mSOL这类币名区分大小写),按原样书写,例如DB5QKorV9KHY54y73h5xWQqYyuD8P3jC1p5Ea8DBpump_SOL。

专属IO指令
指令参数说明返回值
routesymbol, side, qty只询价不下单,口径与下单相同:卖出(sell)按精确输入询价卖出qty个基础币;买入(buy)按精确输出询价买到qty个基础币,没有精确输出路由时(Meteora、PumpSwap等来源不支持精确输出)改按精确输入估价,与限价买单的退路相同(市价买单本身也是精确输入)。见子页exchange.IO("route", ...)。{symbol, side, qty, route, quote, price, priceImpactPct, swapMode, baseQty}:swapMode为ExactIn或ExactOut;baseQty为这个报价实际买入或卖出的基础币数量(买入按精确输入估价时可能与qty略有差异),price为quote除以baseQty。(详见表下)
token[name, mint]登记代币(只在本次运行中有效),登记后的代币名可以直接写在交易对里;不传参数时列出代币表。见子页exchange.IO("token", ...)。登记时返回{symbol, mint, decimals},列表时返回{symbol, mint, decimals, native}数组。
transferto, amount从钱包转出SOL;amount可传all转出全部余额(扣除手续费)。只支持SOL,第三个参数传其它代币会报错。只等广播,不等上链。见子页exchange.IO("transfer", ...)。{signature, amount, lastValidBlockHeight}
receiptsignature[, waitMs]查询一笔Solana交易的状态,可等待到确认或失败(最多10分钟)。查询订单时传订单ID中逗号后面的交易签名。见子页exchange.IO("receipt", ...)。{signature, state, slot, confirmationStatus, err, fee, blockTime},state为success、failed或pending;fee、blockTime只在确认或失败后才有。(详见表下)
dca.createparams创建定投。见子页exchange.IO("dca.*", ...)。{id, version, signature, symbol, side, total, perOrder, numberOfOrders, interval, minPrice, maxPrice, startAt, priorityFeeLamports}:version为v1或v2;v1的id为定投订单账户地址,V2的id为Jupiter的订单UUID,signature为存入交易,另有vault。
dca.list[params]列出钱包的定投(v1在前;配置了API Key或trigger.api为v2时再列V2):params.status为active(缺省,进行中)或history(已结束),params.symbol只列这个交易对。见子页exchange.IO("dca.*", ...)。[{id, version, symbol, side, state, total, perOrder, numberOfOrders, ordersFilled, interval, minPrice, maxPrice, spent, received, filledQty, avgPrice, fee, createdAt, updatedAt, openTx, closeTx, info}]:state为active、completed或canceled,V2另有pending(存入中)、canceling(已撤销、未取回)、failed(存入失败),V2行另有nextFillAt,fee为null(手续费已含在换到的币里);spent为已花出的输入币,received为已换到的输出币(fee为其中被扣的手续费,输出币计),filledQty、avgPrice为按基础币折算的成交量与均价;info为Jupiter的原始行。(详见表下)
dca.cancelid撤销一笔进行中的定投,剩余的输入币退回钱包,按id的形状分v1、V2(V2的定投号是UUID,要配置API Key)。见子页exchange.IO("dca.*", ...)。v1:{id, version, signature, priorityFeeLamports[, indexed]};V2:{id, version, signature, refund, refundCurrency, roundsRemaining, info},signature为取回交易,refund为退回的输入币数量。
dca.simulateparams[, wallet]按dca.create的参数生成交易,用节点的simulateTransaction执行(不签名、不广播),用来在下单前检查余额、最低金额等;params写成{cancel: id}时模拟撤销这笔定投。见子页exchange.IO("dca.*", ...)。{ok, err, reason, logs, unitsConsumed, version, wallet, id, plan, priorityFeeLamports}(version为v1或v2;V2另有vault,没有id):ok为模拟是否成功,失败时reason为原因(付款钱包一个SOL都没有时节点只回err为AccountNotFound,reason注明the paying wallet has no SOL);id为将要新建的定投账户地址;plan为换算后的定投参数。
trigger.simulateparams[, wallet]生成Jupiter限价单的挂单交易并用节点的simulateTransaction执行(不签名、不广播):params为{symbol, side, price, amount, expiry, slippage},含义同下单(amount为基础币数量,expiry、slippage同下单附加参数);写成{cancel: orderId}时模拟撤销这张限价单。见子页exchange.IO("trigger.*", ...)。v1:{ok, err, reason, logs, unitsConsumed, wallet, order, makingAmount, takingAmount, priorityFeeLamports},order为订单账户地址,makingAmount、takingAmount为付出、换回的最小单位数量;V2:{ok, err, reason, logs, unitsConsumed, version, wallet, vault, inputMint, inputAmount, triggerPriceUsd, triggerCondition, expiresAt, priorityFeeLamports}。(详见表下)
trigger.api[mode]新挂的原生限价单(tif为gtc)与新建的定投用哪套接口:auto(缺省)为配置了API Key且计价币为USDC或USDT时用Trigger V2(托管vault),否则用v1;v1为一律用v1(非托管,资金在链上订单账户),配置了API Key也一样;v2为一律用V2,计价币不是USDC、USDT时下单报错,没有配置API Key也照用(Jupiter目前放行不带Key的V2调用,但官方文档写的是必须带Key,随时可能收紧)。见子页exchange.IO("trigger.*", ...)。当前模式:auto、v1或v2。
trigger.vault[action]查询本钱包在Jupiter Trigger V2的托管vault及其中的余额(需要配置API Key,或exchange.IO("trigger.api", "v2"))。见子页exchange.IO("trigger.*", ...)。还没有vault时为{wallet, registered: false};否则为{wallet, registered: true, vault, sol, tokens, info},tokens为[{mint, symbol, amount, raw}](symbol只对代币表中的币给出),info为Jupiter返回的vault信息。
slippage[ratio]市价单的滑点保护比例,范围[0, 0.5),默认0.005(0.5%),由链上程序强制执行。限价单不使用这个设置。不传参数时查询。见子页exchange.IO("slippage", ...)。当前滑点比例。
priorityFee[sol]每笔兑换交易的优先费上限(SOL),范围0到0.1,默认0.001;实际优先费由Jupiter按网络拥堵情况估算,不超过上限。不传参数时查询。见子页exchange.IO("priorityFee", ...)。当前上限(SOL)。
dexes[sources]限定兑换经过的流动性来源(逗号分隔):分组简写pump、meteora、raydium、orca,或Jupiter的来源名(区分大小写);""表示不限定。行情、询价和下单都只经过这些来源。不传参数时查询。见子页exchange.IO("dexes", ...)。当前限定的来源名数组(分组已展开;空数组表示不限定)。
rps[n]请求Jupiter API的每秒最多请求数,范围0.1到500,默认1。请求依次排队,相邻两次至少间隔1/n秒。不传参数时查询。见子页exchange.IO("rps", ...)。当前每秒最多请求数。
base[url]不传参数时返回当前Solana节点地址;传入地址时切换节点(多个用逗号分隔)。切换前的地址。
address—钱包地址(base58)。—
pump.new[options]最近在pump.fun上新建的币,从链上发现:查pump.fun mint authority(TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM,只出现在创建交易里)的最近签名,逐笔取交易解析其中的CreateEvent,新的在前。见子页exchange.IO("pump.*", ...)。[{signature, slot, time, mint, name, symbol, uri, creator, user, bondingCurve, tokenProgram, quote, quoteMint, mayhem, cashback, holderReward, devBuy}]:time为区块时间(毫秒);user为发起创建的钱包(一般就是creator);tokenProgram为spl-token或token-2022;quote为SOL、USDC或报价代币的mint(只有SOL的币能用pump.buy、pump.sell);devBuy为同一笔交易里的首买{tokens, quoteAmount}(quoteAmount含费,报价币不是SOL或USDC时为null),没有首买为null。(详见表下)
pump.infomint币的联合曲线(bonding curve)状态,一次getMultipleAccounts读曲线、mint、全局配置与费率表。不是pump.fun的币时报错。见子页exchange.IO("pump.*", ...)。{mint, bondingCurve, creator, tokenProgram, decimals, quote, quoteMint, complete, migrated, virtualTokenReserves, virtualQuoteReserves, realTokenReserves, realQuoteReserves, tokenTotalSupply, price, marketCap, progress, fees, mayhem, cashback, holderReward}:储备与供应量为可读单位;price为1个币值多少报价币(SOL),marketCap为price乘总供应量;progress为曲线已卖出的比例(%),到100时曲线完成(complete),随后迁移到PumpSwap(migrated,储备清零,price、marketCap、fees为null);fees为当前费率{protocolBps, creatorBps}(万分之几)。
pump.quotemint, side, amount在联合曲线上本地报价(不发交易),公式与费用同链上程序:buy时amount为要花的SOL(含费),sell时为要卖的币数。见子页exchange.IO("pump.*", ...)。{venue, mint, side, quote, amountIn, amountOut, price, spotPrice, priceAfter, priceImpactPct, fees, protocolFeeBps, creatorFeeBps, crossesCurve}:venue为pump(联合曲线)或jupiter(已毕业,另带route为经过的流动性来源);price为含费成交均价(SOL/币),priceImpactPct为不含费均价相对现价spotPrice的偏离(%),fees为协议费加创作者费(SOL);crossesCurve为true表示买穿曲线(见下文「Pump.fun打新」)。(详见表下)
pump.buymint, solAmount[, options]花solAmount SOL(含协议费与创作者费)在联合曲线上买入:先幂等地建钱包的代币账户,再发buy_exact_quote_in_v3,最少到手数量为本地报价×(1 − slippage),由链上程序强制执行。见子页exchange.IO("pump.*", ...)。{txHash, venue, mint, side, solAmount, tokenAmount, price, fee, slot}:venue为pump或jupiter(另带route);solAmount为付出的SOL(含协议费与创作者费,不含网络费与账户押金),tokenAmount为买到的币,fee为网络费(SOL)。(详见表下)
pump.sellmint, amount[, options]在联合曲线上卖出amount个币(all为全部余额),发sell_v3,最少收回的SOL为本地报价×(1 − slippage)。见子页exchange.IO("pump.*", ...)。同pump.buy:solAmount为到手的SOL(已扣协议费与创作者费)。
pump.holdings[wallet]钱包(默认本交易所对象的钱包)持有的pump.fun币:钱包代币余额里有联合曲线的那些,按曲线估值。见子页exchange.IO("pump.*", ...)。[{mint, amount, quote, complete, price, value}]:value为现在按曲线全部卖出可得的报价币(已扣费);曲线已完成或超出曲线能买回的量时price、value为null(已毕业的币用exchange.IO("route", ...)估值)。
lp.poolstoken[, quote]列出代币的Meteora DLMM、Raydium CLMM与Orca Whirlpools池子(指定计价币,或SOL、USDC、USDT):费率、bin步长与active bin(DLMM)或tick间距与当前tick(CLMM)、现价、池子两种代币的余额与TVL;24小时成交与手续费、美元TVL分别取自Meteora的数据API(dlmm.datapi.meteora.ag)、Raydium API v3(api-v3.raydium.io)与Orca的公开API(api.orca.so),现价、余额等从链上读,Raydium的费率取池子所属的AmmConfig账户。见子页exchange.IO("lp.pools", ...)。[{id, protocol, dex, symbol, base, quote, fee, feeRate, feeRateNow, binStep, activeId, price, reserveBase, reserveQuote, tvlQuote, tvlUsd, volume24hUsd, fees24hUsd, enabled, rewards, empty}]:protocol为meteora;price为计价币/代币;fee为基础费率(百万分之几,与Uniswap的fee同单位),feeRate为比例,feeRateNow为含波动附加费的当前费率;rewards为池子farm奖励代币[{mint, symbol}]。(详见表下)
lp.selecttoken, budget[, options]按规则自动选池:options.fee(同lp.pools的fee)或options.binStep指定时只在这些池子里选;在美元TVL不低于max(5000美元, 预算)的池子里选24小时成交最大的,没有成交数据时选TVL最大的,都不够门槛时选TVL最大的。见子页exchange.IO("lp.select", ...)。lp.pools的一行,另带reason(选择理由)。
lp.poolpoolId池子实时状态。见子页exchange.IO("lp.pool", ...)。{id, protocol, dex, tokenX, tokenY, symbolX, symbolY, decimalsX, decimalsY, price, fee, feeRate, feeRateNow, binStep, activeId, reserveX, reserveY, tvlUsd, volume24hUsd, fees24hUsd, enabled, rewards},price为1个X值多少Y(池子自己的顺序)。(详见表下)
lp.tickspoolId[, lowerBinId, upperBinId[, step]]bin区间内的流动性分布(DLMM没有tick,按bin给):每段两种代币的数量,step为合并成的段宽(bin数,默认1)。见子页exchange.IO("lp.ticks", ...)。{pool, activeId, binStep, price, tokenX, tokenY, symbolX, symbolY, segments: [{binLower, binUpper, priceLower, priceUpper, amountX, amountY, current}]},价格为Y/X。(详见表下)
lp.planparams建仓计划(只读,不花钱)。见子页exchange.IO("lp.plan", ...)。{params, symbol, pool, protocol, fee, feeRate, price, shape, strategy, budget, budgetUsd, binStep, activeId, lowerBinId, upperBinId, bins, positions: [{lowerBinId, upperBinId, priceLower, priceUpper, amountBase, amountQuote, share}], needBase, needQuote, haveBase, haveQuote, swap, shortfall, shareOfPool, volume24hUsd, estDailyFeesUsd, slippageBps, maxActiveBinSlippage, binArraysToCreate, rentSol, rentRefundableSol, warning?}:swap为建仓前需要换的币({side, amount, currency}或null);shareOfPool为本计划在active bin里的份额,estDailyFeesUsd = 24小时成交 × 费率 × 这个份额(假设价格一直在区间内);rentSol为建仓要押的租金,其中rentRefundableSol是仓位账户的(撤仓关账户时退回),其余是新建BinArray的(binArraysToCreate,不退)。(详见表下)
lp.simulateplan[, payer]按计划构造完整的建仓交易(新建BinArray、建仓位、建ATA、包装SOL、加流动性、解包),用节点的simulateTransaction执行(不验签、不广播),每个仓位一笔。见子页exchange.IO("lp.simulate", ...)。{pool, protocol, payer, ok, positions: [{position, lowerBinId, upperBinId, amountBase, amountQuote, ok, err, error, logs, unitsConsumed, txBytes}], swapNeeded, shortfall, note}:logs为程序日志尾部,error为失败原因(DLMM、Raydium CLMM、Orca Whirlpool的错误码附名字);Raydium与Orca的行用tickLower、tickUpper代替bin字段,position为仓位NFT的mint。
lp.addplan按计划建仓:需要时先用Jupiter市价单换币并等确认,再按最新池价与余额重算;每个仓位一笔交易(仓位账户或Raydium、Orca的仓位NFT mint用新生成的密钥创建并签名),发送前先模拟,模拟失败不发送;等确认后按交易前后余额给出实际存入的数量。见子页exchange.IO("lp.add", ...)。{txHash, txHashes, swapTxHash, pool, protocol, symbol, positions: [{id, txHash, lowerBinId, upperBinId, priceLower, priceUpper, amountBase, amountQuote, rentSol, feeSol}]},仓位id为meteora:仓位地址、raydium:仓位NFT的mint或orca:仓位NFT的mint;Raydium与Orca的行用tickLower、tickUpper代替bin字段。
lp.increasepositionId, budget[, options]给仓位加仓:budget(计价币)按仓位的bin区间与现价拆成两种代币,缺的那种先换。见子页exchange.IO("lp.increase", ...)。{txHash, swapTxHash, id, symbol, amountBase, amountQuote, feeSol}
lp.decreasepositionId, ratio[, options]按比例(0到1,换算成万分比)从仓位每个有流动性的bin撤出,同时领取全部手续费与farm奖励,仓位保留。见子页exchange.IO("lp.decrease", ...)。{txHash, txHashes, positions: [{id, symbol, txHashes, principalBase, principalQuote, feesBase, feesQuote, receivedBase, receivedQuote, rewards, rentRefundSol, feeSol}], sells}:received*按交易前后余额计算,手续费部分按发送前链上可领的量拆出。
lp.collectpositionIds[, sell]领取手续费与farm奖励(DLMM为claim_fee2、claim_reward2,Raydium为流动性为0的decrease_liquidity_v2,Orca为update_fees_and_rewards + collect_fees_v2 + collect_reward_v2),每个仓位一笔交易;sell为true时把领到的基础币卖成计价币。见子页exchange.IO("lp.collect", ...)。同lp.decrease。
lp.removepositionIds[, ratio[, sell]]撤出流动性并领取手续费与奖励,每个仓位各自的交易;ratio默认1:全部撤出后关掉仓位账户(Raydium为close_position:烧掉NFT、关NFT账户、NFT mint与仓位账户),退回租金(rentRefundSol);小于1时只撤一部分。见子页exchange.IO("lp.remove", ...)。同lp.decrease。
lp.positions[filter[, wallet]]钱包的全部Meteora DLMM仓位(节点getProgramAccounts按主人查,需要节点支持)、Raydium CLMM与Orca Whirlpools仓位(getTokenAccountsByOwner找钱包里数量为1的NFT,再读它们的仓位账户;Orca另列出钱包持有的Position Bundle里的仓位):bin区间、是否在区间内、两种代币当前数量(按每个bin里的份额折算)、价值、未领手续费与farm奖励、押的租金。见子页exchange.IO("lp.positions", ...)。[{id, pool, protocol, symbol, fee, lowerBinId, upperBinId, activeId, binStep, width, priceLower, priceUpper, price, inRange, liquidity, amountBase, amountQuote, value, feesBase, feesQuote, feesValue, rewards, rentSol, feeOwner, closed}],value、feesValue按计价币计,rewards为[{mint, symbol, amount}],liquidity为各bin份额之和。(详见表下)
lp.trackpositionIds登记仓位(meteora:地址、raydium:NFT mint、orca:NFT mint或只写地址——Raydium、Orca也认仓位账户地址;先核对是对应协议的仓位),之后lp.positions也会查这些仓位(主人每次按链上核对,转走的、已关掉的不列)。(详见表下)本进程记住的全部仓位地址。
bridge.chains—跨链桥(LI.FI)支持的链:EVM链与Solana,缓存1小时。见子页exchange.IO("bridge.*", ...)。{id, key, name, chainType, nativeToken}数组,chainType为EVM或SVM。
bridge.tokens[chain]LI.FI认识的某条链上的代币(缺省为Solana),缓存1小时。见子页exchange.IO("bridge.*", ...)。{symbol, address, decimals, name, priceUSD}数组。
bridge.quoteparams跨链报价(只读),源链为本交易所对象的链。见子页exchange.IO("bridge.*", ...)。{tool, toolName, fromChain, toChain, toChainName, fromToken, toToken, fromAmount, toAmount, toAmountMin, fromAmountRaw, toAmountRaw, toAmountMinRaw, fromAmountUSD, toAmountUSD, slippage, toAddress, feeCosts, gasCosts, executionDuration, approvalAddress, steps, transactionId, request}:数量为代币单位(*Raw为最小单位原值);toAmountMin为扣除滑点后保证到手的数量;feeCosts为[{name, amount, token, amountUSD, percentage, included}](included为false的费用另付);gasCosts为源链gas估算;executionDuration为预计耗时(秒);approvalAddress为需要授权的合约(原生币、Solana为null);steps为各步骤(cross为跨链,swap为兑换);request为参数原样回显。
bridge.simulateparams|quote重新报价,用本钱包签名LI.FI给出的序列化交易后simulateTransaction(核对签名),不广播。见子页exchange.IO("bridge.*", ...)。bridge.quote的结果,另有simulated(true)、unitsConsumed、signature。
bridge.sendparams|quote跨链转出:重新报价 → 检查余额 → 用本钱包签名LI.FI给出的序列化交易(本钱包不是签名者时报错)→ simulateTransaction → 经Solana节点广播。见子页exchange.IO("bridge.*", ...)。{txHash, tool, fromChain, toChain, toChainName, fromToken, toToken, fromAmount, toAmount, toAmountMin, toAddress, transactionId},txHash为源链交易签名,可用receipt查状态。
bridge.statussignature[, options]跨链进度(LI.FI /status),参数为bridge.send返回的源链交易签名;options可给{toChain, bridge}加快查找。见子页exchange.IO("bridge.*", ...)。{status, substatus, substatusMessage, tool, sending, receiving, fromAddress, toAddress, explorer, bridgeExplorer}:status为NOT_FOUND、INVALID、PENDING、DONE、FAILED;DONE时substatus为COMPLETED(按报价到账)、PARTIAL(收到的是别的代币)或REFUNDED(已退回);sending、receiving为{txHash, txLink, chainId, amount, amountRaw, token, timestamp},receiving.amount与receiving.token为实际到账的数量与代币。
bridge.apiKey[key]设置LI.FI的API Key(请求头x-lifi-api-key,只对本交易所对象生效,不回显),传""清除;不传参数只查询。没有Key时按出口IP限频,见下文。见子页exchange.IO("bridge.*", ...)。是否已设置Key(布尔值)。

表中长说明的其余部分:

  • lp.track:三家的仓位按主人就能查到,一般不需要登记;保留这个指令与Uniswap一致,本进程lp.add建的仓位会自动记住。查别的钱包的Orca仓位要用节点的getTokenLargestAccounts找NFT持有人(公共节点对它限流很紧)。

通用指令currency见exchange.IO。

不支持通用指令api(调用时报错并返回空值)。

函数支持差异

不支持(调用时报错并返回空值):exchange.GetTickers、exchange.GetTrades、exchange.CreateConditionOrder、exchange.ModifyConditionOrder、exchange.CancelConditionOrder、exchange.GetConditionOrder、exchange.GetConditionOrders、exchange.GetHistoryConditionOrders。

以回退方式支持:

  • exchange.GetRecords:原生周期为1分钟、5分钟、15分钟、1小时、4小时、12小时、1天(GeckoTerminal的周期);其它分钟级以上的周期由托管者合成,秒级周期不可用(没有成交记录接口可供合成)。

注意事项
函数Jupiter交易所的行为
exchange.GetTicker()买一、卖一为约1000美元规模的实际可成交价(两次询价);吃不下1000美元的小币依次缩小到100、10美元,卖方规模不够时再缩小,实际规模见Info的sizeQuote、bidSize。没有24小时统计,High、Low、Open为当前价,Volume为0
exchange.GetDepth()由约1000美元起逐档递增规模的询价推算,每档两次询价。买盘价格严格递减、卖盘严格递增。买卖两边是不同时刻、不同方向的询价,偶尔会交叉(买一不低于卖一):这时取两者的中间价,把交叉的档位并成一档(买一、卖一分别为中间价下浮、上浮0.0001%,数量不丢),原来的买一、卖一见Info的crossed,没有交叉时为null
exchange.GetRecords()K线来自GeckoTerminal的池子级数据:Jupiter是聚合器,取GeckoTerminal上两边正好是这两个代币(SOL按wSOL)的池子里美元流动性最深的一个(不限DEX,在两个代币各自靠前的20个池子里找,选中的池子缓存1小时)。价格为该池子的逐笔成交价(含池子手续费,与exchange.GetTicker()的中间价可能相差约一个池子费率),单位为计价币/基础币,Volume为基础币数量;没有成交的周期按上一根收盘价补平、成交量为0,最后一根可能尚未收盘。GeckoTerminal的数据有几十秒到1分钟的延迟,公开接口约每分钟10次:同一周期的K线缓存1分钟,请求在托管者内排队,被限频时等待重试,仍不行时报错。找不到该交易对的池子时报错
exchange.GetMarkets()代币表中的币与USDC、USDT、SOL组成的交易对(不逐个验证路由)。数量精度为基础币的代币精度,最小下单量为一个最小单位,价格精度固定为8位
exchange.GetAssets()SOL与代币表中各代币的钱包余额,单独持有的wSOL记为WSOL;代币表以外的持仓不进余额列表,列在Info的unlisted中({mint, amount})
exchange.CreateOrder()立即兑换:限价为最差成交价,由链上程序按滑点强制执行,当前报价已经达不到时直接报错、不发交易;市价按滑点保护;市价买入时数量为要花费的计价币。下单附加参数slippage覆盖本单滑点。Jupiter生成交易时会先模拟一遍,余额不足等会直接报错。广播前Solana节点按最新状态再模拟一遍:模拟失败时交易没有发出,连接器重新询价、生成交易再试,最多重试2次(第二次重试起避开失败路由经过的流动性来源,不会因此超出exchange.IO("dexes", ...)的限定),仍失败时报错,错误信息中带模拟的err与相关程序日志;成功时Info的preflightRetries为重试次数。下单选项tif为gtc时不立即兑换,改挂Jupiter原生限价单(配置了API Key且计价币为USDC、USDT时为Trigger V2,否则v1;可用exchange.IO("trigger.api", ...)强制其一),见下文「限价单」
exchange.GetOrder()订单ID形如SOL_USDC,5VERv8…(交易对、逗号、交易签名)。交易确认后为已成交,成交数量按交易前后的钱包余额计算;链上执行失败为已撤销(手续费照扣);超过有效期(约1分钟)仍未上链为已撤销。不是本程序发出的交易只能查已确认成功的(方向按余额变化判断),尚未确认或链上失败的报错。限价单的订单ID为交易对加订单账户地址(v1)或Jupiter的订单UUID(V2),见下文「限价单」
exchange.GetOrders()本程序发出、尚未确认也未过期的兑换,加上钱包的全部活动限价单(不限于本程序挂的;V2限价单只在配置了API Key时列出)
exchange.CancelOrder()只能撤限价单。兑换单不支持:Solana交易发出后无法撤回,未上链的交易约1分钟后自动过期
exchange.ModifyOrder()只能改V2限价单的价格(及下单附加参数slippage),见下文「限价单」。v1限价单与兑换单不支持
exchange.GetHistoryOrders()只有已成交、已撤销的限价单,以及V2的过期单(钱还在vault,状态为未成交,见下文「限价单」),不含兑换单(兑换单用exchange.GetOrder()查)。不传since、limit时v1买卖两个方向各取最近10条、V2取最近10条;传since时取创建时间不早于它的全部,传limit时取够为止。v1与V2合并后按创建时间倒序
  • 请求速率:Jupiter按每秒请求数限流,超过后返回429。连接器按exchange.IO("rps", ...)(默认每秒1次)给请求排队,同一个托管者进程中使用同一个Jupiter API地址的交易所对象共用这个节奏。默认设置下exchange.GetTicker()约需2秒,5档exchange.GetDepth()约需10秒;需要更快时申请Jupiter API Key,并按套餐调高rps。
  • 手续费:每笔交易的Solana基础费与优先费(上限见exchange.IO("priorityFee", ...))从SOL余额中扣除,订单的Info中有fee。第一次买入某个代币时,钱包需要新建该代币的账户,押金约0.002 SOL;押金仍归钱包所有,不计入成交。
Pump.fun打新

exchange.IO("pump.*", ...)直接交易pump.fun(程序6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P)联合曲线上的币,不经过Jupiter。账户、指令与报价公式按pump.fun官方公开文档(GitHub pump-fun/pump-public-docs的IDL与说明)。

  • 新币:pump.new从链上发现新币,策略循环轮询它(见下例)。公共节点按秒限流、延迟高(20笔约需4秒),抢新请在「节点地址」里配置自己的付费节点。
  • 只交易SOL报价的币:pump.fun也有以USDC或其它pump币为报价的币(pump.new的quote),pump.buy、pump.sell对它们报错;cashback币(已停止新建)也报错,可用exchange.Buy、exchange.Sell经Jupiter交易。
  • 价格保护:买入是精确输入(花solAmount,含费),最少到手 = 本地报价×(1 − slippage);卖出最少收回 = 本地报价×(1 − slippage)。默认滑点5%,由链上程序强制执行,达不到时整笔失败,只扣网络费。
  • 费用:协议费与创作者费按Pump Fees程序的费率表随市值分档(2026年10月为0.95% + 0.30%;pump.info、pump.quote返回实际费率,没有创作者的币不收创作者费),另有Solana网络费与优先费。第一次买某个币要建代币账户(押金约0.002 SOL,pump.sell卖all时默认关掉账户退回);钱包第一次在pump.fun交易时程序还会建它的成交量账户(约0.0018 SOL,不退)。
  • 买穿曲线:买入预算超过曲线剩余可卖量时(mayhem币除外),超出部分按迁移后PumpSwap池子的价格成交(官方的「合成迁移」),pump.quote的crossesCurve为true;之后到迁移完成前曲线不能再交易。mayhem币买入超过剩余量时报错。
  • 毕业:曲线完成(complete)的币,pump.buy、pump.sell改用本交易所对象的Jupiter市价兑换(交易对MINT_SOL,价格保护用本单的slippage,Jupiter要求小于0.5),返回的venue为jupiter;这时priorityFee、computeUnitLimit选项不适用(报错),优先费上限按exchange.IO("priorityFee", ...),dryRun也不支持(用pump.quote询价,它对毕业币同样走Jupiter)。曲线刚完成、还没迁移的短时间内两条路都可能失败。
  • 每笔交易发送前都用节点模拟,模拟失败不发送并报出原因(pump.fun的错误码附名字,如BuySlippageBelowMinTokensOut);广播与「是否已发出」的判断同兑换下单,等确认的规则同集中流动性(定不下来时报outcome is unknown并附签名,不说没发生)。
  • 抢新时优先费要给足(options.priorityFee),否则在拥堵时可能过期不上链。

抢新轮询示例(JavaScript):

javascript
var seen = {} var start = Date.now() while (true) { var coins = exchange.IO("pump.new", {limit: 20, since: start}) for (var i = 0; coins && i < coins.length; i++) { var c = coins[i] if (seen[c.mint] || c.quote != "SOL" || c.mayhem) continue seen[c.mint] = true if (c.devBuy && c.devBuy.quoteAmount > 1) continue // 创作者首买过大,跳过 var r = exchange.IO("pump.buy", c.mint, 0.01, {slippage: 0.2, priorityFee: 0.0005}) if (r) Log("bought", r.tokenAmount, c.symbol, "for", r.solAmount, "SOL", r.txHash) } Sleep(1000) }

风险:

  • 绝大多数新币很快归零;创作者或与它捆绑的钱包常在创建同笔或随后几个区块里买入,随时砸盘跑路(rug pull)。
  • 抢新机器人与MEV竞争激烈:同一区块里的先后顺序取决于优先费与小费,滑点设得大会被三明治夹击,按最差价成交。
  • 名称、符号、元数据链接由创建者随意填写,可以冒充知名项目;请以mint地址为准。
  • 协议费、创作者费、网络费与优先费在每次买卖都要付,频繁进出的成本很高。
限价单(tif gtc)

exchange.CreateOrder(symbol, side, price, amount, {tif: "gtc"})(或exchange.Buy、exchange.Sell带同样的下单选项)不立即兑换,而是挂一张Jupiter原生限价单,由Jupiter的keeper在价格到达后异步成交。不带tif或tif为其它值时行为不变(立即兑换)。有两套接口:

Trigger v1Trigger V2
何时使用(trigger.api为缺省的auto)没有配置API Key,或计价币不是USDC、USDT配置了API Key且计价币为USDC或USDT
资金存放链上订单账户(程序j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X),挂单信息链上公开存入Jupiter托管(Privy)的vault,一个钱包一个,所有V2订单共用;订单存在Jupiter链下,成交前不公开
触发与成交按两种代币的兑换比率,按限价成交(默认0滑点),换回数量有保证按基础币的美元价触发,到价后按当时市价经Jupiter路由兑换:换回数量不保证,可以部分成交;滑点缺省由Jupiter自动设定
订单IDSOL_USDC,订单账户地址SOL_USDC,订单UUID
最低金额付出或换回的一边至少值5美元付出的一边至少值10美元
到期可选,缺省不过期;过期后Jupiter不会自动关单,订单仍挂着、钱仍锁在订单账户里,要撤单取回必须有,缺省30天;过期后不再成交,钱留在vault,要撤单取回
改单不支持exchange.ModifyOrder()改价格

填写API Key后默认就是托管的V2:挂单的钱离开钱包、存进Jupiter托管的vault。要保持非托管的v1,调用exchange.IO("trigger.api", "v1");反过来exchange.IO("trigger.api", "v2")在没有API Key时也强制用V2(Jupiter目前放行不带Key的V2调用,但官方文档要求带Key)。

Jupiter官方已把v1标为不再开发(只做关键修复,尚未公布停用),新功能都在V2。已挂的v1单不受配置影响,照常可查、可撤(订单ID的形状决定走哪套接口,与trigger.api无关;V2订单要配置API Key或trigger.api为v2才能查、撤、改)。

通用规则:

  • 数量:amount为基础币数量,买入付出amount × price计价币(向下取整到最小单位,不多付),卖出付出amount基础币(v1另要求换回amount × price计价币,向上取整,不少收)。不支持市价单(price为-1或type为market时报错)。
  • 下单附加参数:expiry为到期时间戳(毫秒);slippage为允许的滑点比例(如0.003)。v1缺省0(按限价精确成交),给了可以提高成交率但可能低于限价成交;V2缺省由Jupiter按市场自动设定,给了就用固定滑点。
  • 状态:挂着为未成交,有部分成交为部分成交;全部成交为已成交;已撤销为已撤销。Info为Jupiter的原始订单行。
  • 过期:Jupiter不会替你关掉过期的单,钱一直锁着,直到exchange.CancelOrder()取回(v1退回本金与订单账户租金,V2从vault取回)。所以过期但还没撤的单仍为未成交(或部分成交),Info.expired为true,Info.note写明要撤单取回。v1过期单照样列在exchange.GetOrders()中(Jupiter仍把它当挂单);V2过期单被Jupiter归入历史,不在exchange.GetOrders()中,用exchange.GetOrder()或exchange.GetHistoryOrders()查到。撤单取回后为已撤销。
  • 撤单:订单已经成交或撤销时exchange.CancelOrder()返回false,原因见GetLastError()。
  • exchange.GetOrders()每次调用都会请求一次v1限价单列表(配置了API Key时再请求一次V2列表),受exchange.IO("rps", ...)节流。
  • 带转账税(transfer fee)或transfer hook扩展的Token-2022代币不能挂限价单(Jupiter不支持)。
  • 挂单前可以用exchange.IO("trigger.simulate", ...)只模拟。

Trigger v1:

  • 挂单与撤单都是连接器签名后经Solana节点广播的链上交易,节点预检(模拟)失败时没有发出并报错;各付一次Solana交易费与优先费,第一次挂某种币的单时要新建代币账户等,押金归钱包。撤单只等广播,结果用exchange.GetOrder()确认。
  • 手续费:Jupiter从换回的币中扣手续费(官方说明稳定币对0.03%,其它0.1%,以每笔成交记录为准),订单的AvgPrice按扣费前计算,实际到账见Info的trades。
  • exchange.GetOrder()先查活动单再查历史单;本程序刚挂、Jupiter还没收录的单按链上状态给出(订单账户存在为挂单中)。

Trigger V2:

  • 认证:连接器用钱包私钥签名Jupiter的登录挑战(只签以Jupiter固定登录文本开头、写明本钱包地址的消息),换取15分钟的访问令牌并自动续期,令牌只在内存中。令牌泄露也不能转走资金(取回要钱包签名交易),但可以撤单、改价。
  • 下单:连接器先查本钱包的vault,没有就注册一个(在Jupiter为钱包新建托管账户;也可以事先用exchange.IO("trigger.vault", "register")注册);再请Jupiter生成存入交易,逐条核对(钱包是付费者,只调用系统、代币、关联代币账户、计算预算、Memo程序,钱包转出的币只进vault一侧、合计正好是下单金额;钱包出租金新建的账户只能是交给vault的本单输入账户(Jupiter用以vault为base的CreateAccountWithSeed建它,撤单或成交后关掉、租金退回钱包)和钱包、vault的关联代币账户),签名后先用节点模拟(模拟失败时没有发出并报错),再连同订单参数交给Jupiter,Jupiter在这次调用中把存入交易上链并返回订单UUID。这次调用出错时存入交易可能已经上链,错误信息中带存入交易签名,请用exchange.IO("receipt", ...)与exchange.IO("trigger.vault")确认后再重试。
  • 触发:买单为基础币的美元价跌到price以下时买入,卖单为涨到price以上时卖出。计价币按1美元看待(USDC、USDT脱锚时触发价随之偏离)。Jupiter不检查价格是否合理:买入价高于市价、卖出价低于市价的单会立即按市价成交。
  • 数量与成交:订单的Amount卖单为存入的基础币,买单为存入的计价币÷价格;DealAmount、AvgPrice按实际消耗与换回的数量计算(手续费已含在换回的数量中,V2不单列)。
  • 改单:exchange.ModifyOrder()只改价格(与slippage),只有挂着、未开始成交的普通单能改,追踪止损单不能改价;数量由存入金额决定,不能改(传入的数量必须等于原数量)。买单改价后花费的计价币不变,Amount随之变为金额÷新价格。
  • 撤单分两步:Jupiter先停止订单(此后不再成交)并生成取回交易,连接器核对(钱包只付手续费)并签名,交给Jupiter补上vault的签名后上链,未成交的币回到钱包。第二步失败时订单停在待取回状态(仍列在exchange.GetOrders()中),再撤一次即可取回。过期的单同样用exchange.CancelOrder()取回。
  • 托管风险:挂单期间资金在Jupiter通过Privy托管的vault中,不在钱包里,余额不计入exchange.GetAssets(),用exchange.IO("trigger.vault")查看。取回依赖Jupiter生成取回交易并补签,Jupiter服务异常时无法自行取回。V2接口官方仍标为beta,行为可能变化。
  • 费用:存入与取回交易由钱包付网络费;成交由keeper执行并付网络费,Jupiter的兑换手续费已从换回的数量中扣除。没有集成方手续费。
  • 请求:每次查询、下单都要先认证(进程内缓存令牌),会多占一两次请求额度;API Key设置了接口权限时必须包含Trigger,否则相关调用报403。
  • 订单函数会列出钱包的全部V2限价单,包括在jup.ag等处挂的(止盈止损、OCO的每一条腿都按一张单列出,价格为它的美元触发价,方向见Info的triggerCondition)。按美元价触发、却不是以USDC或USDT计价、或者不按基础币价格触发的单无法表示为交易对的价格,查询到它们时报错(指定交易对查询时只看这个交易对的单)。
定投(DCA)

exchange.IO("dca.create", ...)、dca.list、dca.cancel、dca.simulate:配置了API Key且计价币为USDC或USDT时新定投默认用Jupiter Trigger V2的DCA(托管vault;exchange.IO("trigger.api", ...)同样适用:v1保持Recurring v1,v2强制V2),否则用Recurring API v1(按时间定投,程序DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M)。Jupiter已不再维护Recurring v1(仍可用),定投功能已并入Trigger V2。dca.list两边都列(V2要配置API Key),dca.cancel按定投ID的形状分v1(地址)、V2(UUID)。定投不进exchange.GetOrders()等订单函数。

  • v1:总额一次存入定投订单账户,由Jupiter的keeper每隔interval秒兑换一份,买到的币自动转回钱包。至少2份、每份至少值50美元;不支持Token-2022代币;Jupiter从换到的币中收0.1%手续费。创建和撤销都是链上交易,要付交易费与优先费;撤销后剩余的币退回钱包。Jupiter收录新定投要几分钟,这期间dca.list按链上账户列出本程序刚建的定投(indexed: false),dca.cancel也照样能撤。
  • V2:认证、vault、存入与托管风险同上文V2限价单。总额存入vault,keeper每轮兑换一份,换到的币直接进钱包,网络费由keeper付;滑点由Jupiter按市场自动设定,不能指定;手续费已含在换到的数量中。至少2份、每份至少值10美元,间隔60秒到1年,开始时间最多30天后,每个钱包最多10个进行中的定投。给了minPrice或maxPrice时只在基础币的美元价落在区间内时兑换,区间外的一轮顺延到下一个间隔。不能修改;撤销分两步(同V2限价单),已成交的轮次不退。
集中流动性(LP)

exchange.IO("lp.*", ...)指令提供Meteora DLMM(程序LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo)、Raydium CLMM(程序CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK)与Orca Whirlpools(程序whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc;这两家与DLMM的不同见下文)池子的集中流动性:选池、规划与模拟、建仓、加减仓、领手续费与farm奖励、撤出和仓位查询。指令名、参数与返回字段对齐Uniswap交易所对象的lp.*,不同之处:

  • 价格离散成bin而不是tick:bin i的价格为(1 + binStep/10000)^i(再按两种代币的精度换算),区间用lowerBinId、upperBinId表示(含两端),现价所在的bin为activeId;range可以写{bins: [lo, hi]}。active bin里两种代币都有,往上的bin只有X、往下的只有Y,所以建仓的形状就是各bin放多少(spot、curve、bidask)。
  • 仓位是一个账户,不是NFT:id写成meteora:仓位地址(也认只写地址);一个仓位最多70个bin,更宽的spot区间拆成多个仓位。
  • 租金:每个仓位账户押一份免租额(按节点getMinimumBalanceForRentExemption,2026年10月约0.042 SOL),lp.remove全部撤出时关掉账户退回;区间里还没有BinArray账户(每个装70个bin)时要先新建,押的租金(2026年10月约0.052 SOL/个)不退。计划的rentSol、rentRefundableSol、binArraysToCreate给出这些数。第一次持有某种代币时还要新建代币账户(约0.0015 SOL,仍归钱包)。
  • SOL自动包装、解包:池子一侧是SOL时,交易里先把要存入的SOL包装成wSOL,交易结尾关掉钱包的wSOL账户(钱包里原有的wSOL也一并换回SOL)。
  • 换币用本交易所对象的Jupiter兑换(市价单,滑点见exchange.IO("slippage", ...))。
  • 写指令每笔交易发送前都用节点模拟一遍,模拟失败不发送并报出原因(DLMM、Raydium CLMM、Orca Whirlpool的错误码附名字);计算单元上限按模拟用量加余量,优先费按最近写这些账户的交易的费率取第75百分位,不超过exchange.IO("priorityFee", ...)的上限。广播与「是否已发出」的判断与兑换下单相同;交易确认后返回,实际数量按交易前后余额计算。等确认时向所有节点查交易状态,只有某个节点的区块高度已超过交易的最后有效高度、且已越过它的节点查不到这笔交易时才报过期(expired without being included … nothing happened,交易确实没有执行);落后或出错的节点不会让交易显得过期。120秒内既没确认也证明不了过期时报outcome is unknown并附交易签名:交易可能已经上链,先用exchange.IO("receipt", 签名)核对再决定是否重试。节点预检报BlockhashNotFound(它还没见过这个区块哈希,交易没有发出)时换新区块哈希重签再发,最多2次。
  • 撤出没有最少到手量的保护:DLMM按bin撤出的是每个bin里的份额,数量取决于撤出时各bin的构成。
  • 不支持带transfer hook的Token-2022代币,以及手续费归属另一个钱包(feeOwner)的仓位;没有lp.history、lp.stake、lp.unstake、lp.claim(farm奖励随lp.collect、lp.decrease、lp.remove一起领取)。
  • lp.positions按主人查仓位用节点的getProgramAccounts;官方公共节点支持,有的节点不支持或限流,这时报错。公共节点按秒限流,连接器遇到限流会退避重试;频繁查询建议配置自己的节点。

Raydium CLMM与Orca Whirlpools(与Uniswap V3相同的tick模型)与上面DLMM的不同:

  • 价格离散成tick:tick i的价格为1.0001^i(再按两种代币的精度换算),仓位区间为[tickLower, tickUpper),两端都是池子tick间距(tickSpacing)的整数倍;现价在区间内时两种代币都放,在区间外时只放一种。形状与layers同Uniswap交易所对象:curve、bidask由多个仓位组成。
  • 仓位是一个NFT:id写成raydium:NFT的mint或orca:NFT的mint(也认只写mint或仓位账户地址);NFT在谁的钱包里,仓位就归谁。lp.positions按钱包里数量为1的NFT找仓位,不需要getProgramAccounts。不支持带transfer hook的Token-2022代币。
  • Raydium:新仓位是Token-2022的NFT,建仓不建元数据,押金最少:仓位账户、NFT mint、NFT账户三份租金(2026年10月合计约0.0053 SOL),lp.remove关仓时全部退回。区间两端所在的TickArray(每个装60个tick间距)还没有时由建仓交易新建,押的租金(2026年10月约0.072 SOL/个)不退,计划的tickArraysToCreate给出要新建的。建仓、加仓以一种代币定量(SOL那一侧优先,否则价值大的一侧),另一种的上限为计划量 × (1 + slippage),价格变动使另一种超出上限时程序报PriceSlippageCheck、交易不发;撤出的最少到手量为现价下的数量 × 0.99。池子所有已初始化的奖励(即使已结束)在每次撤出、领取时一起结算,奖励代币的ATA会先建好。超出池子自带范围的tick要用池子的TickArray bitmap extension账户,没有时报错。查看不在本钱包里的单个仓位(lp.track)时用节点的getProgramAccounts按mint找NFT的持有人(官方公共节点支持)。
  • Orca:新仓位用Token-2022 NFT(带元数据扩展,同Orca官方SDK);旧的SPL Token NFT仓位与Position Bundle里的仓位也能查询、加减仓、领取和关仓。每个仓位押仓位账户、NFT mint、NFT代币账户的免租额与两个tick的租金(2026年10月合计约0.0084 SOL),lp.remove关仓时全部退回;区间两端所在的TickArray(每个覆盖88个tick间距)还没有时先新建变长TickArray,押的租金(约0.0019 SOL/个)不退。加流动性把两种币的数量作为上限交给链上(increase_liquidity_by_token_amounts_v2),链上按执行时的价格算出能加的最大流动性,价格越出slippage对应的界限时失败;撤出有最少到手量的保护(按现价估算的数量减1%)。锁仓(lock_position)的仓位减仓、关仓会在模拟时失败;只支持主部署的程序(不含Orca的immutable部署)。池子统计取自Orca公开API(api.orca.so);查看不在本钱包里的单个仓位时用节点的getTokenLargestAccounts找NFT持有人(公共节点对它限流很紧)。

监控与撤退由策略自己做:lp.positions给出是否在区间内、当前价值与未领手续费,策略据此决定调仓或止损。

风险:

  • 无常损失:价格偏离建仓价越远,仓位价值相对单纯持有越低;价格上涨时仓位逐个bin卖出X,下跌时买入X。
  • 价格出区间后仓位只剩一种代币,不再赚手续费,直到价格回到区间。
  • 开仓押的租金:仓位账户(Raydium、Orca还有NFT)的租金撤仓时退回,新建BinArray、TickArray的租金不退;拆成多个仓位时每个都要押一份。
  • 每次建仓、调仓、领取、撤出都是链上交易,要付手续费与优先费;频繁调仓的成本可能超过手续费收入。
  • 计划中的预估日手续费按过去24小时成交与当前在active bin里的份额估算,不代表未来收益。
跨链桥(bridge)

exchange.IO("bridge.*", ...)经LI.FI聚合的跨链桥(Across、Stargate、CCTP、deBridge、Mayan、Relay、NEAR Intents等)把代币从本交易所对象的链转到另一条链,支持EVM链之间以及EVM与Solana之间(源链为Solana)。报价与交易由LI.FI给出,LI.FI返回序列化交易,由托管者签名、simulateTransaction模拟后广播。请求带集成方标识integrator=fmz,不加收任何费用;报价中的LIFI Fixed Fee等是LI.FI与桥自己的费用,已计入toAmount。

典型流程:bridge.quote看报价 → bridge.simulate模拟 → bridge.send发出 → 每10~30秒bridge.status直到DONE或FAILED。

  • 跨链是异步的:bridge.send返回时只是源链交易已广播,到账要几秒到几十分钟(见报价的executionDuration),必须轮询bridge.status确认;PARTIAL表示目标链收到的是别的代币,REFUNDED表示已退回源链。
  • 跨虚拟机(EVM↔Solana)必须传toAddress,地址格式按目标链检查;地址写错的资金无法找回。
  • 风险:桥合约与跨链消息的安全风险由各桥承担;报价随时变化,bridge.send发出前会重新报价;目标链需要有gas才能继续使用到账的代币。先用小额测试。
  • 限频:没有API Key时LI.FI按出口IP限频,/quote两小时75次(bridge.quote、bridge.simulate、bridge.send各用一次),其它接口每分钟100次;同一托管者上的策略共用额度。用exchange.IO("bridge.apiKey", key)设置Key后每分钟100次。被限频时报错rate limited (HTTP 429 …)。
策略示例

可以直接运行的完整策略:Jupiter限价单网格(原生限价单网格)、DEX定投(原生定投)、pump.fun打新策略、DEX与CEX搬砖,见DEX策略示例。

本章内容整章阅读

名称描述
exchange.IO("route", ...)在Jupiter交易所对象上询价:返回一笔兑换的报价和路由,不下单。
exchange.IO("token", ...)在Jupiter交易所对象上登记代币,或列出代币表。
exchange.IO("transfer", ...)从Jupiter交易所对象的钱包转出SOL。
exchange.IO("receipt", ...)在Jupiter交易所对象上查询一笔Solana交易的状态,可以等待到确认。
exchange.IO("slippage", ...)设置Jupiter交易所对象市价单的滑点保护。
exchange.IO("priorityFee", ...)在Jupiter交易所对象上设置兑换交易的优先费上限。
exchange.IO("dexes", ...)在Jupiter交易所对象上限定兑换经过的流动性来源,例如只在pump.fun、Meteora或Raydium上成交。
exchange.IO("rps", ...)在Jupiter交易所对象上设置请求Jupiter API的速率。
exchange.IO("lp.pools", ...)列出一个代币在Meteora DLMM、Raydium CLMM与Orca Whirlpools上的集中流动性池子,按美元TVL从大到小排列。
exchange.IO("lp.select", ...)按TVL门槛与24小时成交额,为一个代币自动选出一个集中流动性池子。
exchange.IO("lp.pool", ...)读取一个集中流动性池子的实时状态与统计数据。
exchange.IO("lp.ticks", ...)查看池子在一段区间内的流动性分布,按bin或tick分段给出两种代币的数量。
exchange.IO("lp.plan", ...)按预算、价格区间与形状算出建仓计划:用哪个池子、几个仓位、各放多少两种代币、要不要先换币、押多少租金。
exchange.IO("lp.simulate", ...)按建仓计划构造全部建仓交易,用节点模拟执行,不签名、不广播。
exchange.IO("lp.add", ...)按建仓计划建立集中流动性仓位:缺哪种代币先用Jupiter换,每个仓位一笔链上交易。
exchange.IO("lp.increase", ...)给已有的仓位加仓:按仓位的区间与现价把预算拆成两种代币,缺的那种先换。
exchange.IO("lp.decrease", ...)按比例从仓位撤出流动性,同时领取全部手续费与farm奖励,仓位保留。
exchange.IO("lp.collect", ...)领取仓位的手续费与farm奖励,不动本金。
exchange.IO("lp.remove", ...)撤出仓位的流动性并领取手续费与奖励,全部撤出时关掉仓位、退回租金。
exchange.IO("lp.positions", ...)列出钱包的Meteora DLMM、Raydium CLMM与Orca Whirlpools仓位,给出区间、当前数量、价值与未领手续费。
exchange.IO("pump.*", ...)在pump.fun的联合曲线上发现新币、查看曲线状态、报价与买卖,币毕业后自动改走Jupiter兑换。
exchange.IO("dca.*", ...)用Jupiter的定投(DCA)分批买入或卖出:创建、列出、撤销与模拟。
exchange.IO("trigger.*", ...)Jupiter原生限价单的辅助指令:选择v1或V2接口、查看V2的托管vault、模拟挂单与撤单。
exchange.IO("bridge.*", ...)经LI.FI聚合的跨链桥把代币从Solana转到EVM链:查询链与代币、报价、模拟、发送与查询进度。