AMMs (Raydium, Orca, Meteora)
Solana's major AMMs hold concentrated and constant-product liquidity in program-owned pool accounts. Integrate directly when you need custom routing, LP actions, or on-chain CPI swaps outside Jupiter.
Search across all documentation pages
Solana's major AMMs hold concentrated and constant-product liquidity in program-owned pool accounts. Integrate directly when you need custom routing, LP actions, or on-chain CPI swaps outside Jupiter.
Quick-reference recipe card - copy-paste ready.
// Orca Whirlpool swap via SDK (off-chain ix build)
import { swapQuoteByInputToken, WhirlpoolContext } from "@orca-so/whirlpools-sdk";
const quote = await swapQuoteByInputToken(whirlpool, inputTokenMint, amountIn, slippageTolerance, programId);// On-chain: validate pool accounts match expected program + mints
require_keys_eq!(pool_state.token_mint_a, expected_mint_a, ErrorCode::MintMismatch);
require_keys_eq!(pool_state.token_mint_b, expected_mint_b, ErrorCode::MintMismatch);When to reach for this:
import { createSolanaRpc, address } from "@solana/kit";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
// Raydium AMM v4 pool state (example layout - fetch and decode with SDK)
const poolAddress = address("58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2"); // SOL-USDC legacy pool
const poolAccount = await rpc.getAccountInfo(poolAddress, { encoding: "base64" }).send();
if (poolAccount.value) {
console.log("Pool owner:", poolAccount.value.owner);
console.log("Data length:", poolAccount.value.data.length);
}What this demonstrates:
| Venue | Model | Best for | Program note |
|---|---|---|---|
| Raydium AMM v4 | x*y=k | Broad pairs | Mature, high TVL |
| Orca Whirlpool | Concentrated | Stable/volatile tight ranges | Tick array accounts |
| Meteora DLMM | Bin steps | New launches, custom curves | Dynamic fees |
use anchor_lang::prelude::*;
#[account]
pub struct PoolSnapshot {
pub token_a_reserve: u64,
pub token_b_reserve: u64,
pub fee_numerator: u64,
pub fee_denominator: u64,
}
// Always read reserves at execution time - never trust cached client values on-chain| Alternative | Use When | Don't Use When |
|---|---|---|
| Jupiter aggregator | Best price, fewer integrations | You need LP-only actions |
| Phoenix CLOB | Price-time priority order book | You want passive LP yield |
| On-chain oracle pricing | Lending collateral | Spot swaps |
Use Jupiter for swaps. Integrate Raydium directly for LP management, farming, or custom CPI paths.
LPs deposit in a price range (ticks/bins). Capital efficiency is higher but inactive ranges earn no fees.
Use venue explorers, Jupiter routePlan, or SDK getPool helpers - never guess pool PDAs.
Yes - pass all required pool, vault, tick, and oracle accounts. Validate program IDs in your constraints.
Each swap deducts a fee from input before applying the invariant. Fee tiers vary by pool and venue.
Growing support on Orca/Meteora - verify mint owner and transfer hook compatibility before routing.
Clone pool accounts into solana-test-validator or use Surfpool 0.12.0 fork for realistic reserves.
Price moves across bins; each bin holds discrete liquidity. Wrong active bin accounts cause swap failure.
Compare spot price before/after using reserve or sqrt-price fields from pool state.
Pool addresses are stable but liquidity migrates. Refresh pool lists from official sources periodically.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026