use {
crate::{
error::TokenError,
extension::{Extension, ExtensionType},
},
bytemuck::{Pod, Zeroable},
solana_address::Address,
solana_nullable::MaybeNull,
solana_program_error::ProgramResult,
solana_zero_copy::unaligned::Bool,
solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
spl_token_confidential_transfer_proof_extraction::encryption::PodFeeCiphertext,
};
pub mod instruction;
pub type EncryptedFee = PodFeeCiphertext;
pub type EncryptedWithheldAmount = PodElGamalCiphertext;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
pub struct ConfidentialTransferFeeConfig {
pub authority: MaybeNull<Address>,
pub withdraw_withheld_authority_elgamal_pubkey: PodElGamalPubkey,
pub harvest_to_mint_enabled: Bool,
pub withheld_amount: EncryptedWithheldAmount,
}
impl Extension for ConfidentialTransferFeeConfig {
const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeConfig;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
pub struct ConfidentialTransferFeeAmount {
pub withheld_amount: EncryptedWithheldAmount,
}
impl Extension for ConfidentialTransferFeeAmount {
const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeAmount;
}
impl ConfidentialTransferFeeAmount {
pub fn closable(&self) -> ProgramResult {
if self.withheld_amount == EncryptedWithheldAmount::zeroed() {
Ok(())
} else {
Err(TokenError::ConfidentialTransferFeeAccountHasWithheldFee.into())
}
}
}