v0.4.8-pre.008

This commit is contained in:
2026-08-06 06:12:54 +02:00
parent 44088c71c9
commit f576fbade2
52 changed files with 3592 additions and 420 deletions

View File

@@ -1,8 +1,15 @@
<!-- file: kb-app-demo-desktop/CHANGELOG.md -->
<!-- version: 25 -->
<!-- version: 27 -->
# CHANGELOG — kb-app-demo-desktop
## 0.4.8-pre.008
- enregistre `metadata.solana_program_metadata` dans le replay générique afin que les signatures hydratées par `demo_backfill` puissent être décodées ;
- enregistre les trois matérialiseurs spécialisés `MtMetadataMetaplexTokenMetadataMaterializer`, `MtMetadataSolanaProgramMaterializer` et `MtMetadataToken2022Materializer` dans le replay générique ;
- vérifie par test quune observation représentative de chaque domaine metadata possède exactement un matérialiseur runtime ;
- ne modifie ni `demo_execution_metadata`, ni les scénarios Devnet, réservés à `0.4.8-pre.009`.
## 0.4.8-pre.001
- aligne les versions Tauri et frontend sur `0.4.8` pour ouvrir la nouvelle version fonctionnelle ;

View File

@@ -1,5 +1,5 @@
<!-- file: kb-app-demo-desktop/README.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# kb-app-demo-desktop
@@ -10,7 +10,7 @@
- configuration et diagnostics de logging ;
- transport HTTP JSON-RPC et WebSocket ;
- diagnostics PostgreSQL ;
- backfill, extraction Core et replay ;
- backfill, extraction Core et replay, avec enregistrement générique de Solana Program Metadata ;
- démonstrations Solana Core, SPL Memo, SPL Token, ATA et Token-2022 ;
- panneau Metadata avec scénarios synthétiques, préparation du profil et de la base, intents typés, simulation RPC Devnet réelle et soumission explicitement confirmée ;
- progression, annulation et restauration de létat des fenêtres.

View File

