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