solana_trader_client_rust/provider/http/
quote.rs

1use crate::provider::utils::convert_string_enums;
2
3use super::HTTPClient;
4use anyhow::{anyhow, Result};
5use solana_trader_proto::api;
6
7impl HTTPClient {
8    pub async fn get_raydium_quotes(
9        &self,
10        request: &api::GetRaydiumQuotesRequest,
11    ) -> Result<api::GetRaydiumQuotesResponse> {
12        let url = format!(
13            "{}/api/v2/raydium/quotes?inToken={}&outToken={}&inAmount={}&slippage={}",
14            self.base_url, request.in_token, request.out_token, request.in_amount, request.slippage
15        );
16
17        let response = self
18            .client
19            .get(&url)
20            .send()
21            .await
22            .map_err(|e| anyhow!("HTTP GET request failed: {}", e))?;
23
24        self.handle_response(response).await
25    }
26
27    pub async fn get_raydium_cpmm_quotes(
28        &self,
29        request: &api::GetRaydiumCpmmQuotesRequest,
30    ) -> Result<api::GetRaydiumCpmmQuotesResponse> {
31        let url = format!(
32            "{}/api/v2/raydium/cpmm-quotes?inToken={}&outToken={}&inAmount={}&slippage={}",
33            self.base_url, request.in_token, request.out_token, request.in_amount, request.slippage
34        );
35
36        let response = self
37            .client
38            .get(&url)
39            .send()
40            .await
41            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
42
43        self.handle_response(response).await
44    }
45
46    pub async fn get_raydium_clmm_pools(
47        &self,
48        pair_or_address: String
49    ) -> anyhow::Result<api::GetRaydiumClmmPoolsResponse> {
50        let url = format!("{}/api/v2/raydium/clmm-pools?pairOrAddress={}", self.base_url, pair_or_address);
51        println!("{}", url);
52        
53        let response = self
54            .client
55            .get(&url)
56            .send()
57            .await?;
58            
59        let result: api::GetRaydiumClmmPoolsResponse = self.handle_response(response).await?;
60        
61        Ok(result)
62    }
63
64    pub async fn get_raydium_pools(
65        &self
66    ) -> anyhow::Result<api::GetRaydiumPoolsResponse> {
67        let url = format!("{}/api/v2/raydium/pools", self.base_url);
68        println!("{}", url);
69        
70        let response = self
71            .client
72            .get(&url)
73            .send()
74            .await?;
75            
76        let result: api::GetRaydiumPoolsResponse = self.handle_response(response).await?;
77        
78        Ok(result)
79    }
80
81    pub async fn get_raydium_pool_reserve(
82        &self,
83        pairs_or_addresses: Vec<String>
84    ) -> anyhow::Result<api::GetRaydiumPoolReserveResponse> {
85        let pairs_query = pairs_or_addresses.join(",");
86        let url = format!("{}/api/v2/raydium/pool-reserves?pairsOrAddresses={}", self.base_url, pairs_query);
87        println!("{}", url);
88        
89        let response = self
90            .client
91            .get(&url)
92            .send()
93            .await?;
94            
95        let result: api::GetRaydiumPoolReserveResponse = self.handle_response(response).await?;
96        
97        Ok(result)
98    }
99
100    pub async fn get_raydium_clmm_quotes(
101        &self,
102        request: &api::GetRaydiumClmmQuotesRequest,
103    ) -> Result<api::GetRaydiumClmmQuotesResponse> {
104        let url = format!(
105            "{}/api/v2/raydium/clmm-quotes?inToken={}&outToken={}&inAmount={}&slippage={}",
106            self.base_url, request.in_token, request.out_token, request.in_amount, request.slippage
107        );
108
109        let response = self
110            .client
111            .get(&url)
112            .send()
113            .await
114            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
115
116        self.handle_response(response).await
117    }
118
119    pub async fn get_pump_fun_quotes(
120        &self,
121        request: &api::GetPumpFunQuotesRequest,
122    ) -> Result<api::GetPumpFunQuotesResponse> {
123        let url = format!(
124            "{}/api/v2/pumpfun/quotes?mintAddress={}&quoteType={}&amount={}&bondingCurveAddress={}",
125            self.base_url,
126            request.mint_address,
127            request.quote_type,
128            request.amount,
129            request.bonding_curve_address,
130        );
131
132        let response = self
133            .client
134            .get(&url)
135            .send()
136            .await
137            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
138
139        self.handle_response(response).await
140    }
141
142    // NOTE: Fast mode is not used as of 11/1, breaks the endpoint.
143    pub async fn get_jupiter_quotes(
144        &self,
145        request: &api::GetJupiterQuotesRequest,
146    ) -> Result<api::GetJupiterQuotesResponse> {
147        let url = format!(
148            "{}/api/v2/jupiter/quotes?inToken={}&outToken={}&inAmount={}&slippage={}",
149            self.base_url, request.in_token, request.out_token, request.in_amount, request.slippage,
150        );
151
152        let response = self
153            .client
154            .get(&url)
155            .send()
156            .await
157            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
158
159        self.handle_response(response).await
160    }
161
162    pub async fn get_quotes(
163        &self,
164        in_token: &str,
165        out_token: &str,
166        in_amount: f64,
167        slippage: f64,
168        limit: i32,
169        projects: &[api::Project],
170    ) -> Result<api::GetQuotesResponse> {
171        let project_params: Vec<String> = projects
172            .iter()
173            .map(|p| format!("&project={}", *p as i32))
174            .collect();
175
176        let url = format!(
177            "{}/api/v1/market/quote?inToken={}&outToken={}&inAmount={}&slippage={}&limit={}{}",
178            self.base_url,
179            in_token,
180            out_token,
181            in_amount,
182            slippage,
183            limit,
184            project_params.join("")
185        );
186
187        let response = self
188            .client
189            .get(&url)
190            .send()
191            .await
192            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
193
194        let response_text = response.text().await?;
195
196        let mut value: serde_json::Value = serde_json::from_str(&response_text)
197            .map_err(|e| anyhow::anyhow!("Failed to parse response as JSON: {}", e))?;
198
199        convert_string_enums(&mut value);
200
201        serde_json::from_value(value)
202            .map_err(|e| anyhow::anyhow!("Failed to parse response into GetQuotesResponse: {}", e))
203    }
204
205    pub async fn get_raydium_prices(
206        &self,
207        tokens: Vec<String>,
208    ) -> Result<api::GetRaydiumPricesResponse> {
209        let mut url = format!("{}/api/v2/raydium/prices?", self.base_url);
210        for (i, token) in tokens.iter().enumerate() {
211            if i > 0 {
212                url.push('&');
213            }
214            url.push_str(&format!("tokens={}", token));
215        }
216
217        let response = self.client.get(&url).send().await?;
218        self.handle_response(response).await
219    }
220
221    pub async fn get_jupiter_prices(
222        &self,
223        tokens: Vec<String>,
224    ) -> Result<api::GetJupiterPricesResponse> {
225        let mut url = format!("{}/api/v2/jupiter/prices?", self.base_url);
226        for (i, token) in tokens.iter().enumerate() {
227            if i > 0 {
228                url.push('&');
229            }
230            url.push_str(&format!("tokens={}", token));
231        }
232
233        let response = self.client.get(&url).send().await?;
234        self.handle_response(response).await
235    }
236}