use crate::{error::CounterError, state::Key};
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError,
pubkey::Pubkey,
};
pub fn assert_program_owner(
account_name: &str,
account: &AccountInfo,
owner: &Pubkey,
) -> ProgramResult {
if account.owner != owner {
msg!(
"Account \"{}\" [{}] expected program owner [{}], got [{}]",
account_name,
account.key,
owner,
account.owner
);
Err(CounterError::InvalidProgramOwner.into())
} else {
Ok(())
}
}
pub fn assert_pda(
account_name: &str,
account: &AccountInfo,
program_id: &Pubkey,
seeds: &[&[u8]],
) -> Result<u8, ProgramError> {
let (key, bump) = Pubkey::find_program_address(seeds, program_id);
if *account.key != key {
msg!(
"Account \"{}\" [{}] is an invalid PDA. Expected the following valid PDA [{}]",
account_name,
account.key,
key,
);
return Err(CounterError::InvalidPda.into());
}
Ok(bump)
}
pub fn assert_empty(account_name: &str, account: &AccountInfo) -> ProgramResult {
if !account.data_is_empty() {
msg!(
"Account \"{}\" [{}] must be empty",
account_name,
account.key,
);
Err(CounterError::ExpectedEmptyAccount.into())
} else {
Ok(())
}
}
pub fn assert_non_empty(account_name: &str, account: &AccountInfo) -> ProgramResult {
if account.data_is_empty() {
msg!(
"Account \"{}\" [{}] must not be empty",
account_name,
account.key,
);
Err(CounterError::ExpectedNonEmptyAccount.into())
} else {
Ok(())
}
}
pub fn assert_signer(account_name: &str, account: &AccountInfo) -> ProgramResult {
if !account.is_signer {
msg!(
"Account \"{}\" [{}] must be a signer",
account_name,
account.key,
);
Err(CounterError::ExpectedSignerAccount.into())
} else {
Ok(())
}
}
pub fn assert_writable(account_name: &str, account: &AccountInfo) -> ProgramResult {
if !account.is_writable {
msg!(
"Account \"{}\" [{}] must be writable",
account_name,
account.key,
);
Err(CounterError::ExpectedWritableAccount.into())
} else {
Ok(())
}
}
pub fn assert_same_pubkeys(
account_name: &str,
account: &AccountInfo,
expected: &Pubkey,
) -> ProgramResult {
if account.key != expected {
msg!(
"Account \"{}\" [{}] must match the following public key [{}]",
account_name,
account.key,
expected
);
Err(CounterError::AccountMismatch.into())
} else {
Ok(())
}
}
pub fn assert_account_key(account_name: &str, account: &AccountInfo, key: Key) -> ProgramResult {
let key_number = key as u8;
if account.data_len() <= 1 || account.try_borrow_data()?[0] != key_number {
msg!(
"Account \"{}\" [{}] expected account key [{}], got [{}]",
account_name,
account.key,
key_number,
account.try_borrow_data()?[0]
);
Err(CounterError::InvalidAccountKey.into())
} else {
Ok(())
}
}