v0.4.8-pre.011

This commit is contained in:
2026-08-07 07:14:49 +02:00
parent 3167297283
commit dcc1d382d9
38 changed files with 1358 additions and 129 deletions

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder.rs
// version: 16
// version: 17
//! Consolidated decoder modules.
@@ -745,6 +745,8 @@ pub(crate) use self::spl::decoder_spl_token_2022_decode;
pub(crate) use self::spl::decoder_spl_token_2022_entry_for_tag;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use self::spl::decoder_spl_token_2022_parse_token_2022_state;
/// Parses one exact Token Metadata interface value.
pub use self::spl::decoder_spl_token_2022_parse_token_metadata_value;
/// Returns the first byte of one retained Token-2022 payload.
pub(crate) use self::spl::decoder_spl_token_2022_payload_tag;
/// Decodes one bounded classic SPL Token instruction.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/spl.rs
// version: 10
// version: 11
//! `spl` decoder family.
@@ -147,5 +147,7 @@ pub(crate) use self::token_2022::decoder_spl_token_2022_decode;
pub(crate) use self::token_2022::decoder_spl_token_2022_entry_for_tag;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use self::token_2022::decoder_spl_token_2022_parse_token_2022_state;
/// Parses one exact Token Metadata interface value.
pub use self::token_2022::decoder_spl_token_2022_parse_token_metadata_value;
/// Returns the first byte of one retained Token-2022 payload.
pub(crate) use self::token_2022::decoder_spl_token_2022_payload_tag;

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/spl/token_2022.rs
// version: 4
// version: 5
//! Exact Token-2022 instruction and state decoder component.
@@ -18,6 +18,8 @@ pub use self::state::DcToken2022StateKind;
pub use self::state::DcToken2022TlvEntry;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use self::state::decoder_spl_token_2022_parse_token_2022_state;
/// Parses one exact Token Metadata interface value.
pub use self::state::decoder_spl_token_2022_parse_token_metadata_value;
/// Maximum prefix retained in bounded Token-2022 diagnostics.
pub(crate) use self::constants::DC_SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/spl/token_2022/state.rs
// version: 3
// version: 4
//! Strict Token-2022 base-state and TLV parsing.
@@ -429,6 +429,13 @@ fn decode_token_group_member(value: &[u8]) -> Result<serde_json::Value, String>
}));
}
/// Parses one exact Token Metadata interface value with full-consumption checks.
pub fn decoder_spl_token_2022_parse_token_metadata_value(
value: &[u8],
) -> std::result::Result<serde_json::Value, std::string::String> {
return decode_token_metadata(value);
}
fn decode_token_metadata(value: &[u8]) -> Result<serde_json::Value, String> {
if value.len() < 76 {
return Err(format!(

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor.rs
// version: 16
// version: 17
//! Consolidated executor modules.
@@ -714,6 +714,8 @@ pub use self::spl::EX_SPL_TOKEN_2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION;
pub use self::spl::EX_SPL_TOKEN_2022_ELGAMAL_CIPHERTEXT_BYTES;
/// Exposes `EX_SPL_TOKEN_2022_ELGAMAL_PUBKEY_BYTES`.
pub use self::spl::EX_SPL_TOKEN_2022_ELGAMAL_PUBKEY_BYTES;
/// Exposes `EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`.
@@ -844,6 +846,8 @@ pub use self::spl::EX_SPL_TOKEN_2022_UPDATE_METADATA_POINTER_OPERATION;
pub use self::spl::EX_SPL_TOKEN_2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`.
pub use self::spl::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TRANSFER_HOOK_OPERATION`.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/api/execution.rs
// version: 8
// version: 9
//! Typed execution plans, policies and result contracts.
@@ -378,6 +378,9 @@ pub struct ExApiExecutionSimulationResult {
pub estimated_fee_lamports: std::option::Option<u64>,
/// Simulation logs in runtime order.
pub logs: std::vec::Vec<std::string::String>,
/// Program return data retained as provider-neutral JSON when reported.
#[serde(default)]
pub return_data: std::option::Option<serde_json::Value>,
/// Stable or provider error text when simulation failed.
pub error: std::option::Option<std::string::String>,
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/safety/evaluation.rs
// version: 2
// version: 3
//! Safety checks applied before simulation, signing or sending.
@@ -516,6 +516,7 @@ mod tests {
units_consumed: std::option::Option::Some(500),
estimated_fee_lamports: std::option::Option::Some(5_000),
logs: std::vec::Vec::new(),
return_data: std::option::Option::None,
error: std::option::Option::None,
};
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/solana/transaction/core.rs
// version: 9
// version: 10
//! Legacy and durable nonce Solana transaction assembly, simulation binding and signing.
@@ -750,6 +750,7 @@ mod tests {
units_consumed: std::option::Option::Some(500),
estimated_fee_lamports: std::option::Option::Some(5_000),
logs: std::vec::Vec::new(),
return_data: std::option::Option::None,
error: std::option::Option::None,
};
}
@@ -773,6 +774,7 @@ mod tests {
units_consumed: std::option::Option::Some(700),
estimated_fee_lamports: std::option::Option::Some(10_000),
logs: std::vec::Vec::new(),
return_data: std::option::Option::None,
error: std::option::Option::None,
};
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/spl.rs
// version: 7
// version: 8
//! `spl` executor family.
@@ -183,6 +183,8 @@ pub use self::token_2022::EX_SPL_TOKEN_2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPER
pub use self::token_2022::EX_SPL_TOKEN_2022_ELGAMAL_CIPHERTEXT_BYTES;
/// Exposes `EX_SPL_TOKEN_2022_ELGAMAL_PUBKEY_BYTES`.
pub use self::token_2022::EX_SPL_TOKEN_2022_ELGAMAL_PUBKEY_BYTES;
/// Exposes `EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION`.
pub use self::token_2022::EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`.
pub use self::token_2022::EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`.
@@ -313,6 +315,8 @@ pub use self::token_2022::EX_SPL_TOKEN_2022_UPDATE_METADATA_POINTER_OPERATION;
pub use self::token_2022::EX_SPL_TOKEN_2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`.
pub use self::token_2022::EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION`.
pub use self::token_2022::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`.
pub use self::token_2022::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TRANSFER_HOOK_OPERATION`.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/spl/token_2022.rs
// version: 5
// version: 6
//! SPL Token-2022 executor.
@@ -86,6 +86,8 @@ pub use self::intent::EX_SPL_TOKEN_2022_DISABLE_CPI_GUARD_OPERATION;
pub use self::intent::EX_SPL_TOKEN_2022_DISABLE_NON_CONFIDENTIAL_CREDITS_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`.
@@ -214,6 +216,8 @@ pub use self::intent::EX_SPL_TOKEN_2022_UPDATE_METADATA_POINTER_OPERATION;
pub use self::intent::EX_SPL_TOKEN_2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`.
pub use self::intent::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TRANSFER_HOOK_OPERATION`.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/spl/token_2022/builder.rs
// version: 30
// version: 34
//! Official Token-2022 builders and conservative plan validation.
@@ -172,6 +172,41 @@ fn validate_metadata_string(value: &str, field: &str) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_token_metadata_emit_range(
start: std::option::Option<u64>,
end: std::option::Option<u64>,
) -> kb_core::Result<()> {
if let (std::option::Option::Some(start), std::option::Option::Some(end)) = (start, end) {
if start > end {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token_2022_metadata_emit_range_invalid",
format!("Token metadata Emit start {start} exceeds end {end}"),
));
}
if end - start > 1_024 {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token_2022_metadata_emit_range_too_large",
"Token metadata Emit range exceeds the 1024-byte Solana return-data bound",
));
}
}
if let (std::option::Option::None, std::option::Option::Some(end)) = (start, end) {
if end > 1_024 {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token_2022_metadata_emit_range_too_large",
"Token metadata Emit range from zero exceeds the 1024-byte Solana return-data bound",
));
}
}
if let (std::option::Option::Some(_), std::option::Option::None) = (start, end) {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token_2022_metadata_emit_range_end_required",
"Token metadata Emit with a start offset requires an explicit end to remain bounded",
));
}
return std::result::Result::Ok(());
}
fn default_account_state(
state: crate::ExSplTokenDefaultAccountState,
) -> spl_token_2022_interface::state::AccountState {
@@ -1162,6 +1197,40 @@ fn build_single(
*idempotent,
))
},
crate::ExSplTokenSingleOperation::UpdateTokenMetadataAuthority {
metadata,
current_authority,
new_authority,
} => {
let metadata = parse_key!(metadata, "metadata");
let current_authority = parse_key!(current_authority, "current_authority");
let new_authority = parse_optional_key!(new_authority, "new_authority");
let nullable_authority = match new_authority.try_into() {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => {
return std::result::Result::Err(kb_core::Error::new(
"execution_spl_token_2022_metadata_authority_invalid",
"Token metadata authority cannot be encoded as a nullable address",
));
},
};
std::result::Result::Ok(spl_token_metadata_interface::instruction::update_authority(
program_id,
&metadata,
&current_authority,
nullable_authority,
))
},
crate::ExSplTokenSingleOperation::EmitTokenMetadata { metadata, start, end } => {
match validate_token_metadata_emit_range(*start, *end) {
std::result::Result::Ok(()) => {},
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
let metadata = parse_key!(metadata, "metadata");
std::result::Result::Ok(spl_token_metadata_interface::instruction::emit(
program_id, &metadata, *start, *end,
))
},
crate::ExSplTokenSingleOperation::InitializeTokenGroup {
group,
mint,
@@ -3566,6 +3635,22 @@ pub(crate) mod tests {
idempotent: true,
},
),
(
255,
crate::ExSplTokenSingleOperation::UpdateTokenMetadataAuthority {
metadata: first.clone(),
current_authority: second.clone(),
new_authority: std::option::Option::Some(third.clone()),
},
),
(
255,
crate::ExSplTokenSingleOperation::EmitTokenMetadata {
metadata: first.clone(),
start: std::option::Option::Some(0),
end: std::option::Option::Some(64),
},
),
(
255,
crate::ExSplTokenSingleOperation::InitializeTokenGroup {
@@ -4706,6 +4791,7 @@ pub(crate) mod tests {
uri: std::string::String::from("https://example.invalid/token.json"),
},
4_usize,
true,
),
(
crate::ExSplTokenSingleOperation::UpdateTokenMetadataField {
@@ -4717,6 +4803,7 @@ pub(crate) mod tests {
value: std::string::String::from("https://example.invalid"),
},
2_usize,
true,
),
(
crate::ExSplTokenSingleOperation::RemoveTokenMetadataKey {
@@ -4726,6 +4813,25 @@ pub(crate) mod tests {
idempotent: true,
},
2_usize,
true,
),
(
crate::ExSplTokenSingleOperation::UpdateTokenMetadataAuthority {
metadata: first.clone(),
current_authority: second.clone(),
new_authority: std::option::Option::Some(third.clone()),
},
2_usize,
true,
),
(
crate::ExSplTokenSingleOperation::EmitTokenMetadata {
metadata: first.clone(),
start: std::option::Option::Some(8),
end: std::option::Option::Some(72),
},
1_usize,
false,
),
(
crate::ExSplTokenSingleOperation::InitializeTokenGroup {
@@ -4736,6 +4842,7 @@ pub(crate) mod tests {
max_size: 42,
},
3_usize,
true,
),
(
crate::ExSplTokenSingleOperation::UpdateTokenGroupMaxSize {
@@ -4744,6 +4851,7 @@ pub(crate) mod tests {
max_size: 84,
},
2_usize,
true,
),
(
crate::ExSplTokenSingleOperation::InitializeTokenGroupMember {
@@ -4754,9 +4862,10 @@ pub(crate) mod tests {
group_update_authority: second,
},
5_usize,
true,
),
];
for (operation, account_count) in cases {
for (operation, account_count, first_writable) in cases {
let intent = intent(crate::ExSplToken2022Operation::Instruction {
value: std::boxed::Box::new(operation),
});
@@ -4767,7 +4876,63 @@ pub(crate) mod tests {
.unwrap_or_else(|error| panic!("metadata or group plan failed: {error}"));
assert!(plan.instructions[0].data.len() >= 8);
assert_eq!(plan.instructions[0].accounts.len(), account_count);
assert!(plan.instructions[0].accounts[0].is_writable);
assert_eq!(plan.instructions[0].accounts[0].is_writable, first_writable);
}
}
#[test]
fn metadata_update_authority_accepts_nullable_none() {
let planned = planned_single_instruction(
crate::ExSplTokenSingleOperation::UpdateTokenMetadataAuthority {
metadata: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID),
current_authority: pubkey(kb_program_ids::CONFIG_PROGRAM_ID),
new_authority: std::option::Option::None,
},
);
assert_eq!(planned.operation_code, "spl.token_2022.update_token_metadata_authority");
assert_eq!(planned.accounts.len(), 2);
assert!(planned.accounts[0].is_writable);
assert!(planned.accounts[1].is_signer);
}
#[test]
fn metadata_emit_accepts_complete_and_maximum_bounded_ranges() {
for (start, end) in [
(std::option::Option::None, std::option::Option::None),
(std::option::Option::Some(0), std::option::Option::Some(1_024)),
] {
let planned =
planned_single_instruction(crate::ExSplTokenSingleOperation::EmitTokenMetadata {
metadata: pubkey(kb_program_ids::SYSTEM_PROGRAM_ID),
start,
end,
});
assert_eq!(planned.operation_code, "spl.token_2022.emit_token_metadata");
assert_eq!(planned.accounts.len(), 1);
assert!(!planned.accounts[0].is_writable);
}
}
#[test]
fn metadata_emit_rejects_reversed_oversized_and_open_ended_ranges() {
let metadata = pubkey(kb_program_ids::SYSTEM_PROGRAM_ID);
for (start, end) in [
(std::option::Option::Some(9), std::option::Option::Some(8)),
(std::option::Option::Some(0), std::option::Option::Some(1_025)),
(std::option::Option::Some(1), std::option::Option::None),
] {
let value = crate::ExSplTokenSingleOperation::EmitTokenMetadata {
metadata: metadata.clone(),
start,
end,
};
let result = crate::ExApiTypedInstructionExecutor::build_prepared_plan(
&crate::ExSplToken2022Executor,
&intent(crate::ExSplToken2022Operation::Instruction {
value: std::boxed::Box::new(value),
}),
);
assert!(result.is_err());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/spl/token_2022/executor.rs
// version: 23
// version: 25
//! Exact Token-2022 capability dispatch and typed plan construction.
@@ -220,6 +220,86 @@ mod tests {
);
}
fn matrix_operation_name(name: &str) -> &str {
return match name {
"initialize_interest_bearing_mint" | "update_interest_bearing_rate" => {
"interest_bearing_mint_extension"
},
"initialize_transfer_fee_config"
| "set_transfer_fee"
| "transfer_checked_with_fee"
| "withdraw_withheld_tokens_from_mint"
| "withdraw_withheld_tokens_from_accounts"
| "harvest_withheld_tokens_to_mint" => "transfer_fee_extension",
"initialize_default_account_state" | "update_default_account_state" => {
"default_account_state_extension"
},
"enable_required_transfer_memos" | "disable_required_transfer_memos" => {
"memo_transfer_extension"
},
"enable_cpi_guard" | "disable_cpi_guard" => "cpi_guard_extension",
"initialize_transfer_hook" | "update_transfer_hook" => "transfer_hook_extension",
"initialize_metadata_pointer" | "update_metadata_pointer" => {
"metadata_pointer_extension"
},
"initialize_group_pointer" | "update_group_pointer" => "group_pointer_extension",
"initialize_group_member_pointer" | "update_group_member_pointer" => {
"group_member_pointer_extension"
},
"initialize_token_metadata"
| "update_token_metadata_field"
| "remove_token_metadata_key"
| "update_token_metadata_authority"
| "emit_token_metadata" => "token_metadata",
"initialize_token_group" | "update_token_group_max_size" => "token_group",
"initialize_token_group_member" => "token_group_member",
"initialize_scaled_ui_amount" | "update_scaled_ui_amount_multiplier" => {
"scaled_ui_amount_extension"
},
"initialize_pausable_config" | "pause" | "resume" => "pausable_extension",
"initialize_permissioned_burn"
| "permissioned_burn"
| "permissioned_burn_checked"
| "permissioned_confidential_burn" => "permissioned_burn_extension",
"initialize_confidential_transfer_mint"
| "update_confidential_transfer_mint"
| "apply_pending_confidential_balance"
| "approve_confidential_transfer_account"
| "deposit_confidential_tokens"
| "enable_confidential_credits"
| "disable_confidential_credits"
| "enable_non_confidential_credits"
| "disable_non_confidential_credits"
| "configure_confidential_transfer_account"
| "configure_confidential_transfer_account_with_registry"
| "empty_confidential_transfer_account"
| "withdraw_confidential_tokens"
| "transfer_confidential_tokens"
| "transfer_confidential_tokens_with_fee" => "confidential_transfer_extension",
"initialize_confidential_transfer_fee_config"
| "enable_confidential_transfer_fee_harvest"
| "disable_confidential_transfer_fee_harvest"
| "harvest_confidential_withheld_tokens_to_mint"
| "withdraw_confidential_withheld_tokens_from_mint"
| "withdraw_confidential_withheld_tokens_from_accounts" => {
"confidential_transfer_fee_extension"
},
"initialize_confidential_mint_burn_mint"
| "rotate_confidential_supply_elgamal_pubkey"
| "update_confidential_decryptable_supply"
| "apply_pending_confidential_burn"
| "confidential_mint"
| "confidential_burn" => "confidential_mint_burn_extension",
_ => name,
};
}
#[test]
fn token_metadata_operations_share_matrix_family() {
assert_eq!(matrix_operation_name("update_token_metadata_authority"), "token_metadata");
assert_eq!(matrix_operation_name("emit_token_metadata"), "token_metadata");
}
#[test]
fn machine_readable_matrix_matches_executor_policy() {
let matrix = serde_json::from_str::<serde_json::Value>(include_str!(
@@ -242,75 +322,7 @@ mod tests {
let name = operation_code
.strip_prefix("spl.token_2022.")
.unwrap_or_else(|| panic!("invalid operation code {operation_code}"));
let matrix_name = match name {
"initialize_interest_bearing_mint" | "update_interest_bearing_rate" => {
"interest_bearing_mint_extension"
},
"initialize_transfer_fee_config"
| "set_transfer_fee"
| "transfer_checked_with_fee"
| "withdraw_withheld_tokens_from_mint"
| "withdraw_withheld_tokens_from_accounts"
| "harvest_withheld_tokens_to_mint" => "transfer_fee_extension",
"initialize_default_account_state" | "update_default_account_state" => {
"default_account_state_extension"
},
"enable_required_transfer_memos" | "disable_required_transfer_memos" => {
"memo_transfer_extension"
},
"enable_cpi_guard" | "disable_cpi_guard" => "cpi_guard_extension",
"initialize_transfer_hook" | "update_transfer_hook" => "transfer_hook_extension",
"initialize_metadata_pointer" | "update_metadata_pointer" => {
"metadata_pointer_extension"
},
"initialize_group_pointer" | "update_group_pointer" => "group_pointer_extension",
"initialize_group_member_pointer" | "update_group_member_pointer" => {
"group_member_pointer_extension"
},
"initialize_token_metadata"
| "update_token_metadata_field"
| "remove_token_metadata_key" => "token_metadata",
"initialize_token_group" | "update_token_group_max_size" => "token_group",
"initialize_token_group_member" => "token_group_member",
"initialize_scaled_ui_amount" | "update_scaled_ui_amount_multiplier" => {
"scaled_ui_amount_extension"
},
"initialize_pausable_config" | "pause" | "resume" => "pausable_extension",
"initialize_permissioned_burn"
| "permissioned_burn"
| "permissioned_burn_checked"
| "permissioned_confidential_burn" => "permissioned_burn_extension",
"initialize_confidential_transfer_mint"
| "update_confidential_transfer_mint"
| "apply_pending_confidential_balance"
| "approve_confidential_transfer_account"
| "deposit_confidential_tokens"
| "enable_confidential_credits"
| "disable_confidential_credits"
| "enable_non_confidential_credits"
| "disable_non_confidential_credits"
| "configure_confidential_transfer_account"
| "configure_confidential_transfer_account_with_registry"
| "empty_confidential_transfer_account"
| "withdraw_confidential_tokens"
| "transfer_confidential_tokens"
| "transfer_confidential_tokens_with_fee" => "confidential_transfer_extension",
"initialize_confidential_transfer_fee_config"
| "enable_confidential_transfer_fee_harvest"
| "disable_confidential_transfer_fee_harvest"
| "harvest_confidential_withheld_tokens_to_mint"
| "withdraw_confidential_withheld_tokens_from_mint"
| "withdraw_confidential_withheld_tokens_from_accounts" => {
"confidential_transfer_fee_extension"
},
"initialize_confidential_mint_burn_mint"
| "rotate_confidential_supply_elgamal_pubkey"
| "update_confidential_decryptable_supply"
| "apply_pending_confidential_burn"
| "confidential_mint"
| "confidential_burn" => "confidential_mint_burn_extension",
_ => name,
};
let matrix_name = matrix_operation_name(name);
assert!(
matrix_names.contains(matrix_name),
"matrix is missing supported operation {name}"

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/executor/spl/token_2022/intent.rs
// version: 26
// version: 27
//! Typed Token-2022 execution intents.
@@ -138,6 +138,12 @@ pub const EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION: &str =
/// Stable operation code for removing an embedded metadata key.
pub const EX_SPL_TOKEN_2022_REMOVE_TOKEN_METADATA_KEY_OPERATION: &str =
"spl.token_2022.remove_token_metadata_key";
/// Stable operation code for updating or clearing embedded metadata authority.
pub const EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION: &str =
"spl.token_2022.update_token_metadata_authority";
/// Stable operation code for emitting bounded embedded metadata return data.
pub const EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION: &str =
"spl.token_2022.emit_token_metadata";
/// Stable operation code for initializing an embedded token group.
pub const EX_SPL_TOKEN_2022_INITIALIZE_TOKEN_GROUP_OPERATION: &str =
"spl.token_2022.initialize_token_group";
@@ -307,6 +313,8 @@ pub const EX_SPL_TOKEN_2022_SUPPORTED_OPERATION_CODES: &[&str] = &[
EX_SPL_TOKEN_2022_INITIALIZE_TOKEN_METADATA_OPERATION,
EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION,
EX_SPL_TOKEN_2022_REMOVE_TOKEN_METADATA_KEY_OPERATION,
EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION,
EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION,
EX_SPL_TOKEN_2022_INITIALIZE_TOKEN_GROUP_OPERATION,
EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION,
EX_SPL_TOKEN_2022_INITIALIZE_TOKEN_GROUP_MEMBER_OPERATION,
@@ -919,6 +927,24 @@ pub enum ExSplTokenSingleOperation {
/// Whether a missing key is accepted.
idempotent: bool,
},
/// Update or permanently clear embedded metadata authority.
UpdateTokenMetadataAuthority {
/// Metadata account.
metadata: crate::MdPubkey,
/// Current update authority signer.
current_authority: crate::MdPubkey,
/// New authority, or `None` to make metadata immutable.
new_authority: std::option::Option<crate::MdPubkey>,
},
/// Emit all or one bounded range of embedded metadata through return data.
EmitTokenMetadata {
/// Metadata account.
metadata: crate::MdPubkey,
/// Optional inclusive byte-range start.
start: std::option::Option<u64>,
/// Optional exclusive byte-range end.
end: std::option::Option<u64>,
},
/// Initialize a Token Group entry.
InitializeTokenGroup {
/// Group state account, normally the group mint.
@@ -1454,6 +1480,10 @@ impl crate::ExSplTokenSingleOperation {
Self::InitializeTokenMetadata { .. } => crate::EX_SPL_TOKEN_2022_INITIALIZE_TOKEN_METADATA_OPERATION,
Self::UpdateTokenMetadataField { .. } => crate::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION,
Self::RemoveTokenMetadataKey { .. } => crate::EX_SPL_TOKEN_2022_REMOVE_TOKEN_METADATA_KEY_OPERATION,
Self::UpdateTokenMetadataAuthority { .. } => {
crate::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION
},
Self::EmitTokenMetadata { .. } => crate::EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION,
Self::InitializeTokenGroup { .. } => crate::EX_SPL_TOKEN_2022_INITIALIZE_TOKEN_GROUP_OPERATION,
Self::UpdateTokenGroupMaxSize { .. } => crate::EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION,
Self::InitializeTokenGroupMember { .. } => {
@@ -1566,6 +1596,7 @@ impl crate::ExSplTokenSingleOperation {
return !matches!(
self,
Self::GetAccountDataSize { .. }
| Self::EmitTokenMetadata { .. }
| Self::InitializeImmutableOwner { .. }
| Self::AmountToUiAmount { .. }
| Self::UiAmountToAmount { .. }

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/lib.rs
// version: 37
// version: 38
//! Consolidated decoder, executor, materializer and shared model library.
#![warn(missing_docs)]
@@ -401,6 +401,8 @@ pub use self::decoder::decoder_metadata_solana_program_metadata_decode_metadata_
pub use self::decoder::decoder_spl_elgamal_registry_parse_elgamal_registry_state;
/// Parses one Token-2022 Mint, Account, or Multisig state.
pub use self::decoder::decoder_spl_token_2022_parse_token_2022_state;
/// Parses one exact Token Metadata interface value.
pub use self::decoder::decoder_spl_token_2022_parse_token_metadata_value;
/// Stable Solana Program Metadata `Allocate` operation code.
pub use self::executor::EX_METADATA_SPM_ALLOCATE_OPERATION;
/// Stable Solana Program Metadata `Close` operation code.
@@ -791,6 +793,8 @@ pub use self::executor::EX_SPL_TOKEN_2022_DISABLE_REQUIRED_TRANSFER_MEMOS_OPERAT
pub use self::executor::EX_SPL_TOKEN_2022_ELGAMAL_CIPHERTEXT_BYTES;
/// Exposes `EX_SPL_TOKEN_2022_ELGAMAL_PUBKEY_BYTES`.
pub use self::executor::EX_SPL_TOKEN_2022_ELGAMAL_PUBKEY_BYTES;
/// Exposes `EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_2022_EMIT_TOKEN_METADATA_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_2022_EMPTY_CONFIDENTIAL_TRANSFER_ACCOUNT_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_ENABLE_CONFIDENTIAL_CREDITS_OPERATION`.
@@ -921,6 +925,8 @@ pub use self::executor::EX_SPL_TOKEN_2022_UPDATE_METADATA_POINTER_OPERATION;
pub use self::executor::EX_SPL_TOKEN_2022_UPDATE_SCALED_UI_AMOUNT_MULTIPLIER_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_2022_UPDATE_TOKEN_GROUP_MAX_SIZE_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_AUTHORITY_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION`.
pub use self::executor::EX_SPL_TOKEN_2022_UPDATE_TOKEN_METADATA_FIELD_OPERATION;
/// Exposes `EX_SPL_TOKEN_2022_UPDATE_TRANSFER_HOOK_OPERATION`.