use crate::error::{Error, Result};
use crate::pubkey::Pubkey;
use crate::rpc::Account;
pub const NONCE_ACCOUNT_LEN: usize = 80;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NonceState {
pub authority: Pubkey,
pub durable_nonce: [u8; 32],
pub lamports_per_signature: u64,
}
impl NonceState {
pub fn parse(account: &Account) -> Result<Self> {
if !account.owner.is_zeroed() {
return Err(Error::InvalidAccountData(format!(
"nonce account is owned by {}, expected the system program",
account.owner.abbreviated()
)));
}
if account.data.len() < NONCE_ACCOUNT_LEN {
return Err(Error::InvalidAccountData(format!(
"nonce account is {} bytes, expected {NONCE_ACCOUNT_LEN}",
account.data.len()
)));
}
let version = u32::from_le_bytes(account.data[0..4].try_into().unwrap());
match version {
0 => return Err(Error::InvalidAccountData("nonce account is uninitialized".into())),
1 => {}
other => {
return Err(Error::InvalidAccountData(format!(
"unknown nonce account version {other}"
)))
}
}
let mut authority = [0u8; 32];
authority.copy_from_slice(&account.data[4..36]);
let mut durable_nonce = [0u8; 32];
durable_nonce.copy_from_slice(&account.data[36..68]);
Ok(NonceState {
authority: Pubkey::new_from_array(authority),
durable_nonce,
lamports_per_signature: u64::from_le_bytes(account.data[68..76].try_into().unwrap()),
})
}
pub fn nonce_base58(&self) -> String {
bs58::encode(self.durable_nonce).into_string()
}
}