1use solana_program::{
2 account_info::AccountInfo,
3 entrypoint::ProgramResult,
4 msg,
5 program_error::ProgramError,
6 program_pack::Pack,
7 pubkey::Pubkey,
8 sysvar::{rent::Rent, Sysvar},
9};
10use spl_token::state::Account;
11
12pub fn check_account_key(account: &AccountInfo, key: &Pubkey) -> ProgramResult {
14 if account.key != key {
15 msg!("Wrong account key: {} should be {}", account.key, key);
16 return Err(ProgramError::InvalidArgument);
17 }
18 Ok(())
19}
20
21pub fn check_account_owner(account: &AccountInfo, owner: &Pubkey) -> ProgramResult {
22 if account.owner != owner {
23 msg!("Wrong account owner: {} should be {}", account.owner, owner);
24 return Err(ProgramError::InvalidArgument);
25 }
26 Ok(())
27}
28
29pub fn check_signer(account: &AccountInfo) -> ProgramResult {
30 if !(account.is_signer) {
31 msg!("Missing signature for: {}", account.key);
32 return Err(ProgramError::MissingRequiredSignature);
33 }
34 Ok(())
35}
36
37pub fn check_account_derivation(
38 account: &AccountInfo,
39 seeds: &[&[u8]],
40 program_id: &Pubkey,
41) -> Result<u8, ProgramError> {
42 let (key, nonce) = Pubkey::find_program_address(seeds, program_id);
43 check_account_key(account, &key)?;
44 Ok(nonce)
45}
46
47pub fn check_rent_exempt(account: &AccountInfo) -> ProgramResult {
48 let rent = Rent::get()?;
49 if !rent.is_exempt(account.lamports(), account.data_len()) {
50 return Err(ProgramError::AccountNotRentExempt);
51 }
52 Ok(())
53}
54
55pub fn check_token_account_owner(
56 account: &AccountInfo,
57 owner: &Pubkey,
58) -> Result<Account, ProgramError> {
59 check_account_owner(account, &spl_token::ID)?;
60 let token_account = Account::unpack_from_slice(&account.data.borrow())?;
61 if token_account.owner != *owner {
62 msg!(
63 "Wrong account owner: {} should be {}",
64 token_account.owner,
65 owner
66 );
67 return Err(ProgramError::InvalidArgument);
68 }
69 Ok(token_account)
70}