use light_zero_copy::errors::ZeroCopyError;
use spl_token_2022::extension::ExtensionType;
use crate::state::ExtensionStructConfig;
pub const RESTRICTED_EXTENSION_TYPES: [ExtensionType; 6] = [
ExtensionType::Pausable,
ExtensionType::PermanentDelegate,
ExtensionType::TransferFeeConfig,
ExtensionType::TransferHook,
ExtensionType::DefaultAccountState,
ExtensionType::MintCloseAuthority,
];
pub const ALLOWED_EXTENSION_TYPES: [ExtensionType; 16] = [
ExtensionType::MetadataPointer,
ExtensionType::TokenMetadata,
ExtensionType::InterestBearingConfig,
ExtensionType::GroupPointer,
ExtensionType::GroupMemberPointer,
ExtensionType::TokenGroup,
ExtensionType::TokenGroupMember,
ExtensionType::MintCloseAuthority,
ExtensionType::TransferFeeConfig,
ExtensionType::DefaultAccountState,
ExtensionType::PermanentDelegate,
ExtensionType::TransferHook,
ExtensionType::Pausable,
ExtensionType::ConfidentialTransferMint,
ExtensionType::ConfidentialTransferFeeConfig,
ExtensionType::ConfidentialMintBurn,
];
#[inline(always)]
pub const fn is_restricted_extension(ext: &ExtensionType) -> bool {
matches!(
ext,
ExtensionType::Pausable
| ExtensionType::PermanentDelegate
| ExtensionType::TransferFeeConfig
| ExtensionType::TransferHook
| ExtensionType::DefaultAccountState
| ExtensionType::MintCloseAuthority
)
}
#[derive(Debug, Default, Clone, Copy)]
pub struct MintExtensionFlags {
pub has_pausable: bool,
pub has_permanent_delegate: bool,
pub has_default_account_state: bool,
pub default_state_frozen: bool,
pub has_transfer_fee: bool,
pub has_transfer_hook: bool,
pub has_mint_close_authority: bool,
}
impl MintExtensionFlags {
pub fn num_token_account_extensions(&self) -> usize {
let mut count = 0;
if self.has_pausable {
count += 1;
}
if self.has_permanent_delegate {
count += 1;
}
if self.has_transfer_fee {
count += 1;
}
if self.has_transfer_hook {
count += 1;
}
count
}
pub fn calculate_account_size(&self, compressible: bool) -> Result<u64, ZeroCopyError> {
let mut extensions: [ExtensionStructConfig; 5] = [
ExtensionStructConfig::Placeholder0,
ExtensionStructConfig::Placeholder0,
ExtensionStructConfig::Placeholder0,
ExtensionStructConfig::Placeholder0,
ExtensionStructConfig::Placeholder0,
];
let mut count = 0;
if self.has_pausable {
extensions[count] = ExtensionStructConfig::PausableAccount(());
count += 1;
}
if self.has_permanent_delegate {
extensions[count] = ExtensionStructConfig::PermanentDelegateAccount(());
count += 1;
}
if self.has_transfer_fee {
extensions[count] = ExtensionStructConfig::TransferFeeAccount(());
count += 1;
}
if self.has_transfer_hook {
extensions[count] = ExtensionStructConfig::TransferHookAccount(());
count += 1;
}
if compressible {
extensions[count] =
ExtensionStructConfig::Compressible(crate::state::CompressibleExtensionConfig {
info: crate::state::CompressionInfoConfig { rent_config: () },
});
count += 1;
}
let exts = if count == 0 {
None
} else {
Some(&extensions[..count])
};
crate::state::calculate_token_account_size(exts).map(|size| size as u64)
}
pub const fn has_restricted_extensions(&self) -> bool {
self.has_pausable
|| self.has_permanent_delegate
|| self.has_transfer_fee
|| self.has_transfer_hook
|| self.has_default_account_state
|| self.has_mint_close_authority
}
}