1use serde::{Deserialize, Serialize};
2
3use crate::{common::ExecuteRes, models::ultra::GetHoldingsRes, ultra::order::{OrderReq, OrderRes}, JupiterClient, JupiterError};
4
5
6
7
8#[derive(Debug, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct TransactionRequest {
11 pub signed_transaction: String, pub request_id: String, }
14
15
16
17
18
19#[derive(Clone)]
20pub struct UltraService<'a>{
21 client: &'a JupiterClient,
22}
23
24impl<'a> UltraService<'a> {
26 pub fn new(client: &'a JupiterClient) -> Self {
27 Self { client }
28 }
29
30 pub async fn get_order(&self, req: &OrderReq) -> Result<OrderRes, JupiterError> {
31 let path = "/ultra/v1/order";
32 self.client.get_json_with_query(&path, req,).await
33 }
34
35 pub async fn execute(
36 &self,
37 req: &TransactionRequest,
38 ) -> Result<ExecuteRes, JupiterError> {
39 let path = "/ultra/v1/execute";
40 self.client.post(&path, req).await
41 }
42
43
44 pub async fn get_holdings(
48 &self,
49 address: String,
50 ) -> Result<GetHoldingsRes, JupiterError> {
51 let path = format!("/ultra/v1/holdings/{}", address);
52 self.client.get_json(&path).await
53 }
54}
55
56
57
58
59#[cfg(test)]
60mod tests {
61 use crate::ultra::order::OrderReq;
62
63 use super::*;
64
65 #[tokio::test]
66 async fn test_execute() {
67 let client = JupiterClient::new(crate::JupiterConfig::default()).unwrap();
68 let ultra_service = UltraService::new(&client);
69 let res = ultra_service.get_order(&OrderReq {
70 input_mint: "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN".to_string(),
71 output_mint: "So11111111111111111111111111111111111111112".to_string(),
72 amount: "500".to_string(),
73 taker: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM".to_string(),
74 referral_account: None,
75 referral_fee: None,
76 exclude_dexes: None,
77 exclude_routers: None,
78 }).await.unwrap();
79
80 assert_eq!(res.error_code, None);
81 println!("order: {}", serde_json::to_string_pretty(&res).unwrap());
82
83 let ultra_client = UltraService::new(&client);
84
85 let res = ultra_client.execute(&TransactionRequest {
86 signed_transaction: res.transaction.unwrap(),
87 request_id: res.request_id,
88 }).await;
89
90 match res {
91 Ok(res) => {
92 assert_eq!(res.error_code, None);
93 println!("execute: {}", serde_json::to_string_pretty(&res).unwrap());
94 }
95 Err(e) => {
96 panic!("execute error: {}", e);
97 }
98 }
99 }
100
101 #[tokio::test]
102 async fn test_get_holdings() {
103 let client = JupiterClient::new(crate::JupiterConfig::default()).unwrap();
104 let ultra_client = UltraService::new(&client);
105 let res = ultra_client.get_holdings("ANAUcDCU3Jfao3mtxBdttjEH7F3Ja7SyjGBKUa9Cruc5".to_string()).await.unwrap();
106 assert_eq!(res.error_code, None);
107 println!("holdings: {}", serde_json::to_string_pretty(&res).unwrap());
108 }
109
110 #[tokio::test]
111 async fn test_get_order() {
112 let client = JupiterClient::new(crate::JupiterConfig::default()).unwrap();
113 let ultra_service = UltraService::new(&client);
114 let res = ultra_service.get_order(&OrderReq {
115 input_mint: "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN".to_string(),
116 output_mint: "So11111111111111111111111111111111111111112".to_string(),
117 amount: "500".to_string(),
118 taker: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM".to_string(),
119 referral_account: None,
120 referral_fee: None,
121 exclude_dexes: None,
122 exclude_routers: None,
123 }).await.unwrap();
124
125 assert_eq!(res.error_code, None);
126 println!("order: {}", serde_json::to_string_pretty(&res).unwrap());
127 }
128}