solana_trader_client_rust/provider/grpc/
swap.rs1use anyhow::Result;
2use base64::{engine::general_purpose, Engine};
3use solana_sdk::{
4 message::{v0, VersionedMessage},
5 transaction::VersionedTransaction,
6};
7use solana_trader_proto::api::{self, PostPumpFunSwapRequestSol};
8use tonic::Request;
9
10use crate::{
11 common::signing::SubmitParams,
12 provider::utils::{
13 convert_address_lookup_table, convert_jupiter_instructions, convert_raydium_instructions,
14 create_transaction_message,
15 },
16};
17
18use super::GrpcClient;
19
20impl GrpcClient {
21 pub async fn post_raydium_swap(
22 &mut self,
23 request: &api::PostRaydiumSwapRequest,
24 ) -> Result<api::PostRaydiumSwapResponse> {
25 let response = self
26 .client
27 .post_raydium_swap(Request::new(request.clone()))
28 .await
29 .map_err(|e| anyhow::anyhow!("PostRaydiumSwap error: {}", e))?;
30
31 Ok(response.into_inner())
32 }
33
34 pub async fn post_raydium_route_swap(
35 &mut self,
36 request: &api::PostRaydiumRouteSwapRequest,
37 ) -> Result<api::PostRaydiumRouteSwapResponse> {
38 let response = self
39 .client
40 .post_raydium_route_swap(Request::new(request.clone()))
41 .await
42 .map_err(|e| anyhow::anyhow!("PostRaydiumRouteSwap error: {}", e))?;
43
44 Ok(response.into_inner())
45 }
46
47 pub async fn post_raydium_swap_instructions(
48 &mut self,
49 request: &api::PostRaydiumSwapInstructionsRequest,
50 ) -> Result<api::PostRaydiumSwapInstructionsResponse> {
51 Ok(self
52 .client
53 .post_raydium_swap_instructions(request.clone())
54 .await?
55 .into_inner())
56 }
57
58 pub async fn submit_raydium_swap_instructions(
59 &mut self,
60 request: api::PostRaydiumSwapInstructionsRequest,
61 submit_opts: SubmitParams,
62 use_bundle: bool,
63 ) -> Result<Vec<String>> {
64 let swap_instructions = self.post_raydium_swap_instructions(&request).await?;
65
66 let instructions = convert_raydium_instructions(&swap_instructions.instructions)?;
67
68 let block_hash = self
69 .client
70 .get_recent_block_hash_v2(api::GetRecentBlockHashRequestV2 { offset: 0 })
71 .await?
72 .into_inner()
73 .block_hash;
74
75 let tx_message = create_transaction_message(instructions, &block_hash)?;
76
77 self.sign_and_submit(vec![tx_message], submit_opts, use_bundle)
78 .await
79 }
80
81 pub async fn post_raydium_cpmm_swap(
82 &mut self,
83 request: &api::PostRaydiumCpmmSwapRequest,
84 ) -> Result<api::PostRaydiumCpmmSwapResponse> {
85 let response = self
86 .client
87 .post_raydium_cpmm_swap(Request::new(request.clone()))
88 .await
89 .map_err(|e| anyhow::anyhow!("PostRaydiumCPMMSwap error: {}", e))?;
90
91 Ok(response.into_inner())
92 }
93
94 pub async fn post_raydium_clmm_swap(
95 &mut self,
96 request: &api::PostRaydiumSwapRequest,
97 ) -> Result<api::PostRaydiumSwapResponse> {
98 let response = self
99 .client
100 .post_raydium_clmm_swap(Request::new(request.clone()))
101 .await
102 .map_err(|e| anyhow::anyhow!("PostRaydiumCLMMSwap error: {}", e))?;
103
104 Ok(response.into_inner())
105 }
106
107 pub async fn post_raydium_clmm_route_swap(
108 &mut self,
109 request: &api::PostRaydiumRouteSwapRequest,
110 ) -> Result<api::PostRaydiumRouteSwapResponse> {
111 let response = self
112 .client
113 .post_raydium_clmm_route_swap(Request::new(request.clone()))
114 .await
115 .map_err(|e| anyhow::anyhow!("PostRaydiumCLMMRouteSwap error: {}", e))?;
116
117 Ok(response.into_inner())
118 }
119
120 pub async fn post_jupiter_swap(
121 &mut self,
122 request: &api::PostJupiterSwapRequest,
123 ) -> Result<api::PostJupiterSwapResponse> {
124 let response = self
125 .client
126 .post_jupiter_swap(Request::new(request.clone()))
127 .await
128 .map_err(|e| anyhow::anyhow!("PostJupiterSwap error: {}", e))?;
129
130 Ok(response.into_inner())
131 }
132
133 pub async fn post_jupiter_route_swap(
134 &mut self,
135 request: &api::PostJupiterRouteSwapRequest,
136 ) -> Result<api::PostJupiterRouteSwapResponse> {
137 let response = self
138 .client
139 .post_jupiter_route_swap(Request::new(request.clone()))
140 .await
141 .map_err(|e| anyhow::anyhow!("PostJupiterRouteSwap error: {}", e))?;
142
143 Ok(response.into_inner())
144 }
145
146 pub async fn post_jupiter_swap_instructions(
147 &mut self,
148 request: &api::PostJupiterSwapInstructionsRequest,
149 ) -> Result<api::PostJupiterSwapInstructionsResponse> {
150 Ok(self
151 .client
152 .post_jupiter_swap_instructions(request.clone())
153 .await?
154 .into_inner())
155 }
156
157 pub async fn submit_jupiter_swap_instructions(
158 &mut self,
159 request: api::PostJupiterSwapInstructionsRequest,
160 submit_opts: SubmitParams,
161 use_bundle: bool,
162 ) -> Result<Vec<String>> {
163 let swap_instructions = self.post_jupiter_swap_instructions(&request).await?;
164
165 let address_lookup_table =
166 convert_address_lookup_table(&swap_instructions.address_lookup_table_addresses)?;
167
168 let instructions = convert_jupiter_instructions(&swap_instructions.instructions)?;
169
170 let blockhash = self
171 .client
172 .get_recent_block_hash_v2(api::GetRecentBlockHashRequestV2 { offset: 0 })
173 .await?
174 .into_inner()
175 .block_hash;
176
177 let message = VersionedMessage::V0(v0::Message::try_compile(
178 &self.public_key.unwrap(),
179 &instructions,
180 &address_lookup_table,
181 blockhash.parse()?,
182 )?);
183
184 let tx: VersionedTransaction =
185 VersionedTransaction::try_new(message, &[self.keypair.as_mut().unwrap()])?;
186
187 let tx_message = api::TransactionMessage {
188 content: general_purpose::STANDARD.encode(bincode::serialize(&tx)?),
189 is_cleanup: false,
190 };
191
192 self.sign_and_submit(vec![tx_message], submit_opts, use_bundle)
193 .await
194 }
195
196 pub async fn post_pump_swap(
197 &mut self,
198 request: &api::PostPumpFunSwapRequest,
199 ) -> Result<api::PostPumpFunSwapResponse> {
200 let response = self
201 .client
202 .post_pump_fun_swap(Request::new(request.clone()))
203 .await
204 .map_err(|e| anyhow::anyhow!("PostPumpFunSwap error: {}", e))?;
205
206 Ok(response.into_inner())
207 }
208
209 pub async fn post_pump_fun_swap_sol(
210 &mut self,
211 request: &PostPumpFunSwapRequestSol,
212 ) -> Result<api::PostPumpFunSwapResponse> {
213 let response: tonic::Response<api::PostPumpFunSwapResponse> = self
214 .client
215 .post_pump_fun_swap_sol(Request::new(request.clone()))
216 .await
217 .map_err(|e| anyhow::anyhow!("PostPumpFunSwapSol error: {}", e))?;
218
219 return Ok(response.into_inner())
220 }
221
222 pub async fn post_pump_fun_amm_swap(
223 &mut self,
224 request: &api::PostPumpFunAmmSwapRequest,
225 ) -> Result<api::PostPumpFunAmmSwapResponse> {
226 let response = self
227 .client
228 .post_pump_fun_amm_swap(Request::new(request.clone()))
229 .await
230 .map_err(|e| anyhow::anyhow!("PostPumpFunAmmSwap error: {}", e))?;
231
232 Ok(response.into_inner())
233 }
234
235 pub async fn post_trade_swap(
236 &mut self,
237 request: &api::TradeSwapRequest,
238 ) -> Result<api::TradeSwapResponse> {
239 let response = self
240 .client
241 .post_trade_swap(Request::new(request.clone()))
242 .await
243 .map_err(|e| anyhow::anyhow!("PostTradeSwap error: {}", e))?;
244
245 Ok(response.into_inner())
246 }
247
248 pub async fn post_route_trade_swap(
249 &mut self,
250 request: &api::RouteTradeSwapRequest,
251 ) -> Result<api::TradeSwapResponse> {
252 let response = self
253 .client
254 .post_route_trade_swap(Request::new(request.clone()))
255 .await
256 .map_err(|e| anyhow::anyhow!("PostRouteTradeSwap error: {}", e))?;
257
258 Ok(response.into_inner())
259 }
260}