Skip to main content

raydium_amm_swap/
lib.rs

1//! A high‑level client for interacting with Raydium AMM pools on Solana.
2//!
3//! This crate provides:
4//! - Retrieval of on‑chain and off‑chain pool data (`fetch_pool_info`, `fetch_pool_by_id`, etc.)
5//! - Computation of swap quotes with fee and slippage handling (`compute_amount_out`, `compute_amount_in`).
6//! - Execution of swaps against a given pool (`swap_amm`, `swap_clmm`).
7//! - Support for both standard AMM v4 pools and concentrated‑liquidity (CLMM) pools via
8//!   `PoolType::Standard` and `PoolType::Concentrated`.
9//!
10//! # Examples
11//!
12//! ```rust
13//!
14//! use std::env;
15//! use std::str::FromStr;
16//! use anyhow::anyhow;
17//! use raydium_amm_swap::amm::client::AmmSwapClient;
18//! use raydium_amm_swap::consts::SOL_MINT;
19//! use raydium_amm_swap::helpers::from_bytes_to_key_pair;
20//! use raydium_amm_swap::interface::{AmmPool, ClmmPool, ClmmSwapParams, PoolKeys, PoolType};
21//! use solana_address::Address;
22//! use solana_sdk::pubkey::Pubkey;
23//! use solana_sdk::signature::Signer;
24//! use solana_client::nonblocking::rpc_client::RpcClient;
25//! use spl_associated_token_account::get_associated_token_address;
26//! use tracing::info;
27//!
28//!
29//! #[tokio::main]
30//! async fn main() -> anyhow::Result<()> {
31//!     dotenvy::dotenv().ok();
32//!     let amount_in: u64 = 1_000_000;
33//!     let slippage: f64 = 0.01;
34//!     let url = env::var("RPC_URL")?;
35//!     let mint_a_str = env::var("MINT_1").unwrap_or(SOL_MINT.to_string());
36//!     let mint_b_str = env::var("MINT_2")?;
37//!     let rpc_client = RpcClient::new(url);
38//!     let owner = env::var("KEYPAIR").expect("KEYPAIR env is not presented");
39//!     let keypair = from_bytes_to_key_pair(owner);
40//!     let owner_pubkey = keypair.pubkey();
41//!     println!("Owner address {}", owner_pubkey.to_string());
42//!     let amm_swap_client = AmmSwapClient::new(rpc_client, keypair);
43//!
44//!     // Choose which kind of pool to query.
45//!     // You can also pass `PoolType::Concentrated` to work with CLMM pools.
46//!     let pool_type = PoolType::Standard;
47//!
48//!     let all_mint_pools = amm_swap_client
49//!         .fetch_pool_info(&mint_a_str, &mint_b_str, &pool_type, Some(100), None, None, None)
50//!         .await
51//!         .unwrap();
52//!
53//!     match pool_type {
54//!         PoolType::Standard => {
55//!             let first_pool = all_mint_pools.first().ok_or_else(|| anyhow!("no pools"))?;
56//!             let pool_id = Pubkey::from_str(&first_pool.id).unwrap();
57//!             let pool_info = amm_swap_client.fetch_pool_by_id(&pool_id).await.unwrap();
58//!             let pool_keys: PoolKeys<AmmPool> =
59//!                 amm_swap_client.fetch_pools_keys_by_id(&pool_id).await.unwrap();
60//!
61//!             let rpc_data = amm_swap_client
62//!                 .get_rpc_pool_info(&pool_id)
63//!                 .await
64//!                 .map_err(|e| anyhow!("Error fetching rpc pool info {e:?}"))
65//!                 .unwrap();
66//!             let pool = pool_info.data.get(0).unwrap();
67//!             let compute = amm_swap_client
68//!                 .compute_amount_out(&rpc_data, pool, amount_in, slippage)
69//!                 .unwrap();
70//!
71//!             let mint_a_addr = Address::from_str_const(&mint_a_str);
72//!             let mint_b_addr = Address::from_str_const(&mint_b_str);
73//!
74//!             let key = pool_keys.data.get(0).unwrap();
75//!             info!("Standard pool key: {:?}", key);
76//!
77//!             let signature = amm_swap_client
78//!                 .swap_amm(
79//!                     key,
80//!                     &mint_a_addr,
81//!                     &mint_b_addr,
82//!                     amount_in,
83//!                     compute.min_amount_out,
84//!                     None,
85//!                 )
86//!                 .await
87//!                 .unwrap();
88//!             info!("{signature}");
89//!         }
90//!
91//!         PoolType::Concentrated => {
92//!             let first_pool = all_mint_pools.first().ok_or_else(|| anyhow!("no pools"))?;
93//!             let pool_id = Pubkey::from_str(&first_pool.id).unwrap();
94//!             let pool_keys: PoolKeys<ClmmPool> = amm_swap_client
95//!                 .fetch_pools_keys_by_id(&pool_id)
96//!                 .await
97//!                 .unwrap();
98//!             let key = pool_keys.data.get(0).unwrap();
99//!             info!("Standard pool key: {:?}", key);
100//!             let ata_a = solana_pubkey::Pubkey::from(
101//!                 get_associated_token_address(
102//!                     &owner_pubkey,
103//!                     &Address::from_str_const(&mint_a_str),
104//!                 )
105//!                     .to_bytes(),
106//!             );
107//!             let ata_b = solana_pubkey::Pubkey::from(
108//!                 get_associated_token_address(
109//!                     &owner_pubkey,
110//!                     &Address::from_str_const(&mint_b_str),
111//!                 )
112//!                     .to_bytes(),
113//!             );
114//!             println!("ata_a {}", ata_a.to_string());
115//!             let keys = ClmmSwapParams {
116//!                 pool_id: solana_pubkey::Pubkey::from_str(&key.id).unwrap(),
117//!                 user_input_token: ata_a,
118//!                 user_output_token: ata_b,
119//!                 amount_specified: amount_in,
120//!                 limit_price: None,
121//!                 //! if false -> amount is amount_in
122//!                 base_out: false,
123//!                 slippage_bps: 100,
124//!             };
125//!
126//!             let sig = amm_swap_client.swap_clmm(keys).await.unwrap();
127//!             info!("{sig}");
128//!         }
129//!     }
130//!
131//!     Ok(())
132//! }
133//
134use anchor_lang::prelude::declare_id;
135
136// Raydium CLMM program id, used by Anchor
137// account/loader traits for on-chain types.
138declare_id!("CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK");
139pub mod amm;
140pub mod clmm;
141pub mod common;
142pub mod consts;
143pub mod helpers;
144pub mod interface;
145pub mod libraries;
146pub mod states;
147pub mod util;