use std::time::Duration;
use serde::{de::DeserializeOwned, Serialize};
use solana_rpc_client_api::request::RpcRequest;
use solana_sdk::commitment_config::CommitmentConfig;
use crate::client_traits::RpcSender;
use super::RpcClient;
#[cfg(http_rpc_sender)]
use crate::client_traits::rpc_sender::HttpRpcSender;
#[derive(Debug, Default, Clone)]
pub struct GenericRpcClientConfig {
pub commitment_config: CommitmentConfig,
pub confirm_transaction_initial_timeout: Option<Duration>,
}
#[derive(Debug, Clone)]
pub struct GenericRpcClient<S> {
sender: S,
config: GenericRpcClientConfig,
}
impl<S> GenericRpcClient<S> {
pub fn new_with_sender_and_config(sender: S, config: GenericRpcClientConfig) -> Self {
Self { sender, config }
}
}
#[cfg(http_rpc_sender)]
impl GenericRpcClient<HttpRpcSender> {
pub fn new_with_commitment(url: impl ToString, commitment: CommitmentConfig) -> Self {
Self::new_with_sender_and_config(
HttpRpcSender::new(url),
GenericRpcClientConfig {
commitment_config: commitment,
..Default::default()
},
)
}
pub fn new(url: impl ToString) -> Self {
Self::new_with_commitment(url, Default::default())
}
}
impl<S: RpcSender> RpcClient for GenericRpcClient<S> {
fn commitment(&self) -> CommitmentConfig {
self.config.commitment_config
}
async fn send<T>(&self, request: RpcRequest, params: impl Serialize) -> crate::Result<T>
where
T: DeserializeOwned,
{
let params = serde_json::to_value(params)?;
if !params.is_array() && !params.is_null() {
return Err(crate::Error::custom(
"`params` is neither an array nor null",
));
}
let response = self.sender.send(request, params).await?;
Ok(serde_json::from_value(response)?)
}
}