use light_compressed_account::instruction_data::{
compressed_proof::CompressedProof, traits::LightInstructionData,
};
use light_token_interface::{
self,
instructions::mint_action::{CpiContext, MintWithContext},
};
use light_token_types::MintAuthorityType;
use solana_instruction::Instruction;
use solana_pubkey::Pubkey;
use crate::{
compressed_token::mint_action::{
get_mint_action_instruction_account_metas_cpi_write, MintActionMetaConfig,
MintActionMetaConfigCpiWrite,
},
error::{Result, TokenSdkError},
AnchorDeserialize, AnchorSerialize,
};
pub const UPDATE_COMPRESSED_MINT_DISCRIMINATOR: u8 = 105;
#[derive(Debug, Clone, AnchorDeserialize, AnchorSerialize)]
pub struct UpdateMintInputs {
pub compressed_mint_inputs: MintWithContext,
pub authority_type: MintAuthorityType,
pub new_authority: Option<Pubkey>,
pub mint_authority: Option<Pubkey>, pub proof: Option<CompressedProof>,
pub payer: Pubkey,
pub authority: Pubkey,
pub in_merkle_tree: Pubkey,
pub in_output_queue: Pubkey,
pub out_output_queue: Pubkey,
}
pub fn update_compressed_mint_cpi(
input: UpdateMintInputs,
cpi_context: Option<CpiContext>,
) -> Result<Instruction> {
let mut instruction_data =
light_token_interface::instructions::mint_action::MintActionCompressedInstructionData::new(
input.compressed_mint_inputs.clone(),
input.proof,
);
let update_authority = light_token_interface::instructions::mint_action::UpdateAuthority {
new_authority: input.new_authority.map(|auth| auth.to_bytes().into()),
};
instruction_data = match input.authority_type {
MintAuthorityType::MintTokens => {
instruction_data.with_update_mint_authority(update_authority)
}
MintAuthorityType::FreezeAccount => {
instruction_data.with_update_freeze_authority(update_authority)
}
};
if let Some(ctx) = cpi_context {
instruction_data = instruction_data.with_cpi_context(ctx);
}
let meta_config = MintActionMetaConfig::new(
input.payer,
input.authority,
input.in_merkle_tree,
input.in_output_queue,
input.out_output_queue,
);
let account_metas = meta_config.to_account_metas();
let data = instruction_data
.data()
.map_err(|_| TokenSdkError::SerializationError)?;
Ok(Instruction {
program_id: solana_pubkey::Pubkey::new_from_array(
light_token_interface::LIGHT_TOKEN_PROGRAM_ID,
),
accounts: account_metas,
data,
})
}
pub fn update_compressed_mint(input: UpdateMintInputs) -> Result<Instruction> {
update_compressed_mint_cpi(input, None)
}
#[derive(Debug, Clone)]
pub struct UpdateMintInputsCpiWrite {
pub compressed_mint_inputs: MintWithContext,
pub authority_type: MintAuthorityType,
pub new_authority: Option<Pubkey>,
pub payer: Pubkey,
pub authority: Pubkey,
pub cpi_context: CpiContext,
pub cpi_context_pubkey: Pubkey,
}
pub fn create_update_compressed_mint_cpi_write(
inputs: UpdateMintInputsCpiWrite,
) -> Result<Instruction> {
if !inputs.cpi_context.first_set_context && !inputs.cpi_context.set_context {
return Err(TokenSdkError::InvalidCpiContext);
}
let mut instruction_data =
light_token_interface::instructions::mint_action::MintActionCompressedInstructionData::new(
inputs.compressed_mint_inputs.clone(),
None, );
let update_authority = light_token_interface::instructions::mint_action::UpdateAuthority {
new_authority: inputs.new_authority.map(|auth| auth.to_bytes().into()),
};
instruction_data = match inputs.authority_type {
MintAuthorityType::MintTokens => {
instruction_data.with_update_mint_authority(update_authority)
}
MintAuthorityType::FreezeAccount => {
instruction_data.with_update_freeze_authority(update_authority)
}
};
instruction_data = instruction_data.with_cpi_context(inputs.cpi_context);
let meta_config = MintActionMetaConfigCpiWrite {
fee_payer: inputs.payer,
mint_signer: None, authority: inputs.authority,
cpi_context: inputs.cpi_context_pubkey,
};
let account_metas = get_mint_action_instruction_account_metas_cpi_write(meta_config);
let data = instruction_data
.data()
.map_err(|_| TokenSdkError::SerializationError)?;
Ok(Instruction {
program_id: solana_pubkey::Pubkey::new_from_array(
light_token_interface::LIGHT_TOKEN_PROGRAM_ID,
),
accounts: account_metas,
data,
})
}