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_address::Address,
8 solana_nullable::MaybeNull,
9 solana_program_error::ProgramResult,
10 solana_zero_copy::unaligned::Bool,
11 solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
12 spl_token_confidential_transfer_proof_extraction::encryption::PodFeeCiphertext,
13};
14
15pub mod instruction;
17
18pub type EncryptedFee = PodFeeCiphertext;
20pub type EncryptedWithheldAmount = PodElGamalCiphertext;
22
23#[repr(C)]
25#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
26pub struct ConfidentialTransferFeeConfig {
27 pub authority: MaybeNull<Address>,
29
30 pub withdraw_withheld_authority_elgamal_pubkey: PodElGamalPubkey,
37
38 pub harvest_to_mint_enabled: Bool,
40
41 pub withheld_amount: EncryptedWithheldAmount,
44}
45
46impl Extension for ConfidentialTransferFeeConfig {
47 const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeConfig;
48}
49
50#[repr(C)]
52#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
53pub struct ConfidentialTransferFeeAmount {
54 pub withheld_amount: EncryptedWithheldAmount,
56}
57
58impl Extension for ConfidentialTransferFeeAmount {
59 const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeAmount;
60}
61
62impl ConfidentialTransferFeeAmount {
63 pub fn closable(&self) -> ProgramResult {
65 if self.withheld_amount == EncryptedWithheldAmount::zeroed() {
66 Ok(())
67 } else {
68 Err(TokenError::ConfidentialTransferFeeAccountHasWithheldFee.into())
69 }
70 }
71}