354 lines
12 KiB
Markdown
354 lines
12 KiB
Markdown
<!-- file: kb-app-demo-desktop/USAGE.md -->
|
||
<!-- version: 14 -->
|
||
|
||
# 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.
|
||
|
||
## Construire la release desktop
|
||
|
||
Depuis la racine du workspace :
|
||
|
||
```bash
|
||
cargo tauri build -c kb-app-demo-desktop/tauri.conf.json
|
||
```
|
||
|
||
Ne pas lancer `npm run build` directement. Tauri exécute le `beforeBuildCommand` configuré, puis consomme le même répertoire `dist` que Vite. Les commandes npm manuelles sont réservées à l’installation explicite de dépendances nécessaires.
|
||
|
||
## 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, Token-2022 Token Metadata et Solana Program Metadata. Metaplex est porté par un seul module Rust desktop, comme les deux autres domaines : ce module contient à la fois les contrats génériques conservés pour les tests/outils avancés et les campagnes Devnet qualifiées. Les commandes génériques Metaplex (`current_operations`, `operation_template`, `prepare_step`, `execute`) restent disponibles, mais le panneau Devnet n’utilise plus ce chemin comme workflow opérateur principal.
|
||
|
||
Le panneau charge désormais l’inventaire borné avec `demo_execution_metadata_metaplex_campaigns`, puis exécute une campagne complète avec `demo_execution_metadata_metaplex_execute_campaign`.
|
||
|
||
```typescript
|
||
const campaigns = await invoke(
|
||
"demo_execution_metadata_metaplex_campaigns"
|
||
);
|
||
|
||
const summary = await invoke(
|
||
"demo_execution_metadata_metaplex_execute_campaign",
|
||
{
|
||
request: {
|
||
profileName: "devnet",
|
||
campaignId: "create_mint_nft",
|
||
operatorConfirmed: true
|
||
}
|
||
}
|
||
);
|
||
|
||
console.log(campaigns, summary);
|
||
```
|
||
|
||
L’inventaire contient cinq variantes `Create -> Mint`, puis collection `Verify -> Unverify`, `Print -> Burn`, lifecycle pNFT, Token Owned Escrow, Maintenance et le probe Use. Maintenance et Use sont les seules campagnes mixtes/probe : `Use`, `Resize`, `Migrate`, `Collect` et `CloseAccounts` y restent simulation-only lorsqu’elles rencontrent leur indisponibilité qualifiée et ne sont jamais exposées comme boutons de soumission isolés.
|
||
|
||
Dans la colonne de résultats, `Préflight et opérations`, `Simulation et confirmation` et `Postconditions et preuves` sont présentés dans un accordéon commun. La carte `Exigences` reste sous cet accordéon et le journal d’exécution reste sous la grille, sur toute la largeur.
|
||
|
||
### 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 sépare Metaplex Token Metadata, Token-2022 Token Metadata et Solana Program Metadata. Il 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.
|
||
|
||
Les scénarios synthétiques restent disponibles pour inspecter les contrats sans réseau. Le parcours Devnet Metaplex sélectionne au contraire une campagne qualifiée complète ; fixture, simulation, soumission autorisée, replay, matérialisation, idempotence et postconditions restent la responsabilité du runner spécialisé.
|
||
|
||
### Campagnes Metaplex qualifiées
|
||
|
||
Ouvrir **Metaplex Token Metadata -> Campagnes Devnet qualifiées**, sélectionner un profil persistant et préparer PostgreSQL. Le sélecteur présente 11 campagnes : cinq familles `Create -> Mint`, collection, Print/Burn, lifecycle pNFT, escrow, maintenance et Use. Après confirmation opérateur, le desktop appelle le runner correspondant et affiche :
|
||
|
||
- la fixture et son setup ;
|
||
- les exécutions confirmées et les probes indisponibles dans leur ordre réel ;
|
||
- les postconditions de campagne ;
|
||
- les compteurs `confirmed` et `unavailable`.
|
||
|
||
La surface générique par opération reste une API avancée et ne doit pas être utilisée pour reconstruire manuellement ces campagnes dans l’UI.
|
||
|
||
### Campagne Token-2022 Token Metadata
|
||
|
||
Ouvrir l’accordéon **Token-2022 Token Metadata**, sélectionner un profil Devnet persistant et préparer sa base PostgreSQL. Le panneau affiche le contrat fixe de cinq opérations :
|
||
|
||
```text
|
||
Initialize -> UpdateField -> Emit -> RemoveKey -> UpdateAuthority
|
||
```
|
||
|
||
Après confirmation explicite, **Exécuter la campagne Token-2022 Metadata** crée un mint frais avec Metadata Pointer vers lui-même, puis appelle le runner réutilisable pour les cinq opérations. La campagne conserve les simulations, signatures, confirmations, snapshots stateful, postconditions et matérialisations ; `Emit` expose également la return data validée. La fixture et les preuves sont affichées avec le JsonViewer commun.
|
||
|
||
La carte **Exigences** est placée en bas de la colonne droite, après les postconditions. Le journal d’exécution est placé sous les deux colonnes principales et occupe toute la largeur disponible de la page.
|
||
|
||
### 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.
|