meteora
Pre-flight Dependencies (auto-injected by Plugin Store CI)
Run once per session before first use. These checks ensure required tools are installed.
Install onchainos CLI + Skills (auto-injected)
# 1. Install onchainos CLI
onchainos --version 2>/dev/null || curl -fsSL https://raw.githubusercontent.com/okx/onchainos-skills/main/install.sh | sh
# 2. Install onchainos skills (enables AI agent to use onchainos commands)
npx skills add okx/onchainos-skills --yes --global
# 3. Install plugin-store skills (enables plugin discovery and management)
npx skills add okx/plugin-store --skill plugin-store --yes --global
Install meteora binary (auto-injected)
if ! command -v meteora >/dev/null 2>&1; then
OS=$(uname -s | tr A-Z a-z)
ARCH=$(uname -m)
EXT=""
case "${OS}_${ARCH}" in
darwin_arm64) TARGET="aarch64-apple-darwin" ;;
darwin_x86_64) TARGET="x86_64-apple-darwin" ;;
linux_x86_64) TARGET="x86_64-unknown-linux-gnu" ;;
linux_i686) TARGET="i686-unknown-linux-gnu" ;;
linux_aarch64) TARGET="aarch64-unknown-linux-gnu" ;;
linux_armv7l) TARGET="armv7-unknown-linux-gnueabihf" ;;
mingw*_x86_64|msys*_x86_64|cygwin*_x86_64) TARGET="x86_64-pc-windows-msvc"; EXT=".exe" ;;
mingw*_i686|msys*_i686|cygwin*_i686) TARGET="i686-pc-windows-msvc"; EXT=".exe" ;;
mingw*_aarch64|msys*_aarch64|cygwin*_aarch64) TARGET="aarch64-pc-windows-msvc"; EXT=".exe" ;;
esac
mkdir -p ~/.local/bin
curl -fsSL "https://github.com/okx/plugin-store/releases/download/plugins/meteora@0.3.3/meteora-${TARGET}${EXT}" -o ~/.local/bin/meteora${EXT}
chmod +x ~/.local/bin/meteora${EXT}
fi
Report install (auto-injected, runs once)
REPORT_FLAG="$HOME/.plugin-store/reported/meteora"
if [ ! -f "$REPORT_FLAG" ]; then
mkdir -p "$HOME/.plugin-store/reported"
DEV_RAW="$(hostname):$(uname -s):$(uname -m):$HOME"
DEV_ID=$(echo -n "$DEV_RAW" | shasum -a 256 | head -c 32)
_K=$(echo 'OE9nNWFRUFdfSVJkektrMExOV2RNeTIzV2JibXo3ZWNTbExJUDFIWnVoZw==' | base64 -d 2>/dev/null || echo 'OE9nNWFRUFdfSVJkektrMExOV2RNeTIzV2JibXo3ZWNTbExJUDFIWnVoZw==' | openssl base64 -d)
HMAC_SIG=$(echo -n "${_K}${DEV_ID}" | shasum -a 256 | head -c 8)
DIV_ID="${DEV_ID}${HMAC_SIG}"
unset _K
curl -s -X POST "https://plugin-store-dun.vercel.app/install" \
-H "Content-Type: application/json" \
-d '{"name":"meteora","version":"0.3.3"}' >/dev/null 2>&1 || true
curl -s -X POST "https://www.okx.com/priapi/v1/wallet/plugins/download/report" \
-H "Content-Type: application/json" \
-d '{"pluginName":"meteora","divId":"'"$DIV_ID"'"}' >/dev/null 2>&1 || true
touch "$REPORT_FLAG"
fi
Architecture
- Read operations (
get-pools,get-pool-detail,get-swap-quote) → direct REST API calls tohttps://dlmm.datapi.meteora.ag; no wallet or confirmation needed get-user-positions→ queries on-chain via SolanagetProgramAccounts+ BinArray accounts; computes token amounts directly from chain state; no wallet or confirmation needed- Swap (
swap) → after user confirmation, executes viaonchainos swap execute --chain solana; CLI handles signing and broadcast automatically - Add liquidity (
add-liquidity) → builds a Solana transaction natively in Rust (initialize position + add liquidity instructions), submits viaonchainos wallet contract-call --chain 501; uses SpotBalanced strategy distributing tokens across 70-bin position centered at active bin; auto-wraps SOL to WSOL when needed; retries once on simulation errors - Remove liquidity (
remove-liquidity) → buildsremoveLiquidityByRange+ optionalclaimFee+closePositionIfEmptyinstructions, submits viaonchainos wallet contract-call --chain 501; 600k compute budget requested
Supported Operations
get-pools — List liquidity pools
Search and list Meteora DLMM pools. Supports filtering by token pair, sorting by TVL, APY, volume, and fee/TVL ratio.
meteora get-pools [--page <n>] [--page-size <n>] [--sort-key tvl|volume|apr|fee_tvl_ratio] [--order-by asc|desc] [--search-term <token_symbol_or_address>]
Examples:
meteora get-pools --search-term SOL-USDC --sort-key tvl --order-by desc
meteora get-pools --sort-key apr --order-by desc --page-size 5
get-pool-detail — Get pool details
Retrieve full details for a specific DLMM pool: configuration, TVL, fee structure, reserves, APY.
meteora get-pool-detail --address <pool_address>
Example:
meteora get-pool-detail --address 5rCf1DM8LjKTw4YqhnoLcngyZYeNnQqztScTogYHAS6
get-swap-quote — Get swap quote
Get an estimated swap quote for a token pair using the onchainos DEX aggregator on Solana.
meteora get-swap-quote --from-token <mint> --to-token <mint> --amount <readable_amount>
Output fields: from_token, from_symbol, to_token, to_symbol, from_amount_readable, from_amount_raw, to_amount_readable (human-readable, e.g. "84.132157"), to_amount_raw, price_impact_pct, price_impact_warning
Examples:
meteora get-swap-quote --from-token So11111111111111111111111111111111111111112 --to-token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --amount 1.0
get-user-positions — View LP positions
View a user's DLMM LP positions with token amounts computed from on-chain BinArray data.
meteora get-user-positions [--wallet <address>] [--pool <pool_address>]
If --wallet is omitted, uses the currently logged-in onchainos wallet.
Output fields per position: position_address, pool_address, owner,
token_x_mint, token_y_mint, token_x_amount, token_y_amount,
token_x_decimals, token_y_decimals,
bin_range (lower_bin_id / upper_bin_id), active_bins, source
Use
position_addressdirectly as--positionwhen callingremove-liquidity.
Examples:
meteora get-user-positions
meteora get-user-positions --wallet GbE9k66MjLRQC7RnMCkRuSgHi3Lc8LJQXWdCmYFtGo2
meteora get-user-positions --pool 5rCf1DM8LjKTw4YqhnoLcngyZYeNnQqztScTogYHAS6
swap — Execute a token swap
Execute a token swap on Solana via the onchainos DEX aggregator. Supports dry run mode.
meteora swap --from-token <mint> --to-token <mint> --amount <readable_amount> [--slippage <pct>] [--wallet <address>] [--dry-run]
Execution Flow:
- Run with
--dry-runto preview the quote — outputsestimated_output(human-readable),estimated_output_raw,price_impact_pct - Ask user to confirm the swap details (from/to tokens, amount, estimated output, slippage)
- Execute after explicit user approval:
meteora swap --from-token ... --to-token ... --amount ... - Report transaction hash and Solscan link
Examples:
# Preview swap (dry run)
meteora --dry-run swap --from-token So11111111111111111111111111111111111111112 --to-token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --amount 1.0
# Execute swap (after user confirmation)
meteora swap --from-token So11111111111111111111111111111111111111112 --to-token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --amount 1.0 --slippage 0.5
Risk warnings:
- Price impact > 5%: warning displayed, recommend splitting the trade
- APY > 50% on a pool: high-risk warning displayed
add-liquidity — Add liquidity to a DLMM pool
Add liquidity to a Meteora DLMM pool using the SpotBalanced strategy. Creates a new position (width=70 bins, centered at the active bin) if one doesn't exist, and deposits token X and/or token Y into the specified bin range.
meteora add-liquidity --pool <pool_address> [--amount-x <float>] [--amount-y <float>] [--bin-range <n>] [--wallet <address>] [--dry-run]
Parameters:
--pool— DLMM pool (LbPair) address (required)--amount-x— Amount of token X to deposit in human-readable units, e.g.0.01(default: 0)--amount-y— Amount of token Y to deposit in human-readable units, e.g.1.5(default: 0)--bin-range— Half-range in bins around the active bin for liquidity distribution; max 34 (default: 10)--wallet— Wallet address; omit to use the onchainos logged-in wallet--dry-run— Preview only; no transaction submitted
Output fields: ok, pool, wallet, position, amount_x, amount_y, tx_hash, explorer_url
Execution Flow:
- Run with
--dry-runto preview: shows position PDA, bin range, token accounts, estimated transaction - Ask user to confirm token amounts, pool, and that they understand liquidity provisioning risk
- Execute after explicit user approval:
meteora add-liquidity --pool <addr> --amount-x ... --amount-y ... - If position doesn't exist, it is initialized in the same transaction (requires ~0.06 SOL for rent)
- Report position PDA and Solscan link
Notes:
- Position is always 70 bins wide (MAX_BIN_PER_POSITION), centered at the current active bin
- The wallet needs ~0.06 SOL for position account rent when creating a new position
- Liquidity distribution uses SpotBalanced strategy (proportional to current pool ratio)
- Both token amounts are maximums; actual deposited may be less depending on pool ratio
Examples:
# Preview adding liquidity to JitoSOL-USDC pool
meteora add-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --amount-x 0.01 --amount-y 1.5 --dry-run
# Execute (after user confirmation)
meteora add-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --amount-x 0.01 --amount-y 1.5
# Narrow range (5 bins each side instead of default 10)
meteora add-liquidity --pool <addr> --amount-x 0.1 --amount-y 10 --bin-range 5
remove-liquidity — Remove liquidity from a DLMM position
Remove some or all liquidity from an existing Meteora DLMM position. Optionally close the position account afterwards to reclaim rent (~0.057 SOL).
meteora remove-liquidity --pool <pool_address> --position <position_address> [--pct <1-100>] [--close] [--wallet <address>] [--dry-run]
Parameters:
--pool— DLMM pool (LbPair) address (required)--position— Position PDA address; obtain fromget-user-positionsoutput (required)--pct— Percentage of liquidity to remove, 1–100 (default: 100)--close— Close the position account after full removal (100%) to reclaim ~0.057 SOL rent--wallet— Wallet address; omit to use the onchainos logged-in wallet--dry-run— Preview only; no transaction submitted
Output fields: ok, pool, position, wallet, pct_removed, position_closed, tx_hash, explorer_url
Use
position_addressfromget-user-positionsoutput directly as--position.
Execution Flow:
- Run with
--dry-runto preview: shows bin range, token accounts, and whether the position will be closed - Ask user to confirm — especially if
--closeis used (permanent, reclaims rent) - Execute after explicit user approval
- Token X and token Y are returned to the wallet's associated token accounts (created on-chain if missing)
- If
--closeis set and--pct 100, the position account is closed and ~0.057 SOL is returned
Notes:
- Attempting to remove from an empty position without
--closereturns"ok": falsewith a helpful tip; no on-chain call is made --closeonly takes effect when--pct 100(full removal); partial removals cannot close the position- If the position is already empty (liquidity withdrawn) and
--closeis set, the binary automatically claims any pending fees (claim_fee) then closes the account (close_position_if_empty) in a single transaction, reclaiming rent
Examples:
# Preview removing all liquidity from a position
meteora remove-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --position <position_addr> --dry-run
# Remove 50% of liquidity
meteora remove-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --position <position_addr> --pct 50
# Remove all liquidity and close the position (reclaims rent)
meteora remove-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --position <position_addr> --close
Token Addresses (Solana Mainnet)
| Token | Mint Address |
|---|---|
| SOL (native) | 11111111111111111111111111111111 |
| Wrapped SOL | So11111111111111111111111111111111111111112 |
| USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDT | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
Typical User Scenarios
Scenario 1: Swap SOL for USDC on Meteora
# Step 1: Find best SOL-USDC pool
meteora get-pools --search-term SOL-USDC --sort-key tvl --order-by desc --page-size 3
# Step 2: Get swap quote
meteora get-swap-quote --from-token So11111111111111111111111111111111111111112 --to-token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --amount 1.0
# Step 3: Preview swap (dry run)
meteora --dry-run swap --from-token So11111111111111111111111111111111111111112 --to-token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --amount 1.0
# Step 4: Ask user to confirm, then execute
meteora swap --from-token So11111111111111111111111111111111111111112 --to-token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --amount 1.0 --slippage 0.5
Scenario 2: Check LP positions
# View all positions for logged-in wallet
meteora get-user-positions
# Filter by specific pool
meteora get-user-positions --pool 5rCf1DM8LjKTw4YqhnoLcngyZYeNnQqztScTogYHAS6
Scenario 3: Find high-yield pools
# Top pools by APY
meteora get-pools --sort-key apr --order-by desc --page-size 10
Scenario 4: Add liquidity to a pool
# Step 1: Find the pool
meteora get-pools --search-term JitoSOL-USDC --sort-key tvl --order-by desc --page-size 3
# Step 2: Preview the liquidity position
meteora add-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --amount-x 0.01 --amount-y 1.5 --dry-run
# Step 3: Ask user to confirm, then execute
meteora add-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --amount-x 0.01 --amount-y 1.5
Scenario 5: Remove liquidity from a position
# Step 1: Find your positions
meteora get-user-positions
# Step 2: Preview removal (dry run)
meteora remove-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --position <position_addr> --dry-run
# Step 3: Ask user to confirm, then remove all and close position
meteora remove-liquidity --pool 8skykrYgFFpQNMhqhKbZoVKXFss55uGPUXhVMfnCzqJv --position <position_addr> --close