exchange.IO("lp.simulate", ...)
Build all add-liquidity transactions of a plan and run them with the node's simulation, without signing or broadcasting.
exchange.IO(k, plan)
exchange.IO(k, plan, payer)Examples
-
Plan, simulate, and add only when the simulation passes.
javascriptfunction main() { var plan = exchange.IO("lp.plan", {symbol: "SOL_USDC", budget: 100, range: {pct: [-5, 5]}}) if (!plan) { Log("Plan failed:", GetLastError()) return } var sim = exchange.IO("lp.simulate", plan) if (!sim) { Log("Simulation error:", GetLastError()) return } sim.positions.forEach(function(p) { Log(p.ok ? "ok" : "failed", p.amountBase, "SOL", p.amountQuote, "USDC", "compute units", p.unitsConsumed, p.error || "") }) Log("All passed:", sim.ok, sim.note) } -
Check a plan with another wallet as payer (read-only).
javascriptvar PAYER = "" // a wallet address holding SOL and USDC function main() { if (!PAYER) { Log("Set PAYER to a wallet address first") return } var sim = exchange.IO("lp.simulate", {symbol: "SOL_USDC", budget: 200, range: {pct: [-3, 3]}, shape: "spot", protocol: "meteora"}, PAYER) if (!sim) { Log("Simulation error:", GetLastError()) return } Log(sim.protocol, sim.pool, "payer", sim.payer, "all passed", sim.ok) sim.positions.forEach(function(p) { Log("bins", p.lowerBinId, p.upperBinId, p.ok, p.unitsConsumed, p.txBytes, p.error || "") }) }
Returns
| Type | Description |
object / null value |
|
Arguments
| Name | Type | Required | Description |
k | string | Yes | Set to |
plan | object | Yes | A plan returned by |
payer | string | No | Another wallet address, to simulate with it as payer and position owner (read-only, its private key is not needed), for checking a plan when your own wallet is empty. |
See Also
Remarks
What is simulated
- The plan is first re-planned from its
paramsat the latest pool price and the payer's balances, then one complete add transaction is built per position and run with the node'ssimulateTransaction(no signature check). - No swap: when the plan needs a swap first (
swapnotnull) the post-swap amounts are simulated andswapNeededistrue; with a swap or ashortfall,notewarns that the payer must hold the planned amounts for the simulation to pass, otherwisenoteis an empty string. - Transactions by protocol: DLMM creates bin arrays, the position account and ATAs, wraps SOL, adds liquidity and unwraps; Raydium creates ATAs, wraps SOL, runs
open_position_with_token22_nft(creating the position NFT and position account; missing TickArrays are created by the program) and unwraps; Orca creates ATAs, wraps SOL, creates dynamic tick arrays (initialize_dynamic_tick_array), opens the position (open_position_with_token_extensions), adds liquidity by token maxima (increase_liquidity_by_token_amounts_v2) and unwraps.
Each item of positions
| Field | Description |
|---|---|
position | The position account (DLMM) or position NFT mint (Raydium, Orca) generated for this simulation; lp.add generates another |
lowerBinId, upperBinId | The range (tickLower and tickUpper on Raydium and Orca) |
amountBase, amountQuote | The two token amounts this transaction deposits |
ok, err, error | Success, the node's raw error and the failure reason (DLMM, Raydium CLMM and Orca Whirlpool error codes with their names) |
logs | The tail of the program logs |
unitsConsumed, txBytes | Compute units consumed and transaction size in bytes |
Common failures: AccountNotFound means the payer has no SOL (a new or empty wallet); a balance below the planned amounts makes the program report insufficient funds. Before funding your own wallet, set payer to a public wallet holding both tokens to check the plan itself.