v0.1.0-pre.070

This commit is contained in:
2026-07-31 15:44:46 +02:00
parent 94181e4d5c
commit d6bd91c305
22 changed files with 1055 additions and 35 deletions

View File

@@ -117,6 +117,7 @@ Les travaux planifiés pour supprimer une limite temporaire appartiennent au TOD
Les exemples Rust doivent respecter les règles du workspace, y compris les conventions de propagation derreurs.
Chaque API publique significative doit disposer dau moins un exemple ou être couverte par un exemple de scénario explicitement identifié. Les APIs triviales ou regroupées peuvent partager un exemple lorsquil démontre réellement leur usage.
Un `USAGE.md` doit fournir plusieurs exemples lorsque la crate expose plusieurs familles dAPI ou plusieurs étapes dun parcours public. Un unique exemple global nest suffisant que pour une surface publique réellement minimale. Les exemples doivent couvrir en priorité la construction des requêtes, leur validation, lexécution principale, linterprétation du résultat et les invariants opérateur pertinents.
### 4.4 Crates sans API bibliothèque publique

View File

@@ -27,7 +27,10 @@ Pour chaque API ou groupe cohérent :
- valeur retournée ;
- erreurs ;
- invariants ;
- exemple.
- exemple de construction ou configuration ;
- exemple de validation ;
- exemple dexécution ou dappel principal ;
- exemple dinterprétation du résultat lorsque pertinent.
## Types publics importants

View File

@@ -1,8 +1,12 @@
<!-- file: kb-config/CHANGELOG.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# CHANGELOG — kb-config
## 0.1.0-pre.070
- enrichissement de `USAGE.md` avec plusieurs exemples couvrant les familles dAPI publiques significatives.
## 0.1.0-pre.069
### Documentation

View File

