spl_token_2022/extension/confidential_transfer_fee/
mod.rs1use {
2 crate::{
3 error::TokenError,
4 extension::{Extension, ExtensionType},
5 },
6 bytemuck::{Pod, Zeroable},
7 solana_program::entrypoint::ProgramResult,
8 solana_zk_sdk::encryption::pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
9 spl_pod::{optional_keys::OptionalNonZeroPubkey, primitives::PodBool},
10 spl_token_confidential_transfer_proof_extraction::encryption::PodFeeCiphertext,
11};
12
13pub mod instruction;
15
16pub mod processor;
18
19#[cfg(not(target_os = "solana"))]
22pub mod account_info;
23
24pub type EncryptedFee = PodFeeCiphertext;
26pub type EncryptedWithheldAmount = PodElGamalCiphertext;
28
29#[repr(C)]
31#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
32pub struct ConfidentialTransferFeeConfig {
33 pub authority: OptionalNonZeroPubkey,
35
36 pub withdraw_withheld_authority_elgamal_pubkey: PodElGamalPubkey,
43
44 pub harvest_to_mint_enabled: PodBool,
46
47 pub withheld_amount: EncryptedWithheldAmount,
50}
51
52impl Extension for ConfidentialTransferFeeConfig {
53 const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeConfig;
54}
55
56#[repr(C)]
58#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
59pub struct ConfidentialTransferFeeAmount {
60 pub withheld_amount: EncryptedWithheldAmount,
62}
63
64impl Extension for ConfidentialTransferFeeAmount {
65 const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeAmount;
66}
67
68impl ConfidentialTransferFeeAmount {
69 pub fn closable(&self) -> ProgramResult {
71 if self.withheld_amount == EncryptedWithheldAmount::zeroed() {
72 Ok(())
73 } else {
74 Err(TokenError::ConfidentialTransferFeeAccountHasWithheldFee.into())
75 }
76 }
77}