340 lines
12 KiB
Markdown
340 lines
12 KiB
Markdown
<!-- file: kb-pipeline-demo-scenarios/USAGE.md -->
|
||
<!-- version: 9 -->
|
||
|
||
# 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 l’application desktop lorsque la commande correspondante est disponible.
|
||
|
||
## Initialiser l’environnement
|
||
|
||
```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 l’inventaire 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 l’opérateur.
|
||
|
||
## Tests de référence
|
||
|
||
Les tests de cette crate sont particulièrement utiles pour comprendre l’orchestration 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 d’une 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 d’interface graphique.
|
||
|
||
|
||
## Charger les scénarios synthétiques Metaplex
|
||
|
||
```rust
|
||
fn metaplex_scenario_ids() -> Vec<String> {
|
||
kb_pipeline_demo_scenarios::metaplex_token_metadata_synthetic_scenarios()
|
||
.iter()
|
||
.map(|scenario| scenario.id.clone())
|
||
.collect()
|
||
}
|
||
```
|
||
|
||
L’inventaire couvre NFT, SFT, token fongible, collection et pNFT. Ces scénarios sont déterministes et ne soumettent aucune transaction.
|
||
|
||
## Charger la matrice de validation Metaplex
|
||
|
||
```rust
|
||
fn load_metaplex_matrix(
|
||
) -> kb_core::Result<kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationMatrix> {
|
||
let result = kb_pipeline_demo_scenarios::load_metaplex_token_metadata_validation_matrix();
|
||
|
||
match result {
|
||
Ok(matrix) => Ok(matrix),
|
||
Err(error) => Err(error),
|
||
}
|
||
}
|
||
```
|
||
|
||
Une validation réseau ne peut passer à `confirmed` que lorsque toutes les preuves déclarées sont présentes. Les statuts `not_run` et `unavailable` n’acceptent aucune preuve observée.
|
||
|
||
## Inventaire Metaplex Devnet
|
||
|
||
```rust
|
||
let scenarios = kb_pipeline_demo_scenarios::metaplex_token_metadata_devnet_scenarios();
|
||
assert!(scenarios.iter().all(|scenario| {
|
||
scenario.mode == kb_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode::NetworkSimulation
|
||
}));
|
||
```
|
||
|
||
Cet inventaire prépare les tests et campagnes Devnet simulation-first. Il ne constitue pas à lui seul une validation réseau réussie.
|
||
|
||
## Charger le corpus de validation croisée Metaplex
|
||
|
||
```rust
|
||
fn load_metaplex_cross_validation() -> kb_core::Result<usize> {
|
||
let matrix = kb_pipeline_demo_scenarios::load_metaplex_token_metadata_cross_validation_matrix();
|
||
return match matrix {
|
||
Ok(value) => Ok(value.cases.len()),
|
||
Err(error) => Err(error),
|
||
};
|
||
}
|
||
```
|
||
|
||
Les cas marqués `requiresNetworkEvidence` ne peuvent pas être déclarés validés à partir de preuves synthétiques. Une simulation, une soumission ou une confirmation exige les preuves RPC déclarées par le cas.
|
||
|
||
|
||
## Simuler une opération Metaplex réelle sur Devnet
|
||
|
||
L’API réseau prend un intent Metaplex typé déjà lié aux comptes et autorités de la fixture. Le wallet persistant du profil doit être l’unique signer requis.
|
||
|
||
```rust
|
||
async fn simulate_metaplex_operation<O>(
|
||
pool: &kb_onchain_transport::HttpEndpointPool,
|
||
profile: &kb_config::ProfileConfig,
|
||
workspace_root: &std::path::Path,
|
||
operation: kb_lib::ExMetaplexTokenMetadataOperation,
|
||
observer: &O,
|
||
) -> kb_core::Result<kb_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionSummary>
|
||
where
|
||
O: kb_pipeline_demo_scenarios::SolanaExecutionObserver,
|
||
{
|
||
let request = kb_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionRequest::new(
|
||
"metaplex-devnet-simulation",
|
||
operation,
|
||
);
|
||
return kb_pipeline_demo_scenarios::simulate_devnet_metaplex_token_metadata(
|
||
pool,
|
||
profile,
|
||
workspace_root,
|
||
&request,
|
||
observer,
|
||
)
|
||
.await;
|
||
}
|
||
```
|
||
|
||
Pour une soumission, l’appelant doit définir `submit = true` et `operator_confirmed = true`. Les opérations dépréciées sont refusées par cette API automatique. Les lectures `preflight_reads` et `postcondition_reads` doivent décrire les comptes Metadata, Edition, Token Record ou Collection nécessaires au scénario.
|
||
|
||
## Charger la matrice des opérations courantes
|
||
|
||
```rust
|
||
fn load_metaplex_devnet_contract(
|
||
) -> kb_core::Result<kb_pipeline_demo_scenarios::MetaplexTokenMetadataDevnetExecutionMatrix> {
|
||
return kb_pipeline_demo_scenarios::load_metaplex_token_metadata_devnet_execution_matrix();
|
||
}
|
||
```
|
||
|
||
La matrice ne transforme jamais une implémentation disponible en validation réseau. Les valeurs restent `not_run` jusqu’à l’observation d’une simulation ou d’une confirmation réelle.
|
||
## Exécuter une opération Metaplex courante depuis un JSON typé
|
||
|
||
Le runner Devnet commun accepte toute variante non dépréciée de `ExMetaplexTokenMetadataOperation`. Le test opt-in peut être lancé avec :
|
||
|
||
```bash
|
||
KB_DEVNET_METAPLEX_EXECUTION_TEST=1 \
|
||
KB_DEVNET_METAPLEX_OPERATION_JSON='{"operation":"..."}' \
|
||
cargo test -p kb-pipeline-demo-scenarios optional_devnet_current_operation_from_env -- --nocapture
|
||
```
|
||
|
||
Variables optionnelles :
|
||
|
||
- `KB_DEVNET_WALLET_DIR` pour sélectionner le répertoire du wallet persistant ;
|
||
- `KB_DEVNET_METAPLEX_PREFLIGHT_READS_JSON` pour fournir les lectures stateful avant simulation ;
|
||
- `KB_DEVNET_METAPLEX_POSTCONDITION_READS_JSON` pour fournir les lectures après confirmation ;
|
||
- `KB_DEVNET_METAPLEX_SUBMIT=1` pour autoriser la soumission ;
|
||
- `KB_DEVNET_METAPLEX_OPERATOR_CONFIRMED=1` pour confirmer explicitement la soumission.
|
||
|
||
La soumission reste impossible si les deux dernières variables ne sont pas activées. Les opérations dépréciées sont rejetées avant tout appel RPC.
|
||
|
||
## Préparer une campagne Metaplex courante
|
||
|
||
Les exemples contenant `...` ne sont jamais exécutables. Pour connaître les opérations acceptées :
|
||
|
||
```rust
|
||
let operations =
|
||
kb_pipeline_demo_scenarios::metaplex_token_metadata_current_operation_names();
|
||
```
|
||
|
||
Les opérations disposant d’un modèle générique peuvent être inspectées ainsi :
|
||
|
||
```rust
|
||
fn verify_template() -> kb_core::Result<String> {
|
||
kb_pipeline_demo_scenarios::metaplex_token_metadata_current_operation_json_template(
|
||
"verify",
|
||
)
|
||
}
|
||
```
|
||
|
||
Les valeurs entre chevrons doivent être remplacées par les comptes Devnet réels. Le modèle peut ensuite être passé à `DevnetMetaplexTokenMetadataExecutionRequest::from_operation_json`.
|
||
|
||
Pour les parcours créateur, il est préférable de ne pas écrire de JSON manuellement :
|
||
|
||
```rust
|
||
fn creator_verify_request(
|
||
authority: kb_lib::MdPubkey,
|
||
metadata: kb_lib::MdPubkey,
|
||
) -> kb_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionRequest {
|
||
kb_pipeline_demo_scenarios::devnet_metaplex_creator_verify_request(
|
||
"metaplex-verify-creator",
|
||
authority,
|
||
metadata,
|
||
)
|
||
}
|
||
```
|
||
|
||
`devnet_metaplex_creator_unverify_request` fournit le parcours inverse. Les deux requêtes restent en simulation-only par défaut.
|
||
|
||
Le test générique accepte toujours `KB_DEVNET_METAPLEX_OPERATION_JSON`, mais rejette explicitement le placeholder documentaire `...`. Les opérations plus complexes recevront des préparateurs de fixtures dédiés au lieu d’exiger de longs JSON écrits à la main.
|