1use aum_core::prelude::{Request, Response};
2use futures_util::{SinkExt, StreamExt};
3use tokio::net::TcpStream;
4use tokio_tungstenite::{MaybeTlsStream, WebSocketStream, connect_async};
5use tungstenite::http::{Method, Request as WsRequest};
6
7pub struct AumAPI {
8 bind: String,
9}
10impl AumAPI {
11 pub fn new(bind: &str) -> Self {
12 Self {
13 bind: bind.to_owned(),
14 }
15 }
16 pub async fn connect(&self) -> Result<AumConnection, Box<dyn std::error::Error>> {
17 let url = format!("ws://{}", self.bind);
18 let (ws_stream, _) = connect_async(url).await?;
19
20 Ok(AumConnection { ws_stream })
21 }
22}
23
24pub struct AumConnection {
25 ws_stream: WebSocketStream<MaybeTlsStream<TcpStream>>,
26}
27impl AumConnection {
28 pub async fn send_request(
29 &mut self,
30 request: Request,
31 ) -> Result<Response, Box<dyn std::error::Error>> {
32 let request_json = serde_json::to_string(&request)?;
33 self.ws_stream
34 .send(tungstenite::Message::Text(request_json.into()))
35 .await?;
36
37 if let Some(msg) = self.ws_stream.next().await {
38 match msg? {
39 tungstenite::Message::Text(response_json) => {
40 let response: Response = serde_json::from_str(&response_json)?;
41 Ok(response)
42 }
43 _ => Err("Unexpected WebSocket message type".into()),
44 }
45 } else {
46 Err("WebSocket stream closed".into())
47 }
48 }
49
50 pub async fn retrieve_address(&mut self) -> Result<Response, Box<dyn std::error::Error>> {
51 self.send_request(Request::RetrieveAddress).await
52 }
53
54 pub async fn send_transaction(
55 &mut self,
56 to: String,
57 amount: u64,
58 ) -> Result<Response, Box<dyn std::error::Error>> {
59 self.send_request(Request::SendTransaction { to, amount })
60 .await
61 }
62
63 pub async fn send_transaction_from(
64 &mut self,
65 from: String,
66 to: String,
67 amount: u64,
68 ) -> Result<Response, Box<dyn std::error::Error>> {
69 self.send_request(Request::SendTransactionFrom { from, to, amount })
70 .await
71 }
72
73 pub async fn retrieve_balance(
74 &mut self,
75 address: String,
76 ) -> Result<Response, Box<dyn std::error::Error>> {
77 self.send_request(Request::RetrieveBalance { address })
78 .await
79 }
80
81 pub async fn retrieve_balances(&mut self) -> Result<Response, Box<dyn std::error::Error>> {
82 self.send_request(Request::RetrieveBalances).await
83 }
84
85 pub async fn list_wallets(&mut self) -> Result<Response, Box<dyn std::error::Error>> {
86 self.send_request(Request::ListWallets).await
87 }
88
89 pub async fn sync(&mut self) -> Result<Response, Box<dyn std::error::Error>> {
90 self.send_request(Request::Sync).await
91 }
92}