spl_token_2022_interface/extension/confidential_transfer_fee/
mod.rs

1use {
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
13/// Confidential transfer fee extension instructions
14pub mod instruction;
15
16/// ElGamal ciphertext containing a transfer fee
17pub type EncryptedFee = PodFeeCiphertext;
18/// ElGamal ciphertext containing a withheld fee in an account
19pub type EncryptedWithheldAmount = PodElGamalCiphertext;
20
21/// Confidential transfer fee extension data for mints
22#[repr(C)]
23#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
24pub struct ConfidentialTransferFeeConfig {
25    /// Optional authority to set the withdraw withheld authority ElGamal key
26    pub authority: OptionalNonZeroPubkey,
27
28    /// Withheld fees from accounts must be encrypted with this ElGamal key.
29    ///
30    /// Note that whoever holds the ElGamal private key for this ElGamal public
31    /// key has the ability to decode any withheld fee amount that are
32    /// associated with accounts. When combined with the fee parameters, the
33    /// withheld fee amounts can reveal information about transfer amounts.
34    pub withdraw_withheld_authority_elgamal_pubkey: PodElGamalPubkey,
35
36    /// If `false`, the harvest of withheld tokens to mint is rejected.
37    pub harvest_to_mint_enabled: PodBool,
38
39    /// Withheld confidential transfer fee tokens that have been moved to the
40    /// mint for withdrawal.
41    pub withheld_amount: EncryptedWithheldAmount,
42}
43
44impl Extension for ConfidentialTransferFeeConfig {
45    const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeConfig;
46}
47
48/// Confidential transfer fee
49#[repr(C)]
50#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
51pub struct ConfidentialTransferFeeAmount {
52    /// Amount withheld during confidential transfers, to be harvest to the mint
53    pub withheld_amount: EncryptedWithheldAmount,
54}
55
56impl Extension for ConfidentialTransferFeeAmount {
57    const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeAmount;
58}
59
60impl ConfidentialTransferFeeAmount {
61    /// Check if a confidential transfer fee account is in a closable state.
62    pub fn closable(&self) -> ProgramResult {
63        if self.withheld_amount == EncryptedWithheldAmount::zeroed() {
64            Ok(())
65        } else {
66            Err(TokenError::ConfidentialTransferFeeAccountHasWithheldFee.into())
67        }
68    }
69}