mpl_utils/
assertions.rs

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}