Skip to main content
Wallets integrating Raydium typically need to answer four questions per user: what pools does this user have LP in? what positions (CLMM NFTs) do they hold? what farms are they staked in? how much is it all worth? This page documents each.

Detecting Raydium positions

Classic LP tokens (CPMM, AMM v4)

These look like any other SPL Token: the user’s ATA holds a balance. A wallet shows this as just another token by default. To reveal it as a Raydium LP position:
  1. Enumerate user’s token accounts: connection.getParsedTokenAccountsByOwner(user, { programId: TOKEN_PROGRAM_ID }).
  2. For each mint, check Raydium’s mint list: GET https://api-v3.raydium.io/pools/info/lps?lps=<LP_MINT>,... (batch up to ~50 LP mints per call).
  3. For mints that match, the API returns the pool reference. Use it to compute the position’s token-denominated value:
Show both the LP balance and the unwrapped amounts — users think in underlying tokens, not LP units.

CLMM position NFTs

CLMM positions are NFTs. Each position’s PersonalPositionState PDA is derived from the NFT mint. To detect:
  1. Enumerate user’s NFTs. For legacy Metaplex NFTs: filter token accounts to those with supply 1 and decimals 0.
  2. For each NFT mint, try to derive the PersonalPositionState PDA:
  1. Decode via raydium.clmm.getPositionInfo({ positionPda }) to get:
    • poolId → fetch pool to resolve mints
    • tickLower, tickUpper → display range
    • liquidity, tokensOwedA/B → compute position value + pending fees
    • rewardInfos → pending per-stream rewards
  2. For position-NFTs issued under Token-2022 (OpenPositionWithToken22Nft), the NFT mint’s program is Token-2022 rather than SPL Token. Enumerate both when scanning.

Farm stakes

Farm v3 / v5 / v6 each have a per-user ledger PDA. Derivations:
For wallets that prefer fully on-chain detection: iterate possible UserLedger PDAs by hashing the user with a curated list of “likely” farm IDs. Enumerating all farm IDs exhaustively is impractical (thousands exist); use the API.

Computing position value

CPMM / AMM v4 LP

Then multiply each by the mint’s USD price (from raydium.token or a price oracle).

CLMM position

Render as:
  • Liquidity value (current price)
  • Uncollected fees
  • Pending rewards per stream
  • Range: [tickLower_price, tickUpper_price] with a visual bar showing whether current price is in-range

Farm stake

For on-chain computation, mirror the farm’s accounting:
Make sure to refresh reward_per_share_x64 with the lazy-update formula before computing (elapsed time × emission rate ÷ total_staked).

Transaction simulation for preview

Before a user signs, wallets usually preview the balance changes. Use simulateTransaction:
The accounts parameter asks the validator to return post-simulation account state for listed addresses. Much more accurate than trying to predict the balance change from the instruction shape alone.

Simulation pitfalls

  • CLMM swaps need valid tick arrays. If the user’s input size would cross into an uninitialized tick array, simulation reverts (same as execution). Surface this clearly in the UI.
  • Priority fee. Simulation runs without the compute-budget instructions applied. For a large transaction that would exceed the default 200k CU, simulation fails but actual execution with an explicit CU limit succeeds. Always set the CU limit on the simulated tx too.
  • Fresh blockhash. Simulation uses the current blockhash; if signing takes >60s the tx becomes invalid. Re-simulate if the user hesitates.

Token-2022 display

Tokens under the Token-2022 program should be labeled as such in the wallet’s token list, since they have different risk surfaces:
  • Transfer-fee mints: display the current transferFeeBasisPoints as “Transfer fee: X%” next to the balance. Warn when receiving — users may not realize they will receive less than the sender sent.
  • Transfer-hook mints: surface the hook program ID. A malicious hook can block outbound transfers; users should verify the hook is the one they expect.
  • Non-transferable mints: display “Non-transferable” and disable swap/send. These are typically soulbound tokens or credentials.
  • Interest-bearing mints: the UI balance derived from TokenAccount.amount does not reflect accrued interest. Use amountToUiAmount from @solana/spl-token (which applies the scaling factor) for the displayed value.

Farm APR display

APR displayed to users should combine all live reward streams, converted to USD, and annualized:
Display as APR: X.Y%. If the staking mint is an LP token, also compute the underlying LP’s base fee APR and label the sum as “Total APR” or “APR + fees”.

Pointers

Sources:
  • Raydium SDK v2 — position/farm helpers.
  • User-position endpoints on api-v3.raydium.io.