spherenet_program_whitelist_interface/instructions.rs
1//! Instruction types
2
3use {
4 pinocchio::{
5 program_error::ProgramError,
6 pubkey::{Pubkey, PUBKEY_BYTES},
7 },
8 shank::ShankInstruction,
9};
10/// Instructions supported by the program whitelist program.
11#[repr(C)]
12#[derive(Clone, Debug, PartialEq, ShankInstruction)]
13pub enum ProgramWhitelistInstruction {
14 /// Initializes the program whitelist account, setting its initial state
15 /// with the initial authority.
16 ///
17 /// Accounts expected by this instruction:
18 ///
19 /// 0. `[writable]` The whitelist account to initialize
20 /// 1. `[signer]` The authority that will control the whitelist
21 /// 2. `[signer]` Account that will pay for the account creation
22 /// 3. `[]` The system program
23 #[account(
24 0,
25 writable,
26 name = "whitelist_account",
27 desc = "The whitelist account to initialize"
28 )]
29 #[account(
30 1,
31 signer,
32 name = "whitelist_authority",
33 desc = "The authority that will control the whitelist"
34 )]
35 #[account(
36 2,
37 signer,
38 name = "funder",
39 desc = "Account that will pay for the account creation"
40 )]
41 #[account(3, name = "system_program", desc = "System program")]
42 CreateWhitelist {},
43
44 /// Proposes a new authority for the program whitelist. The current
45 /// `whitelist_authority` must sign this instruction. The proposed
46 /// `new_authority` must then sign an `AcceptAuthorityTransfer`
47 /// instruction to finalize the transfer.
48 ///
49 /// Accounts expected by this instruction:
50 ///
51 /// 0. `[writable]` The whitelist account
52 /// 1. `[signer]` The current whitelist authority
53 #[account(
54 0,
55 writable,
56 name = "whitelist_account",
57 desc = "The whitelist account"
58 )]
59 #[account(
60 1,
61 signer,
62 name = "whitelist_authority",
63 desc = "The whitelist authority"
64 )]
65 InitiateAuthorityTransfer { new_authority: Pubkey },
66
67 /// Accepts the pending authority transfer for the program whitelist. The
68 /// `pending_whitelist_authority` must sign this instruction to assume
69 /// authority over the whitelist.
70 ///
71 /// Accounts expected by this instruction:
72 ///
73 /// 0. `[writable]` The whitelist account
74 /// 1. `[signer]` The pending whitelist authority
75 #[account(
76 0,
77 writable,
78 name = "whitelist_account",
79 desc = "The whitelist account"
80 )]
81 #[account(
82 1,
83 signer,
84 name = "pending_whitelist_authority",
85 desc = "The pending whitelist authority"
86 )]
87 AcceptAuthorityTransfer,
88
89 /// Cancels a pending authority transfer for the program whitelist. The
90 /// current `whitelist_authority` must sign this instruction.
91 ///
92 /// Accounts expected by this instruction:
93 ///
94 /// 0. `[writable]` The whitelist account
95 /// 1. `[signer]` The current whitelist authority
96 #[account(
97 0,
98 writable,
99 name = "whitelist_account",
100 desc = "The whitelist account"
101 )]
102 #[account(
103 1,
104 signer,
105 name = "whitelist_authority",
106 desc = "The whitelist authority"
107 )]
108 CancelAuthorityTransfer {},
109
110 /// Adds an address to the program whitelist or unrevokes a previously
111 /// revoked address. If the `whitelist_entry_account` does not exist,
112 /// this instruction creates and initializes it. If the account already
113 /// exists and is marked as revoked, this instruction marks it as active
114 /// again. The `whitelist_authority` must sign.
115 ///
116 /// Accounts expected by this instruction:
117 ///
118 /// 0. `[]` The whitelist account (Used for validation/derivation)
119 /// 1. `[signer]` The whitelist authority
120 /// 2. `[writable]` The whitelist entry account to be created/initialized
121 /// or updated
122 /// 3. `[writable, signer]` Payer account (must be a system account)
123 /// 4. `[]` System program
124 #[account(0, name = "whitelist_account", desc = "The whitelist account")]
125 #[account(
126 1,
127 signer,
128 name = "whitelist_authority",
129 desc = "The whitelist authority"
130 )]
131 #[account(
132 2,
133 writable,
134 name = "whitelist_entry_account",
135 desc = "The whitelist entry account"
136 )]
137 #[account(
138 3,
139 writable,
140 signer,
141 name = "payer",
142 desc = "Payer account (must be a system account)"
143 )]
144 #[account(4, name = "system_program", desc = "System program")]
145 AddEntry { program_authority: Pubkey },
146
147 /// Closes a specific whitelist entry account, transferring its rent
148 /// lamports to a designated destination account. The `whitelist_authority`
149 /// must sign this instruction.
150 ///
151 /// Accounts expected by this instruction:
152 ///
153 /// 0. `[]` The whitelist account (Used for validation)
154 /// 1. `[signer]` The whitelist authority
155 /// 2. `[writable]` The whitelist entry account to close
156 /// 3. `[writable]` The destination account for reclaimed lamports
157 /// 4. `[]` System program
158 #[account(0, name = "whitelist_account", desc = "The whitelist account")]
159 #[account(
160 1,
161 signer,
162 name = "whitelist_authority",
163 desc = "The whitelist authority"
164 )]
165 #[account(
166 2,
167 writable,
168 name = "whitelist_entry_account",
169 desc = "The whitelist entry account to close"
170 )]
171 #[account(
172 3,
173 writable,
174 name = "destination_account",
175 desc = "The destination account for reclaimed lamports"
176 )]
177 #[account(4, name = "system_program", desc = "System program")]
178 RemoveEntry { program_authority: Pubkey },
179}
180
181impl ProgramWhitelistInstruction {
182 /// Unpack a program whitelist instruction from a byte slice.
183 pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
184 // Use the pattern matching style from the example
185 match input.split_first() {
186 Some((&0, [])) => Ok(Self::CreateWhitelist {}),
187 Some((&1, remaining)) if remaining.len() == PUBKEY_BYTES => {
188 let new_authority = Pubkey::try_from(remaining).unwrap();
189 Ok(Self::InitiateAuthorityTransfer { new_authority })
190 }
191 Some((&2, [])) => Ok(Self::AcceptAuthorityTransfer),
192 Some((&3, [])) => Ok(Self::CancelAuthorityTransfer {}),
193 Some((&4, remaining)) if remaining.len() == PUBKEY_BYTES => {
194 let program_authority = Pubkey::try_from(remaining).unwrap();
195 Ok(Self::AddEntry { program_authority })
196 }
197 Some((&5, remaining)) if remaining.len() == PUBKEY_BYTES => {
198 let program_authority = Pubkey::try_from(remaining).unwrap();
199 Ok(Self::RemoveEntry { program_authority })
200 }
201 _ => Err(ProgramError::InvalidInstructionData),
202 }
203 }
204}