Type/to search
Built-in Functions
Structures
Built-in Variables and Constants
Conventions
Exchanges
Capability Matrix
Centralized Exchanges
Decentralized Exchanges (DEX)
Prediction Markets
Securities and Futures
On-chain & Custom

Withdraw a position's liquidity and claim fees and rewards; withdrawing everything closes the position and returns its rent.

exchange.IO(k, positionIds)
exchange.IO(k, positionIds, ratio)
exchange.IO(k, positionIds, ratio, sell)

Examples

Close all SOL/USDC positions and sell the SOL back to USDC.

javascript
function main() { var list = exchange.IO("lp.positions", "SOL_USDC") if (!list || list.length == 0) { Log("No positions") return } var ids = list.map(function(p) { return p.id }) var r = exchange.IO("lp.remove", ids, 1, true) if (!r) { Log("Remove failed:", GetLastError()) return } r.positions.forEach(function(p) { Log(p.id, "principal", p.principalBase, p.principalQuote, "fees", p.feesBase, p.feesQuote, "rent back", p.rentRefundSol, "SOL") }) Log("Sold:", JSON.stringify(r.sells)) }

Returns

TypeDescription

object / null value

{txHash, txHashes, positions, sells}: txHash is the first transaction signature and txHashes all of them; each item of positions is one position's {id, symbol, txHashes, principalBase, principalQuote, feesBase, feesQuote, receivedBase, receivedQuote, rewards, rentRefundSol, feeSol}, and sells lists the swaps back to the quote token, see the remarks. A null value is returned when a position does not belong to this wallet, a simulation fails or a transaction fails.

Arguments

NameTypeRequiredDescription

k

string

Yes

Set to lp.remove to withdraw liquidity.

positionIds

array / string

Yes

An array of position IDs; several IDs may also be passed as separate arguments (a number after them is ratio, a boolean sell). All must belong to this wallet.

ratio

number

No

The share to withdraw, (0, 1], default 1: withdraw everything and close; below 1 only that share is withdrawn and the position stays.

sell

bool

No

With true the base token received is sold for the quote token with a Jupiter market order. Default false.

See Also

Remarks

Closing

With ratio 1 the position is emptied and then closed in the same flow, its rent returned to the wallet (rentRefundSol):

  • Meteora DLMM: withdraws (remove_liquidity_by_range2), claims (claim_fee2, claim_reward2) and closes the position account (close_position_if_empty). Positions wider than 70 bins take one transaction per 70 bins.
  • Raydium CLMM: after decrease_liquidity_v2 empties and claims, close_position burns the NFT and closes the NFT account, the NFT mint and the position account.
  • Orca Whirlpools: after emptying and claiming the position is closed with close_position_with_token_extensions for Token-2022 NFT positions, close_position for older SPL Token NFT positions and close_bundled_position for positions in a Position Bundle; the rent of the position account, the NFT mint and the NFT token account is returned. Locked positions (lock_position) fail at the simulation.

Rent paid for new BinArrays and TickArrays belongs to the pool and is not returned. With ratio below 1 this is lp.decrease for several positions at once.

Position rows in the result
FieldDescription
receivedBase, receivedQuoteThe two token amounts actually received (from the balances before and after)
feesBase, feesQuoteThe fee part of them (split off by the amounts claimable on chain before sending)
principalBase, principalQuoteThe principal part = received − fees
rewardsFarm rewards collected, [{mint, symbol, amount}] (excluding the pool's two tokens)
rentRefundSolRent returned by closing (SOL)
feeSolNetwork fees paid by these transactions (SOL)

The orientation (base and quote) takes the stablecoin (then SOL) as the quote. Each item of sells is {symbol, qty, txHash}, or {symbol, qty, error} when the sale failed; sales are Jupiter market orders that wait for the broadcast only, so check them with exchange.IO("receipt").

Execution

Every transaction is simulated by the node before sending and is not sent when the simulation fails, with the reason reported (DLMM, Raydium CLMM and Orca Whirlpool error codes with their names); the compute-unit limit is the simulated usage plus headroom, and the priority fee is the 75th percentile of recent fees paid by transactions writing the same accounts, capped by exchange.IO("priorityFee"). The call returns after confirmation, with actual amounts from the balances before and after. When within 120 seconds the transaction is neither confirmed nor provably expired, the error says outcome is unknown with the signature: it may have landed, so check it with exchange.IO("receipt") before retrying.