luno_rust_api/luno/
requests.rs

1use super::error::LunoErr;
2use crate::luno::client_builder::LunoClientBuilder;
3use crate::luno::error::ErrKind;
4use crate::luno::structs::{Account, Balance, OrderBook, Tickers};
5use reqwest::{Method, Url};
6use serde_json::from_str;
7use std::collections::HashMap;
8
9const DEFAULT_BASE_URL: &str = "https://api.luno.com";
10const GET_ACCOUNTS: &str = "/api/1/accounts";
11const GET_BALANCE: &str = "/api/1/balance";
12const GET_TICKER: &str = "/api/1/ticker";
13const GET_TICKERS: &str = "/api/1/tickers";
14const GET_ORDERBOOK: &str = "/api/1/orderbook";
15const GET_ORDERBOOK_TOP: &str = "/api/1/orderbook_top";
16
17pub type LunoResult<T> = Result<T, LunoErr>;
18
19#[derive(Debug, Clone)]
20pub struct Luno {
21    client: LunoClientBuilder,
22    pub base_url: String,
23    pub path: Option<Url>,
24    pub method: Method,
25    username: String,
26    password: String,
27}
28
29#[allow(unused)]
30impl Luno {
31    pub async fn init(api_key_id: String, api_key_secret: String) -> Self {
32        Self {
33            client: LunoClientBuilder::new().await,
34            base_url: DEFAULT_BASE_URL.to_string(), //base_url https://api.luno.com
35            username: api_key_id,                   // api_key_id
36            password: api_key_secret,               // api_key_secret
37            path: None,
38            method: Method::GET,
39        }
40    }
41
42    pub async fn create_account(
43        &self,
44        account_name: String,
45        currency_name: String,
46    ) -> LunoResult<Account> {
47        let path = Url::parse(format! {"{}{}", self.base_url, GET_ACCOUNTS}.as_str())?;
48        let result = self
49            .client
50            .create_account_post(
51                path,
52                currency_name,
53                account_name,
54                &self.username,
55                Some(&self.password),
56            )
57            .await;
58
59        match result {
60            Ok(res) => {
61                let res = res.text().await;
62                match res {
63                    Ok(e) => {
64                        let e: Account = from_str(&e).unwrap();
65                        Ok(e)
66                    }
67                    Err(err) => Err(LunoErr {
68                        kind: ErrKind::ErrInvalidArguments,
69                        message: err.to_string(),
70                    }),
71                }
72            }
73            Err(err) => Err(LunoErr {
74                kind: ErrKind::ErrInvalidArguments,
75                message: err.message,
76            }),
77        }
78    }
79
80    pub async fn get_all_balance(&self) -> LunoResult<Vec<Balance>> {
81        let path = Url::parse(format! {"{}{}", self.base_url, GET_BALANCE}.as_str()).unwrap();
82        let result = self
83            .client
84            .get_request(path, &self.username, Some(&self.password))
85            .await;
86        match result {
87            Ok(res) => {
88                let res = res.text().await;
89                match res {
90                    Ok(e) => {
91                        let e: HashMap<String, Vec<_>> = from_str(&e).unwrap();
92                        Ok(e.get("balance").unwrap().to_vec())
93                    }
94                    Err(err) => Err(LunoErr {
95                        kind: ErrKind::ErrInvalidArguments,
96                        message: err.to_string(),
97                    }),
98                }
99            }
100            Err(err) => Err(LunoErr {
101                kind: ErrKind::ErrInvalidArguments,
102                message: err.message,
103            }),
104        }
105    }
106
107    pub async fn get_ticker(&self, pair: &String) -> LunoResult<Tickers> {
108        let path = Url::parse(format! {"{}{}", self.base_url, GET_TICKER}.as_str())?;
109        let result = self
110            .client
111            .get_request_with_params(
112                path,
113                (&"pair".to_string(), pair),
114                &self.username,
115                Some(&self.password),
116            )
117            .await;
118
119        match result {
120            Ok(res) => {
121                let res = res.text().await;
122                match res {
123                    Ok(e) => {
124                        let e: Tickers = from_str(&e).unwrap();
125                        Ok(e)
126                    }
127                    Err(err) => Err(LunoErr {
128                        kind: ErrKind::ErrInvalidArguments,
129                        message: err.to_string(),
130                    }),
131                }
132            }
133            Err(err) => Err(err),
134        }
135    }
136
137    pub async fn get_all_tickers(&self) -> LunoResult<Vec<Tickers>> {
138        let path = Url::parse(format! {"{}{}", self.base_url, GET_TICKERS}.as_str())?;
139        let result = self
140            .client
141            .get_request(path, &self.username, Some(&self.password))
142            .await;
143
144        match result {
145            Ok(res) => {
146                let res = res.text().await;
147                match res {
148                    Ok(res) => {
149                        let res: HashMap<String, Vec<Tickers>> = from_str(&res)?;
150                        Ok(res.get("tickers").unwrap().to_vec())
151                    }
152                    Err(err) => Err(LunoErr {
153                        kind: ErrKind::ErrInvalidArguments,
154                        message: err.to_string(),
155                    }),
156                }
157            }
158            Err(err) => Err(err),
159        }
160    }
161
162    pub async fn get_full_order_book(&self, pair: &String) -> LunoResult<OrderBook> {
163        let path = Url::parse(format! {"{}{}", self.base_url, GET_ORDERBOOK}.as_str())?;
164        let result = self
165            .client
166            .get_request_with_params(
167                path,
168                (&"pair".to_string(), pair),
169                &self.username,
170                Some(&self.password),
171            )
172            .await;
173
174        match result {
175            Ok(res) => {
176                let res = res.text().await;
177                match res {
178                    Ok(e) => {
179                        let e: OrderBook = from_str(&e).unwrap();
180                        Ok(e)
181                    }
182                    Err(err) => Err(LunoErr {
183                        kind: ErrKind::ErrInvalidArguments,
184                        message: err.to_string(),
185                    }),
186                }
187            }
188            Err(err) => Err(err),
189        }
190    }
191
192    pub async fn get_top_order_book(&self, pair: &String) -> LunoResult<OrderBook> {
193        let path = Url::parse(format! {"{}{}", self.base_url, GET_ORDERBOOK_TOP}.as_str())?;
194        let result = self
195            .client
196            .get_request_with_params(
197                path,
198                (&"pair".to_string(), pair),
199                &self.username,
200                Some(&self.password),
201            )
202            .await;
203
204        match result {
205            Ok(res) => {
206                let res = res.text().await;
207                match res {
208                    Ok(e) => {
209                        let e: OrderBook = from_str(&e).unwrap();
210                        Ok(e)
211                    }
212                    Err(err) => Err(LunoErr {
213                        kind: ErrKind::ErrInvalidArguments,
214                        message: err.to_string(),
215                    }),
216                }
217            }
218            Err(err) => Err(err),
219        }
220    }
221
222    pub async fn get_recent_trades(&self, timestamp: String, pair: String) {
223        todo!()
224    }
225}