328 lines
10 KiB
Markdown
328 lines
10 KiB
Markdown
<!-- file: kb-app-demo-desktop/USAGE.md -->
|
||
<!-- version: 10 -->
|
||
|
||
# Utilisation de kb-app-demo-desktop
|
||
|
||
## Objectif
|
||
|
||
L’application expose une interface opérateur pour diagnostiquer, simuler et valider les couches de bot3.
|
||
|
||
## Lancer le desktop
|
||
|
||
Depuis la racine du workspace :
|
||
|
||
```bash
|
||
cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json
|
||
```
|
||
|
||
Le binaire applique un verrou d’instance locale. Une deuxième instance doit échouer proprement.
|
||
|
||
## API Rust publique
|
||
|
||
La bibliothèque expose uniquement `run()` :
|
||
|
||
```rust
|
||
fn launch_desktop() -> kb_core::Result<()> {
|
||
return kb_app_demo_desktop_lib::run();
|
||
}
|
||
```
|
||
|
||
Le binaire `kb-app-demo-desktop` appelle cette fonction et convertit son résultat en `ExitCode`.
|
||
|
||
## Fenêtres initiales
|
||
|
||
La configuration Tauri crée :
|
||
|
||
- `splash` ;
|
||
- `main`.
|
||
|
||
Les autres fenêtres sont ouvertes par les commandes Tauri dédiées :
|
||
|
||
- backfill ;
|
||
- HTTP ;
|
||
- WebSocket ;
|
||
- diagnostics SQL ;
|
||
- candidats replay ;
|
||
- configuration ;
|
||
- extraction Core ;
|
||
- decode replay ;
|
||
- exécution Solana Core ;
|
||
- exécution SPL.
|
||
|
||
## Interface Tauri publique
|
||
|
||
Les commandes Tauri constituent l’interface applicative frontend/backend. Elles ne sont pas des APIs Rust publiques pour les autres crates.
|
||
|
||
### Ouvrir une fenêtre
|
||
|
||
```typescript
|
||
import { invoke } from "@tauri-apps/api/core";
|
||
|
||
await invoke("open_demo_http_window");
|
||
await invoke("open_demo_ws_window");
|
||
await invoke("open_demo_decode_replay_window");
|
||
```
|
||
|
||
### Charger les options HTTP
|
||
|
||
```typescript
|
||
const options = await invoke("demo_http_options");
|
||
console.log(options);
|
||
```
|
||
|
||
### Exécuter une requête HTTP de démonstration
|
||
|
||
```typescript
|
||
const result = await invoke(
|
||
"demo_http_execute_request",
|
||
{
|
||
request: {
|
||
role: "standard",
|
||
method: "getHealth",
|
||
paramsJson: "[]"
|
||
}
|
||
}
|
||
);
|
||
|
||
console.log(result);
|
||
```
|
||
|
||
Les champs exacts du payload doivent rester synchronisés avec les types TS-RS générés.
|
||
|
||
### Gérer une session WebSocket
|
||
|
||
```typescript
|
||
const status = await invoke("demo_ws_status");
|
||
console.log(status);
|
||
|
||
await invoke("demo_ws_connect", {
|
||
request: {
|
||
role: "standard",
|
||
method: "logsSubscribe",
|
||
paramsJson: "[]"
|
||
}
|
||
});
|
||
|
||
await invoke("demo_ws_unsubscribe");
|
||
await invoke("demo_ws_disconnect");
|
||
```
|
||
|
||
La fermeture de la fenêtre ne doit pas être assimilée à une demande de déconnexion.
|
||
|
||
### Lancer un backfill
|
||
|
||
```typescript
|
||
const options = await invoke("demo_backfill_options");
|
||
console.log(options);
|
||
|
||
const summary = await invoke(
|
||
"demo_backfill_execute",
|
||
{
|
||
request: {
|
||
profileName: "devnet",
|
||
address: "11111111111111111111111111111111",
|
||
limit: 100
|
||
}
|
||
}
|
||
);
|
||
|
||
console.log(summary);
|
||
```
|
||
|
||
### Extraction Core
|
||
|
||
```typescript
|
||
const options = await invoke(
|
||
"demo_core_extraction_options"
|
||
);
|
||
|
||
const summary = await invoke(
|
||
"demo_core_extraction_execute",
|
||
{
|
||
request: {
|
||
profileName: "devnet",
|
||
limit: 1000
|
||
}
|
||
}
|
||
);
|
||
|
||
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
|
||
const options = await invoke(
|
||
"demo_decode_replay_options"
|
||
);
|
||
|
||
const summary = await invoke(
|
||
"demo_decode_replay_execute",
|
||
{
|
||
request: {
|
||
profileName: "devnet",
|
||
limit: 1000,
|
||
materialize: true
|
||
}
|
||
}
|
||
);
|
||
|
||
console.log(options, summary);
|
||
```
|
||
|
||
Les diagnostics et annotations sont accessibles par des commandes séparées.
|
||
|
||
### Scénarios Devnet
|
||
|
||
Les commandes couvrent notamment :
|
||
|
||
- `demo_execution_solana_core_execute` ;
|
||
- `demo_execution_spl_memo_execute` ;
|
||
- `demo_execution_spl_token_execute` ;
|
||
- `demo_execution_spl_ata_execute` ;
|
||
- `demo_execution_spl_token_2022_execute`.
|
||
|
||
```typescript
|
||
const scenarios = await invoke(
|
||
"demo_execution_spl_validation_scenarios"
|
||
);
|
||
|
||
console.log(scenarios);
|
||
```
|
||
|
||
La simulation et l’envoi doivent rester explicitement distingués dans les requêtes.
|
||
|
||
### Exécution Metadata Devnet
|
||
|
||
Le backend distingue le module commun Metadata, Metaplex Token Metadata et Solana Program Metadata.
|
||
|
||
Le panneau Metadata charge les opérations courantes depuis `demo_execution_metadata_metaplex_token_metadata_current_operations` et peut demander un modèle avec `demo_execution_metadata_metaplex_token_metadata_operation_template`.
|
||
|
||
```typescript
|
||
const operationJson = await invoke(
|
||
"demo_execution_metadata_metaplex_token_metadata_operation_template",
|
||
{ operation: "verify" }
|
||
);
|
||
|
||
const summary = await invoke(
|
||
"demo_execution_metadata_metaplex_token_metadata_execute",
|
||
{
|
||
request: {
|
||
profileName: "devnet",
|
||
intentId: `desktop-metaplex-${Date.now()}`,
|
||
operationJson,
|
||
preflightReadsJson: "[]",
|
||
postconditionReadsJson: "[]",
|
||
submit: false,
|
||
operatorConfirmed: false
|
||
}
|
||
}
|
||
);
|
||
|
||
console.log(summary);
|
||
```
|
||
|
||
Les valeurs `<...>` d’un modèle doivent être remplacées par des comptes réels avant exécution. `submit: true` exige simultanément `operatorConfirmed: true`. Le résultat distingue le plan, le préflight stateful, la simulation RPC, la signature éventuelle, la confirmation et les états avant/après. Après soumission confirmée, `evidenceJson` contient également l’hydratation canonique, l’extraction Core, le replay, la seconde passe d’idempotence, les matérialisations instructionnelles et le diagnostic post-exécution.
|
||
|
||
### Diagnostics PostgreSQL
|
||
|
||
```typescript
|
||
const diagnostics = await invoke(
|
||
"load_demo_sql_diag"
|
||
);
|
||
const rawTables = await invoke(
|
||
"load_demo_sql_pg_raw"
|
||
);
|
||
const coreTables = await invoke(
|
||
"load_demo_sql_pg_core"
|
||
);
|
||
|
||
console.log(diagnostics, rawTables, coreTables);
|
||
```
|
||
|
||
## Capabilities Tauri
|
||
|
||
Les fenêtres autorisées sont listées dans `capabilities/default.json`. La capability active doit inclure au minimum les permissions Tauri Core et tracing nécessaires aux fenêtres déclarées.
|
||
|
||
Toute nouvelle fenêtre ou commande sensible doit être auditée avant ajout de permissions.
|
||
|
||
## Erreurs et invariants
|
||
|
||
- une simulation ne doit jamais envoyer une transaction ;
|
||
- une soumission nécessite une confirmation opérateur explicite ;
|
||
- les secrets de wallet ne doivent jamais être sérialisés vers le frontend ;
|
||
- les résultats frontend doivent refléter les validations réellement exécutées ;
|
||
- l’état WebSocket appartient à l’application, pas à la durée de vie de la fenêtre ;
|
||
- les commandes Tauri adaptent les APIs réutilisables sans dupliquer leur logique.
|
||
|
||
## Tests de référence
|
||
|
||
- tests des options et payloads HTTP ;
|
||
- tests de cycle de vie WebSocket ;
|
||
- tests de sélection de profil Devnet ;
|
||
- tests de System Transfer et Memo ;
|
||
- tests ATA, SPL Token et Token-2022 ;
|
||
- tests de backfill, extraction Core et decode replay ;
|
||
- tests de diagnostics SQL et exports CSV ;
|
||
- tests de journalisation frontend ;
|
||
- test du verrou d’état applicatif et de la séquence splash.
|
||
|
||
Le nombre de tests évolue avec les surfaces raccordées ; la référence de validation est la dernière exécution réussie de `cargo test -p kb-app-demo-desktop`.
|
||
|
||
## Limites durables
|
||
|
||
- le desktop est une application de démonstration et validation, pas le worker de production ;
|
||
- les payloads Tauri sont une API applicative spécifique au frontend ;
|
||
- l’application nécessite un environnement graphique pour sa validation complète.
|
||
|
||
## Panneau Exécution Metadata
|
||
|
||
Depuis la fenêtre principale, choisir **Exécution Devnet → Exécution Metadata**. Le panneau permet actuellement :
|
||
|
||
- de choisir un scénario synthétique ou un contrat de campagne Devnet ;
|
||
- de sélectionner le profil Devnet ;
|
||
- de préparer et vérifier la base PostgreSQL du profil ;
|
||
- d’afficher les contrats, contrôles de préflight et preuves attendues dans le JSON viewer commun ;
|
||
- de restaurer le scénario sélectionné lors de la réouverture.
|
||
|
||
Un contrat marqué Devnet n’est pas, à lui seul, une exécution réseau. Les champs `networkExecutionPerformed` et `networkEvidenceCollected` doivent rester faux tant qu’aucun appel RPC réel et aucune preuve correspondante n’ont été produits.
|
||
|
||
Le panneau distingue préparation de l’étape, simulation exacte et soumission explicitement confirmée. Les lectures de postcondition et la matérialisation sont dérivées du scénario préparé.
|
||
|
||
### Préparation de la fixture Metaplex `Create`
|
||
|
||
Le panneau desktop peut créer ou réutiliser un mint SPL classique Devnet à zéro décimale. Le préparateur dérive ensuite automatiquement les PDA `metadata` et `master edition` et génère un intent `Create` typé. Les valeurs entre chevrons des modèles génériques restent des placeholders non exécutables.
|
||
|
||
### Campagne Solana Program Metadata
|
||
|
||
Ouvrir l’accordéon **Solana Program Metadata**, sélectionner un profil Devnet persistant et préparer sa base. L’inventaire affiche deux parcours totalisant neuf opérations :
|
||
|
||
```text
|
||
Buffer : Allocate → Extend → Write → SetAuthority → Trim → Close
|
||
Metadata : Initialize → SetData → SetImmutable
|
||
```
|
||
|
||
Après confirmation explicite, le bouton **Exécuter la campagne complète** appelle le runner réutilisable. Celui-ci réalise deux transferts de préfinancement, puis les neuf simulations et soumissions dans l’ordre. Le panneau affiche :
|
||
|
||
- la fixture et les opérations préparées ;
|
||
- les signatures de préfinancement et les PDA frais ;
|
||
- les neuf simulations et confirmations ;
|
||
- les lectures stateful avant/après ;
|
||
- les rapports de postcondition ;
|
||
- les snapshots matérialisés, sauf pour `Close` qui exige l’absence du compte.
|
||
|
||
La campagne s’arrête au premier échec. Elle ne reprend pas un parcours partiellement exécuté et ne réutilise pas les PDA d’une campagne précédente.
|