use {
crate::mint_customizer::interface::MintCustomizer,
solana_account_info::AccountInfo,
solana_cpi::invoke,
solana_program_error::{ProgramError, ProgramResult},
solana_pubkey::Pubkey,
solana_zk_sdk::encryption::pod::elgamal::PodElGamalPubkey,
spl_token_2022::{
extension::{
confidential_transfer::instruction::initialize_mint as initialize_confidential_transfer_mint,
default_account_state::instruction::initialize_default_account_state,
pausable::instruction::initialize as initialize_pausable, ExtensionType,
PodStateWithExtensions,
},
instruction::initialize_permanent_delegate,
pod::PodMint,
state::{AccountState, Mint},
},
std::str::FromStr,
};
pub struct ComplianceMintCustomizer;
pub const PERMANENT_DELEGATE: Pubkey =
solana_pubkey::pubkey!("deLpBmD7UP27BHTuhnxR7mBE9rEV6mWUnwWsXMXTFwR");
pub const CONFIDENTIAL_TRANSFER_AUTHORITY: Pubkey =
solana_pubkey::pubkey!("con2YXp7bKscyhzJzbSQgwz6RFcXqe6otUGK5Rr8saK");
pub const AUDITOR_ELGAMAL_PUBKEY_B64: &str = "yonKhqkoXNvMbN/tU6fjHFhfZuNPpvMj8L55aP2bBG4=";
pub const FREEZE_AUTHORITY: Pubkey =
solana_pubkey::pubkey!("freTRAXwCVELv5k7V6UobnCiG1hmhnj79AezxRwAR3h");
pub const PAUSE_AUTHORITY: Pubkey =
solana_pubkey::pubkey!("pauySfjziLCpPMoaeFsWgvBCe7ygHKr6wXCyvTNZyGv");
impl MintCustomizer for ComplianceMintCustomizer {
fn get_token_2022_mint_space() -> Result<usize, ProgramError> {
ExtensionType::try_calculate_account_len::<Mint>(&[
ExtensionType::PermanentDelegate,
ExtensionType::DefaultAccountState,
ExtensionType::ConfidentialTransferMint,
ExtensionType::Pausable,
])
}
fn initialize_extensions(
wrapped_mint_account: &AccountInfo,
wrapped_token_program_account: &AccountInfo,
) -> ProgramResult {
invoke(
&initialize_permanent_delegate(
wrapped_token_program_account.key,
wrapped_mint_account.key,
&PERMANENT_DELEGATE,
)?,
&[wrapped_mint_account.clone()],
)?;
let elgamal_pubkey = PodElGamalPubkey::from_str(AUDITOR_ELGAMAL_PUBKEY_B64)
.map_err(|_| ProgramError::InvalidArgument)?;
invoke(
&initialize_confidential_transfer_mint(
wrapped_token_program_account.key,
wrapped_mint_account.key,
Some(CONFIDENTIAL_TRANSFER_AUTHORITY), true,
Some(elgamal_pubkey),
)?,
&[wrapped_mint_account.clone()],
)?;
invoke(
&initialize_default_account_state(
wrapped_token_program_account.key,
wrapped_mint_account.key,
&AccountState::Initialized,
)?,
&[wrapped_mint_account.clone()],
)?;
invoke(
&initialize_pausable(
wrapped_token_program_account.key,
wrapped_mint_account.key,
&PAUSE_AUTHORITY,
)?,
&[wrapped_mint_account.clone()],
)?;
Ok(())
}
fn get_freeze_auth_and_decimals(
unwrapped_mint_account: &AccountInfo,
) -> Result<(Option<Pubkey>, u8), ProgramError> {
let unwrapped_mint_data = unwrapped_mint_account.try_borrow_data()?;
let pod_mint = PodStateWithExtensions::<PodMint>::unpack(&unwrapped_mint_data)?.base;
let decimals = pod_mint.decimals;
Ok((Some(FREEZE_AUTHORITY), decimals))
}
}