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_quotes(
47        &self,
48        request: &api::GetRaydiumClmmQuotesRequest,
49    ) -> Result<api::GetRaydiumClmmQuotesResponse> {
50        let url = format!(
51            "{}/api/v2/raydium/clmm-quotes?inToken={}&outToken={}&inAmount={}&slippage={}",
52            self.base_url, request.in_token, request.out_token, request.in_amount, request.slippage
53        );
54
55        let response = self
56            .client
57            .get(&url)
58            .send()
59            .await
60            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
61
62        self.handle_response(response).await
63    }
64
65    pub async fn get_pump_fun_quotes(
66        &self,
67        request: &api::GetPumpFunQuotesRequest,
68    ) -> Result<api::GetPumpFunQuotesResponse> {
69        let url = format!(
70            "{}/api/v2/pumpfun/quotes?mintAddress={}&quoteType={}&amount={}&bondingCurveAddress={}",
71            self.base_url,
72            request.mint_address,
73            request.quote_type,
74            request.amount,
75            request.bonding_curve_address,
76        );
77
78        let response = self
79            .client
80            .get(&url)
81            .send()
82            .await
83            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
84
85        self.handle_response(response).await
86    }
87
88    // NOTE: Fast mode is not used as of 11/1, breaks the endpoint.
89    pub async fn get_jupiter_quotes(
90        &self,
91        request: &api::GetJupiterQuotesRequest,
92    ) -> Result<api::GetJupiterQuotesResponse> {
93        let url = format!(
94            "{}/api/v2/jupiter/quotes?inToken={}&outToken={}&inAmount={}&slippage={}",
95            self.base_url, request.in_token, request.out_token, request.in_amount, request.slippage,
96        );
97
98        let response = self
99            .client
100            .get(&url)
101            .send()
102            .await
103            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
104
105        self.handle_response(response).await
106    }
107
108    pub async fn get_quotes(
109        &self,
110        in_token: &str,
111        out_token: &str,
112        in_amount: f64,
113        slippage: f64,
114        limit: i32,
115        projects: &[api::Project],
116    ) -> Result<api::GetQuotesResponse> {
117        let project_params: Vec<String> = projects
118            .iter()
119            .map(|p| format!("&project={}", *p as i32))
120            .collect();
121
122        let url = format!(
123            "{}/api/v1/market/quote?inToken={}&outToken={}&inAmount={}&slippage={}&limit={}{}",
124            self.base_url,
125            in_token,
126            out_token,
127            in_amount,
128            slippage,
129            limit,
130            project_params.join("")
131        );
132
133        let response = self
134            .client
135            .get(&url)
136            .send()
137            .await
138            .map_err(|e| anyhow::anyhow!("HTTP GET request failed: {}", e))?;
139
140        let response_text = response.text().await?;
141
142        let mut value: serde_json::Value = serde_json::from_str(&response_text)
143            .map_err(|e| anyhow::anyhow!("Failed to parse response as JSON: {}", e))?;
144
145        convert_string_enums(&mut value);
146
147        serde_json::from_value(value)
148            .map_err(|e| anyhow::anyhow!("Failed to parse response into GetQuotesResponse: {}", e))
149    }
150
151    pub async fn get_raydium_prices(
152        &self,
153        tokens: Vec<String>,
154    ) -> Result<api::GetRaydiumPricesResponse> {
155        let mut url = format!("{}/api/v2/raydium/prices?", self.base_url);
156        for (i, token) in tokens.iter().enumerate() {
157            if i > 0 {
158                url.push('&');
159            }
160            url.push_str(&format!("tokens={}", token));
161        }
162
163        let response = self.client.get(&url).send().await?;
164        self.handle_response(response).await
165    }
166
167    pub async fn get_jupiter_prices(
168        &self,
169        tokens: Vec<String>,
170    ) -> Result<api::GetJupiterPricesResponse> {
171        let mut url = format!("{}/api/v2/jupiter/prices?", self.base_url);
172        for (i, token) in tokens.iter().enumerate() {
173            if i > 0 {
174                url.push('&');
175            }
176            url.push_str(&format!("tokens={}", token));
177        }
178
179        let response = self.client.get(&url).send().await?;
180        self.handle_response(response).await
181    }
182}