v0.1.0-pre.071
This commit is contained in:
20
kb-app-demo-desktop/CHANGELOG.md
Normal file
20
kb-app-demo-desktop/CHANGELOG.md
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- file: kb-app-demo-desktop/CHANGELOG.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# CHANGELOG — kb-app-demo-desktop
|
||||
|
||||
## 0.1.0-pre.071
|
||||
|
||||
- ajout du contrat documentaire complet de la crate mixte ;
|
||||
- documentation de la bibliothèque, du binaire et de l’interface Tauri ;
|
||||
- ajout d’exemples frontend pour les principales familles de commandes ;
|
||||
- clarification de la persistance de l’état WebSocket hors cycle de vie de la fenêtre ;
|
||||
- inscription des travaux ElGamal et Metaplex restants dans le TODO.
|
||||
|
||||
## 0.1.0-pre.062
|
||||
|
||||
- migration de l’application de démonstration vers `kb-app-demo-desktop` ;
|
||||
- maintien d’un package unique bibliothèque et binaire ;
|
||||
- migration des fenêtres HTTP, WebSocket, SQL, backfill, extraction, replay et exécution ;
|
||||
- raccordement aux crates consolidées bot3 ;
|
||||
- validation connue de 117 tests.
|
||||
51
kb-app-demo-desktop/README.md
Normal file
51
kb-app-demo-desktop/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
<!-- file: kb-app-demo-desktop/README.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# kb-app-demo-desktop
|
||||
|
||||
`kb-app-demo-desktop` est l’application Tauri de démonstration et de validation opérateur de `khadhroony-bot3`.
|
||||
|
||||
La crate reste volontairement mixte :
|
||||
|
||||
- bibliothèque `kb_app_demo_desktop_lib` ;
|
||||
- binaire `kb-app-demo-desktop`.
|
||||
|
||||
## Responsabilités
|
||||
|
||||
- démarrage Tauri et gestion d’une instance unique ;
|
||||
- chargement de la configuration et du logging ;
|
||||
- fenêtres de diagnostic et démonstration ;
|
||||
- commandes Tauri pour HTTP, WebSocket, SQL, backfill, extraction Core et replay ;
|
||||
- commandes de simulation et exécution Devnet ;
|
||||
- adaptation TS-RS des résultats des crates réutilisables ;
|
||||
- gestion de progression, annulation et état applicatif.
|
||||
|
||||
## Frontière architecturale
|
||||
|
||||
La logique générique reste dans :
|
||||
|
||||
- `kb-pipeline-demo-scenarios` pour les scénarios réutilisables ;
|
||||
- `kb-pipeline` pour l’orchestration ;
|
||||
- `kb-onchain-transport` pour les communications réseau ;
|
||||
- `kb-store` pour PostgreSQL ;
|
||||
- `kb-lib` pour décodage, exécution et matérialisation ;
|
||||
- `kb-wallet` pour les signers locaux.
|
||||
|
||||
Le desktop ne doit pas devenir l’unique endroit où un scénario fonctionnel existe.
|
||||
|
||||
## Validation frontend
|
||||
|
||||
La validation autorisée est :
|
||||
|
||||
```bash
|
||||
cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json
|
||||
```
|
||||
|
||||
Ne pas utiliser `npm --prefix kb-app-demo-desktop run build` comme validation du desktop.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [USAGE.md](USAGE.md)
|
||||
- [TODO.md](TODO.md)
|
||||
- [CHANGELOG.md](CHANGELOG.md)
|
||||
- [Scénarios réutilisables](../kb-pipeline-demo-scenarios/README.md)
|
||||
15
kb-app-demo-desktop/TODO.md
Normal file
15
kb-app-demo-desktop/TODO.md
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- file: kb-app-demo-desktop/TODO.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# TODO — kb-app-demo-desktop
|
||||
|
||||
- [ ] Registre ElGamal - laisser le panneau non exécutable tant que le déploiement réseau et les preuves requises ne sont pas confirmés.
|
||||
- [ ] Registre ElGamal - raccorder un handler fonctionnel uniquement après validation du scénario réutilisable hors desktop.
|
||||
- [ ] Metaplex Token Metadata - ajouter les panneaux nécessaires aux scénarios complétés de la future `0.4.7`.
|
||||
- [ ] Architecture - continuer à extraire les scénarios réutilisables vers `kb-pipeline-demo-scenarios`.
|
||||
- [ ] Tests - maintenir les adaptateurs Tauri et payloads TS-RS synchronisés avec les APIs réutilisables.
|
||||
- [ ] Tests - compléter les tests des cycles d’ouverture, fermeture et réouverture des fenêtres.
|
||||
- [ ] WebSocket - garantir que la fermeture de `demo_ws` ne ferme pas une session active.
|
||||
- [ ] WebSocket - restaurer l’état courant lors de la réouverture de `demo_ws`.
|
||||
- [ ] Documentation - produire un guide opérateur des fenêtres et effets réseau.
|
||||
- [ ] Sécurité - réévaluer les capabilities Tauri à chaque nouvelle fenêtre ou commande.
|
||||
246
kb-app-demo-desktop/USAGE.md
Normal file
246
kb-app-demo-desktop/USAGE.md
Normal file
@@ -0,0 +1,246 @@
|
||||
<!-- file: kb-app-demo-desktop/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# 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`.
|
||||
|
||||
### 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.
|
||||
|
||||
### 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.
|
||||
|
||||
La base validée de `pre.062` contient 117 tests pour cette crate.
|
||||
|
||||
## 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.
|
||||
17
kb-core/CHANGELOG.md
Normal file
17
kb-core/CHANGELOG.md
Normal file
@@ -0,0 +1,17 @@
|
||||
<!-- file: kb-core/CHANGELOG.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# CHANGELOG — kb-core
|
||||
|
||||
## 0.1.0-pre.071
|
||||
|
||||
- réécriture du README pour l’architecture bot3 ;
|
||||
- ajout du TODO, du guide d’utilisation et du changelog de crate ;
|
||||
- documentation des erreurs partagées et des identités de modules ;
|
||||
- ajout d’exemples couvrant les familles d’API publiques.
|
||||
|
||||
## 0.1.0-pre.062
|
||||
|
||||
- migration des primitives communes vers la crate consolidée `kb-core` ;
|
||||
- maintien d’un type d’erreur explicite sans `anyhow` ni `thiserror` ;
|
||||
- adaptation aux normes Rust 2024 et Khadhroony bot3.
|
||||
@@ -1,23 +1,37 @@
|
||||
<!-- file: kb-core/README.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# kb-core
|
||||
|
||||
Ce crate fournit les types minimaux partagés, les erreurs communes et l'identité des modules.
|
||||
`kb-core` fournit les primitives minimales partagées par l’ensemble de `khadhroony-bot3`.
|
||||
|
||||
## Rôle dans l'écosystème
|
||||
## Responsabilités
|
||||
|
||||
Ce module fait partie du découpage strict de Khadhroony Bot2. Il doit conserver des dépendances limitées et ne pas contourner les interfaces communes du workspace.
|
||||
- type d’erreur explicite commun au workspace ;
|
||||
- alias `Result<T>` ;
|
||||
- identité stable des modules ;
|
||||
- classification des grandes familles de traitement.
|
||||
|
||||
## Règles locales
|
||||
La crate reste volontairement petite et ne dépend d’aucune couche fonctionnelle supérieure.
|
||||
|
||||
- Les commentaires de code restent en anglais.
|
||||
- La documentation Markdown reste en français.
|
||||
- Les exports publics sont contrôlés depuis `lib.rs` lorsque le crate expose une bibliothèque.
|
||||
- Les binaires utilisent `main.rs` avec les attributs Rust obligatoires.
|
||||
## API publique
|
||||
|
||||
## Erreurs communes
|
||||
- `Error` ;
|
||||
- `Result<T>` ;
|
||||
- `ModuleName` ;
|
||||
- `ModuleVersion` ;
|
||||
- `ModuleKind`.
|
||||
|
||||
`kb-core::Error` est l'enum d'erreur commune du workspace. Elle fournit des familles stables pour configuration, I/O, JSON, tracing, Tauri, HTTP, WebSocket, base de données, état invalide, client non connecté, fonctionnalité non implémentée et erreurs personnalisées.
|
||||
Voir [USAGE.md](USAGE.md) pour les exemples.
|
||||
|
||||
`kb-core::Error::new(code, message)` reste disponible comme compatibilité courte pendant que les domaines sont progressivement spécialisés.
|
||||
## Relations
|
||||
|
||||
`kb-core` est utilisée par toutes les crates qui ont besoin d’un contrat d’erreur ou d’une identité de module partagée. Elle ne contient ni configuration, ni transport, ni stockage, ni logique Solana.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [USAGE.md](USAGE.md)
|
||||
- [TODO.md](TODO.md)
|
||||
- [CHANGELOG.md](CHANGELOG.md)
|
||||
- [Architecture générale](../docs/architecture/ARCHITECTURE.md)
|
||||
- [Carte des crates](../docs/architecture/CRATE_MAP.md)
|
||||
|
||||
9
kb-core/TODO.md
Normal file
9
kb-core/TODO.md
Normal file
@@ -0,0 +1,9 @@
|
||||
<!-- file: kb-core/TODO.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# TODO — kb-core
|
||||
|
||||
- [ ] Dette technique - réévaluer les variantes génériques de `Error` lorsque les frontières de domaine seront stabilisées.
|
||||
- [ ] Dette technique - réduire progressivement l’usage de `Error::Custom` lorsqu’un code d’erreur mérite une famille dédiée.
|
||||
- [ ] Documentation - maintenir la correspondance entre les familles d’erreur publiques et les crates qui les utilisent.
|
||||
- [ ] Tests - ajouter un test ciblé lorsqu’une nouvelle variante publique d’erreur ou de module est introduite.
|
||||
108
kb-core/USAGE.md
Normal file
108
kb-core/USAGE.md
Normal file
@@ -0,0 +1,108 @@
|
||||
<!-- file: kb-core/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Utilisation de kb-core
|
||||
|
||||
## Objectif
|
||||
|
||||
La crate expose les contrats minimaux communs utilisés par les autres crates du workspace.
|
||||
|
||||
## Résultat partagé
|
||||
|
||||
```rust
|
||||
fn validate_name(name: &str) -> kb_core::Result<()> {
|
||||
if name.trim().is_empty() {
|
||||
return std::result::Result::Err(kb_core::Error::new(
|
||||
"name_empty",
|
||||
"name must not be empty",
|
||||
));
|
||||
}
|
||||
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
```
|
||||
|
||||
## Erreur personnalisée stable
|
||||
|
||||
```rust
|
||||
let error = kb_core::Error::new(
|
||||
"profile_missing",
|
||||
"the requested profile does not exist",
|
||||
);
|
||||
|
||||
assert_eq!(error.code(), "profile_missing");
|
||||
assert_eq!(
|
||||
error.message(),
|
||||
"the requested profile does not exist"
|
||||
);
|
||||
```
|
||||
|
||||
`Error::new` doit recevoir un code stable destiné aux logs, aux tests et aux adaptateurs UI.
|
||||
|
||||
## Familles d’erreur
|
||||
|
||||
```rust
|
||||
let config_error = kb_core::Error::config("missing active profile");
|
||||
let io_error = kb_core::Error::io("cannot read configuration file");
|
||||
let db_error = kb_core::Error::db("database connection refused");
|
||||
|
||||
assert_eq!(config_error.code(), "config");
|
||||
assert_eq!(io_error.code(), "io");
|
||||
assert_eq!(db_error.code(), "db");
|
||||
```
|
||||
|
||||
Les constructeurs publics disponibles couvrent notamment la configuration, les I/O, JSON, tracing, Tauri, HTTP, WebSocket, base de données, état invalide, absence de connexion et fonctionnalité non implémentée.
|
||||
|
||||
## Conversion depuis une erreur I/O
|
||||
|
||||
```rust
|
||||
let read_result = std::fs::read_to_string("missing.file");
|
||||
|
||||
let core_result: kb_core::Result<std::string::String> =
|
||||
match read_result {
|
||||
std::result::Result::Ok(value) => {
|
||||
std::result::Result::Ok(value)
|
||||
},
|
||||
std::result::Result::Err(error) => {
|
||||
std::result::Result::Err(kb_core::Error::from(error))
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Identité d’un module
|
||||
|
||||
```rust
|
||||
let name = kb_core::ModuleName(
|
||||
"spl_token_decoder".to_string(),
|
||||
);
|
||||
let version = kb_core::ModuleVersion(
|
||||
"0.4.6".to_string(),
|
||||
);
|
||||
let kind = kb_core::ModuleKind::Decoder;
|
||||
|
||||
assert_eq!(name.0, "spl_token_decoder");
|
||||
assert_eq!(version.0, "0.4.6");
|
||||
assert_eq!(kind, kb_core::ModuleKind::Decoder);
|
||||
```
|
||||
|
||||
`ModuleKind` distingue actuellement les ingestors, extractors, observers, decoders, materializers, aggregators et validators.
|
||||
|
||||
## Erreurs et invariants
|
||||
|
||||
- le code d’une erreur doit rester stable ;
|
||||
- le message peut être détaillé pour l’opérateur, mais ne doit pas contenir de secret ;
|
||||
- `ModuleName` et `ModuleVersion` sont des identités, pas des mécanismes de résolution dynamique ;
|
||||
- une nouvelle variante publique doit rester compatible avec les consommateurs du workspace.
|
||||
|
||||
## Tests de référence
|
||||
|
||||
- `custom_error_preserves_code_and_message` ;
|
||||
- `family_error_formats_with_family_prefix`.
|
||||
|
||||
Ces tests illustrent le contrat stable entre code, message et représentation textuelle.
|
||||
|
||||
## Limites durables
|
||||
|
||||
- `kb-core` ne remplace pas les types métier spécialisés ;
|
||||
- elle ne fournit pas de journalisation ni de sérialisation automatique des erreurs ;
|
||||
- elle ne contient pas de logique de transport, stockage ou protocole.
|
||||
18
kb-program-ids/CHANGELOG.md
Normal file
18
kb-program-ids/CHANGELOG.md
Normal file
@@ -0,0 +1,18 @@
|
||||
<!-- file: kb-program-ids/CHANGELOG.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# CHANGELOG — kb-program-ids
|
||||
|
||||
## 0.1.0-pre.071
|
||||
|
||||
- réécriture du README comme référence de la façade publique bot3 ;
|
||||
- ajout du TODO, du guide d’utilisation et du changelog de crate ;
|
||||
- clarification de la différence entre Program ID réservé et surface implémentée ;
|
||||
- documentation du futur registre de sources Program IDs et IDL.
|
||||
|
||||
## 0.1.0-pre.062
|
||||
|
||||
- migration et consolidation du registre bot2 ;
|
||||
- conservation des identifiants Solana Core, SPL et des protocoles réservés ;
|
||||
- maintien de la séparation entre programmes natifs exécutables et comptes connus ;
|
||||
- adaptation aux normes Rust 2024 et Khadhroony bot3.
|
||||
@@ -1,25 +1,38 @@
|
||||
<!-- file: kb-program-ids/README.md -->
|
||||
<!-- version: 7 -->
|
||||
<!-- version: 8 -->
|
||||
|
||||
# kb-program-ids
|
||||
|
||||
`kb-program-ids` est la source unique des identifiants de programmes Solana et des comptes natifs connus utilisés par le workspace.
|
||||
`kb-program-ids` est la source Rust canonique des Program IDs Solana et des comptes connus utilisés par le workspace.
|
||||
|
||||
La tranche `0.1.0-pre.004` expose les 18 surfaces exécutables nécessaires au décodeur Solana Core, les comptes natifs associés utilisés par leurs contrats et l’identifiant SPL Token classique employé par les tests de frontière. La tranche `0.1.0-pre.005` ajoute les trois identifiants SPL Memo v1, v3 et v4 sans les classer parmi les surfaces natives. `0.1.0-pre.006` active l’identifiant SPL Token classique dans un décodeur concret tout en le maintenant hors des surfaces natives. `0.1.0-pre.007` ajoute les identifiants SPL Associated Token Account et Token‑2022 nécessaires à la frontière ATA. `0.1.0-pre.008` ajoute le Program ID indépendant du registre ElGamal de Token‑2022. `0.1.0-pre.009` ajoute le Program ID indépendant de Metaplex Token Metadata. Ces programmes restent hors des surfaces natives.
|
||||
## Responsabilités
|
||||
|
||||
La tranche `0.1.0-pre.012` restaure 97 Program IDs supplémentaires utilisés par les squelettes réservés de `kb-lib`. Le registre contient désormais 130 codes et 130 adresses uniques. La réservation Anchor ne possède volontairement aucun Program ID statique.
|
||||
- exposer les constantes Base58 canoniques ;
|
||||
- fournir un registre énumérable et trié ;
|
||||
- distinguer les programmes natifs exécutables des comptes natifs connus ;
|
||||
- offrir une recherche exacte par adresse ;
|
||||
- réserver les identifiants nécessaires aux surfaces futures sans les déclarer implémentées.
|
||||
|
||||
`constants.rs` reste l’unique source des adresses et des tableaux statiques. `programs.rs` porte
|
||||
`ProgramIdEntry`, ses méthodes et toutes les fonctions de consultation. `lib.rs` se limite aux
|
||||
déclarations de modules et aux réexports documentés de la façade.
|
||||
La présence d’un Program ID dans cette crate ne signifie pas qu’un décodeur, exécuteur ou matérialisateur existe.
|
||||
|
||||
## API publique
|
||||
|
||||
- les constantes `*_PROGRAM_ID` et `STAKE_CONFIG_ACCOUNT_ID` exposent les adresses Base58 canoniques ;
|
||||
- `ProgramIdEntry` conserve un code stable et une adresse, accessibles par les champs compatibles `name`/`address` et par `code()`/`program_id()` ;
|
||||
- `native_program_ids()` retourne exactement les 18 surfaces exécutables de Solana Core ;
|
||||
- `native_well_known_account_ids()` sépare les comptes natifs non exécutables ;
|
||||
- `registered_program_ids()` et son alias de compatibilité `entries()` retournent le registre actuellement migré ;
|
||||
- `find_registered_program_id()` effectue une recherche exacte par adresse.
|
||||
- constantes `*_PROGRAM_ID` ;
|
||||
- `STAKE_CONFIG_ACCOUNT_ID` et alias historique associé ;
|
||||
- `ProgramIdEntry` ;
|
||||
- `entries()` ;
|
||||
- `registered_program_ids()` ;
|
||||
- `native_program_ids()` ;
|
||||
- `native_well_known_account_ids()` ;
|
||||
- `find_registered_program_id()`.
|
||||
|
||||
`STAKE_CONFIG_PROGRAM_ID` reste uniquement un alias de compatibilité historique. L’adresse correspondante est un compte de configuration Stake connu, pas un programme exécutable.
|
||||
## Sources documentaires
|
||||
|
||||
La documentation détaillée des Program IDs, de leur vérification et des IDL sera construite séparément. Elle pourra utiliser les archives bot2 et d’autres projets historiques, mais le code de production reste fondé sur les constantes vérifiées de cette crate.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [USAGE.md](USAGE.md)
|
||||
- [TODO.md](TODO.md)
|
||||
- [CHANGELOG.md](CHANGELOG.md)
|
||||
- [Matrice des surfaces](../docs/architecture/SURFACE_CRATE_MATRIX.md)
|
||||
|
||||
12
kb-program-ids/TODO.md
Normal file
12
kb-program-ids/TODO.md
Normal file
@@ -0,0 +1,12 @@
|
||||
<!-- file: kb-program-ids/TODO.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# TODO — kb-program-ids
|
||||
|
||||
- [ ] Documentation - produire le registre documentaire vérifié des Program IDs et de leurs sources.
|
||||
- [ ] Documentation - associer chaque IDL archivée à sa provenance vérifiée et à son Program ID.
|
||||
- [ ] Audit - rescanner les documents historiques bot2 avant de déclarer l’inventaire documentaire complet.
|
||||
- [ ] Audit - intégrer ultérieurement les sources d’un projet antérieur à bot2 lorsqu’elles seront fournies.
|
||||
- [ ] Vérification - confirmer la nature du programme `MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e` avant classement.
|
||||
- [ ] Vérification - déterminer si `pumpup_ai` appartient à la famille Pump ou à un protocole distinct.
|
||||
- [ ] Tests - maintenir l’unicité, le tri et la séparation entre programmes exécutables et comptes connus.
|
||||
134
kb-program-ids/USAGE.md
Normal file
134
kb-program-ids/USAGE.md
Normal file
@@ -0,0 +1,134 @@
|
||||
<!-- file: kb-program-ids/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Utilisation de kb-program-ids
|
||||
|
||||
## Objectif
|
||||
|
||||
La crate fournit des identifiants Solana canoniques et un registre public énumérable.
|
||||
|
||||
## Utiliser une constante canonique
|
||||
|
||||
```rust
|
||||
let token_program =
|
||||
kb_program_ids::SPL_TOKEN_PROGRAM_ID;
|
||||
let token_2022_program =
|
||||
kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID;
|
||||
|
||||
assert_ne!(token_program, token_2022_program);
|
||||
```
|
||||
|
||||
Les constantes sont des chaînes Base58. Le consommateur peut les parser dans le type Solana requis par sa propre API.
|
||||
|
||||
## Parser une constante en `Pubkey`
|
||||
|
||||
```rust
|
||||
use std::str::FromStr; // rust-rules: trait-import
|
||||
|
||||
let program_id = match solana_pubkey::Pubkey::from_str(
|
||||
kb_program_ids::SYSTEM_PROGRAM_ID,
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(
|
||||
kb_core::Error::new(
|
||||
"program_id_invalid",
|
||||
error.to_string(),
|
||||
),
|
||||
);
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Parcourir le registre complet
|
||||
|
||||
```rust
|
||||
for entry in kb_program_ids::registered_program_ids() {
|
||||
println!(
|
||||
"{}={}",
|
||||
entry.code(),
|
||||
entry.program_id()
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
`entries()` est un alias de compatibilité de `registered_program_ids()`.
|
||||
|
||||
## Rechercher une adresse exacte
|
||||
|
||||
```rust
|
||||
let entry = kb_program_ids::find_registered_program_id(
|
||||
kb_program_ids::SYSTEM_PROGRAM_ID,
|
||||
);
|
||||
|
||||
match entry {
|
||||
std::option::Option::Some(value) => {
|
||||
assert_eq!(value.code(), "system");
|
||||
},
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(
|
||||
kb_core::Error::new(
|
||||
"program_id_not_registered",
|
||||
"system program must be registered",
|
||||
),
|
||||
);
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Distinguer programmes natifs et comptes connus
|
||||
|
||||
```rust
|
||||
let native_programs =
|
||||
kb_program_ids::native_program_ids();
|
||||
let native_accounts =
|
||||
kb_program_ids::native_well_known_account_ids();
|
||||
|
||||
assert!(native_programs.iter().any(|entry| {
|
||||
entry.program_id()
|
||||
== kb_program_ids::SYSTEM_PROGRAM_ID
|
||||
}));
|
||||
|
||||
assert!(native_accounts.iter().any(|entry| {
|
||||
entry.program_id()
|
||||
== kb_program_ids::STAKE_CONFIG_ACCOUNT_ID
|
||||
}));
|
||||
```
|
||||
|
||||
`STAKE_CONFIG_ACCOUNT_ID` désigne un compte connu, pas un programme exécutable. `STAKE_CONFIG_PROGRAM_ID` reste un alias historique de compatibilité.
|
||||
|
||||
## Construire un ensemble de filtrage
|
||||
|
||||
```rust
|
||||
let supported = [
|
||||
kb_program_ids::SPL_MEMO_V4_PROGRAM_ID,
|
||||
kb_program_ids::SPL_TOKEN_PROGRAM_ID,
|
||||
kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
|
||||
];
|
||||
|
||||
let matches = supported.contains(
|
||||
&observed_program_id.as_str(),
|
||||
);
|
||||
```
|
||||
|
||||
## Erreurs et invariants
|
||||
|
||||
- les recherches sont exactes et sensibles à la casse ;
|
||||
- les codes du registre sont stables et triés ;
|
||||
- une constante réservée ne prouve pas l’implémentation d’une surface ;
|
||||
- les comptes connus non exécutables doivent rester séparés des programmes ;
|
||||
- les sources documentaires futures ne remplacent pas la vérification du code.
|
||||
|
||||
## Tests de référence
|
||||
|
||||
- `registry_entries_are_unique_and_non_empty` ;
|
||||
- `native_registry_contains_exactly_every_solana_core_surface` ;
|
||||
- `stake_config_is_a_well_known_account_not_an_executable_program` ;
|
||||
- `registry_lookup_finds_system_program` ;
|
||||
- `protocol_primitives_are_registered_without_joining_native_surfaces`.
|
||||
|
||||
## Limites durables
|
||||
|
||||
- la crate ne vérifie pas en temps réel le déploiement réseau d’un programme ;
|
||||
- elle ne télécharge pas d’IDL ;
|
||||
- elle ne détermine pas si une surface est décodée, exécutée ou matérialisée.
|
||||
18
kb-wallet/CHANGELOG.md
Normal file
18
kb-wallet/CHANGELOG.md
Normal file
@@ -0,0 +1,18 @@
|
||||
<!-- file: kb-wallet/CHANGELOG.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# CHANGELOG — kb-wallet
|
||||
|
||||
## 0.1.0-pre.071
|
||||
|
||||
- réécriture du README avec indication explicite du statut d’ébauche ;
|
||||
- ajout du TODO détaillant les fonctionnalités prévues pour `0.5.x` ;
|
||||
- ajout du guide d’utilisation et de plusieurs exemples publics ;
|
||||
- clarification de la frontière entre signer, politique et exécution.
|
||||
|
||||
## 0.1.0-pre.062
|
||||
|
||||
- migration et renommage du wallet temporaire vers `kb-wallet` ;
|
||||
- conservation des alias validés, keypairs temporaires et stockage local ;
|
||||
- ajout des contrôles de permissions, type de fichier et effacement des buffers secrets ;
|
||||
- adaptation aux normes Rust 2024 et Khadhroony bot3.
|
||||
@@ -1,18 +1,46 @@
|
||||
<!-- file: kb-wallet/README.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# kb-wallet
|
||||
|
||||
Frontière locale de portefeuille et de signature pour Khadhroony Bot3.
|
||||
`kb-wallet` fournit actuellement une frontière locale minimale de portefeuille pour les démonstrations et tests d’intégration.
|
||||
|
||||
La crate fournit :
|
||||
## État actuel
|
||||
|
||||
- des alias de portefeuille validés et non secrets ;
|
||||
- des portefeuilles temporaires en mémoire ;
|
||||
- un stockage JSON Solana persistant pour le développement et les tests d’intégration ;
|
||||
- la signature de messages sans exposition des octets secrets ;
|
||||
- des permissions Unix privées (`0700` pour le répertoire, `0600` pour les fichiers) ;
|
||||
- le rejet des liens symboliques, fichiers non réguliers, permissions trop ouvertes et keypairs invalides ;
|
||||
- l’effacement explicite des buffers contenant des octets secrets via `zeroize`.
|
||||
La crate est une ébauche fonctionnelle, pas un gestionnaire de wallets complet.
|
||||
|
||||
Cette crate ne décide pas si une transaction peut être envoyée. Les limites de dépense, la simulation et les politiques d’exécution restent dans `kb-lib` et les couches d’orchestration.
|
||||
Elle fournit :
|
||||
|
||||
- alias validés ;
|
||||
- wallet temporaire en mémoire ;
|
||||
- stockage local JSON d’un keypair Solana ;
|
||||
- chargement ou création atomique ;
|
||||
- résumé non secret ;
|
||||
- accès au trait `Signer` sans exposition des octets ;
|
||||
- signature de messages ;
|
||||
- permissions Unix privées et contrôles de fichiers ;
|
||||
- effacement des buffers secrets utilisés lors de la lecture ou écriture.
|
||||
|
||||
## Hors capacités actuelles
|
||||
|
||||
Les fonctions suivantes ne sont pas encore implémentées :
|
||||
|
||||
- chiffrement par mot de passe ;
|
||||
- plusieurs wallets gérés comme collection ;
|
||||
- sélection persistante du wallet actif ;
|
||||
- import/export contrôlé ;
|
||||
- changement de mot de passe ;
|
||||
- verrouillage et déverrouillage ;
|
||||
- sauvegarde et restauration ;
|
||||
- politiques de sécurité complètes.
|
||||
|
||||
## Relations
|
||||
|
||||
`kb-wallet` fournit un signer. Les limites de dépense, la simulation, l’autorisation opérateur et l’envoi sont gérés par `kb-lib`, `kb-pipeline-demo-scenarios` et les applications.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [USAGE.md](USAGE.md)
|
||||
- [TODO.md](TODO.md)
|
||||
- [CHANGELOG.md](CHANGELOG.md)
|
||||
- [ROADMAP général](../ROADMAP.md)
|
||||
|
||||
16
kb-wallet/TODO.md
Normal file
16
kb-wallet/TODO.md
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- file: kb-wallet/TODO.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# TODO — kb-wallet
|
||||
|
||||
- [ ] Fonctionnalité - gérer plusieurs wallets persistants.
|
||||
- [ ] Fonctionnalité - ajouter la sélection et la persistance du wallet actif.
|
||||
- [ ] Sécurité - ajouter le chiffrement et le déchiffrement protégés par mot de passe.
|
||||
- [ ] Sécurité - ajouter le changement de mot de passe.
|
||||
- [ ] Sécurité - ajouter le verrouillage et le déverrouillage explicites.
|
||||
- [ ] Fonctionnalité - ajouter l’import et l’export contrôlés de wallets.
|
||||
- [ ] Fonctionnalité - ajouter la sauvegarde et la restauration.
|
||||
- [ ] Sécurité - définir des politiques de stockage, de session et d’autorisation de signature.
|
||||
- [ ] Intégration - relier la sélection du wallet aux profils et signers des scénarios.
|
||||
- [ ] Tests - ajouter les tests de corruption, concurrence et récupération pour les nouvelles fonctionnalités.
|
||||
- [ ] Documentation - produire un guide de sécurité avant tout usage hors démonstration.
|
||||
182
kb-wallet/USAGE.md
Normal file
182
kb-wallet/USAGE.md
Normal file
@@ -0,0 +1,182 @@
|
||||
<!-- file: kb-wallet/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Utilisation de kb-wallet
|
||||
|
||||
## Objectif
|
||||
|
||||
La crate fournit des wallets temporaires en mémoire ou persistés localement pour les démonstrations et tests d’intégration.
|
||||
|
||||
## Valider un alias
|
||||
|
||||
```rust
|
||||
let alias = match kb_wallet::WalletAlias::parse(
|
||||
"devnet-operator",
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(alias.as_str(), "devnet-operator");
|
||||
```
|
||||
|
||||
Un alias doit contenir entre 1 et 64 octets, commencer par un caractère alphanumérique ASCII et ne contenir ensuite que des caractères alphanumériques, `_` ou `-`.
|
||||
|
||||
## Générer un wallet en mémoire
|
||||
|
||||
```rust
|
||||
let alias = match kb_wallet::WalletAlias::parse(
|
||||
"ephemeral",
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
let wallet =
|
||||
kb_wallet::TemporaryWallet::generate(alias);
|
||||
let summary = wallet.summary();
|
||||
|
||||
assert!(summary.storage_path.is_none());
|
||||
println!("public key={}", summary.public_key);
|
||||
```
|
||||
|
||||
## Signer un message
|
||||
|
||||
```rust
|
||||
let signature = match wallet.sign_message(
|
||||
b"khadhroony demo authorization",
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
println!("signature={signature}");
|
||||
```
|
||||
|
||||
`as_signer()` retourne une référence au trait Solana `Signer` sans exposer les octets du keypair.
|
||||
|
||||
## Créer un stockage local
|
||||
|
||||
```rust
|
||||
let store = match kb_wallet::TemporaryWalletStore::new(
|
||||
"./data/wallets",
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
println!(
|
||||
"wallet directory={}",
|
||||
store.directory().display()
|
||||
);
|
||||
```
|
||||
|
||||
## Créer un wallet persistant
|
||||
|
||||
```rust
|
||||
let alias = match kb_wallet::WalletAlias::parse(
|
||||
"devnet-payer",
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
let wallet = match store.create(alias).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
let summary = wallet.summary();
|
||||
assert!(summary.storage_path.is_some());
|
||||
```
|
||||
|
||||
`create` refuse d’écraser un fichier existant.
|
||||
|
||||
## Charger ou créer atomiquement
|
||||
|
||||
```rust
|
||||
let alias = match kb_wallet::WalletAlias::parse(
|
||||
"shared-devnet",
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
let wallet = match store.load_or_create(alias).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
println!("wallet={}", wallet.public_key());
|
||||
```
|
||||
|
||||
## Vérifier l’existence et le chemin
|
||||
|
||||
```rust
|
||||
let path = store.wallet_path(&alias);
|
||||
let exists = match store.exists(&alias).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error);
|
||||
},
|
||||
};
|
||||
|
||||
println!("path={}, exists={exists}", path.display());
|
||||
```
|
||||
|
||||
## Politique non secrète
|
||||
|
||||
```rust
|
||||
let policy = kb_wallet::WalletPolicy {
|
||||
signing_enabled: true,
|
||||
lamport_spend_limit: std::option::Option::Some(
|
||||
1_000_000,
|
||||
),
|
||||
};
|
||||
|
||||
assert!(policy.signing_enabled);
|
||||
```
|
||||
|
||||
`WalletPolicy` transporte une intention de politique. Son application effective appartient à la couche d’exécution.
|
||||
|
||||
## Erreurs et invariants
|
||||
|
||||
- les octets secrets ne sont jamais exposés par l’API publique ;
|
||||
- les résumés ne contiennent que l’alias, la clé publique et le chemin ;
|
||||
- un fichier existant n’est pas écrasé ;
|
||||
- les liens symboliques et fichiers non réguliers sont refusés ;
|
||||
- sur Unix, les permissions privées sont vérifiées ;
|
||||
- les buffers secrets temporaires sont effacés ;
|
||||
- cette crate ne décide pas si une transaction est autorisée.
|
||||
|
||||
## Tests de référence
|
||||
|
||||
- validation des alias ;
|
||||
- génération et signature sans persistance ;
|
||||
- création, chargement et `load_or_create` ;
|
||||
- refus d’écrasement ;
|
||||
- rejet des keypairs corrompus ;
|
||||
- vérification des permissions Unix privées ;
|
||||
- rejet des liens symboliques et permissions trop ouvertes.
|
||||
|
||||
## Limites durables
|
||||
|
||||
- le format persistant actuel est le tableau JSON standard du keypair Solana ;
|
||||
- la crate ne signe pas automatiquement une transaction ;
|
||||
- elle ne transmet aucun secret à une interface frontend.
|
||||
Reference in New Issue
Block a user