Skip to content

Raydium

Connector for Raydium protocol.

almanak.framework.connectors.raydium

Raydium CLMM concentrated liquidity connector.

Provides LP operations on Raydium CLMM pools on Solana: - Open concentrated liquidity positions - Close positions (decrease liquidity + burn NFT)

Unlike Jupiter/Kamino (REST API), Raydium CLMM builds instructions locally using solders and submits via SolanaExecutionPlanner.

RaydiumAdapter

RaydiumAdapter(
    config: RaydiumConfig,
    token_resolver: TokenResolver | None = None,
)

Adapter for Raydium CLMM integration with the Intent system.

Converts LP intents to ActionBundles containing serialized Solana VersionedTransactions built from Raydium CLMM instructions.

Example

config = RaydiumConfig(wallet_address="your-solana-pubkey") adapter = RaydiumAdapter(config)

intent = LPOpenIntent( pool="SOL/USDC/60", amount0=Decimal("1"), amount1=Decimal("150"), range_lower=Decimal("100"), range_upper=Decimal("200"), protocol="raydium_clmm", ) bundle = adapter.compile_lp_open_intent(intent)

compile_lp_open_intent

compile_lp_open_intent(
    intent: LPOpenIntent,
) -> ActionBundle

Compile an LPOpenIntent to an ActionBundle.

Builds Raydium CLMM openPosition instructions, serializes them into a VersionedTransaction, and wraps in an ActionBundle.

Parameters:

Name Type Description Default
intent LPOpenIntent

The LPOpenIntent to compile.

required

Returns:

Type Description
ActionBundle

ActionBundle containing serialized Solana transaction(s).

compile_lp_close_intent

compile_lp_close_intent(
    intent: LPCloseIntent,
) -> ActionBundle

Compile an LPCloseIntent to an ActionBundle.

Decreases all liquidity from the position and closes it.

Parameters:

Name Type Description Default
intent LPCloseIntent

The LPCloseIntent to compile.

required

Returns:

Type Description
ActionBundle

ActionBundle containing serialized Solana transaction(s).

RaydiumConfig

RaydiumConfig(wallet_address: str, rpc_url: str = '')

Configuration for Raydium adapter.

Attributes:

Name Type Description
wallet_address

Solana wallet public key (Base58).

rpc_url

Solana RPC endpoint URL (for pool queries via RPC).

RaydiumAPIError

RaydiumAPIError(
    message: str, status_code: int = 0, endpoint: str = ""
)

Bases: RaydiumError

Error communicating with the Raydium API.

RaydiumConfigError

RaydiumConfigError(message: str, parameter: str = '')

Bases: RaydiumError

Invalid Raydium configuration.

RaydiumError

Bases: Exception

Base exception for Raydium operations.

RaydiumPoolError

Bases: RaydiumError

Error with pool state or operations.

RaydiumTickError

Bases: RaydiumError

Error with tick calculations.

RaydiumPool dataclass

RaydiumPool(
    address: str,
    mint_a: str,
    mint_b: str,
    symbol_a: str = "",
    symbol_b: str = "",
    decimals_a: int = 9,
    decimals_b: int = 6,
    tick_spacing: int = 60,
    current_price: float = 0.0,
    tvl: float = 0.0,
    vault_a: str = "",
    vault_b: str = "",
    amm_config: str = "",
    fee_rate: int = 3000,
    observation_address: str = "",
    program_id: str = "",
    raw_response: dict[str, Any] = dict(),
)

Raydium CLMM pool information.

Can be constructed from the Raydium API response or on-chain data.

Attributes:

Name Type Description
address str

Pool state account address (Base58).

mint_a str

Token A mint address.

mint_b str

Token B mint address.

symbol_a str

Token A symbol (e.g., "SOL").

symbol_b str

Token B symbol (e.g., "USDC").

decimals_a int

Token A decimals.

decimals_b int

Token B decimals.

tick_spacing int

Tick spacing for this pool.

current_price float

Current price of token A in terms of token B.

tvl float

Total value locked in USD.

vault_a str

Token A vault address.

vault_b str

Token B vault address.

amm_config str

AMM config account address.

fee_rate int

Fee rate in basis points (e.g., 3000 = 0.30%).

observation_address str

Observation account address.

program_id str

CLMM program ID.

from_api_response classmethod

from_api_response(data: dict[str, Any]) -> RaydiumPool

Create from Raydium API /pools/info/list response item.

RaydiumPosition dataclass

RaydiumPosition(
    nft_mint: str,
    pool_address: str,
    tick_lower: int,
    tick_upper: int,
    liquidity: int = 0,
    token_fees_owed_a: int = 0,
    token_fees_owed_b: int = 0,
    personal_position_address: str = "",
)

Raydium CLMM position (owned by the user).

Attributes:

