|
@@ -661,6 +661,16 @@ fn generate_constraint_init_group(
|
|
|
decimals,
|
|
|
freeze_authority,
|
|
|
token_program,
|
|
|
+ group_pointer_authority,
|
|
|
+ group_pointer_group_address,
|
|
|
+ group_member_pointer_authority,
|
|
|
+ group_member_pointer_member_address,
|
|
|
+ metadata_pointer_authority,
|
|
|
+ metadata_pointer_metadata_address,
|
|
|
+ close_authority,
|
|
|
+ permanent_delegate,
|
|
|
+ transfer_hook_authority,
|
|
|
+ transfer_hook_program_id,
|
|
|
} => {
|
|
|
let token_program = match token_program {
|
|
|
Some(t) => t.to_token_stream(),
|
|
@@ -672,6 +682,59 @@ fn generate_constraint_init_group(
|
|
|
None => quote! {},
|
|
|
};
|
|
|
|
|
|
+ // extension checks
|
|
|
+
|
|
|
+ let group_pointer_authority_check = match group_pointer_authority {
|
|
|
+ Some(gpa) => check_scope.generate_check(gpa),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_pointer_group_address_check = match group_pointer_group_address {
|
|
|
+ Some(gpga) => check_scope.generate_check(gpga),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_member_pointer_authority_check = match group_member_pointer_authority {
|
|
|
+ Some(gmpa) => check_scope.generate_check(gmpa),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_member_pointer_member_address_check =
|
|
|
+ match group_member_pointer_member_address {
|
|
|
+ Some(gmpm) => check_scope.generate_check(gmpm),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let metadata_pointer_authority_check = match metadata_pointer_authority {
|
|
|
+ Some(mpa) => check_scope.generate_check(mpa),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let metadata_pointer_metadata_address_check = match metadata_pointer_metadata_address {
|
|
|
+ Some(mpma) => check_scope.generate_check(mpma),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let close_authority_check = match close_authority {
|
|
|
+ Some(ca) => check_scope.generate_check(ca),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let transfer_hook_authority_check = match transfer_hook_authority {
|
|
|
+ Some(tha) => check_scope.generate_check(tha),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let transfer_hook_program_id_check = match transfer_hook_program_id {
|
|
|
+ Some(thpid) => check_scope.generate_check(thpid),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let permanent_delegate_check = match permanent_delegate {
|
|
|
+ Some(pd) => check_scope.generate_check(pd),
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
let system_program_optional_check = check_scope.generate_check(system_program);
|
|
|
let token_program_optional_check = check_scope.generate_check(&token_program);
|
|
|
let rent_optional_check = check_scope.generate_check(rent);
|
|
@@ -682,23 +745,126 @@ fn generate_constraint_init_group(
|
|
|
#rent_optional_check
|
|
|
#owner_optional_check
|
|
|
#freeze_authority_optional_check
|
|
|
+ #group_pointer_authority_check
|
|
|
+ #group_pointer_group_address_check
|
|
|
+ #group_member_pointer_authority_check
|
|
|
+ #group_member_pointer_member_address_check
|
|
|
+ #metadata_pointer_authority_check
|
|
|
+ #metadata_pointer_metadata_address_check
|
|
|
+ #close_authority_check
|
|
|
+ #transfer_hook_authority_check
|
|
|
+ #transfer_hook_program_id_check
|
|
|
+ #permanent_delegate_check
|
|
|
};
|
|
|
|
|
|
let payer_optional_check = check_scope.generate_check(payer);
|
|
|
|
|
|
+ let mut extensions = vec![];
|
|
|
+ if group_pointer_authority.is_some() || group_pointer_group_address.is_some() {
|
|
|
+ extensions.push(quote! {::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::GroupPointer});
|
|
|
+ }
|
|
|
+
|
|
|
+ if group_member_pointer_authority.is_some()
|
|
|
+ || group_member_pointer_member_address.is_some()
|
|
|
+ {
|
|
|
+ extensions.push(quote! {::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::GroupMemberPointer});
|
|
|
+ }
|
|
|
+
|
|
|
+ if metadata_pointer_authority.is_some() || metadata_pointer_metadata_address.is_some() {
|
|
|
+ extensions.push(quote! {::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::MetadataPointer});
|
|
|
+ }
|
|
|
+
|
|
|
+ if close_authority.is_some() {
|
|
|
+ extensions.push(quote! {::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::MintCloseAuthority});
|
|
|
+ }
|
|
|
+
|
|
|
+ if transfer_hook_authority.is_some() || transfer_hook_program_id.is_some() {
|
|
|
+ extensions.push(quote! {::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::TransferHook});
|
|
|
+ }
|
|
|
+
|
|
|
+ if permanent_delegate.is_some() {
|
|
|
+ extensions.push(quote! {::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::PermanentDelegate});
|
|
|
+ }
|
|
|
+
|
|
|
+ let mint_space = if extensions.is_empty() {
|
|
|
+ quote! { ::anchor_spl::token::Mint::LEN }
|
|
|
+ } else {
|
|
|
+ quote! { ::anchor_spl::token_interface::find_mint_account_size(Some(&vec![#(#extensions),*]))? }
|
|
|
+ };
|
|
|
+
|
|
|
+ let extensions = if extensions.is_empty() {
|
|
|
+ quote! {Option::<&::anchor_spl::token_interface::ExtensionsVec>::None}
|
|
|
+ } else {
|
|
|
+ quote! {Option::<&::anchor_spl::token_interface::ExtensionsVec>::Some(&vec![#(#extensions),*])}
|
|
|
+ };
|
|
|
+
|
|
|
+ let freeze_authority = match freeze_authority {
|
|
|
+ Some(fa) => quote! { Option::<&anchor_lang::prelude::Pubkey>::Some(&#fa.key()) },
|
|
|
+ None => quote! { Option::<&anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_pointer_authority = match group_pointer_authority {
|
|
|
+ Some(gpa) => quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#gpa.key()) },
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_pointer_group_address = match group_pointer_group_address {
|
|
|
+ Some(gpga) => quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#gpga.key()) },
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_member_pointer_authority = match group_member_pointer_authority {
|
|
|
+ Some(gmpa) => quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#gmpa.key()) },
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_member_pointer_member_address = match group_member_pointer_member_address {
|
|
|
+ Some(gmpma) => {
|
|
|
+ quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#gmpma.key()) }
|
|
|
+ }
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let metadata_pointer_authority = match metadata_pointer_authority {
|
|
|
+ Some(mpa) => quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#mpa.key()) },
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let metadata_pointer_metadata_address = match metadata_pointer_metadata_address {
|
|
|
+ Some(mpma) => quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#mpma.key()) },
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let close_authority = match close_authority {
|
|
|
+ Some(ca) => quote! { Option::<&anchor_lang::prelude::Pubkey>::Some(&#ca.key()) },
|
|
|
+ None => quote! { Option::<&anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let permanent_delegate = match permanent_delegate {
|
|
|
+ Some(pd) => quote! { Option::<&anchor_lang::prelude::Pubkey>::Some(&#pd.key()) },
|
|
|
+ None => quote! { Option::<&anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let transfer_hook_authority = match transfer_hook_authority {
|
|
|
+ Some(tha) => quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#tha.key()) },
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
+ let transfer_hook_program_id = match transfer_hook_program_id {
|
|
|
+ Some(thpid) => {
|
|
|
+ quote! { Option::<anchor_lang::prelude::Pubkey>::Some(#thpid.key()) }
|
|
|
+ }
|
|
|
+ None => quote! { Option::<anchor_lang::prelude::Pubkey>::None },
|
|
|
+ };
|
|
|
+
|
|
|
let create_account = generate_create_account(
|
|
|
field,
|
|
|
- quote! {::anchor_spl::token::Mint::LEN},
|
|
|
+ mint_space,
|
|
|
quote! {&#token_program.key()},
|
|
|
quote! {#payer},
|
|
|
seeds_with_bump,
|
|
|
);
|
|
|
|
|
|
- let freeze_authority = match freeze_authority {
|
|
|
- Some(fa) => quote! { Option::<&anchor_lang::prelude::Pubkey>::Some(&#fa.key()) },
|
|
|
- None => quote! { Option::<&anchor_lang::prelude::Pubkey>::None },
|
|
|
- };
|
|
|
-
|
|
|
quote! {
|
|
|
// Define the bump and pda variable.
|
|
|
#find_pda
|
|
@@ -715,6 +881,78 @@ fn generate_constraint_init_group(
|
|
|
// Create the account with the system program.
|
|
|
#create_account
|
|
|
|
|
|
+ // Initialize extensions.
|
|
|
+ if let Some(extensions) = #extensions {
|
|
|
+ for e in extensions {
|
|
|
+ match e {
|
|
|
+ ::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::GroupPointer => {
|
|
|
+ let cpi_program = #token_program.to_account_info();
|
|
|
+ let accounts = ::anchor_spl::token_interface::GroupPointerInitialize {
|
|
|
+ token_program_id: #token_program.to_account_info(),
|
|
|
+ mint: #field.to_account_info(),
|
|
|
+ };
|
|
|
+ let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
+ ::anchor_spl::token_interface::group_pointer_initialize(cpi_ctx, #group_pointer_authority, #group_pointer_group_address)?;
|
|
|
+ },
|
|
|
+ ::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::GroupMemberPointer => {
|
|
|
+ let cpi_program = #token_program.to_account_info();
|
|
|
+ let accounts = ::anchor_spl::token_interface::GroupMemberPointerInitialize {
|
|
|
+ token_program_id: #token_program.to_account_info(),
|
|
|
+ mint: #field.to_account_info(),
|
|
|
+ };
|
|
|
+ let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
+ ::anchor_spl::token_interface::group_member_pointer_initialize(cpi_ctx, #group_member_pointer_authority, #group_member_pointer_member_address)?;
|
|
|
+ },
|
|
|
+ ::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::MetadataPointer => {
|
|
|
+ let cpi_program = #token_program.to_account_info();
|
|
|
+ let accounts = ::anchor_spl::token_interface::MetadataPointerInitialize {
|
|
|
+ token_program_id: #token_program.to_account_info(),
|
|
|
+ mint: #field.to_account_info(),
|
|
|
+ };
|
|
|
+ let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
+ ::anchor_spl::token_interface::metadata_pointer_initialize(cpi_ctx, #metadata_pointer_authority, #metadata_pointer_metadata_address)?;
|
|
|
+ },
|
|
|
+ ::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::MintCloseAuthority => {
|
|
|
+ let cpi_program = #token_program.to_account_info();
|
|
|
+ let accounts = ::anchor_spl::token_interface::MintCloseAuthorityInitialize {
|
|
|
+ token_program_id: #token_program.to_account_info(),
|
|
|
+ mint: #field.to_account_info(),
|
|
|
+ };
|
|
|
+ let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
+ ::anchor_spl::token_interface::mint_close_authority_initialize(cpi_ctx, #close_authority)?;
|
|
|
+ },
|
|
|
+ ::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::TransferHook => {
|
|
|
+ let cpi_program = #token_program.to_account_info();
|
|
|
+ let accounts = ::anchor_spl::token_interface::TransferHookInitialize {
|
|
|
+ token_program_id: #token_program.to_account_info(),
|
|
|
+ mint: #field.to_account_info(),
|
|
|
+ };
|
|
|
+ let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
+ ::anchor_spl::token_interface::transfer_hook_initialize(cpi_ctx, #transfer_hook_authority, #transfer_hook_program_id)?;
|
|
|
+ },
|
|
|
+ ::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::NonTransferable => {
|
|
|
+ let cpi_program = #token_program.to_account_info();
|
|
|
+ let accounts = ::anchor_spl::token_interface::NonTransferableMintInitialize {
|
|
|
+ token_program_id: #token_program.to_account_info(),
|
|
|
+ mint: #field.to_account_info(),
|
|
|
+ };
|
|
|
+ let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
+ ::anchor_spl::token_interface::non_transferable_mint_initialize(cpi_ctx)?;
|
|
|
+ },
|
|
|
+ ::anchor_spl::token_interface::spl_token_2022::extension::ExtensionType::PermanentDelegate => {
|
|
|
+ let cpi_program = #token_program.to_account_info();
|
|
|
+ let accounts = ::anchor_spl::token_interface::PermanentDelegateInitialize {
|
|
|
+ token_program_id: #token_program.to_account_info(),
|
|
|
+ mint: #field.to_account_info(),
|
|
|
+ };
|
|
|
+ let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
+ ::anchor_spl::token_interface::permanent_delegate_initialize(cpi_ctx, #permanent_delegate.unwrap())?;
|
|
|
+ },
|
|
|
+ _ => {} // do nothing
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
// Initialize the mint account.
|
|
|
let cpi_program = #token_program.to_account_info();
|
|
|
let accounts = ::anchor_spl::token_interface::InitializeMint2 {
|
|
@@ -723,6 +961,7 @@ fn generate_constraint_init_group(
|
|
|
let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
|
|
|
::anchor_spl::token_interface::initialize_mint2(cpi_ctx, #decimals, &#owner.key(), #freeze_authority)?;
|
|
|
}
|
|
|
+
|
|
|
let pa: #ty_decl = #from_account_info_unchecked;
|
|
|
if #if_needed {
|
|
|
if pa.mint_authority != anchor_lang::solana_program::program_option::COption::Some(#owner.key()) {
|
|
@@ -1068,12 +1307,203 @@ fn generate_constraint_mint(
|
|
|
}
|
|
|
None => quote! {},
|
|
|
};
|
|
|
+
|
|
|
+ let group_pointer_authority_check = match &c.group_pointer_authority {
|
|
|
+ Some(group_pointer_authority) => {
|
|
|
+ let group_pointer_authority_optional_check =
|
|
|
+ optional_check_scope.generate_check(group_pointer_authority);
|
|
|
+ quote! {
|
|
|
+ let group_pointer = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::group_pointer::GroupPointer>(#account_ref);
|
|
|
+ if group_pointer.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupPointerExtension.into());
|
|
|
+ }
|
|
|
+ #group_pointer_authority_optional_check
|
|
|
+ if group_pointer.unwrap().authority != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#group_pointer_authority.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupPointerExtensionAuthority.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_pointer_group_address_check = match &c.group_pointer_group_address {
|
|
|
+ Some(group_pointer_group_address) => {
|
|
|
+ let group_pointer_group_address_optional_check =
|
|
|
+ optional_check_scope.generate_check(group_pointer_group_address);
|
|
|
+ quote! {
|
|
|
+ let group_pointer = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::group_pointer::GroupPointer>(#account_ref);
|
|
|
+ if group_pointer.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupPointerExtension.into());
|
|
|
+ }
|
|
|
+ #group_pointer_group_address_optional_check
|
|
|
+ if group_pointer.unwrap().group_address != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#group_pointer_group_address.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupPointerExtensionGroupAddress.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_member_pointer_authority_check = match &c.group_member_pointer_authority {
|
|
|
+ Some(group_member_pointer_authority) => {
|
|
|
+ let group_member_pointer_authority_optional_check =
|
|
|
+ optional_check_scope.generate_check(group_member_pointer_authority);
|
|
|
+ quote! {
|
|
|
+ let group_member_pointer = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::group_member_pointer::GroupMemberPointer>(#account_ref);
|
|
|
+ if group_member_pointer.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupMemberPointerExtension.into());
|
|
|
+ }
|
|
|
+ #group_member_pointer_authority_optional_check
|
|
|
+ if group_member_pointer.unwrap().authority != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#group_member_pointer_authority.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupMemberPointerExtensionAuthority.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let group_member_pointer_member_address_check = match &c.group_member_pointer_member_address {
|
|
|
+ Some(group_member_pointer_member_address) => {
|
|
|
+ let group_member_pointer_member_address_optional_check =
|
|
|
+ optional_check_scope.generate_check(group_member_pointer_member_address);
|
|
|
+ quote! {
|
|
|
+ let group_member_pointer = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::group_member_pointer::GroupMemberPointer>(#account_ref);
|
|
|
+ if group_member_pointer.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupMemberPointerExtension.into());
|
|
|
+ }
|
|
|
+ #group_member_pointer_member_address_optional_check
|
|
|
+ if group_member_pointer.unwrap().member_address != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#group_member_pointer_member_address.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintGroupMemberPointerExtensionMemberAddress.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let metadata_pointer_authority_check = match &c.metadata_pointer_authority {
|
|
|
+ Some(metadata_pointer_authority) => {
|
|
|
+ let metadata_pointer_authority_optional_check =
|
|
|
+ optional_check_scope.generate_check(metadata_pointer_authority);
|
|
|
+ quote! {
|
|
|
+ let metadata_pointer = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::metadata_pointer::MetadataPointer>(#account_ref);
|
|
|
+ if metadata_pointer.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintMetadataPointerExtension.into());
|
|
|
+ }
|
|
|
+ #metadata_pointer_authority_optional_check
|
|
|
+ if metadata_pointer.unwrap().authority != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#metadata_pointer_authority.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintMetadataPointerExtensionAuthority.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let metadata_pointer_metadata_address_check = match &c.metadata_pointer_metadata_address {
|
|
|
+ Some(metadata_pointer_metadata_address) => {
|
|
|
+ let metadata_pointer_metadata_address_optional_check =
|
|
|
+ optional_check_scope.generate_check(metadata_pointer_metadata_address);
|
|
|
+ quote! {
|
|
|
+ let metadata_pointer = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::metadata_pointer::MetadataPointer>(#account_ref);
|
|
|
+ if metadata_pointer.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintMetadataPointerExtension.into());
|
|
|
+ }
|
|
|
+ #metadata_pointer_metadata_address_optional_check
|
|
|
+ if metadata_pointer.unwrap().metadata_address != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#metadata_pointer_metadata_address.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintMetadataPointerExtensionMetadataAddress.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let close_authority_check = match &c.close_authority {
|
|
|
+ Some(close_authority) => {
|
|
|
+ let close_authority_optional_check =
|
|
|
+ optional_check_scope.generate_check(close_authority);
|
|
|
+ quote! {
|
|
|
+ let close_authority = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::mint_close_authority::MintCloseAuthority>(#account_ref);
|
|
|
+ if close_authority.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintCloseAuthorityExtension.into());
|
|
|
+ }
|
|
|
+ #close_authority_optional_check
|
|
|
+ if close_authority.unwrap().close_authority != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#close_authority.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintCloseAuthorityExtensionAuthority.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let permanent_delegate_check = match &c.permanent_delegate {
|
|
|
+ Some(permanent_delegate) => {
|
|
|
+ let permanent_delegate_optional_check =
|
|
|
+ optional_check_scope.generate_check(permanent_delegate);
|
|
|
+ quote! {
|
|
|
+ let permanent_delegate = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::permanent_delegate::PermanentDelegate>(#account_ref);
|
|
|
+ if permanent_delegate.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintPermanentDelegateExtension.into());
|
|
|
+ }
|
|
|
+ #permanent_delegate_optional_check
|
|
|
+ if permanent_delegate.unwrap().delegate != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#permanent_delegate.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintPermanentDelegateExtensionDelegate.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let transfer_hook_authority_check = match &c.transfer_hook_authority {
|
|
|
+ Some(transfer_hook_authority) => {
|
|
|
+ let transfer_hook_authority_optional_check =
|
|
|
+ optional_check_scope.generate_check(transfer_hook_authority);
|
|
|
+ quote! {
|
|
|
+ let transfer_hook = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::transfer_hook::TransferHook>(#account_ref);
|
|
|
+ if transfer_hook.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintTransferHookExtension.into());
|
|
|
+ }
|
|
|
+ #transfer_hook_authority_optional_check
|
|
|
+ if transfer_hook.unwrap().authority != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#transfer_hook_authority.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintTransferHookExtensionAuthority.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ let transfer_hook_program_id_check = match &c.transfer_hook_program_id {
|
|
|
+ Some(transfer_hook_program_id) => {
|
|
|
+ let transfer_hook_program_id_optional_check =
|
|
|
+ optional_check_scope.generate_check(transfer_hook_program_id);
|
|
|
+ quote! {
|
|
|
+ let transfer_hook = ::anchor_spl::token_interface::get_mint_extension_data::<::anchor_spl::token_interface::spl_token_2022::extension::transfer_hook::TransferHook>(#account_ref);
|
|
|
+ if transfer_hook.is_err() {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintTransferHookExtension.into());
|
|
|
+ }
|
|
|
+ #transfer_hook_program_id_optional_check
|
|
|
+ if transfer_hook.unwrap().program_id != ::anchor_spl::token_2022_extensions::spl_pod::optional_keys::OptionalNonZeroPubkey::try_from(Some(#transfer_hook_program_id.key()))? {
|
|
|
+ return Err(anchor_lang::error::ErrorCode::ConstraintMintTransferHookExtensionProgramId.into());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
quote! {
|
|
|
{
|
|
|
#decimal_check
|
|
|
#mint_authority_check
|
|
|
#freeze_authority_check
|
|
|
#token_program_check
|
|
|
+ #group_pointer_authority_check
|
|
|
+ #group_pointer_group_address_check
|
|
|
+ #group_member_pointer_authority_check
|
|
|
+ #group_member_pointer_member_address_check
|
|
|
+ #metadata_pointer_authority_check
|
|
|
+ #metadata_pointer_metadata_address_check
|
|
|
+ #close_authority_check
|
|
|
+ #permanent_delegate_check
|
|
|
+ #transfer_hook_authority_check
|
|
|
+ #transfer_hook_program_id_check
|
|
|
}
|
|
|
}
|
|
|
}
|