use {
num_enum::{IntoPrimitive, TryFromPrimitive},
shank::ShankInstruction,
solana_program::{
incinerator,
instruction::{AccountMeta, Instruction},
program_error::ProgramError,
pubkey::Pubkey,
system_program,
},
};
#[rustfmt::skip]
#[derive(Clone, Debug, PartialEq, IntoPrimitive, ShankInstruction, TryFromPrimitive)]
#[repr(u8)]
pub enum FeatureGateInstruction {
#[account(
0,
writable,
signer,
name = "feature",
description = "The feature account to revoke"
)]
#[account(
1,
writable,
name = "incinerator",
description = "The incinerator account"
)]
#[account(
2,
name = "system_program",
description = "The system program"
)]
RevokePendingActivation,
}
impl FeatureGateInstruction {
pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
if input.len() != 1 {
return Err(ProgramError::InvalidInstructionData);
}
Self::try_from(input[0]).map_err(|_| ProgramError::InvalidInstructionData)
}
pub fn pack(&self) -> Vec<u8> {
vec![self.to_owned().into()]
}
}
pub fn revoke_pending_activation(feature_id: &Pubkey) -> Instruction {
let accounts = vec![
AccountMeta::new(*feature_id, true),
AccountMeta::new(incinerator::id(), false),
AccountMeta::new_readonly(system_program::id(), false),
];
let data = FeatureGateInstruction::RevokePendingActivation.pack();
Instruction {
program_id: crate::id(),
accounts,
data,
}
}
#[cfg(test)]
mod test {
use super::*;
fn test_pack_unpack(instruction: &FeatureGateInstruction) {
let packed = instruction.pack();
let unpacked = FeatureGateInstruction::unpack(&packed).unwrap();
assert_eq!(instruction, &unpacked);
}
#[test]
fn test_pack_unpack_revoke_pending_activation() {
test_pack_unpack(&FeatureGateInstruction::RevokePendingActivation);
}
}