@@ -1,5 +1,5 @@
<!-- file: kb-config/USAGE.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Utilisation de kb-config
@@ -29,10 +29,25 @@ let report = match kb_config::load_workspace_environment(std::path::Path::new(".
Ok(value) => value,
Err(error) => return Err(error),
};
for path in report.loaded_files {
println!("environment file: {}", path.display());
}
```
`EnvironmentLoadReport` indique les fichiers chargés. Les placeholders non résolus sans fallback restent visibles afin que la validation ou le consommateur puisse les signaler explicitement.
## Résolution explicite des placeholders
```rust
let raw = r#"{"databaseUrl":"${KB_DATABASE_URL:-postgres://localhost/kb}"}"#;
let resolved = kb_config::resolve_environment_placeholders(raw);
assert!(resolved.contains("databaseUrl"));
```
Cette API est utile pour un outil de diagnostic qui veut afficher le JSON résolu avant parsing.
## Validation et parsing
```rust
@@ -61,6 +76,14 @@ let pretty = match kb_config::serialize_config_json_pretty(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
let write_result = std::fs::write("config/generated.config.json", pretty);
if let Err(error) = write_result {
return Err(kb_core::Error::new(
"config_write_failed",
format!("cannot write generated configuration: {error}"),
));
}
```
La configuration est validée avant sérialisation.
@@ -73,10 +96,30 @@ let schema_value = match kb_config::config_json_schema_value() {
Ok(value) => value,
Err(error) => return Err(error),
};
let property_count = schema_value
.get("properties")
.and_then(serde_json::Value::as_object)
.map_or(0, serde_json::Map::len);
println!("embedded schema bytes={}, properties={property_count}", schema_text.len());
```
Le schéma actif est aussi disponible sous [`../config/schema.config.json`](../config/schema.config.json). Le fichier [`../config/example.config.json`](../config/example.config.json) fournit un exemple utilisateur complet.
## Sélection du profil actif
```rust
let profile = match kb_config::active_profile(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("active profile: {}", profile.name);
println!("http endpoints: {}", profile.solana.http_endpoints.len());
println!("websocket endpoints: {}", profile.solana.ws_endpoints.len());
```
## Types publics importants
- `AppConfig`, `ProfileConfig`, `AppSectionConfig` ;

View File

@@ -1,8 +1,12 @@
<!-- file: kb-lib/CHANGELOG.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# CHANGELOG — kb-lib
## 0.1.0-pre.070
- enrichissement de `USAGE.md` avec plusieurs exemples couvrant les familles dAPI publiques significatives.
## 0.1.0-pre.069
### Documentation

View File

@@ -1,5 +1,5 @@
<!-- file: kb-lib/USAGE.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Utilisation de kb-lib
@@ -30,6 +30,19 @@ let result = DcApiInstructionDecoder::decode(&decoder, &input);
Le consommateur doit vérifier le résultat typé et ses diagnostics. Une transaction échouée peut produire une intention structurée, mais pas une mutation committée.
```rust
let execution = DcApiInstructionDecoder::decode(&decoder, &input);
match execution {
Ok(result) => {
println!("status={:?}", result.status);
println!("observations={}", result.observations.len());
println!("diagnostics={}", result.diagnostics.len());
},
Err(error) => return Err(error),
}
```
Décodeurs fonctionnels principaux :
- `DcSolanaCoreDecoder` ;
@@ -45,13 +58,26 @@ Les types réservés `Dc*Decoder` ne doivent pas être interprétés comme des d
## Lecture détats Token-2022 et ElGamal
```rust
let state = kb_lib::decoder_spl_token_2022_parse_token_2022_state(
&program_id,
let state = match kb_lib::decoder_spl_token_2022_parse_token_2022_state(
kb_lib::DcToken2022StateKind::Account,
&account_data,
);
let registry = kb_lib::decoder_spl_elgamal_registry_parse_elgamal_registry_state(
) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("parsed token-2022 state: {state:#?}");
```
```rust
let registry = match kb_lib::decoder_spl_elgamal_registry_parse_elgamal_registry_state(
&account_data,
);
) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("parsed registry state: {registry:#?}");
```
Les parseurs vérifient les bornes et formats quils annoncent. Ils ne reconstruisent pas un état historique depuis un RPC courant.
@@ -60,6 +86,37 @@ Les parseurs vérifient les bornes et formats quils annoncent. Ils ne reconst
Les fonctions `decoder_metadata_metaplex_token_metadata_decode_*_account` décodent les familles de comptes publiques prises en charge. Le consommateur doit fournir les données et le contexte attendus par la signature exacte de la fonction concernée. Les parseurs conservent les variantes historiques et refusent les longueurs, propriétaires ou suffixes incompatibles.
```rust
let metadata = match kb_lib::decoder_metadata_metaplex_token_metadata_decode_metadata_account(
metadata_account.as_str(),
metadata_owner.as_str(),
&account_data,
) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("metadata mint={}", metadata.mint);
println!("metadata name={}", metadata.name);
```
```rust
let edition = match kb_lib::decoder_metadata_metaplex_token_metadata_decode_edition_account(
edition_account.as_str(),
metadata_owner.as_str(),
mint.as_str(),
&account_data,
) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("edition kind={:?}", edition.kind);
println!("edition parent={:?}", edition.parent);
```
Les signatures exactes doivent être vérifiées lors de lutilisation : certaines familles exigent un contexte ou une identité canonique supplémentaire.
## Exécution typée
`ExApiTypedInstructionExecutor` produit un `ExApiPreparedExecutionPlan` à partir dune intention et dune politique explicites. Les exécuteurs concrets incluent notamment :
@@ -84,16 +141,58 @@ let plan = ExApiTypedInstructionExecutor::build_prepared_plan(
Le plan ne signe et nenvoie rien. La simulation, la confirmation opérateur, la soumission et la confirmation réseau appartiennent aux couches dorchestration et de transport.
```rust
let plan = match ExApiTypedInstructionExecutor::build_prepared_plan(
&executor,
&intent,
) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("instructions={}", plan.instructions.len());
println!("required_signers={}", plan.required_signers.len());
```
Memo v1 et v3 restent non exécutables. Memo v4 est la seule génération exécutable.
## Sécurité
Les types `ExSafetyChecker`, `ExSafetyDecision`, `ExSafetyEvaluation` et `ExSafetyViolation` permettent dévaluer un plan avant son utilisation. Une décision conservatrice doit être respectée par le consommateur ; elle ne doit pas être contournée par lapplication.
```rust
let evaluation = match checker.evaluate_prepared_plan(&plan) {
Ok(value) => value,
Err(error) => return Err(error),
};
match evaluation.decision {
kb_lib::ExSafetyDecision::Allow => {
println!("execution plan accepted");
},
kb_lib::ExSafetyDecision::Deny => {
for violation in evaluation.violations {
eprintln!("safety violation: {violation:#?}");
}
},
}
```
## Matérialisation
`MtApiEventMaterializer` définit le contrat public de matérialisation. Les résultats `MtApiMaterializerExecutionResult` contiennent les sorties et diagnostics sans dépendre dun backend de stockage.
```rust
let result = kb_lib::MtApiEventMaterializer::materialize(
&materializer,
&decoded_observation,
);
println!("status={:?}", result.status);
println!("outputs={}", result.outputs.len());
println!("diagnostics={}", result.diagnostics.len());
```
Les fonctions stateful publiques comprennent notamment :
- `materializer_admin_materialize_token_2022_state_snapshots` ;
@@ -107,6 +206,17 @@ Les fonctions stateful publiques comprennent notamment :
`MdCoreInstructionReplayInput` représente une instruction extraite avec son contexte transactionnel. Il constitue la frontière entre lextraction Core, le pipeline de replay et les décodeurs.
```rust
let recognition = DcApiInstructionDecoder::recognize(&decoder, &replay_input);
if recognition.compatible {
let decoded = DcApiInstructionDecoder::decode(&decoder, &replay_input);
if let Err(error) = decoded {
return Err(error);
}
}
```
## Tests et matrices utiles
Les tests unitaires du décodeur Metaplex et du décodeur Solana Core chargent directement certaines matrices de [`../test-fixtures/contract-matrices/`](../test-fixtures/contract-matrices/). Ils vérifient notamment légalité entre les entrées compilées et les contrats JSON, les discriminants, les bornes et les comportements historiques.

View File

@@ -1,8 +1,12 @@
<!-- file: kb-logging/CHANGELOG.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# CHANGELOG — kb-logging
## 0.1.0-pre.070
- enrichissement de `USAGE.md` avec plusieurs exemples couvrant les familles dAPI publiques significatives.
## 0.1.0-pre.069
### Documentation

View File

@@ -1,5 +1,5 @@
<!-- file: kb-logging/USAGE.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Utilisation de kb-logging
@@ -37,14 +37,97 @@ assert_eq!(guard.guard_count(), 1);
assert_eq!(guard.route_names(), &["console".to_string()]);
```
## Routes fichier
## Route fichier JSON
```rust
let file_route = kb_logging::LogTargetConfig {
name: "operations-json".to_string(),
enabled: true,
sink: "file".to_string(),
level: "debug".to_string(),
path: "logs/operations.jsonl".to_string(),
rotation: "daily".to_string(),
format: "json".to_string(),
ansi: false,
targets: vec![
"kb-pipeline*".to_string(),
"kb-onchain-transport*".to_string(),
],
};
let config = kb_logging::LoggingConfig {
default_level: "info".to_string(),
targets: vec![file_route],
target_filters: Vec::new(),
};
let guard = match kb_logging::init_logging(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
```
Pour une route `file`, `path` doit désigner le fichier cible et `rotation` doit être une valeur supportée (`none`, `never`, `daily` ou `hourly`). Les formats supportés sont `human`, `compact`, `pretty` et `json`.
## Filtres de targets
```rust
let config = kb_logging::LoggingConfig {
default_level: "warn".to_string(),
targets: vec![kb_logging::LogTargetConfig {
name: "console".to_string(),
enabled: true,
sink: "console".to_string(),
level: "info".to_string(),
path: String::new(),
rotation: "none".to_string(),
format: "compact".to_string(),
ansi: true,
targets: vec!["kb-*".to_string()],
}],
target_filters: vec![
kb_logging::LogTargetFilterConfig {
target: "kb-pipeline".to_string(),
level: "debug".to_string(),
},
kb_logging::LogTargetFilterConfig {
target: "kb-store".to_string(),
level: "info".to_string(),
},
],
};
```
Les routes acceptent des targets exactes et des préfixes wildcard. Les `target_filters` ajoutent des niveaux spécifiques aux routes wildcard. Une route derreur conserve la sémantique stricte prévue par limplémentation.
## Émission dévénements après initialisation
```rust
tracing::info!(
target: kb_logging::tracing_target(),
action = "startup",
"logging runtime initialized"
);
tracing::debug!(
target: "kb-pipeline.demo",
scenario = "token_2022",
"scenario preparation started"
);
```
Les targets doivent suivre la nomenclature canonique du workspace pour que les routes et filtres restent prévisibles.
## Inspection des routes actives
```rust
for route_name in guard.route_names() {
println!("active logging route: {route_name}");
}
assert_eq!(guard.route_count(), guard.route_names().len());
```
## Erreurs
Les erreurs utilisent `kb_core::Error`. Les cas principaux sont :

View File

@@ -0,0 +1,19 @@
<!-- file: kb-onchain-transport/CHANGELOG.md -->
<!-- version: 1 -->
# CHANGELOG — kb-onchain-transport
## 0.1.0-pre.070
- enrichissement du `USAGE.md` avec plusieurs exemples couvrant les principales familles dAPI publiques ;
- ajout du contrat documentaire de la crate ;
- description des APIs publiques HTTP, WebSocket, JSON-RPC et exécution ;
- clarification de la séparation entre transport, pipeline, décodage et stockage ;
- classement des travaux futurs de streaming et résilience dans le TODO.
## 0.1.0-pre.062
- migration et consolidation des anciennes crates RPC de bot2 ;
- renommage en `kb-onchain-transport` ;
- conservation des transports HTTP, WebSocket, acquisition canonique, simulation, soumission et confirmation ;
- adaptation aux normes Rust 2024 et Khadhroony bot3.

View File

@@ -0,0 +1,37 @@
<!-- file: kb-onchain-transport/README.md -->
<!-- version: 1 -->
# kb-onchain-transport
`kb-onchain-transport` fournit les transports Solana on-chain de `khadhroony-bot3`.
## Responsabilités
- requêtes JSON-RPC HTTP standard ;
- sessions et pools WebSocket ;
- routage par rôle dendpoint ;
- adaptation des réponses RPC vers les contrats canoniques ;
- simulation, soumission et confirmation de transactions ;
- acquisition de signatures et transactions pour le backfill ;
- validation bornée des paramètres et réponses réseau.
La crate ne décode pas les programmes Solana et ne persiste pas directement les données. Elle alimente `kb-pipeline`, qui orchestre lacquisition, lextraction et le replay, et utilise les contrats de `kb-core` et `kb-lib`.
## Surfaces publiques principales
- `HttpClient`, `HttpEndpointPool` ;
- `SolanaRpcClient`, `RpcEndpoint` ;
- contrats JSON-RPC ;
- méthodes HTTP standard et leurs types de configuration ;
- `WsClient`, `WsEndpointPool`, sessions et abonnements WebSocket ;
- adaptateurs `getTransaction`, `getSignaturesForAddress` et méthodes dexécution RPC.
Voir [USAGE.md](USAGE.md) pour les APIs publiques et les exemples.
## Documentation
- [USAGE.md](USAGE.md)
- [TODO.md](TODO.md)
- [CHANGELOG.md](CHANGELOG.md)
- [Architecture du pipeline](../docs/architecture/PIPELINE_ARCHITECTURE.md)
- [Carte des crates](../docs/architecture/CRATE_MAP.md)

View File

@@ -0,0 +1,11 @@
<!-- file: kb-onchain-transport/TODO.md -->
<!-- version: 1 -->
# TODO — kb-onchain-transport
- [ ] Transport temps réel - étendre le support WebSocket Helius selon les contrats retenus pour `0.13.x`.
- [ ] Transport temps réel - auditer létat réel de LaserStream et définir les compléments nécessaires.
- [ ] Transport temps réel - concevoir lintégration Yellowstone gRPC sans coupler le pipeline à un fournisseur.
- [ ] Résilience - formaliser les politiques de reprise, continuité, reconnexion, backpressure et métriques des transports streaming.
- [ ] Documentation - créer le guide transversal RPC, backfill et streaming à partir des APIs bot3 actuelles.
- [ ] Tests - compléter les tests dintégration opt-in pour les rôles dendpoints et les scénarios de reconnexion.

View File

@@ -0,0 +1,147 @@
<!-- file: kb-onchain-transport/USAGE.md -->
<!-- version: 2 -->
# Utilisation de kb-onchain-transport
## Objectif
La crate expose les contrats publics nécessaires aux communications RPC HTTP et WebSocket avec Solana.
## Prérequis
- une configuration `kb-config` contenant au moins un endpoint compatible ;
- un runtime Tokio pour les opérations asynchrones ;
- des limites et engagements adaptés à lopération demandée.
## Construire un client HTTP
```rust
fn build_http_client(
endpoint: kb_config::HttpEndpointConfig,
) -> kb_core::Result<kb_onchain_transport::HttpClient> {
let result = kb_onchain_transport::HttpClient::new(endpoint);
match result {
Ok(client) => Ok(client),
Err(error) => Err(error),
}
}
```
## Construire et interroger un pool HTTP
```rust
fn select_query_client(
profile: &kb_config::ProfileConfig,
) -> kb_core::Result<kb_onchain_transport::HttpClient> {
let pool_result = kb_onchain_transport::HttpEndpointPool::from_profile(profile);
let pool = match pool_result {
Ok(pool) => pool,
Err(error) => return Err(error),
};
pool.select_client_for_role_and_method("http_queries", "getBalance")
}
```
`HttpEndpointPool::snapshot` fournit un état sérialisable des endpoints actifs et de leurs rôles.
## Classer une méthode RPC
```rust
fn classify_method(method: &str) -> String {
kb_onchain_transport::request_kind_from_method(method)
}
assert_eq!(classify_method("getTransaction"), "transaction_read");
```
La valeur retournée sert au routage par rôle. Elle ne remplace pas le nom RPC exact utilisé sur le wire.
## Parser une réponse JSON-RPC
```rust
fn parse_response(
text: &str,
) -> kb_core::Result<kb_onchain_transport::JsonRpcResponse> {
let result = kb_onchain_transport::parse_json_rpc_text(text);
match result {
Ok(response) => Ok(response),
Err(error) => Err(error),
}
}
```
Le parseur distingue les réponses de succès, les erreurs JSON-RPC et les notifications.
## Charger un solde
```rust
async fn load_balance(
client: &kb_onchain_transport::HttpClient,
address: &str,
) -> kb_core::Result<u64> {
let result = client
.get_balance(
address,
kb_onchain_transport::GetBalanceConfig::default(),
)
.await;
match result {
Ok(balance) => Ok(balance.value),
Err(error) => Err(error),
}
}
```
## Adapter une transaction canonique
`GetTransactionAdapter` et `CanonicalTransactionAdapter` convertissent une réponse RPC standard en acquisition canonique sans imposer au pipeline le format brut du fournisseur.
```rust
fn adapt_transaction(
raw: serde_json::Value,
config: &kb_onchain_transport::GetTransactionConfig,
) -> kb_core::Result<kb_onchain_transport::GetTransactionAcquisition> {
let result = kb_onchain_transport::adapt_get_transaction_result(raw, config);
match result {
Ok(acquisition) => Ok(acquisition),
Err(error) => Err(error),
}
}
```
## Exécution RPC
Les types suivants couvrent les opérations dexécution :
- `SimulateTransactionConfig` et `SimulateTransactionResult` ;
- `SendTransactionConfig` et `SendTransactionResult` ;
- `ConfirmTransactionConfig` ;
- `GetLatestBlockhashConfig` ;
- `GetSignatureStatusesConfig`.
La soumission ne remplace pas les contrôles de sécurité, préflights et confirmations opérateur réalisés par les couches supérieures.
## Erreurs et invariants
- les réponses sont validées et adaptées avant exposition aux couches supérieures ;
- les tailles, encodages et listes sont bornés par les contrats de la crate ;
- une erreur RPC distante reste distincte dune erreur de transport ou dadaptation ;
- les endpoints ne doivent pas être supposés interchangeables lorsquils ont des rôles différents.
## Tests de référence
- tests déquivalence des fixtures `getTransaction` ;
- tests legacy, v0, ALT, CPI et Token-2022 dans `tests/fixtures/` ;
- tests de `standard_methods.rs` vérifiant la matrice contractuelle RPC ;
- tests des pools HTTP/WebSocket et du routage par rôle.
## Limites durables
- la crate traite les transports on-chain ; elle ne gère pas les métadonnées HTTP, IPFS ou Arweave ;
- elle ne décode pas les instructions de programmes ;
- elle ne décide pas seule de lautorisation denvoyer une transaction.

View File

@@ -0,0 +1,20 @@
<!-- file: kb-pipeline-demo-scenarios/CHANGELOG.md -->
<!-- version: 1 -->
# CHANGELOG — kb-pipeline-demo-scenarios
## 0.1.0-pre.070
- enrichissement du `USAGE.md` avec plusieurs exemples couvrant les principales familles dAPI publiques ;
- ajout du contrat documentaire de la crate mixte ;
- inventaire des scénarios publics et du binaire CLI ;
- documentation des tests Devnet comme références dexécution réelle ;
- classement des travaux dautonomie CLI, fixtures et Metaplex dans le TODO.
## 0.1.0-pre.062
- extraction des scénarios de démonstration hors du desktop ;
- conservation du nom de bibliothèque `kb_pipeline_demo_scenarios` ;
- création du binaire explicite `kb-pipeline-demo-scenarios-cli` avec `autobins = false` ;
- migration des scénarios System Transfer, Memo v4, ATA, SPL Token et Token-2022 ;
- validation connue de 39 tests de bibliothèque et 1 test de binaire.

View File

@@ -1,16 +1,29 @@
<!-- file: kb-pipeline-demo-scenarios/README.md -->
<!-- version: 1 -->
## Environnement des scénarios
# kb-pipeline-demo-scenarios
Les exécutables et tests opt-in peuvent appeler `initialize_demo_scenario_environment(workspace_root)` avant de lire leurs variables. Cette fonction délègue à `kb-config` et applique la même priorité que l'application desktop. La crate ne dépend pas directement de `dotenvy`.
`kb-pipeline-demo-scenarios` fournit des scénarios opérateur et Devnet réutilisables au-dessus de `kb-pipeline`.
## Préparation de la fixture Token-2022
La crate est mixte :
```bash
cargo run -p kb-pipeline-demo-scenarios --bin kb-pipeline-demo-scenarios-cli -- prepare-token-2022-fixture \
--rpc-url https://api.devnet.solana.com \
--wallet wallets/temporary/local_devnet/local-devnet-operator.json \
--wallet-dir wallets/temporary/local_devnet \
--decimals 9
```
- bibliothèque Rust `kb_pipeline_demo_scenarios` ;
- binaire `kb-pipeline-demo-scenarios-cli`.
La commande crée ou réutilise un mint avec freeze authority, trois comptes Token-2022 distincts et un delegate, puis écrit `spl_token_2022_validation/fixture.env`. Les keypairs sont générés avec `solana-keygen --silent` et ne sont jamais inclus dans la sortie JSON.
## Responsabilités
- préparation de lenvironnement et du profil Devnet ;
- scénarios System Program, Memo v4, ATA, SPL Token et Token-2022 ;
- simulation ou soumission explicitement autorisée ;
- préparation de fixtures publiques ;
- validation des matrices et rapports Token-2022 ;
- progression observable et annulation coopérative.
Elle ne remplace ni le pipeline générique ni lapplication desktop.
## Documentation
- [USAGE.md](USAGE.md)
- [TODO.md](TODO.md)
- [CHANGELOG.md](CHANGELOG.md)
- [Architecture du pipeline](../docs/architecture/PIPELINE_ARCHITECTURE.md)

View File

@@ -0,0 +1,13 @@
<!-- file: kb-pipeline-demo-scenarios/TODO.md -->
<!-- version: 1 -->
# TODO — kb-pipeline-demo-scenarios
- [ ] CLI - rendre chaque scénario public exécutable hors `kb-app-demo-desktop`.
- [ ] CLI - compléter les arguments, sorties structurées et diagnostics du binaire.
- [ ] Fixtures - améliorer la création, réutilisation et validation des fixtures publiques.
- [ ] Metaplex Token Metadata - ajouter les scénarios de démonstration requis pour la future `0.4.7`.
- [ ] Registre ElGamal - ne créer un scénario exécutable quaprès confirmation du déploiement et disponibilité des preuves requises.
- [ ] Tests Devnet - conserver les tests réseau en opt-in et documenter précisément leurs prérequis.
- [ ] Tests Devnet - compléter les validations de bout en bout manquantes sans dépendre de linterface desktop.
- [ ] Documentation - ajouter un guide opérateur des scénarios et de leurs effets réseau.

View File

@@ -0,0 +1,181 @@
<!-- file: kb-pipeline-demo-scenarios/USAGE.md -->
<!-- version: 2 -->
# Utilisation de kb-pipeline-demo-scenarios
## Objectif
La bibliothèque expose des scénarios Devnet contrôlés. Le binaire permet leur exécution hors de lapplication desktop lorsque la commande correspondante est disponible.
## Initialiser lenvironnement
```rust
fn initialize_environment() -> kb_core::Result<()> {
kb_pipeline_demo_scenarios::initialize_demo_scenario_environment()
}
```
`resolve_demo_devnet_profile` sélectionne un profil Devnet configuré et `prepare_demo_devnet_profile_store` vérifie ou initialise son stockage PostgreSQL.
## Observer une exécution
`NoopSolanaExecutionObserver` convient aux appels sans progression personnalisée.
```rust
fn observer() -> kb_pipeline_demo_scenarios::NoopSolanaExecutionObserver {
kb_pipeline_demo_scenarios::NoopSolanaExecutionObserver
}
```
Une application peut implémenter `SolanaExecutionObserver` pour recevoir les événements et demander une annulation coopérative.
## Préparer une simulation System Program
```rust
fn system_transfer_request(
recipient: kb_lib::MdPubkey,
) -> kb_pipeline_demo_scenarios::DevnetSystemTransferRequest {
kb_pipeline_demo_scenarios::DevnetSystemTransferRequest::new(
"system-transfer-001",
recipient,
1_000,
)
}
```
Le constructeur crée une requête conservative : `submit` et `operator_confirmed` restent à `false`.
## Préparer et exécuter un Memo v4
```rust
fn memo_request() -> kb_pipeline_demo_scenarios::DevnetMemoExecutionRequest {
kb_pipeline_demo_scenarios::DevnetMemoExecutionRequest::new(
"memo-001",
"khadhroony-bot3 Devnet validation",
)
}
```
```rust
async fn run_memo<S, O>(
store: &S,
observer: &O,
request: kb_pipeline_demo_scenarios::DevnetMemoExecutionRequest,
) -> kb_core::Result<kb_pipeline_demo_scenarios::DevnetMemoExecutionSummary>
where
S: kb_store::Store + Sync,
O: kb_pipeline_demo_scenarios::SolanaExecutionObserver,
{
let result = kb_pipeline_demo_scenarios::execute_devnet_memo(
store,
observer,
request,
)
.await;
match result {
Ok(summary) => Ok(summary),
Err(error) => Err(error),
}
}
```
## Simuler Token-2022
```rust
async fn simulate_token_2022<O>(
request: kb_pipeline_demo_scenarios::DevnetSplToken2022ExecutionRequest,
observer: &O,
) -> kb_core::Result<kb_pipeline_demo_scenarios::DevnetSplToken2022ExecutionSummary>
where
O: kb_pipeline_demo_scenarios::SolanaExecutionObserver,
{
let result =
kb_pipeline_demo_scenarios::simulate_devnet_spl_token_2022(request, observer).await;
match result {
Ok(summary) => Ok(summary),
Err(error) => Err(error),
}
}
```
## Charger la matrice de validation Token-2022
```rust
fn load_validation_matrix(
) -> kb_core::Result<kb_pipeline_demo_scenarios::Token2022ValidationMatrix> {
let result = kb_pipeline_demo_scenarios::load_token_2022_validation_matrix();
match result {
Ok(matrix) => Ok(matrix),
Err(error) => Err(error),
}
}
```
La matrice provient de `test-fixtures/contract-matrices/SPL_TOKEN_2022_VALIDATION_MATRIX.json` et est validée avant dêtre retournée.
## Parcourir les scénarios publics
```rust
fn scenario_ids() -> Vec<String> {
kb_pipeline_demo_scenarios::devnet_spl_validation_scenarios()
.iter()
.map(|scenario| scenario.id.clone())
.collect()
}
```
Cette liste permet au CLI ou au desktop de présenter linventaire sans dupliquer les identifiants.
## Préparer une fixture Token-2022
```rust
async fn prepare_fixture(
wallet_path: std::path::PathBuf,
wallet_dir: std::path::PathBuf,
) -> kb_core::Result<kb_pipeline_demo_scenarios::Token2022FixturePreparationSummary> {
let options = kb_pipeline_demo_scenarios::Token2022FixturePreparationOptions {
rpc_url: "https://api.devnet.solana.com".to_string(),
wallet_path,
wallet_dir,
decimals: 9,
};
let result = kb_pipeline_demo_scenarios::prepare_token_2022_fixture(&options).await;
match result {
Ok(summary) => Ok(summary),
Err(error) => Err(error),
}
}
```
La préparation peut créer des comptes et exécuter des commandes Solana CLI. Elle doit rester explicitement déclenchée par lopérateur.
## Tests de référence
Les tests de cette crate sont particulièrement utiles pour comprendre lorchestration réelle :
- validation de la matrice Token-2022 ;
- préparation et réutilisation des fixtures ;
- simulation et exécution des scénarios ;
- hydratation canonique, extraction Core, replay et matérialisation ;
- idempotence et confirmation des états finaux ;
- test du binaire `kb-pipeline-demo-scenarios-cli`.
Les tests Devnet restent opt-in et peuvent produire des transactions réelles lorsque la soumission est explicitement activée.
## Erreurs et invariants
- aucun envoi ne doit résulter dune simple demande de simulation ;
- le profil doit cibler Devnet pour les scénarios Devnet ;
- les secrets restent gérés par `kb-wallet` ;
- les résumés ne doivent pas déclarer une validation non observée ;
- ElGamal ne doit pas être présenté comme validé sur réseau.
## Limites durables
- cette crate est destinée aux démonstrations, validations et outils opérateur, pas au moteur de production autonome ;
- les scénarios réseau exigent un endpoint, un wallet et des fonds compatibles ;
- la bibliothèque ne fournit pas dinterface graphique.

20
kb-pipeline/CHANGELOG.md Normal file
View File

@@ -0,0 +1,20 @@
<!-- file: kb-pipeline/CHANGELOG.md -->
<!-- version: 1 -->
# CHANGELOG — kb-pipeline
## 0.1.0-pre.070
- enrichissement du `USAGE.md` avec plusieurs exemples couvrant les principales familles dAPI publiques ;
- ajout du contrat documentaire de la crate ;
- classement des APIs publiques par campagnes, replay et inspections stateful ;
- clarification des invariants de déterminisme, bornage et matérialisation ;
- inscription des travaux Metaplex et ElGamal restants dans le TODO.
## 0.1.0-pre.062
- migration du pipeline bot2 dans larchitecture consolidée bot3 ;
- reprise du backfill, de lextraction Core, du decode replay et des matérialisations ;
- migration des préflights, corrélations et orchestrations Token-2022 ;
- migration des contrats stateful SPL Token, ATA et registre ElGamal ;
- adaptation aux normes Rust 2024 et Khadhroony bot3.

36
kb-pipeline/README.md Normal file
View File

@@ -0,0 +1,36 @@
<!-- file: kb-pipeline/README.md -->
<!-- version: 1 -->
# kb-pipeline
`kb-pipeline` orchestre les traitements on-chain de `khadhroony-bot3`.
## Responsabilités
- backfill HTTP borné ;
- extraction des transactions canoniques vers le modèle Core ;
- replay contextualisé des décodeurs ;
- matérialisation optionnelle et idempotente ;
- préflights et inspections stateful ;
- orchestration Token-2022, preuves et postconditions ;
- corrélation entre instructions observées et états finaux.
La crate coordonne `kb-onchain-transport`, `kb-store`, `kb-lib`, `kb-core` et `kb-program-ids`. Elle ne contient pas linterface desktop ni les scénarios opérateur de démonstration.
## Familles publiques
- backfill ;
- extraction Core ;
- decode replay ;
- inspections stateful Solana Core, SPL Token, ATA, Token-2022 et registre ElGamal ;
- préflight cryptographique et orchestration dexécution Token-2022.
Voir [USAGE.md](USAGE.md) pour les contrats publics.
## Documentation
- [USAGE.md](USAGE.md)
- [TODO.md](TODO.md)
- [CHANGELOG.md](CHANGELOG.md)
- [Architecture du pipeline](../docs/architecture/PIPELINE_ARCHITECTURE.md)
- [Architecture du stockage](../docs/architecture/STORAGE_ARCHITECTURE.md)

12
kb-pipeline/TODO.md Normal file
View File

@@ -0,0 +1,12 @@
<!-- file: kb-pipeline/TODO.md -->
<!-- version: 1 -->
# TODO — kb-pipeline
- [ ] Metaplex Token Metadata - intégrer la matérialisation migrée et les étapes restantes au replay bot3.
- [ ] Metaplex Token Metadata - ajouter lorchestration nécessaire à lexécuteur et aux validations de la future `0.4.7`.
- [ ] Registre ElGamal - confirmer lexistence et le déploiement du programme avant toute campagne réseau.
- [ ] Registre ElGamal - compléter uniquement les couches pipeline justifiées par un scénario réellement exécutable.
- [ ] Tests - ajouter les tests ciblés correspondant aux écarts identifiés par laudit dalignement `0.4.6`.
- [ ] Documentation - compléter le guide de replay, extraction Core et matérialisation à partir des contrats bot3.
- [ ] Dette technique - vérifier les duplications résiduelles entre les orchestrations SPL Token classique et Token-2022.

180
kb-pipeline/USAGE.md Normal file
View File

@@ -0,0 +1,180 @@
<!-- file: kb-pipeline/USAGE.md -->
<!-- version: 2 -->
# Utilisation de kb-pipeline
## Objectif
La crate expose les campagnes bornées dacquisition, dextraction, de replay et les inspections stateful nécessaires aux applications et scénarios.
## Valider une requête dextraction Core
```rust
fn validate_pending_extraction() -> kb_core::Result<()> {
let request = kb_pipeline::CoreExtractionRequest {
source: kb_pipeline::CoreExtractionSource::Pending,
limit: 1_000,
max_concurrent_extractions: 4,
force_replay: false,
};
request.validate()
}
```
Une extraction ciblée peut utiliser `CoreExtractionSource::Signatures`, `SlotRange` ou `ProgramId`.
## Exécuter une campagne dextraction Core
```rust
async fn run_core_extraction<S, O>(
store: &S,
observer: &O,
request: kb_pipeline::CoreExtractionRequest,
) -> kb_core::Result<kb_pipeline::CoreExtractionSummary>
where
S: kb_store::CanonicalTransactionStore
+ kb_store::CoreExtractionStore
+ Sync,
O: kb_pipeline::CoreExtractionObserver,
{
let result = kb_pipeline::execute_core_extraction(store, observer, request).await;
match result {
Ok(summary) => Ok(summary),
Err(error) => Err(error),
}
}
```
## Préparer une requête de decode replay
```rust
fn validate_decode_request(
selection: kb_store::DecodeSelectionFilter,
) -> kb_core::Result<()> {
let request = kb_pipeline::DecodeReplayRequest {
campaign_id: "manual-replay-001".to_string(),
selection,
decoder_names: Vec::new(),
dispatch_policy: kb_pipeline::DecodeDispatchPolicy::HighestPriority,
max_concurrent_inputs: 4,
force_replay: false,
force_replay_all_matching: false,
materialize_after_decode: true,
};
request.validate()
}
```
Une liste vide dans `decoder_names` signifie que tous les décodeurs fournis à lorchestrateur restent éligibles.
## Exécuter un decode replay
```rust
async fn run_decode_replay<S, O>(
store: &S,
observer: &O,
request: kb_pipeline::DecodeReplayRequest,
decoders: &[&dyn kb_lib::MdApiInstructionDecoder],
materializers: &[&dyn kb_lib::MdApiEventMaterializer],
) -> kb_core::Result<kb_pipeline::DecodeReplaySummary>
where
S: kb_store::DecodeReplayStore + Sync,
O: kb_pipeline::DecodeReplayObserver,
{
let result = kb_pipeline::execute_decode_replay(
store,
observer,
request,
decoders,
materializers,
)
.await;
match result {
Ok(summary) => Ok(summary),
Err(error) => Err(error),
}
}
```
## Backfill HTTP
La surface principale utilise `BackfillRequest`, `BackfillObserver`, `execute_http_backfill` et `BackfillSummary`.
```rust
async fn run_backfill<S, O>(
store: &S,
observer: &O,
request: kb_pipeline::BackfillRequest,
) -> kb_core::Result<kb_pipeline::BackfillSummary>
where
S: kb_store::CanonicalTransactionStore + Sync,
O: kb_pipeline::BackfillObserver,
{
let result = kb_pipeline::execute_http_backfill(store, observer, request).await;
match result {
Ok(summary) => Ok(summary),
Err(error) => Err(error),
}
}
```
## Inspections stateful
Les familles publiques comprennent :
- `inspect_solana_core_stateful_readiness` ;
- inspections SPL Token et ATA ;
- inspections et corrélations Token-2022 ;
- préflight cryptographique Token-2022 ;
- lecture et matérialisation stateful du registre ElGamal.
```rust
async fn inspect_classic_token<S>(
store: &S,
request: kb_pipeline::SplTokenStatefulReadinessRequest,
) -> kb_core::Result<kb_pipeline::SplTokenStatefulReadinessReport>
where
S: kb_store::CanonicalTransactionStore + Sync,
{
let result = kb_pipeline::inspect_spl_token_stateful_readiness(store, request).await;
match result {
Ok(report) => Ok(report),
Err(error) => Err(error),
}
}
```
Les rapports stateful ne constituent jamais une autorisation implicite dexécution.
## Observateurs
Les campagnes longues exposent des traits dobservation distincts pour le backfill, lextraction Core et le replay. Lobservateur peut publier la progression et participer à lannulation coopérative selon le contrat concerné.
## Erreurs et invariants
- toutes les campagnes sont bornées ;
- la progression persistée ne doit avancer quaprès traitement cohérent ;
- le replay doit rester déterministe pour une même entrée et une même version de pipeline ;
- une matérialisation ne doit pas inventer un état confirmé ;
- les erreurs de transport, stockage, décodage et préflight restent distinguées.
## Tests de référence
- tests de frontière contiguë et reprise du backfill ;
- tests dextraction Core et didempotence ;
- tests de decode replay, dispatch et matérialisation ;
- tests stateful SPL Token, ATA et Token-2022 ;
- tests de preuves, préflight cryptographique et postconditions ;
- tests du registre ElGamal fail-closed.
## Limites durables
- la crate orchestre les traitements mais ne fournit pas dinterface opérateur ;
- elle ne conserve pas de secret de wallet ;
- elle ne remplace pas les scénarios Devnet et validations explicites de `kb-pipeline-demo-scenarios`.

View File

@@ -1,8 +1,12 @@
<!-- file: kb-store/CHANGELOG.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# CHANGELOG — kb-store
## 0.1.0-pre.070
- enrichissement de `USAGE.md` avec plusieurs exemples couvrant les familles dAPI publiques significatives.
## 0.1.0-pre.069
### Documentation

View File

@@ -1,5 +1,5 @@
<!-- file: kb-store/USAGE.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Utilisation de kb-store
@@ -8,23 +8,23 @@
```rust
let options = match kb_store::PostgresStoreOptions::new(
database_url,
"public".to_string(),
10,
std::time::Duration::from_secs(10),
10_000,
true,
) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("postgres endpoint: {}", options.masked_dsn());
let store = match kb_store::PostgresStore::connect(options).await {
Ok(value) => value,
Err(error) => return Err(error),
};
if let Err(error) = store.initialize_store_schema().await {
return Err(error);
}
```
`PostgresStoreOptions::new` valide le DSN, le schéma, le nombre de connexions et le timeout. Utiliser `masked_dsn` ou `mask_postgres_dsn` dans les logs ; ne jamais journaliser le DSN brut.
`PostgresStoreOptions::new` valide le DSN, le nombre de connexions et le timeout. Lorsque `auto_initialize_schema` vaut `true`, la connexion applique les schémas idempotents. Utiliser `masked_dsn` ou `mask_postgres_dsn` dans les logs ; ne jamais journaliser le DSN brut.
## Diagnostics
@@ -32,10 +32,44 @@ if let Err(error) = store.initialize_store_schema().await {
let health = store.health_snapshot().await;
let migrations = store.migration_snapshot().await;
let backend = store.backend_diagnostics().await;
println!("health={:?}", health.status);
println!("migration={:?}", migrations.status);
println!("backend={:?}", backend.descriptor.backend);
```
Les diagnostics de tables raw, Core et decode/materialization sont également disponibles par les méthodes `*_table_diagnostics`.
```rust
let raw_tables = match store.raw_table_diagnostics().await {
Ok(value) => value,
Err(error) => return Err(error),
};
for table in raw_tables {
println!(
"table={} domain={} exists={}",
table.table_name,
table.domain,
table.exists
);
}
```
## Pagination bornée
```rust
let first_page = kb_store::PageRequest::first_page();
let next_page = match kb_store::PageRequest::new(250, 250) {
Ok(value) => value,
Err(error) => return Err(error),
};
assert_eq!(first_page.limit, kb_store::DEFAULT_PAGE_SIZE);
assert!(next_page.limit <= kb_store::MAX_PAGE_SIZE);
```
## Contrats de repositories
Les traits publics principaux sont :
@@ -55,9 +89,32 @@ Ils permettent au pipeline de dépendre dun contrat async plutôt que dune
## Replay et requêtes bornées
```rust
let candidates = store.replay_transaction_candidates(filter).await;
let programs = store.replay_program_summaries(program_filter).await;
let entities = store.replay_entity_summaries(entity_filter).await;
let candidates = match store.replay_transaction_candidates(filter).await {
Ok(value) => value,
Err(error) => return Err(error),
};
for candidate in candidates {
println!(
"signature={} slot={}",
candidate.signature,
candidate.slot
);
}
```
```rust
let programs = match store.replay_program_summaries(program_filter).await {
Ok(value) => value,
Err(error) => return Err(error),
};
let entities = match store.replay_entity_summaries(entity_filter).await {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("programs={}, entities={}", programs.len(), entities.len());
```
Les filtres refusent les limites nulles ou supérieures aux bornes publiques. `PageRequest` impose également `DEFAULT_PAGE_SIZE` et `MAX_PAGE_SIZE`.
@@ -66,6 +123,24 @@ Les filtres refusent les limites nulles ou supérieures aux bornes publiques. `P
Les bundles `CoreExtractionBundle`, `DecodePersistenceBundle` et `MaterializationPersistenceBundle` regroupent les écritures qui doivent réussir ou être annulées ensemble. Les consommateurs ne doivent pas reproduire manuellement ces transactions avec des écritures isolées.
## Validation des noms de tables
```rust
if let Err(error) = kb_store::validate_raw_store_table_names() {
return Err(error);
}
if let Err(error) = kb_store::validate_core_store_table_names() {
return Err(error);
}
if let Err(error) = kb_store::validate_decode_store_table_names() {
return Err(error);
}
assert!(kb_store::is_valid_solana_table_name(
kb_store::CORE_TRANSACTIONS_TABLE_NAME
));
```
## Schéma et tables
Les constantes `RAW_STORE_TABLE_NAMES`, `CORE_STORE_TABLE_NAMES` et `DECODE_STORE_TABLE_NAMES` exposent les noms canoniques. Les fonctions `validate_*_table_names` et `is_valid_solana_table_name` servent aux audits et outils dadministration.