spl_token_2022_interface/extension/confidential_transfer_fee/
mod.rs1use {
2 crate::{
3 error::TokenError,
4 extension::{Extension, ExtensionType},
5 },
6 bytemuck::{Pod, Zeroable},
7 solana_program_error::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 type EncryptedFee = PodFeeCiphertext;
18pub type EncryptedWithheldAmount = PodElGamalCiphertext;
20
21#[repr(C)]
23#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
24pub struct ConfidentialTransferFeeConfig {
25 pub authority: OptionalNonZeroPubkey,
27
28 pub withdraw_withheld_authority_elgamal_pubkey: PodElGamalPubkey,
35
36 pub harvest_to_mint_enabled: PodBool,
38
39 pub withheld_amount: EncryptedWithheldAmount,
42}
43
44impl Extension for ConfidentialTransferFeeConfig {
45 const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeConfig;
46}
47
48#[repr(C)]
50#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
51pub struct ConfidentialTransferFeeAmount {
52 pub withheld_amount: EncryptedWithheldAmount,
54}
55
56impl Extension for ConfidentialTransferFeeAmount {
57 const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeAmount;
58}
59
60impl ConfidentialTransferFeeAmount {
61 pub fn closable(&self) -> ProgramResult {
63 if self.withheld_amount == EncryptedWithheldAmount::zeroed() {
64 Ok(())
65 } else {
66 Err(TokenError::ConfidentialTransferFeeAccountHasWithheldFee.into())
67 }
68 }
69}