use crate::error::{Result, ZeraError};
use crate::grpc::{GrpcWebTransport, UnaryTransport, ValidatorApiClient};
use crate::types::RpcConfig;
pub async fn get_nonce(address: &str, config: RpcConfig) -> Result<u64> {
let client = ValidatorApiClient::new(config)?;
get_nonce_with_client(address, &client).await
}
pub async fn get_nonce_with_client<T>(address: &str, client: &ValidatorApiClient<T>) -> Result<u64>
where
T: UnaryTransport,
{
if address.trim().is_empty() {
return Err(ZeraError::InvalidInput(
"Address must be a non-empty string".to_string(),
));
}
let response = client
.get_nonce(address)
.await
.map_err(|error| ZeraError::Rpc(format!("Failed to get nonce from validator: {error}")))?;
Ok(if response.nonce == 0 {
1
} else {
response.nonce + 1
})
}
pub async fn get_nonces(addresses: &[String], config: RpcConfig) -> Result<Vec<u64>> {
let client = ValidatorApiClient::<GrpcWebTransport>::new(config)?;
get_nonces_with_client(addresses, &client).await
}
pub async fn get_nonces_with_client<T>(
addresses: &[String],
client: &ValidatorApiClient<T>,
) -> Result<Vec<u64>>
where
T: UnaryTransport,
{
if addresses.is_empty() {
return Err(ZeraError::InvalidInput(
"Addresses must be a non-empty array".to_string(),
));
}
let mut nonces = Vec::with_capacity(addresses.len());
for address in addresses {
nonces.push(get_nonce_with_client(address, client).await?);
}
Ok(nonces)
}