ogmios_client/
jsonrpsee.rs1use crate::{OgmiosClient, OgmiosClientError, OgmiosParams, query_ledger_state::QueryLedgerState};
5use jsonrpsee::{
6 core::{ClientError, client::ClientT, traits::ToRpcParams},
7 http_client::{HttpClient, HttpClientBuilder},
8 ws_client::{WsClient, WsClientBuilder},
9};
10use serde::de::DeserializeOwned;
11use serde_json::json;
12use std::time::Duration;
13
14fn request_to_json(method: &str, params: impl ToRpcParams) -> Result<String, OgmiosClientError> {
16 let params = params
17 .to_rpc_params()
18 .map_err(|err| OgmiosClientError::ParametersError(err.to_string()))?
19 .unwrap_or_default();
20
21 let req = json!({
22 "method": method,
23 "params": params
24 });
25
26 serde_json::to_string(&req).map_err(|err| OgmiosClientError::ParametersError(err.to_string()))
27}
28
29fn response_to_json(resp: &Result<serde_json::Value, ClientError>) -> String {
31 match &resp {
32 Ok(resp) => serde_json::to_string(&resp).unwrap(),
33 Err(jsonrpsee::core::ClientError::Call(err)) => serde_json::to_string(&err).unwrap(),
34 Err(err) => err.to_string(),
35 }
36}
37
38pub enum OgmiosClients {
40 HttpClient(HttpClient),
41 WsClient(WsClient),
42}
43
44pub async fn client_for_url(addr: &str, timeout: Duration) -> Result<OgmiosClients, String> {
47 if addr.starts_with("http") || addr.starts_with("https") {
48 let client = HttpClientBuilder::default()
49 .max_response_size(250 * 1024 * 1024)
50 .request_timeout(timeout)
51 .build(addr)
52 .map_err(|e| format!("Couldn't create HTTP client: {}", e))?;
53
54 let http_client = OgmiosClients::HttpClient(client);
55
56 http_client
58 .get_tip()
59 .await
60 .map_err(|e| format!("Failed to test HTTP connection: {}", e))?;
61
62 Ok(http_client)
63 } else if addr.starts_with("ws") || addr.starts_with("wss") {
64 let client = WsClientBuilder::default()
65 .max_response_size(250 * 1024 * 1024)
66 .request_timeout(timeout)
67 .build(addr.to_owned())
68 .await
69 .map_err(|e| format!("Couldn't create WebSockets client: {}", e))?;
70 Ok(OgmiosClients::WsClient(client))
71 } else {
72 Err(format!("Invalid Schema of URL: '{}'. Expected http, https, ws or wss.", addr))
73 }
74}
75
76impl OgmiosClient for OgmiosClients {
77 async fn request<T: DeserializeOwned>(
79 &self,
80 method: &str,
81 params: OgmiosParams,
82 ) -> Result<T, OgmiosClientError> {
83 log::debug!("request: {}", request_to_json(method, params.clone())?);
84 let response = match self {
85 OgmiosClients::HttpClient(client) => {
86 ClientT::request::<serde_json::Value, _>(client, method, params).await
87 },
88 OgmiosClients::WsClient(client) => {
89 ClientT::request::<serde_json::Value, _>(client, method, params).await
90 },
91 };
92 log::debug!("response: {}", response_to_json(&response));
93
94 serde_json::from_value(response?)
95 .map_err(|err| OgmiosClientError::ResponseError(err.to_string()))
96 }
97}
98
99impl From<jsonrpsee::core::ClientError> for OgmiosClientError {
100 fn from(e: jsonrpsee::core::ClientError) -> Self {
101 match e {
102 jsonrpsee::core::ClientError::ParseError(e) => {
103 OgmiosClientError::ResponseError(e.to_string())
104 },
105 e => OgmiosClientError::RequestError(e.to_string()),
106 }
107 }
108}