1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
use crate::rpc_client::RpcClient; use solana_sdk::{ account::Account, account_utils::StateMut, commitment_config::CommitmentConfig, nonce::{ state::{Data, Versions}, State, }, pubkey::Pubkey, system_program, }; #[derive(Debug, thiserror::Error, PartialEq)] pub enum Error { #[error("invalid account owner")] InvalidAccountOwner, #[error("invalid account data")] InvalidAccountData, #[error("unexpected account data size")] UnexpectedDataSize, #[error("query hash does not match stored hash")] InvalidHash, #[error("query authority does not match account authority")] InvalidAuthority, #[error("invalid state for requested operation")] InvalidStateForOperation, #[error("client error: {0}")] Client(String), } pub fn get_account(rpc_client: &RpcClient, nonce_pubkey: &Pubkey) -> Result<Account, Error> { get_account_with_commitment(rpc_client, nonce_pubkey, CommitmentConfig::default()) } pub fn get_account_with_commitment( rpc_client: &RpcClient, nonce_pubkey: &Pubkey, commitment: CommitmentConfig, ) -> Result<Account, Error> { rpc_client .get_account_with_commitment(nonce_pubkey, commitment) .map_err(|e| Error::Client(format!("{}", e))) .and_then(|result| { result .value .ok_or_else(|| Error::Client(format!("AccountNotFound: pubkey={}", nonce_pubkey))) }) .and_then(|a| match account_identity_ok(&a) { Ok(()) => Ok(a), Err(e) => Err(e), }) } pub fn account_identity_ok(account: &Account) -> Result<(), Error> { if account.owner != system_program::id() { Err(Error::InvalidAccountOwner) } else if account.data.is_empty() { Err(Error::UnexpectedDataSize) } else { Ok(()) } } pub fn state_from_account(account: &Account) -> Result<State, Error> { account_identity_ok(account)?; StateMut::<Versions>::state(account) .map_err(|_| Error::InvalidAccountData) .map(|v| v.convert_to_current()) } pub fn data_from_account(account: &Account) -> Result<Data, Error> { account_identity_ok(account)?; state_from_account(account).and_then(|ref s| data_from_state(s).map(|d| d.clone())) } pub fn data_from_state(state: &State) -> Result<&Data, Error> { match state { State::Uninitialized => Err(Error::InvalidStateForOperation), State::Initialized(data) => Ok(data), } }