use async_trait::async_trait;
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_client::rpc_config::RpcSendTransactionConfig;
use solana_sdk::hash::Hash;
use solana_sdk::transaction::Transaction;
use crate::error::{Result, ZeraError};
#[async_trait]
pub trait SolanaRpc: Send + Sync {
async fn latest_blockhash(&self) -> Result<Hash>;
async fn send_transaction(
&self,
transaction: &Transaction,
skip_preflight: bool,
) -> Result<String>;
async fn send_and_confirm_transaction(
&self,
transaction: &Transaction,
skip_preflight: bool,
) -> Result<String>;
}
#[async_trait]
impl SolanaRpc for RpcClient {
async fn latest_blockhash(&self) -> Result<Hash> {
self.get_latest_blockhash()
.await
.map_err(|error| ZeraError::Rpc(error.to_string()))
}
async fn send_transaction(
&self,
transaction: &Transaction,
skip_preflight: bool,
) -> Result<String> {
let signature = if skip_preflight {
self.send_transaction_with_config(
transaction,
RpcSendTransactionConfig {
skip_preflight: true,
preflight_commitment: Some(self.commitment().commitment),
..RpcSendTransactionConfig::default()
},
)
.await
} else {
self.send_transaction(transaction).await
}
.map_err(|error| ZeraError::Rpc(error.to_string()))?;
Ok(signature.to_string())
}
async fn send_and_confirm_transaction(
&self,
transaction: &Transaction,
skip_preflight: bool,
) -> Result<String> {
let signature = if skip_preflight {
self.send_and_confirm_transaction_with_spinner_and_config(
transaction,
self.commitment(),
RpcSendTransactionConfig {
skip_preflight: true,
preflight_commitment: Some(self.commitment().commitment),
..RpcSendTransactionConfig::default()
},
)
.await
} else {
self.send_and_confirm_transaction(transaction).await
}
.map_err(|error| ZeraError::Rpc(error.to_string()))?;
Ok(signature.to_string())
}
}