melwallet_client/
client.rs

1use std::net::SocketAddr;
2
3use async_trait::async_trait;
4use http_types::{Method, Request, Response, Url};
5use nanorpc::{JrpcRequest, JrpcResponse, RpcTransport};
6use smol::net::TcpStream;
7
8use anyhow::anyhow;
9
10/// A client to a particular wallet daemon.
11#[derive(Clone, Debug)]
12pub struct DaemonClient {
13    endpoint: SocketAddr,
14}
15
16#[async_trait]
17impl RpcTransport for DaemonClient {
18    type Error = anyhow::Error;
19
20    async fn call_raw(&self, req: JrpcRequest) -> Result<JrpcResponse, Self::Error> {
21        let to_send = serde_json::to_string(&req).unwrap();
22        let mut res = http_post(self.endpoint, "", &to_send)
23            .await
24            .map_err(|_| anyhow!("failed to POST to melwalletd"))?;
25        let result: JrpcResponse = res
26            .body_json()
27            .await
28            .map_err(|_| anyhow!("Unable to deserialize response"))?;
29        return Ok(result);
30    }
31}
32impl DaemonClient {
33    /// Creates a new client.
34    pub fn new(endpoint: SocketAddr) -> Self {
35        Self { endpoint }
36    }
37}
38
39async fn http_post(endpoint: SocketAddr, _path: &str, body: &str) -> http_types::Result<Response> {
40    let conn = TcpStream::connect(endpoint).await?;
41    let mut req = Request::new(Method::Post, Url::parse(&format!("http://{}/", endpoint))?);
42    req.set_body(body);
43    async_h1::connect(conn, req).await
44}