spl-token-2022 11.1.0

Solana Program Library Token 2022
Documentation
#[cfg(feature = "zk-ops")]
use {
    crate::extension::confidential_mint_burn::processor::process_confidential_burn,
    spl_token_2022_interface::extension::confidential_mint_burn::instruction::BurnInstructionData,
};
use {
    crate::{
        pod_instruction::{AmountCheckedData, AmountData},
        processor::{BurnInstructionVariant, InstructionVariant, Processor},
    },
    solana_account_info::{next_account_info, AccountInfo},
    solana_address::Address,
    solana_msg::msg,
    solana_program_error::{ProgramError, ProgramResult},
    spl_token_2022_interface::{
        check_program_account,
        extension::{
            permissioned_burn::{
                instruction::{InitializeInstructionData, PermissionedBurnInstruction},
                PermissionedBurnConfig,
            },
            BaseStateWithExtensionsMut, PodStateWithExtensionsMut,
        },
        instruction::{decode_instruction_data, decode_instruction_type},
        pod::PodMint,
    },
};

fn process_initialize(
    _program_id: &Address,
    accounts: &[AccountInfo],
    authority: &Address,
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let mint_account_info = next_account_info(account_info_iter)?;
    check_program_account(mint_account_info.owner)?;

    let mut mint_data = mint_account_info.data.borrow_mut();
    let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack_uninitialized(&mut mint_data)?;

    let extension = mint.init_extension::<PermissionedBurnConfig>(true)?;
    extension.authority = Some(*authority)
        .try_into()
        .map_err(|_| ProgramError::InvalidArgument)?;

    Ok(())
}

pub(crate) fn process_instruction(
    program_id: &Address,
    accounts: &[AccountInfo],
    input: &[u8],
) -> ProgramResult {
    check_program_account(program_id)?;

    match decode_instruction_type(input)? {
        PermissionedBurnInstruction::Initialize => {
            msg!("PermissionedBurnInstruction::Initialize");
            let InitializeInstructionData { authority } = decode_instruction_data(input)?;
            process_initialize(program_id, accounts, authority)
        }
        PermissionedBurnInstruction::Burn => {
            msg!("PermissionedBurnInstruction::Burn");
            let data = decode_instruction_data::<AmountData>(input)?;
            Processor::process_burn(
                program_id,
                accounts,
                data.amount.into(),
                BurnInstructionVariant::Permissioned,
                InstructionVariant::Unchecked,
            )
        }
        PermissionedBurnInstruction::BurnChecked => {
            msg!("PermissionedBurnInstruction::BurnChecked");
            let data = decode_instruction_data::<AmountCheckedData>(input)?;
            Processor::process_burn(
                program_id,
                accounts,
                data.amount.into(),
                BurnInstructionVariant::Permissioned,
                InstructionVariant::Checked {
                    decimals: data.decimals,
                },
            )
        }
        PermissionedBurnInstruction::ConfidentialBurn => {
            msg!("PermissionedBurnInstruction::ConfidentialBurn");
            #[cfg(feature = "zk-ops")]
            {
                let data = decode_instruction_data::<BurnInstructionData>(input)?;
                process_confidential_burn(
                    program_id,
                    accounts,
                    data,
                    BurnInstructionVariant::Permissioned,
                )
            }
            #[cfg(not(feature = "zk-ops"))]
            Err(solana_program_error::ProgramError::InvalidInstructionData)
        }
    }
}