1#[cfg(feature = "client")]
2#[derive(Clone)]
3pub struct HttpClient {
4 client: reqwest::Client,
5 url: String,
6}
7
8#[cfg(feature = "client")]
9impl HttpClient {
10 pub fn new(url: String) -> Self {
11 Self {
12 client: reqwest::Client::new(),
13 url,
14 }
15 }
16
17 pub fn url(&self) -> &str {
18 &self.url
19 }
20
21 pub fn with_client(url: String, client: reqwest::Client) -> Self {
22 Self { client, url }
23 }
24
25 pub async fn rpc(
26 &self,
27 method: &str,
28 params: &serde_json::value::RawValue,
29 ) -> anyhow::Result<serde_json::Value> {
30 let response_body = self
31 .client
32 .post(&self.url)
33 .header("content-type", "application/json")
34 .body(serde_json::to_string(&serde_json::json!({
35 "jsonrpc": "2.0",
36 "id": 0,
37 "method": method,
38 "params": params,
39 }))?)
40 .send()
41 .await?
42 .error_for_status()?
43 .bytes()
44 .await?;
45 let result = serde_json::from_slice::<jsonrpc_core::Response>(&response_body[..])?;
46 let result = match result {
47 jsonrpc_core::Response::Single(o) => match o {
48 jsonrpc_core::Output::Success(s) => s.result,
49 jsonrpc_core::Output::Failure(f) => return Err(f.error.into()),
50 },
51 _ => anyhow::bail!("unexpected batch response"),
52 };
53 Ok(result)
54 }
55}
56
57#[cfg(feature = "blocking-client")]
58#[derive(Clone)]
59pub struct BlockingHttpClient {
60 client: reqwest::blocking::Client,
61 url: String,
62}
63
64#[cfg(feature = "blocking-client")]
65impl BlockingHttpClient {
66 pub fn new(url: String) -> Self {
67 Self {
68 client: reqwest::blocking::Client::new(),
69 url,
70 }
71 }
72
73 pub fn url(&self) -> &str {
74 &self.url
75 }
76
77 pub fn with_client(url: String, client: reqwest::blocking::Client) -> Self {
78 Self { client, url }
79 }
80
81 pub fn rpc(
82 &self,
83 method: &str,
84 params: &serde_json::value::RawValue,
85 ) -> anyhow::Result<serde_json::Value> {
86 let response_body = self
87 .client
88 .post(&self.url)
89 .header("content-type", "application/json")
90 .body(serde_json::to_string(&serde_json::json!({
91 "jsonrpc": "2.0",
92 "id": 0,
93 "method": method,
94 "params": params,
95 }))?)
96 .send()?
97 .error_for_status()?
98 .bytes()?;
99 let result = serde_json::from_slice::<jsonrpc_core::Response>(&response_body[..])?;
100 let result = match result {
101 jsonrpc_core::Response::Single(o) => match o {
102 jsonrpc_core::Output::Success(s) => s.result,
103 jsonrpc_core::Output::Failure(f) => return Err(f.error.into()),
104 },
105 _ => anyhow::bail!("unexpected batch response"),
106 };
107 Ok(result)
108 }
109}