1use solana_program::{
2 account_info::AccountInfo,
3 entrypoint::ProgramResult,
4 program_error::ProgramError,
5 program_pack::{IsInitialized, Pack},
6 pubkey::Pubkey,
7 rent::Rent,
8};
9
10use crate::cmp_pubkeys;
11
12pub fn assert_signer(account_info: &AccountInfo) -> ProgramResult {
13 if !account_info.is_signer {
14 Err(ProgramError::MissingRequiredSignature)
15 } else {
16 Ok(())
17 }
18}
19
20pub fn assert_initialized<T: Pack + IsInitialized>(
21 account_info: &AccountInfo,
22 error: impl Into<ProgramError>,
23) -> Result<T, ProgramError> {
24 let account: T = T::unpack_unchecked(&account_info.data.borrow())?;
25 if !account.is_initialized() {
26 Err(error.into())
27 } else {
28 Ok(account)
29 }
30}
31
32pub fn assert_owned_by(
33 account: &AccountInfo,
34 owner: &Pubkey,
35 error: impl Into<ProgramError>,
36) -> ProgramResult {
37 if account.owner != owner {
38 Err(error.into())
39 } else {
40 Ok(())
41 }
42}
43
44pub fn assert_owner_in(
45 account: &AccountInfo,
46 owners: &[Pubkey],
47 error: impl Into<ProgramError>,
48) -> ProgramResult {
49 if owners.iter().any(|owner| cmp_pubkeys(owner, account.owner)) {
50 Ok(())
51 } else {
52 Err(error.into())
53 }
54}
55
56pub fn assert_derivation(
57 program_id: &Pubkey,
58 account: &AccountInfo,
59 path: &[&[u8]],
60 error: impl Into<ProgramError>,
61) -> Result<u8, ProgramError> {
62 let (key, bump) = Pubkey::find_program_address(path, program_id);
63 if key != *account.key {
64 return Err(error.into());
65 }
66 Ok(bump)
67}
68
69pub fn assert_derivation_with_bump(
70 program_id: &Pubkey,
71 account: &AccountInfo,
72 path: &[&[u8]],
73 error: impl Into<ProgramError>,
74) -> Result<(), ProgramError> {
75 let key = Pubkey::create_program_address(path, program_id)?;
76 if key != *account.key {
77 return Err(error.into());
78 }
79 Ok(())
80}
81
82pub fn assert_rent_exempt(
83 rent: &Rent,
84 account_info: &AccountInfo,
85 error: impl Into<ProgramError>,
86) -> ProgramResult {
87 if !rent.is_exempt(account_info.lamports(), account_info.data_len()) {
88 Err(error.into())
89 } else {
90 Ok(())
91 }
92}