ogmios_client/
lib.rs

1//! This module provides a high-level API for interacting with the Ogmios JSON-RPC API.
2//!
3//! Ogmios is a JSON-RPC server that provides a high-level API for interacting with the Cardano blockchain.
4//! It can be accessed via a HTTP or WebSocket connection.
5//!
6//! More information about Ogmios API can be found at https://ogmios.dev/api/
7
8#[cfg(feature = "jsonrpsee-client")]
9pub mod jsonrpsee;
10pub mod query_ledger_state;
11pub mod query_network;
12pub mod transactions;
13pub mod types;
14
15use ::jsonrpsee::core::{
16	params::{ArrayParams, ObjectParams},
17	traits::ToRpcParams,
18};
19use serde::de::DeserializeOwned;
20use std::collections::HashMap;
21
22#[derive(Debug, Clone, thiserror::Error)]
23/// Represents an error that can occur when interacting with the Ogmios JSON-RPC API.
24pub enum OgmiosClientError {
25	#[error("Couldn't construct parameters: '{0}'")]
26	/// Represents an error that can occur when incorrect parameters are provided to the Ogmios JSON-RPC API.
27	ParametersError(String),
28	#[error("JsonRPC request failed: '{0}'")]
29	/// Represents an error that can occur when the JSON-RPC request fails.
30	RequestError(String),
31	#[error("Could not parse response: '{0}'")]
32	/// Represents an error that can occur when the response from the Ogmios JSON-RPC API cannot be parsed.
33	ResponseError(String),
34}
35
36/// Trait for interacting with the Ogmios JSON-RPC API.
37pub trait OgmiosClient {
38	#[allow(async_fn_in_trait)]
39	/// Sends a JSON-RPC request to the Ogmios server and returns the response.
40	async fn request<T: DeserializeOwned>(
41		&self,
42		method: &str,
43		params: OgmiosParams,
44	) -> Result<T, OgmiosClientError>;
45}
46
47#[derive(Clone)]
48/// Enum representing the parameters for a JSON-RPC request to the Ogmios server.
49pub enum OgmiosParams {
50	/// Represents positional parameters.
51	Positional(Vec<serde_json::Value>),
52	/// Represents named parameters.
53	ByName(HashMap<&'static str, serde_json::Value>),
54}
55
56impl OgmiosParams {
57	pub fn empty_positional() -> Self {
58		OgmiosParams::Positional(Vec::new())
59	}
60
61	pub fn empty_by_name() -> Self {
62		OgmiosParams::ByName(HashMap::new())
63	}
64}
65
66impl ToRpcParams for OgmiosParams {
67	fn to_rpc_params(self) -> Result<Option<Box<serde_json::value::RawValue>>, serde_json::Error> {
68		match self {
69			OgmiosParams::ByName(map) => {
70				let mut object_params = ObjectParams::new();
71				map.into_iter().try_for_each(|(k, v)| object_params.insert(k, v))?;
72				object_params.to_rpc_params()
73			},
74			OgmiosParams::Positional(v) => {
75				let mut array_params = ArrayParams::new();
76				v.into_iter().try_for_each(|v| array_params.insert(v))?;
77				array_params.to_rpc_params()
78			},
79		}
80	}
81}
82
83/// Builder for named parameters.
84pub struct ByNameParamsBuilder {
85	/// The parameters.
86	params: HashMap<&'static str, serde_json::Value>,
87}
88
89impl Default for ByNameParamsBuilder {
90	fn default() -> Self {
91		Self::new()
92	}
93}
94
95impl ByNameParamsBuilder {
96	/// Creates a new builder for named parameters.
97	pub fn new() -> Self {
98		ByNameParamsBuilder { params: HashMap::new() }
99	}
100
101	/// Inserts a new parameter into the builder.
102	pub fn insert<T: serde::Serialize>(
103		self,
104		key: &'static str,
105		value: T,
106	) -> Result<Self, OgmiosClientError> {
107		let value = serde_json::to_value(value)
108			.map_err(|e| OgmiosClientError::ParametersError(e.to_string()))?;
109		let mut params = self.params;
110		params.insert(key, value);
111		Ok(Self { params })
112	}
113
114	/// Builds the named parameters.
115	pub fn build(self) -> OgmiosParams {
116		OgmiosParams::ByName(self.params)
117	}
118}