use {
crate::{
error::TokenError,
extension::{Extension, ExtensionType},
pod::*,
},
bytemuck::{Pod, Zeroable},
safecoin_program::{entrypoint::ProgramResult, pubkey::Pubkey},
safe_zk_token_sdk::zk_token_elgamal::pod,
};
pub mod instruction;
pub mod processor;
pub type EncryptionPubkey = pod::ElGamalPubkey;
pub type EncryptedBalance = pod::ElGamalCiphertext;
pub type DecryptableBalance = pod::AeCiphertext;
pub type EncryptedFee = pod::FeeEncryption;
pub type EncryptedWithheldAmount = pod::ElGamalCiphertext;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
pub struct ConfidentialTransferMint {
pub authority: Pubkey,
pub auto_approve_new_accounts: PodBool,
pub auditor_pubkey: EncryptionPubkey,
pub withdraw_withheld_authority_pubkey: EncryptionPubkey,
pub withheld_amount: EncryptedWithheldAmount,
}
impl Extension for ConfidentialTransferMint {
const TYPE: ExtensionType = ExtensionType::ConfidentialTransferMint;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
pub struct ConfidentialTransferAccount {
pub approved: PodBool,
pub encryption_pubkey: EncryptionPubkey,
pub pending_balance: EncryptedBalance,
pub available_balance: EncryptedBalance,
pub decryptable_available_balance: DecryptableBalance,
pub allow_balance_credits: PodBool,
pub pending_balance_credit_counter: PodU64,
pub expected_pending_balance_credit_counter: PodU64,
pub actual_pending_balance_credit_counter: PodU64,
pub withheld_amount: EncryptedWithheldAmount,
}
impl Extension for ConfidentialTransferAccount {
const TYPE: ExtensionType = ExtensionType::ConfidentialTransferAccount;
}
impl ConfidentialTransferAccount {
pub fn approved(&self) -> ProgramResult {
if bool::from(&self.approved) {
Ok(())
} else {
Err(TokenError::ConfidentialTransferAccountNotApproved.into())
}
}
pub fn closable(&self) -> ProgramResult {
if self.pending_balance == EncryptedBalance::zeroed()
&& self.available_balance == EncryptedBalance::zeroed()
&& self.withheld_amount == EncryptedWithheldAmount::zeroed()
{
Ok(())
} else {
Err(TokenError::ConfidentialTransferAccountHasBalance.into())
}
}
}