light_token_interface/
token_2022_extensions.rs1use light_zero_copy::errors::ZeroCopyError;
2use spl_token_2022::extension::ExtensionType;
3
4use crate::state::ExtensionStructConfig;
5
6pub const RESTRICTED_EXTENSION_TYPES: [ExtensionType; 6] = [
10 ExtensionType::Pausable,
11 ExtensionType::PermanentDelegate,
12 ExtensionType::TransferFeeConfig,
13 ExtensionType::TransferHook,
14 ExtensionType::DefaultAccountState,
15 ExtensionType::MintCloseAuthority,
16];
17
18pub const ALLOWED_EXTENSION_TYPES: [ExtensionType; 16] = [
26 ExtensionType::MetadataPointer,
28 ExtensionType::TokenMetadata,
29 ExtensionType::InterestBearingConfig,
31 ExtensionType::GroupPointer,
32 ExtensionType::GroupMemberPointer,
33 ExtensionType::TokenGroup,
34 ExtensionType::TokenGroupMember,
35 ExtensionType::MintCloseAuthority,
37 ExtensionType::TransferFeeConfig,
38 ExtensionType::DefaultAccountState,
39 ExtensionType::PermanentDelegate,
40 ExtensionType::TransferHook,
41 ExtensionType::Pausable,
42 ExtensionType::ConfidentialTransferMint,
43 ExtensionType::ConfidentialTransferFeeConfig,
44 ExtensionType::ConfidentialMintBurn,
45];
46
47#[inline(always)]
49pub const fn is_restricted_extension(ext: &ExtensionType) -> bool {
50 matches!(
51 ext,
52 ExtensionType::Pausable
53 | ExtensionType::PermanentDelegate
54 | ExtensionType::TransferFeeConfig
55 | ExtensionType::TransferHook
56 | ExtensionType::DefaultAccountState
57 | ExtensionType::MintCloseAuthority
58 )
59}
60
61#[derive(Debug, Default, Clone, Copy)]
63pub struct MintExtensionFlags {
64 pub has_pausable: bool,
66 pub has_permanent_delegate: bool,
68 pub has_default_account_state: bool,
70 pub default_state_frozen: bool,
72 pub has_transfer_fee: bool,
74 pub has_transfer_hook: bool,
76 pub has_mint_close_authority: bool,
78}
79
80impl MintExtensionFlags {
81 pub fn num_token_account_extensions(&self) -> usize {
82 let mut count = 0;
83 if self.has_pausable {
84 count += 1;
85 }
86 if self.has_permanent_delegate {
87 count += 1;
88 }
89 if self.has_transfer_fee {
90 count += 1;
91 }
92 if self.has_transfer_hook {
93 count += 1;
94 }
95 count
96 }
97
98 pub fn calculate_account_size(&self, compressible: bool) -> Result<u64, ZeroCopyError> {
107 let mut extensions: [ExtensionStructConfig; 5] = [
110 ExtensionStructConfig::Placeholder0,
111 ExtensionStructConfig::Placeholder0,
112 ExtensionStructConfig::Placeholder0,
113 ExtensionStructConfig::Placeholder0,
114 ExtensionStructConfig::Placeholder0,
115 ];
116 let mut count = 0;
117
118 if self.has_pausable {
119 extensions[count] = ExtensionStructConfig::PausableAccount(());
120 count += 1;
121 }
122 if self.has_permanent_delegate {
123 extensions[count] = ExtensionStructConfig::PermanentDelegateAccount(());
124 count += 1;
125 }
126 if self.has_transfer_fee {
127 extensions[count] = ExtensionStructConfig::TransferFeeAccount(());
128 count += 1;
129 }
130 if self.has_transfer_hook {
131 extensions[count] = ExtensionStructConfig::TransferHookAccount(());
132 count += 1;
133 }
134 if compressible {
135 extensions[count] =
136 ExtensionStructConfig::Compressible(crate::state::CompressibleExtensionConfig {
137 info: crate::state::CompressionInfoConfig { rent_config: () },
138 });
139 count += 1;
140 }
141
142 let exts = if count == 0 {
143 None
144 } else {
145 Some(&extensions[..count])
146 };
147 crate::state::calculate_token_account_size(exts).map(|size| size as u64)
148 }
149
150 pub const fn has_restricted_extensions(&self) -> bool {
154 self.has_pausable
155 || self.has_permanent_delegate
156 || self.has_transfer_fee
157 || self.has_transfer_hook
158 || self.has_default_account_state
159 || self.has_mint_close_authority
160 }
161}