1use crate::{
2 get_admin_pda, get_allowlist_program_pda, get_private_allowed_account_pda,
3 get_private_allowlist_pda, get_public_allowed_account_pda,
4};
5use borsh::{BorshDeserialize, BorshSerialize};
6use solana_instruction::{AccountMeta, Instruction};
7use solana_program_error::ProgramError;
8use solana_pubkey::Pubkey;
9
10const SYSTEM_PROGRAM_ID: Pubkey = Pubkey::from_str_const("11111111111111111111111111111111");
11
12#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize)]
13pub enum AllowlistInstruction {
14 InitializeAdminAuthority,
29
30 UpdateAdminAuthority,
40
41 AdminAddPrivateAllowlist,
53
54 AdminRemovePrivateAllowlist,
66
67 Thaw {
79 user_system_account: Pubkey,
81 },
82
83 AdminAddPublicAllowedAccount,
93
94 AdminAddPrivateAllowedAccount,
105
106 AdminRemovePublicAllowedAccount,
117
118 AdminRemovePrivateAllowedAccount,
130
131 AdminFreeze,
143
144 AdminBurn {
161 amount: u64,
163 decimals: u8,
165 },
166}
167
168pub fn initialize_admin_authority(
169 allowlist_program_id: &Pubkey,
170 admin_authority_pubkey: &Pubkey,
171) -> Result<Instruction, ProgramError> {
172 let data = borsh::to_vec(&AllowlistInstruction::InitializeAdminAuthority)?;
173
174 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
175
176 let accounts = vec![
177 AccountMeta::new(*admin_authority_pubkey, true),
178 AccountMeta::new(global_admin_pda, false),
179 AccountMeta::new_readonly(SYSTEM_PROGRAM_ID, false),
180 ];
181
182 Ok(Instruction {
183 program_id: *allowlist_program_id,
184 accounts,
185 data,
186 })
187}
188
189pub fn update_admin_authority(
190 allowlist_program_id: &Pubkey,
191 current_admin_authority_pubkey: &Pubkey,
192 new_admin_authority_pubkey: &Pubkey,
193) -> Result<Instruction, ProgramError> {
194 let data = borsh::to_vec(&AllowlistInstruction::UpdateAdminAuthority)?;
195
196 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
197
198 let accounts = vec![
199 AccountMeta::new(*current_admin_authority_pubkey, true),
200 AccountMeta::new(*new_admin_authority_pubkey, true),
201 AccountMeta::new(global_admin_pda, false),
202 ];
203
204 Ok(Instruction {
205 program_id: *allowlist_program_id,
206 accounts,
207 data,
208 })
209}
210
211pub fn admin_add_private_allowlist(
212 allowlist_program_id: &Pubkey,
213 admin_authority_pubkey: &Pubkey,
214 mint_pubkey: &Pubkey,
215 system_program_pubkey: &Pubkey,
216) -> Result<Instruction, ProgramError> {
217 let data = borsh::to_vec(&AllowlistInstruction::AdminAddPrivateAllowlist)?;
218
219 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
220 let (private_allowlist_pda, _) = get_private_allowlist_pda(mint_pubkey, allowlist_program_id);
221
222 let accounts = vec![
223 AccountMeta::new(*admin_authority_pubkey, true),
224 AccountMeta::new_readonly(global_admin_pda, false),
225 AccountMeta::new_readonly(*mint_pubkey, false),
226 AccountMeta::new(private_allowlist_pda, false),
227 AccountMeta::new_readonly(*system_program_pubkey, false),
228 ];
229
230 Ok(Instruction {
231 program_id: *allowlist_program_id,
232 accounts,
233 data,
234 })
235}
236
237pub fn admin_remove_private_allowlist(
238 allowlist_program_id: &Pubkey,
239 admin_authority_pubkey: &Pubkey,
240 mint_pubkey: &Pubkey,
241) -> Result<Instruction, ProgramError> {
242 let data = borsh::to_vec(&AllowlistInstruction::AdminRemovePrivateAllowlist)?;
243
244 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
245 let (private_allowlist_pda, _) = get_private_allowlist_pda(mint_pubkey, allowlist_program_id);
246
247 let accounts = vec![
248 AccountMeta::new(*admin_authority_pubkey, true),
249 AccountMeta::new_readonly(global_admin_pda, false),
250 AccountMeta::new_readonly(*mint_pubkey, false),
251 AccountMeta::new(private_allowlist_pda, false),
252 ];
253
254 Ok(Instruction {
255 program_id: *allowlist_program_id,
256 accounts,
257 data,
258 })
259}
260
261pub fn admin_add_public_allowed_account(
262 allowlist_program_id: &Pubkey,
263 admin_authority_pubkey: &Pubkey,
264 user_account_pubkey: &Pubkey,
265 user_account_is_payer: bool,
266 system_program_id: &Pubkey,
267) -> Result<Instruction, ProgramError> {
268 let data = borsh::to_vec(&AllowlistInstruction::AdminAddPublicAllowedAccount)?;
269
270 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
271 let (user_allowed_account_to_add, _) =
272 get_public_allowed_account_pda(user_account_pubkey, allowlist_program_id);
273
274 let user_account_meta = if user_account_is_payer {
275 AccountMeta::new(*user_account_pubkey, true)
276 } else {
277 AccountMeta::new_readonly(*user_account_pubkey, false)
278 };
279
280 let accounts = vec![
281 AccountMeta::new(*admin_authority_pubkey, true),
282 AccountMeta::new_readonly(global_admin_pda, false),
283 user_account_meta,
284 AccountMeta::new(user_allowed_account_to_add, false),
285 AccountMeta::new_readonly(*system_program_id, false),
286 ];
287
288 Ok(Instruction {
289 program_id: *allowlist_program_id,
290 accounts,
291 data,
292 })
293}
294
295pub fn admin_add_private_allowed_account(
296 allowlist_program_id: &Pubkey,
297 admin_authority_pubkey: &Pubkey,
298 user_account_pubkey: &Pubkey,
299 user_account_is_payer: bool,
300 mint_pubkey: &Pubkey,
301 system_program_pubkey: &Pubkey,
302) -> Result<Instruction, ProgramError> {
303 let data = borsh::to_vec(&AllowlistInstruction::AdminAddPrivateAllowedAccount)?;
304
305 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
306 let (user_allowed_account_to_add, _) =
307 get_private_allowed_account_pda(user_account_pubkey, mint_pubkey, allowlist_program_id);
308
309 let user_account_meta = if user_account_is_payer {
310 AccountMeta::new(*user_account_pubkey, true)
311 } else {
312 AccountMeta::new_readonly(*user_account_pubkey, false)
313 };
314
315 let accounts = vec![
316 AccountMeta::new(*admin_authority_pubkey, true),
317 AccountMeta::new_readonly(global_admin_pda, false),
318 user_account_meta,
319 AccountMeta::new(user_allowed_account_to_add, false),
320 AccountMeta::new_readonly(*mint_pubkey, false),
321 AccountMeta::new_readonly(*system_program_pubkey, false),
322 ];
323
324 Ok(Instruction {
325 program_id: *allowlist_program_id,
326 accounts,
327 data,
328 })
329}
330
331pub fn admin_remove_public_allowed_account(
332 allowlist_program_id: &Pubkey,
333 admin_authority_pubkey: &Pubkey,
334 user_account_pubkey: &Pubkey,
335) -> Result<Instruction, ProgramError> {
336 let data = borsh::to_vec(&AllowlistInstruction::AdminRemovePublicAllowedAccount)?;
337
338 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
339 let (user_allowed_account_to_remove, _) =
340 get_public_allowed_account_pda(user_account_pubkey, allowlist_program_id);
341
342 let accounts = vec![
343 AccountMeta::new(*admin_authority_pubkey, true),
344 AccountMeta::new_readonly(global_admin_pda, false),
345 AccountMeta::new_readonly(*user_account_pubkey, false),
346 AccountMeta::new(user_allowed_account_to_remove, false),
347 ];
348
349 Ok(Instruction {
350 program_id: *allowlist_program_id,
351 accounts,
352 data,
353 })
354}
355
356pub fn admin_remove_private_allowed_account(
357 allowlist_program_id: &Pubkey,
358 admin_authority_pubkey: &Pubkey,
359 user_account_pubkey: &Pubkey,
360 mint_pubkey: &Pubkey,
361) -> Result<Instruction, ProgramError> {
362 let data = borsh::to_vec(&AllowlistInstruction::AdminRemovePrivateAllowedAccount)?;
363
364 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
365 let (user_allowed_account_to_remove, _) =
366 get_private_allowed_account_pda(user_account_pubkey, mint_pubkey, allowlist_program_id);
367
368 let accounts = vec![
369 AccountMeta::new(*admin_authority_pubkey, true),
370 AccountMeta::new_readonly(global_admin_pda, false),
371 AccountMeta::new_readonly(*user_account_pubkey, false),
372 AccountMeta::new(user_allowed_account_to_remove, false),
373 AccountMeta::new_readonly(*mint_pubkey, false),
374 ];
375
376 Ok(Instruction {
377 program_id: *allowlist_program_id,
378 accounts,
379 data,
380 })
381}
382
383pub fn thaw(
384 allowlist_program_id: &Pubkey,
385 mint_pubkey: &Pubkey,
386 user_token_account_owner_pubkey: &Pubkey,
387 user_token_account_pubkey: &Pubkey,
388 token_program_id: &Pubkey,
389) -> Result<Instruction, ProgramError> {
390 let data = borsh::to_vec(&AllowlistInstruction::Thaw {
391 user_system_account: *user_token_account_owner_pubkey,
392 })?;
393
394 let (user_public_allowed_account_pda, _) =
395 get_public_allowed_account_pda(user_token_account_owner_pubkey, allowlist_program_id);
396
397 let (user_private_allowed_account_pda, _) = get_private_allowed_account_pda(
398 user_token_account_owner_pubkey,
399 mint_pubkey,
400 allowlist_program_id,
401 );
402
403 let (allowlist_pda, _) = get_allowlist_program_pda(allowlist_program_id);
404
405 let (private_allowlist_pda, _) = get_private_allowlist_pda(mint_pubkey, allowlist_program_id);
406
407 let accounts = vec![
408 AccountMeta::new_readonly(*mint_pubkey, false),
409 AccountMeta::new(*user_token_account_pubkey, false),
410 AccountMeta::new_readonly(user_public_allowed_account_pda, false),
411 AccountMeta::new_readonly(user_private_allowed_account_pda, false),
412 AccountMeta::new_readonly(private_allowlist_pda, false),
413 AccountMeta::new_readonly(*token_program_id, false),
414 AccountMeta::new_readonly(allowlist_pda, false),
415 ];
416
417 Ok(Instruction {
418 program_id: *allowlist_program_id,
419 accounts,
420 data,
421 })
422}
423
424pub fn admin_freeze(
425 allowlist_program_id: &Pubkey,
426 admin_authority_pubkey: &Pubkey,
427 user_token_account_owner_pubkey: &Pubkey,
428 user_token_account_pubkey: &Pubkey,
429 mint_pubkey: &Pubkey,
430 token_program_id: &Pubkey,
431) -> Result<Instruction, ProgramError> {
432 let data = borsh::to_vec(&AllowlistInstruction::AdminFreeze)?;
433
434 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
435
436 let (allowlist_pda, _) = get_allowlist_program_pda(allowlist_program_id);
437
438 let accounts = vec![
439 AccountMeta::new(*admin_authority_pubkey, true),
440 AccountMeta::new(global_admin_pda, false),
441 AccountMeta::new_readonly(*user_token_account_owner_pubkey, false),
442 AccountMeta::new(*user_token_account_pubkey, false),
443 AccountMeta::new_readonly(*mint_pubkey, false),
444 AccountMeta::new_readonly(*token_program_id, false),
445 AccountMeta::new_readonly(allowlist_pda, false),
446 ];
447
448 Ok(Instruction {
449 program_id: *allowlist_program_id,
450 accounts,
451 data,
452 })
453}
454
455#[allow(clippy::too_many_arguments)]
456pub fn admin_burn(
457 allowlist_program_id: &Pubkey,
458 admin_authority_pubkey: &Pubkey,
459 user_token_account_owner_pubkey: &Pubkey,
460 user_token_account_pubkey: &Pubkey,
461 mint_pubkey: &Pubkey,
462 token_program_id: &Pubkey,
463 amount: u64,
464 decimals: u8,
465) -> Result<Instruction, ProgramError> {
466 let data = borsh::to_vec(&AllowlistInstruction::AdminBurn { amount, decimals })?;
467
468 let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
469
470 let (allowlist_pda, _) = get_allowlist_program_pda(allowlist_program_id);
471
472 let accounts = vec![
473 AccountMeta::new(*admin_authority_pubkey, true),
474 AccountMeta::new_readonly(global_admin_pda, false),
475 AccountMeta::new_readonly(*user_token_account_owner_pubkey, false),
476 AccountMeta::new(*user_token_account_pubkey, false),
477 AccountMeta::new(*mint_pubkey, false),
478 AccountMeta::new_readonly(*token_program_id, false),
479 AccountMeta::new_readonly(allowlist_pda, false),
480 ];
481
482 Ok(Instruction {
483 program_id: *allowlist_program_id,
484 accounts,
485 data,
486 })
487}