manifest/validation/
solana_checkers.rs1use crate::require;
2use solana_program::{
3 account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, system_program,
4};
5use std::ops::Deref;
6
7#[derive(Clone)]
8pub struct Program<'a, 'info> {
9 pub info: &'a AccountInfo<'info>,
10}
11
12impl<'a, 'info> Program<'a, 'info> {
13 pub fn new(
14 info: &'a AccountInfo<'info>,
15 expected_program_id: &Pubkey,
16 ) -> Result<Program<'a, 'info>, ProgramError> {
17 require!(
18 info.key == expected_program_id,
19 ProgramError::IncorrectProgramId,
20 "Incorrect program id",
21 )?;
22 Ok(Self { info })
23 }
24}
25
26impl<'a, 'info> AsRef<AccountInfo<'info>> for Program<'a, 'info> {
27 fn as_ref(&self) -> &AccountInfo<'info> {
28 self.info
29 }
30}
31
32#[derive(Clone)]
33pub struct TokenProgram<'a, 'info> {
34 pub info: &'a AccountInfo<'info>,
35}
36
37impl<'a, 'info> TokenProgram<'a, 'info> {
38 pub fn new(info: &'a AccountInfo<'info>) -> Result<TokenProgram<'a, 'info>, ProgramError> {
39 require!(
40 *info.key == spl_token::id() || *info.key == spl_token_2022::id(),
41 ProgramError::IncorrectProgramId,
42 "Incorrect token program id: {:?}",
43 info.key
44 )?;
45 Ok(Self { info })
46 }
47}
48
49impl<'a, 'info> AsRef<AccountInfo<'info>> for TokenProgram<'a, 'info> {
50 fn as_ref(&self) -> &AccountInfo<'info> {
51 self.info
52 }
53}
54
55impl<'a, 'info> Deref for TokenProgram<'a, 'info> {
56 type Target = AccountInfo<'info>;
57
58 fn deref(&self) -> &Self::Target {
59 self.info
60 }
61}
62
63#[derive(Clone)]
64pub struct Signer<'a, 'info> {
65 pub info: &'a AccountInfo<'info>,
66}
67
68impl<'a, 'info> Signer<'a, 'info> {
69 pub fn new(info: &'a AccountInfo<'info>) -> Result<Signer<'a, 'info>, ProgramError> {
70 require!(
71 info.is_signer,
72 ProgramError::MissingRequiredSignature,
73 "Missing required signature",
74 )?;
75 Ok(Self { info })
76 }
77
78 pub fn new_payer(info: &'a AccountInfo<'info>) -> Result<Signer<'a, 'info>, ProgramError> {
79 require!(
80 info.is_writable,
81 ProgramError::InvalidInstructionData,
82 "Payer is not writable",
83 )?;
84 require!(
85 info.is_signer,
86 ProgramError::MissingRequiredSignature,
87 "Missing required signature for payer",
88 )?;
89 Ok(Self { info })
90 }
91}
92
93impl<'a, 'info> AsRef<AccountInfo<'info>> for Signer<'a, 'info> {
94 fn as_ref(&self) -> &AccountInfo<'info> {
95 self.info
96 }
97}
98
99impl<'a, 'info> Deref for Signer<'a, 'info> {
100 type Target = AccountInfo<'info>;
101
102 fn deref(&self) -> &Self::Target {
103 self.info
104 }
105}
106
107#[derive(Clone)]
108pub struct EmptyAccount<'a, 'info> {
109 pub info: &'a AccountInfo<'info>,
110}
111
112impl<'a, 'info> EmptyAccount<'a, 'info> {
113 pub fn new(info: &'a AccountInfo<'info>) -> Result<EmptyAccount<'a, 'info>, ProgramError> {
114 require!(
115 info.data_is_empty(),
116 ProgramError::InvalidAccountData,
117 "Account must be uninitialized",
118 )?;
119 require!(
120 info.owner == &system_program::id(),
121 ProgramError::IllegalOwner,
122 "Empty accounts must be owned by the system program",
123 )?;
124 Ok(Self { info })
125 }
126}
127
128impl<'a, 'info> AsRef<AccountInfo<'info>> for EmptyAccount<'a, 'info> {
129 fn as_ref(&self) -> &AccountInfo<'info> {
130 self.info
131 }
132}