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
¶
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 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 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
¶
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
¶
RaydiumConfigError
¶
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
¶
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
¶
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 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 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 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 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
¶
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
¶
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 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
¶
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 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). |