Solana Swaps (Jupiter)
The Jupiter exchange object (exchange.GetName() returns Jupiter) connects to the Jupiter aggregator on Solana and maps swaps to the spot trading functions. One exchange object corresponds to one Solana wallet: quotes and swap transactions are generated by Jupiter (which splits and routes orders across the many DEXs and market makers on Solana), signed by the docker with the configured private key and broadcast through a Solana node. For swaps on EVM chains see EVM On-chain Swaps (Uniswap, KyberSwap, 1inch).
Configuring the exchange object
Private Key: Solana wallet private key: the base58 string exported by Phantom or Solflare, or the JSON byte array of a solana-keygen file. The key can be kept locally on the docker, seeLocal Credential FilesRpc Address: Solana RPC nodes, separated by commas; when one fails the next one is used. Defaults to the official public node and publicnodeJupiter Api Key: Optional. Without it the freelite-api.jup.agis used; with itapi.jup.agis used and the request rate can be raised according to your planLiquidity Sources: Optional; restricts the liquidity sources swaps go through, comma-separated:pump(the pump.fun bonding curve and PumpSwap),meteora,raydium,orca, or Jupiter source names (such asMeteora DLMM). Empty means all sources
The wallet needs SOL for fees: each transaction's base fee and priority fee are paid from the SOL balance (the priority fee cap defaults to 0.001 SOL and is changed with exchange.IO("priorityFee", ...)). The first time you buy a token, the wallet has to create an account for it, with a deposit of about 0.002 SOL that still belongs to the wallet.
Trading pairs
- Pairs are written as
SOL_USDC,JUP_USDC,BONK_SOL. SOL is the native coin and is wrapped and unwrapped automatically during swaps. - Built-in common tokens can be written by name. Other tokens can be written as the exact name of a verified token in Jupiter's token list, as the mint address, or registered first with
exchange.IO("token", name, mintAddress). - Pairs are not upper-cased: mint addresses and names such as
mSOLare case-sensitive, so write them as they are, e.g.DB5QKorV9KHY54y73h5xWQqYyuD8P3jC1p5Ea8DBpump_SOL. exchange.GetMarkets()lists pairs of the token table's coins against USDC, USDT and SOL;exchange.GetAssets()lists only the balances of SOL and the token table's tokens.
Orders
- Every order is a swap executed immediately. The limit price is the worst execution price, enforced on chain through the slippage setting; if the current quote cannot reach the limit, an error is reported and nothing is sent. Market orders are protected by slippage (0.5% by default, changed with
exchange.IO("slippage", ratio)). For a market buy the amount is the quote coin to spend. - Jupiter simulates the transaction when generating it, so problems such as an insufficient balance are reported when the order is placed.
- Order IDs look like
SOL_USDC,5VERv8…(the pair, a comma and the transaction signature). Once confirmed the order is filled, with the filled amount computed from the wallet balances before and after; a transaction that fails on chain shows as canceled (the fee is still paid); a transaction not included within about a minute expires and shows as canceled. exchange.GetOrders()returns the swaps sent by this program that are neither confirmed nor expired.- No cancellation: a sent Solana transaction cannot be recalled;
exchange.CancelOrder()reports an error and fails. Just wait for the transaction to expire. exchange.GetTrades(),exchange.GetRecords(),exchange.GetTickers()andexchange.GetHistoryOrders()are not supported.
Request rate
Jupiter limits requests per second and returns 429 beyond the limit. The connector queues requests at the rate set with exchange.IO("rps", ...) (1 per second by default), shared by all Jupiter exchange objects in the same docker process. One exchange.GetTicker() needs two quotes (about 2 seconds), and a 5-level exchange.GetDepth() about 10 seconds. If you need more speed, get a Jupiter API key and raise rps according to your plan.
Common commands
route (quote only), token (register tokens), transfer (send SOL), receipt (transaction status), slippage, priorityFee, dexes (change liquidity sources at run time), rps, plus base (switch nodes) and address (wallet address). For their parameters and return values and the detailed behavior of each function, see the Jupiter exchange page of the syntax manual.
Examples
Quote, then market sell. CreateOrder sends a real transaction.
javascript
function main() {
exchange.IO("slippage", 0.01) // market order slippage 1%
var t = exchange.GetTicker("SOL_USDC")
Log("bid:", t.Buy, "ask:", t.Sell)
// quote only: how much USDC selling 0.1 SOL gets
var r = exchange.IO("route", "SOL_USDC", "sell", 0.1)
if (!r || r.route === null) {
Log("no route:", GetLastError())
return
}
Log("receive:", r.quote, "USDC", "average price:", r.price, "route:", r.route.join(" + "))
// market sell 0.1 SOL; the order ID looks like SOL_USDC,5VERv8…
var id = exchange.CreateOrder("SOL_USDC", "sell", -1, 0.1)
if (!id) {
Log("order failed:", GetLastError())
return
}
while (true) {
var o = exchange.GetOrder(id)
if (o && o.Status != ORDER_STATE_PENDING) {
Log("status:", o.Status, "filled:", o.DealAmount, "average fill price:", o.AvgPrice)
break
}
Sleep(2000)
}
}See Also