This commit is contained in:
2026-07-23 16:37:12 +02:00
parent 99c345f2f2
commit 0da75c1311
2159 changed files with 230833 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
// file: kb_materializer_metadata/src/lib.rs
// version: 5
//! Materializer crate for `metadata`.
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
mod materializer;
/// Exposes the materializer type implemented by this crate.
pub use crate::materializer::MetadataMaterializer;
/// Materialize one canonical non-Metadata Metaplex account snapshot.
pub use crate::materializer::materialize_metaplex_account_snapshot;
/// Materialize one canonical Metaplex Metadata account snapshot without instruction-state duplication.
pub use crate::materializer::materialize_metaplex_metadata_snapshot;
/// Materialize Token-2022 embedded metadata and group state from one parsed mint snapshot.
pub use crate::materializer::materialize_token_2022_metadata_snapshot;

View File

@@ -0,0 +1,585 @@
// file: kb_materializer_metadata/src/materializer.rs
// version: 7
//! Materializer scaffold for the `kb_materializer_metadata` crate.
/// Initial materializer implementation placeholder.
#[derive(Clone, Debug, Default)]
pub struct MetadataMaterializer;
impl kb_materializer_api::Materializer for crate::MetadataMaterializer {
fn materializer_name(&self) -> &'static str {
return "kb_materializer_metadata";
}
fn materializer_version(&self) -> &'static str {
return env!("CARGO_PKG_VERSION");
}
fn accepts_event(&self, _event: &kb_model::DecodedProtocolEvent) -> bool {
return false;
}
fn materialize_event(
&self,
event: &kb_model::DecodedProtocolEvent,
) -> kb_core::Result<std::vec::Vec<kb_model::MaterializedEvent>> {
let materialized = kb_model::MaterializedEvent {
signature: event.signature.clone(),
slot: event.slot,
decoded_family: event.event_family,
materialized_family: kb_model::MaterializedEventFamily::Metadata,
};
return std::result::Result::Ok(std::vec![materialized]);
}
}
/// Materialize embedded Token-2022 metadata, group, and group-member extensions.
pub fn materialize_token_2022_metadata_snapshot(
account_key: &str,
slot: u64,
state: &kb_decoder_spl_token_2022::state::Token2022State,
) -> std::result::Result<std::vec::Vec<kb_materializer_api::MaterializedOutput>, String> {
if account_key.is_empty() {
return std::result::Result::Err(
"Token-2022 metadata snapshot requires a non-empty account key".to_string(),
);
}
if state.kind != kb_decoder_spl_token_2022::state::Token2022StateKind::Mint {
return std::result::Result::Err(
"Token-2022 metadata snapshot requires a parsed mint state".to_string(),
);
}
let mut outputs = std::vec::Vec::new();
for entry in &state.extensions {
let projection_kind = match entry.extension_name {
"token_metadata" => std::option::Option::Some("token_metadata"),
"token_group" => std::option::Option::Some("token_group"),
"token_group_member" => std::option::Option::Some("token_group_member"),
_ => std::option::Option::None,
};
let kind = match projection_kind {
std::option::Option::Some(value) => value,
std::option::Option::None => continue,
};
outputs.push(kb_materializer_api::MaterializedOutput {
output_key: format!("token_2022_metadata_snapshot:{account_key}:{slot}:{kind}"),
family: kb_model::MaterializedEventFamily::Metadata,
payload_json: serde_json::json!({
"projectionVersion": 1,
"domain": "spl_token_2022_embedded_metadata",
"projectionSemantics": "authoritative_bounded_mint_extension_snapshot",
"idempotenceKey": format!("token_2022_metadata:{account_key}:{slot}:{kind}"),
"accountKey": account_key,
"slot": slot,
"programId": kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
"metadataSource": "token_2022_embedded_tlv",
"projectionKind": kind,
"extensionType": entry.extension_type,
"extensionName": entry.extension_name,
"valueHex": entry.value_hex,
"valueFields": entry.value_fields,
"externalUriFetched": false,
"identityAuthority": "mint_address",
"finalAccountStateCaptured": true,
"provenance": {
"processorName": "kb_materializer_metadata",
"processorVersion": env!("CARGO_PKG_VERSION"),
"source": "bounded_token_2022_state_parser"
}
}),
});
}
return std::result::Result::Ok(outputs);
}
/// Materialize one canonical Metaplex `MetadataV1` account snapshot.
///
/// Account snapshots are authoritative for current state. Instruction observations may describe
/// mutations, but must not emit a second competing metadata-state projection.
pub fn materialize_metaplex_metadata_snapshot(
snapshot: &kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot,
) -> std::result::Result<kb_materializer_api::MaterializedOutput, String> {
if !snapshot.provenance.committed {
return std::result::Result::Err(
"Metaplex metadata state materialization requires committed provenance".to_string(),
);
}
if snapshot.identity.materialization
!= kb_decoder_metadata_metaplex_token_metadata::CanonicalMaterializationPolicy::ActiveState
{
return std::result::Result::Err(
"Metaplex MetadataV1 materialization requires active-state policy".to_string(),
);
}
let metadata = match &snapshot.state {
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::Metadata(
value,
) => value,
_ => {
return std::result::Result::Err(
"Metaplex metadata materializer received another account layout".to_string(),
);
},
};
let slot = snapshot.provenance.slot.map(|value| return value.to_string());
let write_version = snapshot.provenance.write_version.map(|value| return value.to_string());
let payload = serde_json::json!({
"projectionVersion": 1,
"domain": "metaplex_token_metadata",
"projectionSemantics": "authoritative_committed_account_snapshot",
"stableId": snapshot.identity.stable_id,
"account": metadata.account,
"mint": metadata.mint,
"updateAuthority": metadata.update_authority,
"name": metadata.name,
"symbol": metadata.symbol,
"uri": metadata.uri,
"sellerFeeBasisPoints": metadata.seller_fee_basis_points,
"primarySaleHappened": metadata.primary_sale_happened,
"isMutable": metadata.is_mutable,
"layout": snapshot.identity.layout,
"layoutDiscriminant": snapshot.identity.discriminant,
"canonicalVersion": snapshot.identity.canonical_version,
"lifecycle": "active",
"materializationPolicy": "active_state",
"metadataSource": "metaplex_owned_account",
"accountState": metadata.payload_json,
"externalUriFetched": false,
"stateAuthority": "owned_account_snapshot",
"instructionProjectionRole": "mutation_observation_only_no_duplicate_state",
"provenance": {
"source": format!("{:?}", snapshot.provenance.source),
"slot": slot,
"writeVersion": write_version,
"signature": snapshot.provenance.signature,
"instructionIndex": snapshot.provenance.instruction_index,
"innerInstructionIndex": snapshot.provenance.inner_instruction_index,
"committed": snapshot.provenance.committed,
"processorName": "kb_materializer_metadata",
"processorVersion": env!("CARGO_PKG_VERSION")
}
});
return std::result::Result::Ok(kb_materializer_api::MaterializedOutput {
output_key: format!("metaplex_metadata_state:{}", metadata.account),
family: kb_model::MaterializedEventFamily::Metadata,
payload_json: payload,
});
}
#[cfg(test)]
mod tests_metaplex_metadata_state {
pub(super) fn snapshot(
committed: bool,
) -> kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot {
let metadata = kb_decoder_metadata_metaplex_token_metadata::MetadataAccountSnapshot {
account: "metadata111".to_string(),
bump: 1,
mint: "mint111".to_string(),
update_authority: "authority111".to_string(),
name: "Asset".to_string(),
symbol: "AST".to_string(),
uri: "https://example.invalid/asset.json".to_string(),
seller_fee_basis_points: 500,
primary_sale_happened: true,
is_mutable: false,
payload_json: serde_json::json!({
"creators": [{"address":"creator111","verified":true,"share":100}],
"collection": {"verified":true,"key":"collection111"},
"uses": {"useMethod":"Single","remaining":"0","total":"1"},
"tokenStandard": "ProgrammableNonFungible",
"programmableConfig": {"ruleSet":"rules111"}
}),
};
return kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot::from_metadata(
metadata,
kb_decoder_metadata_metaplex_token_metadata::CanonicalAccountProvenance {
source: kb_decoder_metadata_metaplex_token_metadata::CanonicalObservationSource::Backfill,
slot: std::option::Option::Some(42),
write_version: std::option::Option::Some(7),
signature: std::option::Option::Some("signature111".to_string()),
instruction_index: std::option::Option::Some(3),
inner_instruction_index: std::option::Option::None,
committed,
},
);
}
#[test]
fn account_snapshot_is_one_stable_authoritative_metadata_projection() {
let first = crate::materialize_metaplex_metadata_snapshot(&snapshot(true));
let second = crate::materialize_metaplex_metadata_snapshot(&snapshot(true));
assert_eq!(first, second);
assert_eq!(
first.as_ref().map(|value| return value.output_key.as_str()),
std::result::Result::Ok("metaplex_metadata_state:metadata111")
);
assert_eq!(
first.as_ref().map(|value| return value.payload_json["metadataSource"].clone()),
std::result::Result::Ok(serde_json::json!("metaplex_owned_account"))
);
assert_eq!(
first
.as_ref()
.map(|value| return value.payload_json["instructionProjectionRole"].clone()),
std::result::Result::Ok(serde_json::json!(
"mutation_observation_only_no_duplicate_state"
))
);
assert_eq!(
first
.as_ref()
.map(|value| return value.payload_json["accountState"]["creators"][0]["share"]
.clone()),
std::result::Result::Ok(serde_json::json!(100))
);
}
#[test]
fn uncommitted_or_non_metadata_state_is_rejected() {
assert!(crate::materialize_metaplex_metadata_snapshot(&snapshot(false)).is_err());
let mut wrong = snapshot(true);
wrong.state = kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::EditionMarker(
kb_decoder_metadata_metaplex_token_metadata::EditionMarkerAccountSnapshot {
account: "marker111".to_string(),
bump: 1,
mint: "mint111".to_string(),
kind: kb_decoder_metadata_metaplex_token_metadata::EditionMarkerAccountKind::EditionMarkerV1,
marker_group: std::option::Option::Some(0),
edition: 1,
byte_index: 0,
bit_mask: 64,
edition_taken: true,
ledger: std::vec![64],
payload_json: serde_json::json!({}),
},
);
assert!(crate::materialize_metaplex_metadata_snapshot(&wrong).is_err());
}
}
/// Materialize any canonical Metaplex account state other than `MetadataV1`.
///
/// Every account address maps to one stable state key. Historical layouts remain materializable
/// with an explicit historical lifecycle, while execution policy remains independently disabled.
pub fn materialize_metaplex_account_snapshot(
snapshot: &kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot,
) -> std::result::Result<kb_materializer_api::MaterializedOutput, String> {
if !snapshot.provenance.committed {
return std::result::Result::Err(
"Metaplex account-state materialization requires committed provenance".to_string(),
);
}
let (projection_kind, fact_owner, state_json) = match &snapshot.state {
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::Metadata(_) => {
return std::result::Result::Err(
"MetadataV1 must use the dedicated metadata-state materializer".to_string(),
);
},
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::Edition(value) => (
"edition_state",
"kb_materializer_metadata",
value.payload_json.clone(),
),
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::EditionMarker(value) => (
"edition_marker_state",
"kb_materializer_metadata",
value.payload_json.clone(),
),
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::TokenRecord(value) => (
"programmable_token_state",
"kb_materializer_lifecycle",
value.payload_json.clone(),
),
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::DelegateRecord(value) => (
"delegate_admin_state",
"kb_materializer_admin",
value.payload_json.clone(),
),
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::AuthorityRecord(value) => (
"authority_admin_state",
"kb_materializer_admin",
value.payload_json.clone(),
),
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::TokenOwnedEscrow(value) => (
"token_owned_escrow_state",
"kb_materializer_lifecycle",
value.payload_json.clone(),
),
kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountState::ReservationList(value) => (
"historical_reservation_state",
"kb_materializer_metadata",
value.payload_json.clone(),
),
};
let lifecycle = match snapshot.identity.lifecycle {
kb_decoder_metadata_metaplex_token_metadata::CanonicalAccountLifecycle::Active => "active",
kb_decoder_metadata_metaplex_token_metadata::CanonicalAccountLifecycle::ActiveExperimental => {
"active_experimental"
},
kb_decoder_metadata_metaplex_token_metadata::CanonicalAccountLifecycle::Historical => {
"historical"
},
};
let materialization_policy = match snapshot.identity.materialization {
kb_decoder_metadata_metaplex_token_metadata::CanonicalMaterializationPolicy::ActiveState => {
"active_state"
},
kb_decoder_metadata_metaplex_token_metadata::CanonicalMaterializationPolicy::HistoricalState => {
"historical_state"
},
};
let execution_policy = match snapshot.identity.execution {
kb_decoder_metadata_metaplex_token_metadata::CanonicalExecutionPolicy::CurrentCandidate => {
"current_candidate"
},
kb_decoder_metadata_metaplex_token_metadata::CanonicalExecutionPolicy::ExperimentalCandidate => {
"experimental_candidate"
},
kb_decoder_metadata_metaplex_token_metadata::CanonicalExecutionPolicy::NeverHistorical => {
"never_historical"
},
};
return std::result::Result::Ok(kb_materializer_api::MaterializedOutput {
output_key: format!("metaplex_account_state:{}", snapshot.identity.account),
family: kb_model::MaterializedEventFamily::Metadata,
payload_json: serde_json::json!({
"projectionVersion": 1,
"domain": "metaplex_token_metadata",
"projectionKind": projection_kind,
"projectionSemantics": "authoritative_committed_owned_account_snapshot",
"stableId": snapshot.identity.stable_id,
"account": snapshot.identity.account,
"programId": snapshot.identity.program_id,
"layout": snapshot.identity.layout,
"layoutDiscriminant": snapshot.identity.discriminant,
"canonicalVersion": snapshot.identity.canonical_version,
"lifecycle": lifecycle,
"materializationPolicy": materialization_policy,
"executionPolicy": execution_policy,
"factOwner": fact_owner,
"metadataSource": "metaplex_owned_account",
"accountState": state_json,
"instructionProjectionRole": "mutation_observation_only_no_duplicate_state",
"provenance": {
"source": format!("{:?}", snapshot.provenance.source),
"slot": snapshot.provenance.slot.map(|value: u64| return value.to_string()),
"writeVersion": snapshot.provenance.write_version.map(|value: u64| return value.to_string()),
"signature": snapshot.provenance.signature,
"instructionIndex": snapshot.provenance.instruction_index,
"innerInstructionIndex": snapshot.provenance.inner_instruction_index,
"committed": snapshot.provenance.committed,
"processorName": "kb_materializer_metadata",
"processorVersion": env!("CARGO_PKG_VERSION")
}
}),
});
}
#[cfg(test)]
mod tests_metaplex_account_state {
fn provenance() -> kb_decoder_metadata_metaplex_token_metadata::CanonicalAccountProvenance {
return kb_decoder_metadata_metaplex_token_metadata::CanonicalAccountProvenance {
source:
kb_decoder_metadata_metaplex_token_metadata::CanonicalObservationSource::Backfill,
slot: std::option::Option::Some(90),
write_version: std::option::Option::Some(2),
signature: std::option::Option::None,
instruction_index: std::option::Option::None,
inner_instruction_index: std::option::Option::None,
committed: true,
};
}
#[test]
fn historical_edition_and_reservation_are_stable_materializable_state() {
let edition = kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot::from_edition(
kb_decoder_metadata_metaplex_token_metadata::EditionAccountSnapshot {
account: "master-v1".to_string(),
bump: 1,
mint: "mint-v1".to_string(),
kind: kb_decoder_metadata_metaplex_token_metadata::EditionAccountKind::MasterEditionV1,
supply: std::option::Option::Some(3),
max_supply: std::option::Option::Some(10),
parent: std::option::Option::None,
edition: std::option::Option::None,
printing_mint: std::option::Option::Some("printing".to_string()),
one_time_printing_authorization_mint: std::option::Option::Some("authorization".to_string()),
payload_json: serde_json::json!({"supply":"3","maxSupply":"10"}),
},
provenance(),
);
let reservation = kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot::from_reservation_list(
kb_decoder_metadata_metaplex_token_metadata::ReservationListAccountSnapshot {
account: "reservation-v2".to_string(),
bump: 2,
kind: kb_decoder_metadata_metaplex_token_metadata::ReservationListAccountKind::V2,
master_edition: "master-v1".to_string(),
resource: "resource".to_string(),
supply_snapshot: std::option::Option::Some(3),
reservations: std::vec::Vec::new(),
total_reservation_spots: 0,
current_reservation_spots: 0,
payload_json: serde_json::json!({"reservations":[]}),
},
provenance(),
);
let first = crate::materialize_metaplex_account_snapshot(&edition);
let second = crate::materialize_metaplex_account_snapshot(&reservation);
assert_eq!(
first.as_ref().map(|value| return value.payload_json["lifecycle"].clone()),
std::result::Result::Ok(serde_json::json!("historical"))
);
assert_eq!(
first.as_ref().map(|value| return value.payload_json["executionPolicy"].clone()),
std::result::Result::Ok(serde_json::json!("never_historical"))
);
assert_eq!(
second.as_ref().map(|value| return value.output_key.as_str()),
std::result::Result::Ok("metaplex_account_state:reservation-v2")
);
}
#[test]
fn programmable_delegate_authority_and_escrow_keep_unique_fact_owners() {
let token = kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot::from_token_record(
kb_decoder_metadata_metaplex_token_metadata::TokenRecordAccountSnapshot {
account: "token-record".to_string(),
bump: 1,
mint: "mint".to_string(),
token: "token".to_string(),
stored_bump: 1,
state: "Locked".to_string(),
rule_set_revision: std::option::Option::Some(4),
delegate: std::option::Option::Some("delegate".to_string()),
delegate_role: std::option::Option::Some("Transfer".to_string()),
locked_transfer: std::option::Option::Some("destination".to_string()),
locked: true,
payload_json: serde_json::json!({"state":"Locked"}),
},
provenance(),
);
let output = crate::materialize_metaplex_account_snapshot(&token);
assert_eq!(
output.as_ref().map(|value| return value.payload_json["factOwner"].clone()),
std::result::Result::Ok(serde_json::json!("kb_materializer_lifecycle"))
);
assert_eq!(
output.as_ref().map(|value| return value.payload_json["projectionKind"].clone()),
std::result::Result::Ok(serde_json::json!("programmable_token_state"))
);
}
#[test]
fn uncommitted_and_metadata_snapshots_use_explicit_boundaries() {
let mut marker = kb_decoder_metadata_metaplex_token_metadata::CanonicalMetadataAccountSnapshot::from_edition_marker(
kb_decoder_metadata_metaplex_token_metadata::EditionMarkerAccountSnapshot {
account: "marker".to_string(),
bump: 1,
mint: "mint".to_string(),
kind: kb_decoder_metadata_metaplex_token_metadata::EditionMarkerAccountKind::EditionMarkerV2,
marker_group: std::option::Option::None,
edition: 8,
byte_index: 1,
bit_mask: 128,
edition_taken: true,
ledger: std::vec![0, 128],
payload_json: serde_json::json!({"editionTaken":true}),
},
provenance(),
);
marker.provenance.committed = false;
assert!(crate::materialize_metaplex_account_snapshot(&marker).is_err());
assert!(
crate::materialize_metaplex_account_snapshot(
&super::tests_metaplex_metadata_state::snapshot(true)
)
.is_err()
);
}
}
#[cfg(test)]
mod tests_token_2022_state {
#[test]
fn embedded_metadata_group_and_member_have_distinct_stable_outputs() {
let state = kb_decoder_spl_token_2022::state::Token2022State {
kind: kb_decoder_spl_token_2022::state::Token2022StateKind::Mint,
base_fields: serde_json::json!({"supply":"1","decimals":0}),
base_hex: "00".repeat(82),
account_type: std::option::Option::Some(1),
extensions: std::vec![
kb_decoder_spl_token_2022::state::Token2022TlvEntry {
extension_type: 19,
extension_name: "token_metadata",
value_hex: "01".to_string(),
value_fields: serde_json::json!({"name":"Token","symbol":"TOK","uri":"https://example.invalid/token.json"}),
},
kb_decoder_spl_token_2022::state::Token2022TlvEntry {
extension_type: 20,
extension_name: "token_group",
value_hex: "02".to_string(),
value_fields: serde_json::json!({"mint":"mint111","size":"1","maxSize":"10"}),
},
kb_decoder_spl_token_2022::state::Token2022TlvEntry {
extension_type: 21,
extension_name: "token_group_member",
value_hex: "03".to_string(),
value_fields: serde_json::json!({"mint":"mint111","group":"group111","memberNumber":"1"}),
},
],
};
let outputs = crate::materialize_token_2022_metadata_snapshot("mint111", 9, &state);
assert_eq!(outputs.as_ref().map(|values| return values.len()), std::result::Result::Ok(3));
assert_eq!(
outputs
.as_ref()
.map(|values| return values[0].payload_json["metadataSource"].clone()),
std::result::Result::Ok(serde_json::json!("token_2022_embedded_tlv"))
);
assert_eq!(
outputs
.as_ref()
.map(|values| return values[0].payload_json["externalUriFetched"].clone()),
std::result::Result::Ok(serde_json::json!(false))
);
assert_eq!(
outputs
.as_ref()
.map(|values| return values[1].payload_json["projectionKind"].clone()),
std::result::Result::Ok(serde_json::json!("token_group"))
);
}
#[test]
fn snapshot_is_idempotent_filters_unrelated_extensions_and_requires_mint_identity() {
let state = kb_decoder_spl_token_2022::state::Token2022State {
kind: kb_decoder_spl_token_2022::state::Token2022StateKind::Mint,
base_fields: serde_json::json!({}),
base_hex: "00".repeat(82),
account_type: std::option::Option::Some(1),
extensions: std::vec![kb_decoder_spl_token_2022::state::Token2022TlvEntry {
extension_type: 1,
extension_name: "transfer_fee_config",
value_hex: "00".to_string(),
value_fields: serde_json::json!({}),
}],
};
let first = crate::materialize_token_2022_metadata_snapshot("mint111", 9, &state);
let second = crate::materialize_token_2022_metadata_snapshot("mint111", 9, &state);
assert_eq!(first, second);
assert_eq!(first.as_ref().map(|values| return values.len()), std::result::Result::Ok(0));
assert!(crate::materialize_token_2022_metadata_snapshot("", 9, &state).is_err());
let account_state = kb_decoder_spl_token_2022::state::Token2022State {
kind: kb_decoder_spl_token_2022::state::Token2022StateKind::Account,
base_fields: serde_json::json!({}),
base_hex: "00".repeat(165),
account_type: std::option::Option::None,
extensions: std::vec::Vec::new(),
};
assert!(
crate::materialize_token_2022_metadata_snapshot("account111", 9, &account_state)
.is_err()
);
}
}