Skip to main content
Raydium does not publish an official Python SDK. The patterns here compose three well-maintained community libraries: solders (Rust-bound Solana primitives), solana-py (RPC client), and anchorpy (Anchor-style instruction builders from IDLs). The combination covers everything the TS SDK does; it is just less polished.

Environment

Versions that work together as of this writing:
anchorpy periodically lags anchor-lang’s version; for a recently deployed Raydium program, verify the IDL compiles under your pinned anchorpy before committing.

Connection and keypair

AsyncClient is the async variant; the sync Client is available for quick scripts but async is preferred for anything that sends multiple requests.

Reading pool state

Most production usage reads decoded pool state from Raydium’s REST API (see sdk-api/rest-api) rather than decoding on-chain data manually — it is simpler and the latency is acceptable for most use cases.
For bots that need lowest-possible latency, decode on-chain bytes directly:
The full layout is in src/raydium/cpmm/layout.ts (TS source); port it to construct as needed. anchorpy can do this automatically given the IDL — see below.

Building and sending a swap

For simplicity, use Raydium’s server-built-transaction endpoint. The server returns a signed-ready transaction; you only need to add your signature:
This is the fastest path to a working bot. The server quote expires quickly (≈30s); do not cache.

Building a swap client-side (via anchorpy)

For lower latency or when you cannot reach Raydium’s API (sanctioned regions, air-gapped setups):
PDA derivations (observation state, pool authority) follow the same formulas as in the CPMM chapter. anchorpy does not auto-derive them.

Typical bot architecture

A common Python Raydium bot structure:
Key decisions for production:
  • RPC provider. Public mainnet RPCs rate-limit aggressively. Use a dedicated provider (Helius, QuickNode, Triton) for sustained traffic.
  • WebSocket for pool state. client.account_subscribe(pool_id) pushes updates on every state change. Much tighter than polling.
  • Priority fee provider. Helius has a getPriorityFeeEstimate endpoint; Triton has their own. Size your fee based on the 75th percentile of recent fees on the target program.
  • Bundles for MEV-sensitive trades. Route through Jito’s block engine if you cannot tolerate sandwich risk. Python libs: jito-sdk-python (third-party, quality varies).

Reading farm state

anchorpy’s .account["X"].decode(bytes) gives a native Python object matching the IDL struct.

Pitfalls

1. Decimal handling

Python’s native float is IEEE-754 double; amounts in 9-decimal mints (1 SOL = 1e9 units) stay accurate but ratios and products lose precision. Use int (solders returns int for all amount fields) and route through decimal.Decimal for any price arithmetic.

2. Slot-based vs timestamp-based reasoning

Some farm versions use slot counters; LaunchLab uses timestamps. solana-py returns slot in RPC responses, but converting slot → timestamp is lossy (varies by leader schedule). If you need wall-clock time, call get_block_time(slot) explicitly.

3. Connection pool exhaustion

AsyncClient opens one HTTP connection per request by default. Under high load, reuse httpx.AsyncClient sessions and set an appropriate limits=httpx.Limits(max_connections=100).

4. Transaction size limits

Python-built transactions are not smaller than TS-built ones — the 1232-byte limit applies equally. Use V0 transactions (address lookup tables) for anything that routes through more than ~2 pools.

Pointers

Sources: