v0.4.7-pre.004

This commit is contained in:
2026-08-02 09:57:55 +02:00
parent 1bddeb834d
commit d3b63e3a3c
14 changed files with 478 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor.rs
// version: 11
// version: 12
//! Consolidated executor modules.
@@ -214,12 +214,18 @@ pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_CREATE_OPERATION;
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES;
/// Stable deprecated Metaplex PuffMetadata operation code.
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION;
/// Stable deprecated Metaplex SetCollectionSize operation code.
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION;
/// Stable deprecated Metaplex SetTokenStandard operation code.
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION;
/// Current and deprecated Metaplex Token Metadata operations.
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES;
/// Stable operation code for the current Metaplex Unverify wrapper.
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION;
/// Stable operation code for the current Metaplex Update wrapper.
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_UPDATE_OPERATION;
/// Stable operation code for the current Metaplex Verify wrapper.
pub use self::metadata::EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION;
/// Exposes the Metaplex Token Metadata executor.
pub use self::metadata::ExMetadataMetaplexTokenMetadataExecutor;
/// Reserved `kb-lib.executor.metadata.solana_program_metadata` executor.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/metadata.rs
// version: 5
// version: 6
//! `metadata` executor family.
@@ -10,9 +10,12 @@ mod spl_name_service;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_CREATE_OPERATION;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_UPDATE_OPERATION;
pub use self::metaplex_token_metadata::EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION;
pub use self::metaplex_token_metadata::ExMetadataMetaplexTokenMetadataExecutor;
pub use self::metaplex_token_metadata::ExMetaplexTokenMetadataExecutionIntent;
pub use self::metaplex_token_metadata::ExMetaplexTokenMetadataOperation;

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/metadata/metaplex_token_metadata.rs
// version: 7
// version: 8
//! Metaplex Token Metadata typed execution surface.
@@ -15,12 +15,18 @@ pub use self::intent::EX_METAPLEX_TOKEN_METADATA_CREATE_OPERATION;
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES;
/// Stable deprecated operation code for PuffMetadata.
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION;
/// Stable deprecated operation code for SetCollectionSize.
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION;
/// Stable deprecated operation code for SetTokenStandard.
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION;
/// Current and deprecated operations implemented by this prerelease.
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES;
/// Stable operation code for the current Unverify wrapper.
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION;
/// Stable operation code for the current Update wrapper.
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_UPDATE_OPERATION;
/// Stable operation code for the current Verify wrapper.
pub use self::intent::EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION;
/// Exposes the complete Metaplex Token Metadata execution intent.
pub use self::intent::ExMetaplexTokenMetadataExecutionIntent;
/// Exposes the current and deprecated Metaplex Token Metadata operation intent.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/metadata/metaplex_token_metadata/builder.rs
// version: 4
// version: 5
//! Official Metaplex builders and conservative plan validation.
@@ -106,6 +106,51 @@ pub(crate) fn executor_metaplex_token_metadata_build_prepared_plan(
mint,
edition,
} => build_set_token_standard(metadata, update_authority, mint, edition.as_ref()),
crate::ExMetaplexTokenMetadataOperation::Verify {
authority,
delegate_record,
metadata,
collection_mint,
collection_metadata,
collection_master_edition,
verification_args,
} => build_verify(
authority,
delegate_record.as_ref(),
metadata,
collection_mint.as_ref(),
collection_metadata.as_ref(),
collection_master_edition.as_ref(),
verification_args,
),
crate::ExMetaplexTokenMetadataOperation::Unverify {
authority,
delegate_record,
metadata,
collection_mint,
collection_metadata,
verification_args,
} => build_unverify(
authority,
delegate_record.as_ref(),
metadata,
collection_mint.as_ref(),
collection_metadata.as_ref(),
verification_args,
),
crate::ExMetaplexTokenMetadataOperation::SetCollectionSize {
collection_metadata,
collection_authority,
collection_mint,
collection_authority_record,
size,
} => build_set_collection_size(
collection_metadata,
collection_authority,
collection_mint,
collection_authority_record.as_ref(),
*size,
),
};
let instruction = match instruction_result {
std::result::Result::Ok(value) => value,
@@ -152,7 +197,7 @@ fn validate_intent(intent: &crate::ExMetaplexTokenMetadataExecutionIntent) -> kb
if !intent.policy.dry_run {
return std::result::Result::Err(kb_core::Error::new(
"execution_metaplex_dry_run_required",
"Metaplex Token Metadata pre.003 intents are simulation-only",
"Metaplex Token Metadata pre.004 intents are simulation-only",
));
}
match intent.policy.cost_limit.max_fee_lamports {
@@ -391,6 +436,223 @@ fn build_set_token_standard(
return std::result::Result::Ok(convert_official_instruction!(official));
}
#[allow(clippy::too_many_arguments)]
fn build_verify(
authority: &crate::MdPubkey,
delegate_record: std::option::Option<&crate::MdPubkey>,
metadata: &crate::MdPubkey,
collection_mint: std::option::Option<&crate::MdPubkey>,
collection_metadata: std::option::Option<&crate::MdPubkey>,
collection_master_edition: std::option::Option<&crate::MdPubkey>,
verification_args: &mpl_token_metadata::types::VerificationArgs,
) -> kb_core::Result<solana_instruction::Instruction> {
if matches!(verification_args, mpl_token_metadata::types::VerificationArgs::CollectionV1)
&& (collection_mint.is_none()
|| collection_metadata.is_none()
|| collection_master_edition.is_none())
{
return std::result::Result::Err(kb_core::Error::new(
"execution_metaplex_collection_accounts_incomplete",
"collection verification requires mint, metadata and master edition accounts",
));
}
if matches!(verification_args, mpl_token_metadata::types::VerificationArgs::CreatorV1)
&& (collection_mint.is_some()
|| collection_metadata.is_some()
|| collection_master_edition.is_some())
{
return std::result::Result::Err(kb_core::Error::new(
"execution_metaplex_creator_accounts_unexpected",
"creator verification must not provide collection accounts",
));
}
let parsed_collection_mint = match parse_optional_pubkey(collection_mint, "collection_mint") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let parsed_collection_metadata =
match parse_optional_pubkey(collection_metadata, "collection_metadata") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let parsed_collection_master_edition =
match parse_optional_pubkey(collection_master_edition, "collection_master_edition") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
if let (
std::option::Option::Some(mint),
std::option::Option::Some(metadata),
std::option::Option::Some(edition),
) = (
parsed_collection_mint.as_ref(),
parsed_collection_metadata.as_ref(),
parsed_collection_master_edition.as_ref(),
) {
if let std::result::Result::Err(error) = validate_metadata_pda(metadata, mint) {
return std::result::Result::Err(error);
}
if let std::result::Result::Err(error) = validate_edition_pda(edition, mint) {
return std::result::Result::Err(error);
}
}
let official = mpl_token_metadata::instructions::Verify {
authority: parse_official_pubkey!(&authority.0, "authority"),
delegate_record: match delegate_record {
std::option::Option::Some(value) => {
std::option::Option::Some(parse_official_pubkey!(&value.0, "delegate_record"))
},
std::option::Option::None => std::option::Option::None,
},
metadata: parse_official_pubkey!(&metadata.0, "metadata"),
collection_mint: match parsed_collection_mint.as_ref() {
std::option::Option::Some(value) => std::option::Option::Some(parse_official_pubkey!(
&value.to_string(),
"collection_mint"
)),
std::option::Option::None => std::option::Option::None,
},
collection_metadata: match parsed_collection_metadata.as_ref() {
std::option::Option::Some(value) => std::option::Option::Some(parse_official_pubkey!(
&value.to_string(),
"collection_metadata"
)),
std::option::Option::None => std::option::Option::None,
},
collection_master_edition: match parsed_collection_master_edition.as_ref() {
std::option::Option::Some(value) => std::option::Option::Some(parse_official_pubkey!(
&value.to_string(),
"collection_master_edition"
)),
std::option::Option::None => std::option::Option::None,
},
system_program: parse_official_pubkey!(kb_program_ids::SYSTEM_PROGRAM_ID, "system_program"),
sysvar_instructions: parse_official_pubkey!(
kb_program_ids::SYSVAR_INSTRUCTIONS_PROGRAM_ID,
"sysvar_instructions"
),
}
.instruction(mpl_token_metadata::instructions::VerifyInstructionArgs {
verification_args: verification_args.clone(),
});
return std::result::Result::Ok(convert_official_instruction!(official));
}
#[allow(clippy::too_many_arguments)]
fn build_unverify(
authority: &crate::MdPubkey,
delegate_record: std::option::Option<&crate::MdPubkey>,
metadata: &crate::MdPubkey,
collection_mint: std::option::Option<&crate::MdPubkey>,
collection_metadata: std::option::Option<&crate::MdPubkey>,
verification_args: &mpl_token_metadata::types::VerificationArgs,
) -> kb_core::Result<solana_instruction::Instruction> {
if matches!(verification_args, mpl_token_metadata::types::VerificationArgs::CollectionV1)
&& (collection_mint.is_none() || collection_metadata.is_none())
{
return std::result::Result::Err(kb_core::Error::new(
"execution_metaplex_collection_accounts_incomplete",
"collection unverification requires mint and metadata accounts",
));
}
if matches!(verification_args, mpl_token_metadata::types::VerificationArgs::CreatorV1)
&& (collection_mint.is_some() || collection_metadata.is_some())
{
return std::result::Result::Err(kb_core::Error::new(
"execution_metaplex_creator_accounts_unexpected",
"creator unverification must not provide collection accounts",
));
}
let parsed_collection_mint = match parse_optional_pubkey(collection_mint, "collection_mint") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let parsed_collection_metadata =
match parse_optional_pubkey(collection_metadata, "collection_metadata") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
if let (std::option::Option::Some(mint), std::option::Option::Some(metadata)) =
(parsed_collection_mint.as_ref(), parsed_collection_metadata.as_ref())
{
if let std::result::Result::Err(error) = validate_metadata_pda(metadata, mint) {
return std::result::Result::Err(error);
}
}
let official = mpl_token_metadata::instructions::Unverify {
authority: parse_official_pubkey!(&authority.0, "authority"),
delegate_record: match delegate_record {
std::option::Option::Some(value) => {
std::option::Option::Some(parse_official_pubkey!(&value.0, "delegate_record"))
},
std::option::Option::None => std::option::Option::None,
},
metadata: parse_official_pubkey!(&metadata.0, "metadata"),
collection_mint: match parsed_collection_mint.as_ref() {
std::option::Option::Some(value) => std::option::Option::Some(parse_official_pubkey!(
&value.to_string(),
"collection_mint"
)),
std::option::Option::None => std::option::Option::None,
},
collection_metadata: match parsed_collection_metadata.as_ref() {
std::option::Option::Some(value) => std::option::Option::Some(parse_official_pubkey!(
&value.to_string(),
"collection_metadata"
)),
std::option::Option::None => std::option::Option::None,
},
system_program: parse_official_pubkey!(kb_program_ids::SYSTEM_PROGRAM_ID, "system_program"),
sysvar_instructions: parse_official_pubkey!(
kb_program_ids::SYSVAR_INSTRUCTIONS_PROGRAM_ID,
"sysvar_instructions"
),
}
.instruction(mpl_token_metadata::instructions::UnverifyInstructionArgs {
verification_args: verification_args.clone(),
});
return std::result::Result::Ok(convert_official_instruction!(official));
}
fn build_set_collection_size(
collection_metadata: &crate::MdPubkey,
collection_authority: &crate::MdPubkey,
collection_mint: &crate::MdPubkey,
collection_authority_record: std::option::Option<&crate::MdPubkey>,
size: u64,
) -> kb_core::Result<solana_instruction::Instruction> {
let mint = match parse_pubkey(collection_mint, "collection_mint") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let metadata = match parse_pubkey(collection_metadata, "collection_metadata") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
if let std::result::Result::Err(error) = validate_metadata_pda(&metadata, &mint) {
return std::result::Result::Err(error);
}
let official = mpl_token_metadata::instructions::SetCollectionSize {
collection_metadata: parse_official_pubkey!(&metadata.to_string(), "collection_metadata"),
collection_authority: parse_official_pubkey!(
&collection_authority.0,
"collection_authority"
),
collection_mint: parse_official_pubkey!(&mint.to_string(), "collection_mint"),
collection_authority_record: match collection_authority_record {
std::option::Option::Some(value) => std::option::Option::Some(parse_official_pubkey!(
&value.0,
"collection_authority_record"
)),
std::option::Option::None => std::option::Option::None,
},
}
.instruction(mpl_token_metadata::instructions::SetCollectionSizeInstructionArgs {
set_collection_size_args: mpl_token_metadata::types::SetCollectionSizeArgs { size },
});
return std::result::Result::Ok(convert_official_instruction!(official));
}
fn validate_metadata_pda(
metadata: &solana_pubkey::Pubkey,
mint: &solana_pubkey::Pubkey,
@@ -527,6 +789,7 @@ fn required_signers(
#[cfg(test)]
mod tests {
#[allow(deprecated)]
fn approved_puff_intent() -> crate::ExMetaplexTokenMetadataExecutionIntent {
let fee_payer = crate::MdPubkey("11111111111111111111111111111111".to_string());
let mut policy = crate::ExApiExecutionPolicy::default();
@@ -634,4 +897,59 @@ mod tests {
assert_eq!(plan.required_signers[0].pubkey, intent.fee_payer);
assert_eq!(plan.required_signers[0].role, "fee_payer");
}
#[test]
fn creator_verify_and_unverify_build_current_wrappers() {
let fee_payer = crate::MdPubkey("11111111111111111111111111111111".to_string());
let authority = crate::MdPubkey("SysvarRent111111111111111111111111111111111".to_string());
let metadata = crate::MdPubkey("SysvarC1ock11111111111111111111111111111111".to_string());
let mut policy = crate::ExApiExecutionPolicy::default();
policy.cost_limit.max_fee_lamports = std::option::Option::Some(5_000);
policy.cost_limit.max_spend_lamports = std::option::Option::Some(10_000);
policy.authorized_signers = vec![fee_payer.clone(), authority.clone()];
for operation in [
crate::ExMetaplexTokenMetadataOperation::Verify {
authority: authority.clone(),
delegate_record: std::option::Option::None,
metadata: metadata.clone(),
collection_mint: std::option::Option::None,
collection_metadata: std::option::Option::None,
collection_master_edition: std::option::Option::None,
verification_args: mpl_token_metadata::types::VerificationArgs::CreatorV1,
},
crate::ExMetaplexTokenMetadataOperation::Unverify {
authority: authority.clone(),
delegate_record: std::option::Option::None,
metadata: metadata.clone(),
collection_mint: std::option::Option::None,
collection_metadata: std::option::Option::None,
verification_args: mpl_token_metadata::types::VerificationArgs::CreatorV1,
},
] {
let intent = crate::ExMetaplexTokenMetadataExecutionIntent {
intent_id: "metaplex-verification-test".to_string(),
fee_payer: fee_payer.clone(),
max_rent_lamports: 10_000,
policy: policy.clone(),
allow_deprecated_operation: false,
operation,
};
let result = super::executor_metaplex_token_metadata_build_prepared_plan(&intent);
assert!(result.is_ok());
let plan = match result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
assert_eq!(plan.instructions.len(), 1);
assert_eq!(
plan.instructions[0].data.first().copied(),
match intent.operation {
crate::ExMetaplexTokenMetadataOperation::Verify { .. } =>
std::option::Option::Some(52),
crate::ExMetaplexTokenMetadataOperation::Unverify { .. } =>
std::option::Option::Some(53),
_ => std::option::Option::None,
}
);
}
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/metadata/metaplex_token_metadata/executor.rs
// version: 3
// version: 4
//! Exact Metaplex Token Metadata capability dispatch.
@@ -129,6 +129,7 @@ impl crate::ExApiInstructionExecutor for crate::ExMetadataMetaplexTokenMetadataE
#[cfg(test)]
mod tests {
#[allow(deprecated)]
fn approved_puff_intent() -> crate::ExMetaplexTokenMetadataExecutionIntent {
let fee_payer = crate::MdPubkey("11111111111111111111111111111111".to_string());
let mut policy = crate::ExApiExecutionPolicy::default();
@@ -158,7 +159,7 @@ mod tests {
let supported = <crate::ExMetadataMetaplexTokenMetadataExecutor as crate::ExApiTypedInstructionExecutor>::capability(
&executor,
&program_id,
crate::EX_METAPLEX_TOKEN_METADATA_CREATE_OPERATION,
crate::EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION,
);
assert!(matches!(supported, crate::ExApiExecutionCapability::Supported { .. }));
let unknown = <crate::ExMetadataMetaplexTokenMetadataExecutor as crate::ExApiTypedInstructionExecutor>::capability(

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/metadata/metaplex_token_metadata/intent.rs
// version: 3
// version: 4
//! Typed current and deprecated Metaplex Token Metadata execution intents.
@@ -17,17 +17,30 @@ pub const EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION: &str =
/// Stable deprecated operation code for SetTokenStandard, discriminator 35.
pub const EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION: &str =
"metadata.metaplex_token_metadata.set_token_standard";
/// Stable operation code for the current Verify wrapper, discriminator 52.
pub const EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION: &str =
"metadata.metaplex_token_metadata.verify";
/// Stable operation code for the current Unverify wrapper, discriminator 53.
pub const EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION: &str =
"metadata.metaplex_token_metadata.unverify";
/// Stable deprecated operation code for SetCollectionSize, discriminator 34.
pub const EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION: &str =
"metadata.metaplex_token_metadata.set_collection_size";
/// Deprecated operations that require explicit operator approval at runtime.
pub const EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES: &[&str] = &[
EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION,
EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION,
EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION,
];
/// Current and deprecated operations implemented by `0.4.7-pre.003`.
/// Current and deprecated operations implemented through `0.4.7-pre.004`.
pub const EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES: &[&str] = &[
EX_METAPLEX_TOKEN_METADATA_CREATE_OPERATION,
EX_METAPLEX_TOKEN_METADATA_UPDATE_OPERATION,
EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION,
EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION,
EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION,
EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION,
EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION,
];
/// One current or explicitly deprecated Metaplex Token Metadata operation.
@@ -104,6 +117,57 @@ pub enum ExMetaplexTokenMetadataOperation {
/// Optional canonical edition PDA.
edition: std::option::Option<crate::MdPubkey>,
},
/// Build the current unified Verify wrapper for a creator or collection.
Verify {
/// Creator, collection update authority or delegated authority signer.
authority: crate::MdPubkey,
/// Optional delegate record PDA.
delegate_record: std::option::Option<crate::MdPubkey>,
/// Metadata account whose creator or collection relation is verified.
metadata: crate::MdPubkey,
/// Optional collection mint; required for collection verification.
collection_mint: std::option::Option<crate::MdPubkey>,
/// Optional canonical collection metadata PDA.
collection_metadata: std::option::Option<crate::MdPubkey>,
/// Optional canonical collection master edition PDA.
collection_master_edition: std::option::Option<crate::MdPubkey>,
/// Official unified verification variant.
#[ts(type = "unknown")]
verification_args: mpl_token_metadata::types::VerificationArgs,
},
/// Build the current unified Unverify wrapper for a creator or collection.
Unverify {
/// Creator, collection update authority or delegated authority signer.
authority: crate::MdPubkey,
/// Optional delegate record PDA.
delegate_record: std::option::Option<crate::MdPubkey>,
/// Metadata account whose creator or collection relation is unverified.
metadata: crate::MdPubkey,
/// Optional collection mint; required for collection unverification.
collection_mint: std::option::Option<crate::MdPubkey>,
/// Optional canonical collection metadata PDA.
collection_metadata: std::option::Option<crate::MdPubkey>,
/// Official unified verification variant.
#[ts(type = "unknown")]
verification_args: mpl_token_metadata::types::VerificationArgs,
},
/// Build obsolete SetCollectionSize retained for compatibility workflows.
#[deprecated(
since = "0.4.7",
note = "SetCollectionSize is obsolete; prefer canonical collection creation and update flows"
)]
SetCollectionSize {
/// Canonical collection metadata PDA.
collection_metadata: crate::MdPubkey,
/// Collection authority signer.
collection_authority: crate::MdPubkey,
/// Collection mint.
collection_mint: crate::MdPubkey,
/// Optional collection authority record PDA.
collection_authority_record: std::option::Option<crate::MdPubkey>,
/// New collection size.
size: u64,
},
}
#[allow(deprecated)]
@@ -119,12 +183,22 @@ impl crate::ExMetaplexTokenMetadataOperation {
Self::SetTokenStandard { .. } => {
crate::EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION
},
Self::Verify { .. } => crate::EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION,
Self::Unverify { .. } => crate::EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION,
Self::SetCollectionSize { .. } => {
crate::EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION
},
};
}
/// Returns whether the operation is obsolete and requires explicit operator approval.
pub fn is_deprecated(&self) -> bool {
return matches!(self, Self::PuffMetadata { .. } | Self::SetTokenStandard { .. });
return matches!(
self,
Self::PuffMetadata { .. }
| Self::SetTokenStandard { .. }
| Self::SetCollectionSize { .. }
);
}
}
@@ -154,12 +228,12 @@ mod tests {
#[test]
#[allow(deprecated)]
fn operation_codes_are_exact_unique_and_partition_deprecated_operations() {
assert_eq!(crate::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES.len(), 4);
assert_eq!(crate::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES.len(), 7);
let mut unique = std::collections::BTreeSet::new();
for operation_code in crate::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES {
assert!(unique.insert(*operation_code));
}
assert_eq!(crate::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES.len(), 2);
assert_eq!(crate::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES.len(), 3);
assert!(
crate::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES
.contains(&crate::EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION,)
@@ -176,6 +250,14 @@ mod tests {
!crate::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES
.contains(&crate::EX_METAPLEX_TOKEN_METADATA_UPDATE_OPERATION,)
);
assert!(
!crate::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES
.contains(&crate::EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION,)
);
assert!(
!crate::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES
.contains(&crate::EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION,)
);
}
#[test]

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/lib.rs
// version: 28
// version: 29
//! Consolidated decoder, executor, materializer and shared model library.
#![warn(missing_docs)]
@@ -364,12 +364,18 @@ pub use self::executor::EX_METAPLEX_TOKEN_METADATA_CREATE_OPERATION;
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES;
/// Stable deprecated Metaplex PuffMetadata operation code.
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_PUFF_METADATA_OPERATION;
/// Stable deprecated Metaplex SetCollectionSize operation code.
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_SET_COLLECTION_SIZE_OPERATION;
/// Stable deprecated Metaplex SetTokenStandard operation code.
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_SET_TOKEN_STANDARD_OPERATION;
/// Current and deprecated Metaplex Token Metadata operations.
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES;
/// Stable operation code for the current Metaplex Unverify wrapper.
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_UNVERIFY_OPERATION;
/// Stable operation code for the current Metaplex Update wrapper.
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_UPDATE_OPERATION;
/// Stable operation code for the current Metaplex Verify wrapper.
pub use self::executor::EX_METAPLEX_TOKEN_METADATA_VERIFY_OPERATION;
/// Exposes the Address Lookup Table close operation code.
pub use self::executor::EX_SOLANA_CORE_ADDRESS_LOOKUP_TABLE_CLOSE_OPERATION;
/// Exposes the Address Lookup Table create operation code.