phoenix/program/validation/checkers/
mod.rs1use crate::program::error::assert_with_msg;
2use solana_program::{
3 account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, system_program,
4};
5use std::ops::Deref;
6
7pub mod phoenix_checkers;
8pub mod token_checkers;
9
10pub use token_checkers::*;
11
12#[derive(Clone)]
13pub struct PDA<'a, 'info> {
14 info: &'a AccountInfo<'info>,
15}
16
17impl<'a, 'info> PDA<'a, 'info> {
18 pub fn new(
19 info: &'a AccountInfo<'info>,
20 known_address: &Pubkey,
21 ) -> Result<PDA<'a, 'info>, ProgramError> {
22 assert_with_msg(
23 info.key == known_address,
24 ProgramError::InvalidInstructionData,
25 "Incorrect account key",
26 )?;
27 Ok(Self { info })
28 }
29}
30
31impl<'a, 'info> AsRef<AccountInfo<'info>> for PDA<'a, 'info> {
32 fn as_ref(&self) -> &AccountInfo<'info> {
33 self.info
34 }
35}
36
37impl<'a, 'info> Deref for PDA<'a, 'info> {
38 type Target = AccountInfo<'info>;
39
40 fn deref(&self) -> &Self::Target {
41 self.info
42 }
43}
44
45#[derive(Clone)]
46pub struct Program<'a, 'info> {
47 info: &'a AccountInfo<'info>,
48}
49
50impl<'a, 'info> Program<'a, 'info> {
51 pub fn new(
52 info: &'a AccountInfo<'info>,
53 expected_program_id: &Pubkey,
54 ) -> Result<Program<'a, 'info>, ProgramError> {
55 assert_with_msg(
56 info.key == expected_program_id,
57 ProgramError::IncorrectProgramId,
58 "Incorrect program id",
59 )?;
60 Ok(Self { info })
61 }
62}
63
64impl<'a, 'info> AsRef<AccountInfo<'info>> for Program<'a, 'info> {
65 fn as_ref(&self) -> &AccountInfo<'info> {
66 self.info
67 }
68}
69
70impl<'a, 'info> Deref for Program<'a, 'info> {
71 type Target = AccountInfo<'info>;
72
73 fn deref(&self) -> &Self::Target {
74 self.info
75 }
76}
77
78#[derive(Clone)]
79pub struct Signer<'a, 'info> {
80 info: &'a AccountInfo<'info>,
81}
82
83impl<'a, 'info> Signer<'a, 'info> {
84 pub fn new(info: &'a AccountInfo<'info>) -> Result<Signer<'a, 'info>, ProgramError> {
85 assert_with_msg(
86 info.is_signer,
87 ProgramError::MissingRequiredSignature,
88 "Missing required signature",
89 )?;
90 Ok(Self { info })
91 }
92
93 pub fn new_with_key(
94 info: &'a AccountInfo<'info>,
95 key: &Pubkey,
96 ) -> Result<Signer<'a, 'info>, ProgramError> {
97 let signer = Self::new(info)?;
98 assert_with_msg(
99 signer.key == key,
100 ProgramError::MissingRequiredSignature,
101 "Incorrect key for signer",
102 )?;
103 Ok(signer)
104 }
105
106 pub fn new_payer(info: &'a AccountInfo<'info>) -> Result<Signer<'a, 'info>, ProgramError> {
107 assert_with_msg(
108 info.is_writable,
109 ProgramError::InvalidInstructionData,
110 "Payer is not writable",
111 )?;
112 assert_with_msg(
113 info.is_signer,
114 ProgramError::MissingRequiredSignature,
115 "Missing required signature for payer",
116 )?;
117 Ok(Self { info })
118 }
119}
120
121impl<'a, 'info> AsRef<AccountInfo<'info>> for Signer<'a, 'info> {
122 fn as_ref(&self) -> &AccountInfo<'info> {
123 self.info
124 }
125}
126
127impl<'a, 'info> Deref for Signer<'a, 'info> {
128 type Target = AccountInfo<'info>;
129
130 fn deref(&self) -> &Self::Target {
131 self.info
132 }
133}
134
135#[derive(Clone)]
136pub struct EmptyAccount<'a, 'info> {
137 info: &'a AccountInfo<'info>,
138}
139
140impl<'a, 'info> EmptyAccount<'a, 'info> {
141 pub fn new(info: &'a AccountInfo<'info>) -> Result<EmptyAccount<'a, 'info>, ProgramError> {
142 assert_with_msg(
143 info.data_is_empty(),
144 ProgramError::InvalidAccountData,
145 "Account must be uninitialized",
146 )?;
147 assert_with_msg(
148 info.owner == &system_program::id(),
149 ProgramError::IllegalOwner,
150 "Empty accounts must be owned by the system program",
151 )?;
152 Ok(Self { info })
153 }
154}
155
156impl<'a, 'info> AsRef<AccountInfo<'info>> for EmptyAccount<'a, 'info> {
157 fn as_ref(&self) -> &AccountInfo<'info> {
158 self.info
159 }
160}
161
162impl<'a, 'info> Deref for EmptyAccount<'a, 'info> {
163 type Target = AccountInfo<'info>;
164
165 fn deref(&self) -> &Self::Target {
166 self.info
167 }
168}