Name Type Description
nft_mint str

Position NFT mint address.

pool_address str

Pool state account address.

tick_lower int

Lower tick boundary.

tick_upper int

Upper tick boundary.

liquidity int

Current liquidity in the position.

token_fees_owed_a int

Accumulated fees for token A.

token_fees_owed_b int

Accumulated fees for token B.

personal_position_address str

PersonalPositionState PDA address.

RaydiumTransactionBundle dataclass

RaydiumTransactionBundle(
    transactions: list[str],
    action: str,
    position_nft_mint: str = "",
    metadata: dict[str, Any] = dict(),
)

Bundle of serialized transactions for a Raydium operation.

Attributes:

Name Type Description
transactions list[str]

List of base64-encoded VersionedTransactions.

action str

Action type ("open_position", "increase_liquidity", etc.).

position_nft_mint str

NFT mint address (for open_position).

metadata dict[str, Any]

Additional metadata.

RaydiumReceiptParser

RaydiumReceiptParser(**kwargs: Any)

Parser for Raydium CLMM transaction receipts.

Extracts position IDs, liquidity amounts, and token balances from Solana transaction receipts.

Supports the extraction methods required by ResultEnricher: - extract_position_id(receipt) -> str | None - extract_liquidity(receipt) -> dict | None - extract_lp_close_data(receipt) -> dict | None

Extraction approach: 1. Parse log messages for Raydium program events 2. Use preTokenBalances/postTokenBalances for actual amounts 3. Look for NFT mint in innerInstructions

Initialize RaydiumReceiptParser.

Parameters:

Name Type Description Default
**kwargs Any

Keyword arguments from receipt_registry (e.g., chain).

{}

parse_receipt

parse_receipt(receipt: dict[str, Any]) -> dict[str, Any]

Parse a receipt for ReceiptParser protocol compatibility.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Solana transaction receipt dict

required

Returns:

Type Description
dict[str, Any]

Dict with parsed LP data

extract_position_id

extract_position_id(receipt: dict[str, Any]) -> str | None

Extract the position NFT mint from a Raydium LP open receipt.

The position NFT is minted during openPosition. We find it by looking for a new token account with amount=1 in postTokenBalances that wasn't in preTokenBalances.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Solana transaction receipt dict.

required

Returns:

Type Description
str | None

Position NFT mint address (Base58), or None if not found.

extract_liquidity

extract_liquidity(
    receipt: dict[str, Any],
) -> dict[str, Any] | None

Extract liquidity data from an LP open/increase receipt.

Uses balance deltas to determine actual deposited amounts.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Solana transaction receipt dict.

required

Returns:

Type Description
dict[str, Any] | None

Dict with amount_a, amount_b, position_nft_mint, or None.

extract_lp_close_data

extract_lp_close_data(
    receipt: dict[str, Any],
) -> dict[str, Any] | None

Extract LP close data from a receipt.

Uses balance deltas to determine received amounts.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Solana transaction receipt dict.

required

Returns:

Type Description
dict[str, Any] | None

Dict with received amounts, or None.

RaydiumCLMMSDK

RaydiumCLMMSDK(
    wallet_address: str,
    base_url: str = RAYDIUM_API_BASE_URL,
    timeout: int = 30,
)

SDK for building Raydium CLMM instructions.

Provides methods to: - Fetch pool data from the Raydium API - Build Solana instructions for LP operations - Compute PDAs for positions, tick arrays, etc.

Example

sdk = RaydiumCLMMSDK(wallet_address="your-pubkey", rpc_url="...") pool = sdk.get_pool_info("pool-address") ixs, nft_mint = sdk.build_open_position_ix( pool=pool, tick_lower=-100, tick_upper=100, amount_a=1_000_000, amount_b=500_000_000, liquidity=1000000, )

get_pool_info

get_pool_info(pool_address: str) -> RaydiumPool

Fetch pool information from the Raydium API.

Uses two endpoints: - /pools/key/ids: provides vault addresses, observation IDs, lookup tables - /pools/info/ids: provides price, TVL, volume data

Parameters:

Name Type Description Default
pool_address str

Pool state account address (Base58).

required

Returns:

Type Description
RaydiumPool

RaydiumPool with current pool data.

Raises:

Type Description
RaydiumPoolError

If pool not found.

RaydiumAPIError

If API request fails.

find_pool_by_tokens

find_pool_by_tokens(
    token_a: str, token_b: str, tick_spacing: int = 60
) -> RaydiumPool | None

Find a CLMM pool by token pair.

Parameters:

Name Type Description Default
token_a str

Token A mint address or symbol.

required
token_b str

Token B mint address or symbol.

required
tick_spacing int

Preferred tick spacing (default: 60 = 0.30% fee).

60

Returns:

Type Description
RaydiumPool | None