@@ -1,5 +1,5 @@
<!-- file: kb-app-demo-desktop/USAGE.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Utilisation de kb-app-demo-desktop
@@ -151,6 +151,17 @@ console.log(options, summary);
Une campagne longue peut être annulée avec `demo_core_extraction_cancel`.
### Validation historique Solana Program Metadata
Avant les scénarios Devnet, utiliser les fenêtres généralistes dans cet ordre :
1. `demo_backfill` avec un échantillon borné de signatures confirmées contenant `ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S` ;
2. extraction Core sur les mêmes signatures ;
3. decode replay avec le Program ID `ProgM6…`, le décodeur `metadata.solana_program_metadata` et la matérialisation activée ;
4. lecture des événements du processor `materializer.metadata.solana_program_metadata`.
Ce parcours ne dépend pas de `kb-pipeline-demo-scenarios`. La fenêtre `demo_execution_metadata` et les scénarios Devnet `ProgM6…` seront ajoutés séparément dans `0.4.8-pre.009`.
### Decode replay
```typescript

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_decode_replay.rs
// version: 37
// version: 39
//! Tauri commands and UI payloads for contextual instruction decode replay.
@@ -662,10 +662,13 @@ fn available_materializers() -> std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEv
std::sync::Arc::new(kb_lib::MtComplianceAuditMaterializer),
std::sync::Arc::new(kb_lib::MtFeesMaterializer),
std::sync::Arc::new(kb_lib::MtLifecycleMaterializer),
std::sync::Arc::new(kb_lib::MtMetadataMetaplexTokenMetadataMaterializer),
std::sync::Arc::new(kb_lib::MtMetadataSolanaProgramMaterializer),
std::sync::Arc::new(kb_lib::MtMetadataToken2022Materializer),
std::sync::Arc::new(kb_lib::MtStakingMaterializer),
std::sync::Arc::new(kb_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(kb_lib::MtRiskMaterializer),
std::sync::Arc::new(kb_lib::MtTransactionAnnotationMaterializer,),
std::sync::Arc::new(kb_lib::MtTransactionAnnotationMaterializer),
];
}
@@ -673,7 +676,8 @@ fn available_decoders() -> std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstruc
return std::vec![
std::sync::Arc::new(kb_lib::DcSolanaCoreDecoder),
std::sync::Arc::new(kb_lib::DcMetadataMetaplexTokenMetadataDecoder),
std::sync::Arc::new(kb_lib::DcSplAssociatedTokenAccountDecoder,),
std::sync::Arc::new(kb_lib::DcMetadataSolanaProgramMetadataDecoder),
std::sync::Arc::new(kb_lib::DcSplAssociatedTokenAccountDecoder),
std::sync::Arc::new(kb_lib::DcSplElgamalRegistryDecoder),
std::sync::Arc::new(kb_lib::DcSplMemoDecoder),
std::sync::Arc::new(kb_lib::DcSplTokenDecoder),
@@ -1020,10 +1024,47 @@ mod tests {
};
}
fn metadata_observation(
program_id: &str,
surface: &str,
entry: &str,
) -> kb_lib::DcApiDecodedObservation {
return kb_lib::DcApiDecodedObservation {
event_key: format!("{surface}:{entry}:0"),
event: kb_lib::MdDecodedProtocolEvent {
signature: kb_lib::MdSignature("signature".to_string()),
slot: kb_lib::MdSlot(1),
instruction_path: kb_lib::MdInstructionPath("0".to_string()),
program_id: kb_lib::MdProgramId(program_id.to_string()),
protocol_code: kb_lib::MdProtocolCode(surface.to_string()),
surface_code: kb_lib::MdSurfaceCode(surface.to_string()),
event_code: kb_lib::MdEventCode(format!("{surface}.{entry}")),
event_name: kb_lib::MdEventName(entry.to_string()),
event_family: kb_lib::MdEventFamily::Metadata,
source_kind: kb_lib::MdEventSourceKind::Instruction,
confidence: kb_lib::MdDecoderConfidence::ManualExact,
},
payload_json: serde_json::json!({
"programId": program_id,
"instruction": entry,
"parameters": {},
"accounts": []
}),
transaction_failed: false,
transaction_error: std::option::Option::None,
observation_committed: true,
proof: kb_lib::DcApiDecoderProof {
kind: kb_lib::DcApiDecoderProofKind::Manual,
confidence: kb_lib::MdDecoderConfidence::ManualExact,
evidence: std::vec!["fixture".to_string()],
},
};
}
#[test]
fn native_memo_token_2022_elgamal_classic_token_and_ata_decoders_are_registered() {
fn current_core_spl_and_metadata_decoders_are_registered() {
let decoders = super::available_decoders();
assert_eq!(decoders.len(), 7);
assert_eq!(decoders.len(), 8);
let mut names = decoders
.iter()
.map(|decoder| return decoder.identity().name)
@@ -1031,6 +1072,7 @@ mod tests {
names.sort();
let mut expected_names = std::vec![
"metadata.metaplex_token_metadata".to_string(),
"metadata.solana_program_metadata".to_string(),
"solana.core".to_string(),
"spl.associated_token_account".to_string(),
"spl.elgamal_registry".to_string(),
@@ -1045,7 +1087,7 @@ mod tests {
#[test]
fn runtime_materializer_registry_is_complete_for_current_instructional_surfaces() {
let materializers = super::available_materializers();
assert_eq!(materializers.len(), 8);
assert_eq!(materializers.len(), 11);
let names = materializers
.iter()
.map(|materializer| return materializer.identity().name)
@@ -1057,6 +1099,9 @@ mod tests {
"materializer.compliance.audit".to_string(),
"materializer.fees".to_string(),
"materializer.lifecycle".to_string(),
"materializer.metadata.metaplex_token_metadata".to_string(),
"materializer.metadata.solana_program_metadata".to_string(),
"materializer.metadata.token_2022".to_string(),
"materializer.staking".to_string(),
"materializer.token.accounts".to_string(),
"materializer.risk".to_string(),
@@ -1065,6 +1110,38 @@ mod tests {
);
}
#[test]
fn metadata_materializer_ownership_is_exact_in_the_runtime_registry() {
for (program_id, surface, entry, expected) in [
(
kb_program_ids::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID,
"metadata.metaplex_token_metadata",
"create_metadata_account_v3",
"materializer.metadata.metaplex_token_metadata",
),
(
kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID,
"metadata.solana_program_metadata",
"initialize",
"materializer.metadata.solana_program_metadata",
),
(
kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
"spl.token_2022",
"initialize_token_metadata",
"materializer.metadata.token_2022",
),
] {
let observation = metadata_observation(program_id, surface, entry);
let owners = super::available_materializers()
.iter()
.filter(|materializer| return materializer.accepts_observation(&observation))
.map(|materializer| return materializer.identity().name)
.collect::<std::vec::Vec<_>>();
assert_eq!(owners, std::vec![expected.to_string()]);
}
}
#[test]
fn ata_materializer_ownership_is_exact_in_the_runtime_registry() {
for (entry, expected) in [