use crate::{write_bytes, UNINIT_BYTE};
use core::slice::from_raw_parts;
use hayabusa_cpi::{CpiCtx, CheckProgramId};
use hayabusa_errors::Result;
use pinocchio::{account_info::AccountInfo, cpi::{invoke, invoke_signed}, instruction::{AccountMeta, Instruction}, pubkey::Pubkey};
pub struct InitializeMint2<'a> {
pub mint: &'a AccountInfo,
}
impl CheckProgramId for InitializeMint2<'_> {
const ID: Pubkey = crate::ID;
}
const DISCRIMINATOR: [u8; 1] = [20];
#[inline(always)]
pub fn initialize_mint2<'a>(
cpi_ctx: CpiCtx<'a, '_, '_, '_, InitializeMint2<'a>>,
decimals: u8,
mint_authority: &Pubkey,
freeze_authority: Option<&Pubkey>,
) -> Result<()> {
let infos = [cpi_ctx.mint];
let metas = [AccountMeta::writable(cpi_ctx.mint.key())];
let mut instruction_data = [UNINIT_BYTE; 67];
let mut length = instruction_data.len();
write_bytes(&mut instruction_data, &DISCRIMINATOR);
write_bytes(&mut instruction_data[1..2], &[decimals]);
write_bytes(&mut instruction_data[2..34], mint_authority);
if let Some(freeze_auth) = freeze_authority {
write_bytes(&mut instruction_data[34..35], &[1]);
write_bytes(&mut instruction_data[35..], freeze_auth);
} else {
write_bytes(&mut instruction_data[34..35], &[0]);
length = 35;
}
let instruction = Instruction {
program_id: &crate::ID,
accounts: &metas,
data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) },
};
if let Some(signers) = cpi_ctx.signers {
invoke_signed(&instruction, &infos, signers)
} else {
invoke(&instruction, &infos)
}
}