use crate::{
get_admin_pda, get_allowlist_program_pda, get_private_allowed_account_pda,
get_private_allowlist_pda, get_public_allowed_account_pda,
};
use borsh::{BorshDeserialize, BorshSerialize};
use solana_instruction::{AccountMeta, Instruction};
use solana_program_error::ProgramError;
use solana_pubkey::Pubkey;
const SYSTEM_PROGRAM_ID: Pubkey = Pubkey::from_str_const("11111111111111111111111111111111");
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize)]
pub enum AllowlistInstruction {
InitializeAdminAuthority,
UpdateAdminAuthority,
AdminAddPrivateAllowlist,
AdminRemovePrivateAllowlist,
Thaw {
user_system_account: Pubkey,
},
AdminAddPublicAllowedAccount,
AdminAddPrivateAllowedAccount,
AdminRemovePublicAllowedAccount,
AdminRemovePrivateAllowedAccount,
AdminFreeze,
AdminBurn {
amount: u64,
decimals: u8,
},
}
pub fn initialize_admin_authority(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::InitializeAdminAuthority)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new(global_admin_pda, false),
AccountMeta::new_readonly(SYSTEM_PROGRAM_ID, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn update_admin_authority(
allowlist_program_id: &Pubkey,
current_admin_authority_pubkey: &Pubkey,
new_admin_authority_pubkey: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::UpdateAdminAuthority)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let accounts = vec![
AccountMeta::new(*current_admin_authority_pubkey, true),
AccountMeta::new(*new_admin_authority_pubkey, true),
AccountMeta::new(global_admin_pda, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn admin_add_private_allowlist(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
mint_pubkey: &Pubkey,
system_program_pubkey: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminAddPrivateAllowlist)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (private_allowlist_pda, _) = get_private_allowlist_pda(mint_pubkey, allowlist_program_id);
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new_readonly(global_admin_pda, false),
AccountMeta::new_readonly(*mint_pubkey, false),
AccountMeta::new(private_allowlist_pda, false),
AccountMeta::new_readonly(*system_program_pubkey, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn admin_remove_private_allowlist(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
mint_pubkey: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminRemovePrivateAllowlist)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (private_allowlist_pda, _) = get_private_allowlist_pda(mint_pubkey, allowlist_program_id);
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new_readonly(global_admin_pda, false),
AccountMeta::new_readonly(*mint_pubkey, false),
AccountMeta::new(private_allowlist_pda, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn admin_add_public_allowed_account(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
user_account_pubkey: &Pubkey,
user_account_is_payer: bool,
system_program_id: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminAddPublicAllowedAccount)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (user_allowed_account_to_add, _) =
get_public_allowed_account_pda(user_account_pubkey, allowlist_program_id);
let user_account_meta = if user_account_is_payer {
AccountMeta::new(*user_account_pubkey, true)
} else {
AccountMeta::new_readonly(*user_account_pubkey, false)
};
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new_readonly(global_admin_pda, false),
user_account_meta,
AccountMeta::new(user_allowed_account_to_add, false),
AccountMeta::new_readonly(*system_program_id, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn admin_add_private_allowed_account(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
user_account_pubkey: &Pubkey,
user_account_is_payer: bool,
mint_pubkey: &Pubkey,
system_program_pubkey: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminAddPrivateAllowedAccount)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (user_allowed_account_to_add, _) =
get_private_allowed_account_pda(user_account_pubkey, mint_pubkey, allowlist_program_id);
let user_account_meta = if user_account_is_payer {
AccountMeta::new(*user_account_pubkey, true)
} else {
AccountMeta::new_readonly(*user_account_pubkey, false)
};
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new_readonly(global_admin_pda, false),
user_account_meta,
AccountMeta::new(user_allowed_account_to_add, false),
AccountMeta::new_readonly(*mint_pubkey, false),
AccountMeta::new_readonly(*system_program_pubkey, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn admin_remove_public_allowed_account(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
user_account_pubkey: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminRemovePublicAllowedAccount)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (user_allowed_account_to_remove, _) =
get_public_allowed_account_pda(user_account_pubkey, allowlist_program_id);
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new_readonly(global_admin_pda, false),
AccountMeta::new_readonly(*user_account_pubkey, false),
AccountMeta::new(user_allowed_account_to_remove, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn admin_remove_private_allowed_account(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
user_account_pubkey: &Pubkey,
mint_pubkey: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminRemovePrivateAllowedAccount)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (user_allowed_account_to_remove, _) =
get_private_allowed_account_pda(user_account_pubkey, mint_pubkey, allowlist_program_id);
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new_readonly(global_admin_pda, false),
AccountMeta::new_readonly(*user_account_pubkey, false),
AccountMeta::new(user_allowed_account_to_remove, false),
AccountMeta::new_readonly(*mint_pubkey, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn thaw(
allowlist_program_id: &Pubkey,
mint_pubkey: &Pubkey,
user_token_account_owner_pubkey: &Pubkey,
user_token_account_pubkey: &Pubkey,
token_program_id: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::Thaw {
user_system_account: *user_token_account_owner_pubkey,
})?;
let (user_public_allowed_account_pda, _) =
get_public_allowed_account_pda(user_token_account_owner_pubkey, allowlist_program_id);
let (user_private_allowed_account_pda, _) = get_private_allowed_account_pda(
user_token_account_owner_pubkey,
mint_pubkey,
allowlist_program_id,
);
let (allowlist_pda, _) = get_allowlist_program_pda(allowlist_program_id);
let (private_allowlist_pda, _) = get_private_allowlist_pda(mint_pubkey, allowlist_program_id);
let accounts = vec![
AccountMeta::new_readonly(*mint_pubkey, false),
AccountMeta::new(*user_token_account_pubkey, false),
AccountMeta::new_readonly(user_public_allowed_account_pda, false),
AccountMeta::new_readonly(user_private_allowed_account_pda, false),
AccountMeta::new_readonly(private_allowlist_pda, false),
AccountMeta::new_readonly(*token_program_id, false),
AccountMeta::new_readonly(allowlist_pda, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
pub fn admin_freeze(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
user_token_account_owner_pubkey: &Pubkey,
user_token_account_pubkey: &Pubkey,
mint_pubkey: &Pubkey,
token_program_id: &Pubkey,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminFreeze)?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (allowlist_pda, _) = get_allowlist_program_pda(allowlist_program_id);
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new(global_admin_pda, false),
AccountMeta::new_readonly(*user_token_account_owner_pubkey, false),
AccountMeta::new(*user_token_account_pubkey, false),
AccountMeta::new_readonly(*mint_pubkey, false),
AccountMeta::new_readonly(*token_program_id, false),
AccountMeta::new_readonly(allowlist_pda, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}
#[allow(clippy::too_many_arguments)]
pub fn admin_burn(
allowlist_program_id: &Pubkey,
admin_authority_pubkey: &Pubkey,
user_token_account_owner_pubkey: &Pubkey,
user_token_account_pubkey: &Pubkey,
mint_pubkey: &Pubkey,
token_program_id: &Pubkey,
amount: u64,
decimals: u8,
) -> Result<Instruction, ProgramError> {
let data = borsh::to_vec(&AllowlistInstruction::AdminBurn { amount, decimals })?;
let (global_admin_pda, _) = get_admin_pda(allowlist_program_id);
let (allowlist_pda, _) = get_allowlist_program_pda(allowlist_program_id);
let accounts = vec![
AccountMeta::new(*admin_authority_pubkey, true),
AccountMeta::new_readonly(global_admin_pda, false),
AccountMeta::new_readonly(*user_token_account_owner_pubkey, false),
AccountMeta::new(*user_token_account_pubkey, false),
AccountMeta::new(*mint_pubkey, false),
AccountMeta::new_readonly(*token_program_id, false),
AccountMeta::new_readonly(allowlist_pda, false),
];
Ok(Instruction {
program_id: *allowlist_program_id,
accounts,
data,
})
}