Best matching RaydiumPool, or None if not found.

get_position_state

get_position_state(
    nft_mint: str, rpc_url: str
) -> RaydiumPosition

Query on-chain PersonalPositionState for a Raydium CLMM position.

Derives the PDA from the NFT mint, calls getAccountInfo, and parses the account data to extract tick range and liquidity.

PersonalPositionState layout (Anchor, 8-byte discriminator): [0:8] discriminator [8:9] bump (u8) [9:41] nft_mint (Pubkey) [41:73] pool_id (Pubkey) [73:77] tick_lower_index (i32 LE) [77:81] tick_upper_index (i32 LE) [81:97] liquidity (u128 LE)

Parameters:

Name Type Description Default
nft_mint str

Position NFT mint address (Base58).

required
rpc_url str

Solana RPC endpoint URL.

required

Returns:

Type Description
RaydiumPosition

RaydiumPosition with on-chain tick range and liquidity.

Raises:

Type Description
RaydiumPoolError

If position account not found or data invalid.

build_open_position_ix

build_open_position_ix(
    pool: RaydiumPool,
    tick_lower: int,
    tick_upper: int,
    amount_a_max: int,
    amount_b_max: int,
    liquidity: int,
    with_metadata: bool = True,
) -> tuple[list[Instruction], Keypair]

Build instructions for opening a new CLMM position.

Creates a new position NFT, initializes the PersonalPositionState, and deposits the specified amounts of token A and B.

Parameters:

Name Type Description Default
pool RaydiumPool

Pool information.

required
tick_lower int

Lower tick boundary (must be aligned to tick spacing).

required
tick_upper int

Upper tick boundary (must be aligned to tick spacing).

required
amount_a_max int

Maximum amount of token A in smallest units.

required
amount_b_max int

Maximum amount of token B in smallest units.

required
liquidity int

Target liquidity amount (u128).

required
with_metadata bool

Whether to create Metaplex NFT metadata.

True

Returns:

Type Description
list[Instruction]

Tuple of (instructions, nft_mint_keypair).

Keypair

The nft_mint_keypair must be included as a signer.

Raises:

Type Description
RaydiumPoolError

If pool data is incomplete.

build_decrease_liquidity_ix

build_decrease_liquidity_ix(
    pool: RaydiumPool,
    position: RaydiumPosition,
    liquidity: int,
    amount_a_min: int = 0,
    amount_b_min: int = 0,
) -> list[Instruction]

Build instructions for removing liquidity from a position.

Parameters:

Name Type Description Default
pool RaydiumPool

Pool information.

required
position RaydiumPosition

Position to decrease.

required
liquidity int

Amount of liquidity to remove.

required
amount_a_min int

Minimum acceptable token A out (slippage protection).

0
amount_b_min int

Minimum acceptable token B out (slippage protection).

0

Returns:

Type Description
list[Instruction]

List of Solana instructions.

build_close_position_ix

build_close_position_ix(
    position: RaydiumPosition,
) -> list[Instruction]

Build instructions for closing a position (burn NFT, recover rent).

The position must have zero liquidity and zero fees owed.

Parameters:

Name Type Description Default
position RaydiumPosition

Position to close.

required

Returns:

Type Description
list[Instruction]

List of Solana instructions.

build_open_position_transaction

build_open_position_transaction(
    pool: RaydiumPool,
    price_lower: float,
    price_upper: float,
    amount_a: int,
    amount_b: int,
    slippage_bps: int = 100,
) -> tuple[list[Instruction], Keypair, dict[str, Any]]

Build a complete open position transaction from price bounds.

High-level method that handles tick conversion, alignment, liquidity calculation, and slippage.

Parameters:

Name Type Description Default
pool RaydiumPool

Pool information.

required
price_lower float

Lower price bound (human-readable, token_b per token_a).

required
price_upper float

Upper price bound.

required
amount_a int

Amount of token A in smallest units.

required
amount_b int

Amount of token B in smallest units.

required
slippage_bps int

Slippage tolerance in basis points (default: 100 = 1%).

100

Returns:

Type Description
tuple[list[Instruction], Keypair, dict[str, Any]]

Tuple of (instructions, nft_mint_keypair, metadata).

build_close_position_transaction

build_close_position_transaction(
    pool: RaydiumPool,
    position: RaydiumPosition,
    slippage_bps: int = 100,
) -> tuple[list[Instruction], dict[str, Any]]

Build instructions to fully close a position.

Decreases all liquidity, then closes the position account.

Parameters:

Name Type Description Default
pool RaydiumPool

Pool information.

required
position RaydiumPosition

Position to close.

required
slippage_bps int

Slippage tolerance for decrease liquidity.

100

Returns:

Type Description
tuple[list[Instruction], dict[str, Any]]

Tuple of (all_instructions, metadata).