0.5.1-pre.002

This commit is contained in:
2026-08-09 19:34:08 +02:00
parent 816eee59a9
commit 6a680767ae
767 changed files with 12257 additions and 12195 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: CHANGELOG.md -->
<!-- version: 13 -->
<!-- version: 14 -->
# CHANGELOG — khadhroony-bot3
@@ -20,7 +20,7 @@ Ce changelog décrit les évolutions fonctionnelles globales du projet. Il ne re
- confirmation du split futur entre configuration généraliste et configuration logging, avec documents, schémas et profils indépendants ;
- cadrage d'une séparation entre configuration source, runtime résolue et surfaces publiques/diagnostiques afin qu'aucun secret résolu ne puisse être exposé involontairement ;
- caractérisation du format wallet `0.4.8` comme contrat de migration à préserver ou importer explicitement en `0.5.2` ;
- audit de `kb-store` confirmant les frontières existantes tout en identifiant `block_time`, provenance et index trading/routing comme axes de `0.5.3` ;
- audit de `ks-store` confirmant les frontières existantes tout en identifiant `block_time`, provenance et index trading/routing comme axes de `0.5.3` ;
- décision de migrer en `0.5.3` les tables Solana `kb_sol_*` vers `k_sol_*`, `kb_*` restant réservé aux éventuelles données réellement spécifiques au Bot.
### Scénarios et exécution
@@ -58,7 +58,7 @@ Ce changelog décrit les évolutions fonctionnelles globales du projet. Il ne re
### Desktop et cohérence transversale
- finalisation de `demo_execution_metadata` avec trois domaines séparés, campagnes réutilisables, JsonViewer, accordéons de preuves et journal pleine largeur ;
- centralisation des scénarios réseau réutilisables dans `kb-pipeline-demo-scenarios` plutôt que dans ladaptateur Tauri ;
- centralisation des scénarios réseau réutilisables dans `ks-pipeline-demo-scenarios` plutôt que dans ladaptateur Tauri ;
- réconciliation des matrices, registres runtime, exports publics, IDL, TODO et stockage ;
- confirmation quaucune migration PostgreSQL spécialisée Metadata nest nécessaire.
@@ -77,7 +77,7 @@ Ce changelog décrit les évolutions fonctionnelles globales du projet. Il ne re
- décodeurs dinstructions et de comptes, PDA, owners, modèles et variantes historiques ;
- matérialisation metadata, administration, lifecycle et risques applicables ;
- intents typés, builders, exécuteur, préflight stateful, simulation-first et postconditions ;
- intégration dans `kb-pipeline`, scénarios synthétiques et runner Devnet réutilisable ;
- intégration dans `ks-pipeline`, scénarios synthétiques et runner Devnet réutilisable ;
- intégration desktop sans fetch HTTP/IPFS/Arweave.
### Validation
@@ -92,8 +92,8 @@ Ce changelog décrit les évolutions fonctionnelles globales du projet. Il ne re
- clôture de la migration principale de bot2 vers larchitecture consolidée bot3 ;
- onze crates documentées et versionnées `0.4.6` ;
- décodeurs, exécuteurs et matérialisateurs regroupés dans `kb-lib` ;
- stockage consolidé dans `kb-store` et transports RPC dans `kb-onchain-transport`.
- décodeurs, exécuteurs et matérialisateurs regroupés dans `ks-lib` ;
- stockage consolidé dans `ks-store` et transports RPC dans `ks-onchain-transport`.
### Capacités
@@ -114,7 +114,7 @@ Ce changelog décrit les évolutions fonctionnelles globales du projet. Il ne re
- registre ElGamal non déclaré validé réellement sur Devnet ou Mainnet faute de déploiement et de preuves disponibles ;
- achèvement de Metaplex Token Metadata reporté à `0.4.7` ;
- SPL Token Metadata et décision sur `kb-offchain-transport` reportés à `0.4.8` ;
- améliorations structurelles de `kb-config`, `kb-logging` et `kb-store` reportées à `0.5.x`.
- améliorations structurelles de `ks-config`, `ks-logging` et `ks-store` reportées à `0.5.x`.
## 0.1.0-mig-from-kbot2 — transition architecturale vers khadhroony-bot3
@@ -123,13 +123,13 @@ Cette entrée de transition regroupe la migration structurelle et fonctionnelle
### Architecture
- consolidation de plus de 250 crates historiques en 11 crates de workspace ;
- regroupement des modèles, décodeurs, exécuteurs et matérialisateurs dans `kb-lib` ;
- consolidation du stockage dans `kb-store` ;
- renommage de `kb-rpc` en `kb-onchain-transport` ;
- migration du pipeline dans `kb-pipeline` ;
- extraction des scénarios de démonstration dans `kb-pipeline-demo-scenarios` ;
- regroupement des modèles, décodeurs, exécuteurs et matérialisateurs dans `ks-lib` ;
- consolidation du stockage dans `ks-store` ;
- renommage de `kb-rpc` en `ks-onchain-transport` ;
- migration du pipeline dans `ks-pipeline` ;
- extraction des scénarios de démonstration dans `ks-pipeline-demo-scenarios` ;
- maintien de `kb-app-demo-desktop` comme crate mixte bibliothèque et binaire ;
- migration et renommage du portefeuille en `kb-wallet`.
- migration et renommage du portefeuille en `ks-wallet`.
### Normes

View File

@@ -1,24 +1,24 @@
# file: Cargo.toml
# version: 45
# version: 46
[workspace]
resolver = "3"
members = [
"kb-core",
"kb-config",
"kb-lib",
"kb-logging",
"kb-program-ids",
"kb-pipeline",
"kb-pipeline-demo-scenarios",
"kb-onchain-transport",
"kb-store",
"kb-wallet",
"ks-core",
"ks-config",
"ks-lib",
"ks-logging",
"ks-program-ids",
"ks-pipeline",
"ks-pipeline-demo-scenarios",
"ks-onchain-transport",
"ks-store",
"ks-wallet",
"kb-app-demo-desktop",
]
[workspace.package]
version = "0.5.1-pre.1"
version = "0.5.1-pre.2"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-bot3"

View File

@@ -1,5 +1,5 @@
<!-- file: README.md -->
<!-- version: 20 -->
<!-- version: 21 -->
# Khadhroony Bot3
@@ -9,16 +9,16 @@
Le workspace contient onze crates :
- `kb-core` : erreurs et primitives transversales ;
- `kb-config` : chargement et validation de la configuration ;
- `kb-lib` : modèles, décodeurs, exécuteurs et matérialisateurs ;
- `kb-logging` : logging et tracing ;
- `kb-program-ids` : registre canonique des programmes et comptes Solana ;
- `kb-pipeline` : pipeline généraliste de backfill, extraction, replay et orchestration ;
- `kb-pipeline-demo-scenarios` : scénarios synthétiques et campagnes Devnet/Testnet automatisables ;
- `kb-onchain-transport` : transports RPC HTTP et WebSocket ;
- `kb-store` : contrats de stockage et adaptateur PostgreSQL ;
- `kb-wallet` : frontière de wallet et signataires ;
- `ks-core` : erreurs et primitives transversales ;
- `ks-config` : chargement et validation de la configuration ;
- `ks-lib` : modèles, décodeurs, exécuteurs et matérialisateurs ;
- `ks-logging` : logging et tracing ;
- `ks-program-ids` : registre canonique des programmes et comptes Solana ;
- `ks-pipeline` : pipeline généraliste de backfill, extraction, replay et orchestration ;
- `ks-pipeline-demo-scenarios` : scénarios synthétiques et campagnes Devnet/Testnet automatisables ;
- `ks-onchain-transport` : transports RPC HTTP et WebSocket ;
- `ks-store` : contrats de stockage et adaptateur PostgreSQL ;
- `ks-wallet` : frontière de wallet et signataires ;
- `kb-app-demo-desktop` : application Tauri de démonstration et validation opérateur.
La série `0.5.x` prépare la séparation explicite entre le domaine applicatif `khadhroony-bot` et les bibliothèques généralistes `khadhroony-solana`. En `0.5.1`, les dix crates généralistes doivent migrer vers les noms `ks-*` / `ks_*`, tandis que `kb-app-demo-desktop` conserve son nom et reste une application du workspace Bot. Le workspace, le dépôt et le répertoire racine restent nommés `khadhroony-bot3` pendant cette migration et ne doivent pas être renommés avant `1.0` ou une version ultérieure explicitement dédiée. La politique de migration est définie dans [`docs/decisions/KHADHROONY_SOLANA_NAMESPACE_POLICY.md`](docs/decisions/KHADHROONY_SOLANA_NAMESPACE_POLICY.md).

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md -->
<!-- version: 34 -->
<!-- version: 35 -->
# ROADMAP — khadhroony-bot3
@@ -18,7 +18,7 @@ Version clôturée : surface Metaplex Token Metadata indépendante, bornée et i
- décodeur dinstructions et de comptes, PDA, owners et variantes historiques ;
- matérialisation metadata, administration, lifecycle et risques applicables ;
- intents typés, builders, exécuteur, préflights, simulation exacte et postconditions ;
- intégration généraliste dans `kb-pipeline` ;
- intégration généraliste dans `ks-pipeline` ;
- scénarios synthétiques NFT, SFT, fungible, collection et pNFT ;
- runner Devnet réutilisable et panneau `kb-app-demo-desktop` ;
- fixtures Rust natives sans dépendance à une CLI externe ;
@@ -68,7 +68,7 @@ La politique de namespace et d'ownership adoptée pendant `0.5.0` est documenté
Cadrage clôturé avant toute restructuration majeure :
- audit des responsabilités et couplages de `kb-config`, `kb-logging`, `kb-wallet`, `kb-store`, `kb-pipeline-demo-scenarios` et `kb-app-demo-desktop` ;
- audit des responsabilités et couplages de `ks-config`, `ks-logging`, `ks-wallet`, `ks-store`, `ks-pipeline-demo-scenarios` et `kb-app-demo-desktop` ;
- inventaire des contrats publics, formats persistés, migrations, dépendances, scénarios et preuves de validation ;
- confirmation du split futur entre configuration généraliste et configuration logging ;
- définition de la politique de secrets et du namespace d'environnement `KS_*` ;
@@ -84,7 +84,7 @@ Cadrage clôturé avant toute restructuration majeure :
Cette version effectue la migration de namespace des bibliothèques Solana et restructure la configuration sur la nouvelle fondation.
- renommer les dix crates généralistes : `kb-core`, `kb-config`, `kb-lib`, `kb-logging`, `kb-program-ids`, `kb-pipeline`, `kb-pipeline-demo-scenarios`, `kb-onchain-transport`, `kb-store` et `kb-wallet` vers leurs équivalents `ks-*` ;
- renommer les dix crates généralistes : `ks-core`, `ks-config`, `ks-lib`, `ks-logging`, `ks-program-ids`, `ks-pipeline`, `ks-pipeline-demo-scenarios`, `ks-onchain-transport`, `ks-store` et `ks-wallet` vers leurs équivalents `ks-*` ;
- migrer les identifiants Rust correspondants vers `ks_*`, les manifests, chemins, imports, exports, tests externes, scripts et documentation ;
- conserver `kb-app-demo-desktop` comme application du domaine Bot, consommatrice des composants `ks-*` ;
- migrer les identités runtime/persistées généralistes vers la nomenclature `ks-*`, notamment `ks-lib-decoder.*`, `ks-lib-materializer.*` et `ks-lib-executor.*`, après inventaire exhaustif des chaînes concernées ;

View File

@@ -1,5 +1,5 @@
<!-- file: config/README.md -->
<!-- version: 17 -->
<!-- version: 18 -->
# Configuration locale
@@ -13,7 +13,7 @@ Ce dossier contient les exemples et le schéma de configuration JSON.
- Un profil actif doit être présent et unique.
- Les profils non actifs peuvent rester dans le fichier pour les tests devnet, mainnet lecture seule, backfill ou future production.
- Le contrat courant couvre HTTP JSON-RPC Solana et WebSocket JSON-RPC générique.
- Helius `transactionSubscribe` et Yellowstone gRPC seront ajoutés plus tard dans `kb_onchain_transport`, avec évolution explicite du schéma quand les transports seront réellement utilisés.
- Helius `transactionSubscribe` et Yellowstone gRPC seront ajoutés plus tard dans `ks_onchain_transport`, avec évolution explicite du schéma quand les transports seront réellement utilisés.
- Les IDLs restent des artefacts de développement et ne font pas partie de la configuration runtime.
## Fichiers
@@ -67,13 +67,13 @@ Lexemple configure, pour chacun des trois profils, quatre fichiers globaux pu
Les matérialisateurs natifs consolidés rejoignent la console et disposent de leurs routes propres sous :
```text
logs/<profil>/kb-lib/materializer/admin/
logs/<profil>/kb-lib/materializer/compliance/audit/
logs/<profil>/kb-lib/materializer/lifecycle/
logs/<profil>/kb-lib/materializer/risk/
logs/<profil>/kb-lib/materializer/staking/
logs/<profil>/kb-lib/materializer/token/accounts/
logs/<profil>/kb-lib/materializer/transaction/annotations/
logs/<profil>/ks-lib/materializer/admin/
logs/<profil>/ks-lib/materializer/compliance/audit/
logs/<profil>/ks-lib/materializer/lifecycle/
logs/<profil>/ks-lib/materializer/risk/
logs/<profil>/ks-lib/materializer/staking/
logs/<profil>/ks-lib/materializer/token/accounts/
logs/<profil>/ks-lib/materializer/transaction/annotations/
```
Le test de configuration découvre dynamiquement toutes les crates déclarant `tracing.workspace = true` et vérifie leurs trois routes dans chaque profil. Les logs ne doivent contenir ni secret, ni DSN non masqué, ni payload Config ou bytecode complet.

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
<!-- file: docs/DEVNET_EXECUTION_GUIDE.md -->
<!-- version: 24 -->
<!-- version: 25 -->
# Guide dexécution Devnet
## 1. Objet et ordre de validation
Ce guide décrit la campagne Devnet de `kb-app-demo-desktop` et `kb-pipeline-demo-scenarios`. Après une modification de nomenclature persistée ou une recréation de la base Devnet, reprendre les scénarios depuis le début dans lordre suivant :
Ce guide décrit la campagne Devnet de `kb-app-demo-desktop` et `ks-pipeline-demo-scenarios`. Après une modification de nomenclature persistée ou une recréation de la base Devnet, reprendre les scénarios depuis le début dans lordre suivant :
1. préparation commune et base PostgreSQL propre ;
2. Solana Core — System Transfer ;
@@ -241,7 +241,7 @@ La création du compte destination par CLI est acceptable ici : `S03A` et `S03B`
Le workspace fournit une commande idempotente qui prépare les comptes publics requis par les huit scénarios Token-2022 :
```bash
cargo run -p kb-pipeline-demo-scenarios --bin kb-pipeline-demo-scenarios-cli -- prepare-token-2022-fixture --rpc-url "$KB_DEVNET_RPC_URL" --wallet "$KB_DEVNET_WALLET" --wallet-dir "$PWD/wallets/temporary/local_devnet" --decimals 9 | tee "$KB_DEVNET_VALIDATION_DIR/50-spl-token-2022-fixture-preparation.json"
cargo run -p ks-pipeline-demo-scenarios --bin ks-pipeline-demo-scenarios-cli -- prepare-token-2022-fixture --rpc-url "$KB_DEVNET_RPC_URL" --wallet "$KB_DEVNET_WALLET" --wallet-dir "$PWD/wallets/temporary/local_devnet" --decimals 9 | tee "$KB_DEVNET_VALIDATION_DIR/50-spl-token-2022-fixture-preparation.json"
```
Lorsque `--rpc-url` et `--wallet` sont omis, la commande utilise respectivement `KB_DEVNET_RPC_URL` et `KB_DEVNET_WALLET`. Lorsque `--wallet-dir` est omis, elle utilise le répertoire parent du wallet.
@@ -623,7 +623,7 @@ export KB_DEVNET_SCENARIO="50-spl-token-2022"
5. Cliquer **Charger la fixture Token-2022**.
6. Vérifier que le message indique le chemin de `fixture.env` et le Program ID Token-2022.
Le bouton lit le `fixture.env` produit par `kb-pipeline-demo-scenarios` et remplit automatiquement :
Le bouton lit le `fixture.env` produit par `ks-pipeline-demo-scenarios` et remplit automatiquement :
- compte source ou cible ;
- mint ;

View File

@@ -1,5 +1,5 @@
<!-- file: docs/IDEA_REMINDERS.md -->
<!-- version: 8 -->
<!-- version: 9 -->
# Rappels didées
@@ -24,7 +24,7 @@ La décision normative et son calendrier sont dans [`decisions/KHADHROONY_SOLANA
- autocomplétion Token et Pool lorsque des tables de référence fiables existeront ;
- pagination SQL/IPC côté serveur avant lexploitation de volumes massifs ;
- résolution configurable du chemin de base de `kb-store` ;
- résolution configurable du chemin de base de `ks-store` ;
- sélection indépendante du profil de logging ;
## Pipeline et PostgreSQL

View File

@@ -1,7 +1,7 @@
<!-- file: docs/IDL_TO_KB_LIB_NOMENCLATURE.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Correspondance IDL ↔ `kb-lib`
# Correspondance IDL ↔ `ks-lib`
Ce tableau constitue la cible de classification pour les futurs décodeurs et exécuteurs.
Il ne signifie pas que tous les modules proposés sont déjà implémentés.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/MISSING_PROGRAM_IDLS.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Programmes ou IDL manquants
@@ -7,7 +7,7 @@ Cette liste distingue l'absence d'un fichier dans `idls_v3` de l'absence d'une I
## Surfaces Bot3 déjà implémentées sans IDL correspondante dans l'archive
| Classification `kb-lib` | Program ID | Situation |
| Classification `ks-lib` | Program ID | Situation |
|--------------------------------|------------------------------------------------|-------------------------------------------------|
| `spl/memo/v1` | `Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo` | aucune IDL correspondante dans `idls_v2` |
| `spl/memo/v4` | `Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH` | aucune IDL correspondante dans `idls_v2` |
@@ -19,4 +19,4 @@ Cette liste distingue l'absence d'un fichier dans `idls_v3` de l'absence d'une I
- Le fichier Memo présent correspond à `MemoSq4...`, donc à la génération v3 dans la nomenclature Bot3.
- L'absence d'IDL ne signifie pas l'absence de source normative : les crates d'interface officielles,
le code runtime et les matrices wire restent utilisables.
- La liste devra être recalculée après chaque ajout de programme à `kb-program-ids`.
- La liste devra être recalculée après chaque ajout de programme à `ks-program-ids`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/OPERATION_NAMING_CONVENTION.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Convention canonique des identités runtime et des codes dopération
@@ -41,7 +41,7 @@ metadata_metaplex_token_metadata.create_metadata_account_v3
## 2.1 Frontière avec les codes de registre
La notation par points sapplique aux identités runtime, processeurs, surfaces, opérations et événements persistés. Elle ne sapplique pas aux codes techniques du registre `kb-program-ids`, qui restent des identifiants Rust/registre en `lower_snake_case` afin de préserver leur ordre lexical, leur compatibilité et leur rôle de clé interne.
La notation par points sapplique aux identités runtime, processeurs, surfaces, opérations et événements persistés. Elle ne sapplique pas aux codes techniques du registre `ks-program-ids`, qui restent des identifiants Rust/registre en `lower_snake_case` afin de préserver leur ordre lexical, leur compatibilité et leur rôle de clé interne.
Exemples de codes de registre :
@@ -267,7 +267,7 @@ Une surface `decode_only` peut avoir `operationCode` et `executorName` à `null`
Avant de fusionner une nouvelle opération :
1. choisir son domaine et sa famille ;
2. identifier le Program ID canonique dans `kb-program-ids` ;
2. identifier le Program ID canonique dans `ks-program-ids` ;
3. définir `processor_name` et `surface_code` ;
4. définir séparément `operation_code` et `event_code` ;
5. ajouter les constantes Rust ;

View File

@@ -1,5 +1,5 @@
<!-- file: docs/README.md -->
<!-- version: 31 -->
<!-- version: 32 -->
# Documentation active de Khadhroony Bot3
@@ -70,16 +70,16 @@ Elles peuvent être chargées directement par les tests unitaires ou dintégr
Les onze crates possèdent `README.md`, `TODO.md`, `USAGE.md` et `CHANGELOG.md` :
- [`kb-core`](../kb-core/README.md) ;
- [`kb-config`](../kb-config/README.md) ;
- [`kb-lib`](../kb-lib/README.md) ;
- [`kb-logging`](../kb-logging/README.md) ;
- [`kb-program-ids`](../kb-program-ids/README.md) ;
- [`kb-pipeline`](../kb-pipeline/README.md) ;
- [`kb-pipeline-demo-scenarios`](../kb-pipeline-demo-scenarios/README.md) ;
- [`kb-onchain-transport`](../kb-onchain-transport/README.md) ;
- [`kb-store`](../kb-store/README.md) ;
- [`kb-wallet`](../kb-wallet/README.md) ;
- [`ks-core`](../ks-core/README.md) ;
- [`ks-config`](../ks-config/README.md) ;
- [`ks-lib`](../ks-lib/README.md) ;
- [`ks-logging`](../ks-logging/README.md) ;
- [`ks-program-ids`](../ks-program-ids/README.md) ;
- [`ks-pipeline`](../ks-pipeline/README.md) ;
- [`ks-pipeline-demo-scenarios`](../ks-pipeline-demo-scenarios/README.md) ;
- [`ks-onchain-transport`](../ks-onchain-transport/README.md) ;
- [`ks-store`](../ks-store/README.md) ;
- [`ks-wallet`](../ks-wallet/README.md) ;
- [`kb-app-demo-desktop`](../kb-app-demo-desktop/README.md).
## 8. Guides

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/ARCHITECTURE.md -->
<!-- version: 6 -->
<!-- version: 7 -->
# Architecture générale
@@ -12,7 +12,7 @@ configuration ─────┐
logging ───────────┼──────────────┐
program IDs ───────┘ │
v
transport -> store -> pipeline -> kb-lib
transport -> store -> pipeline -> ks-lib
│ │
v v
demo scenarios wallet/signers
@@ -28,32 +28,32 @@ Cette représentation indique les relations dominantes. Elle ne remplace pas le
### 2.1 Fondations
- `kb-core` fournit les erreurs et identités transversales minimales.
- `kb-config` charge, résout et valide la configuration.
- `kb-logging` initialise le logging et le tracing.
- `kb-program-ids` centralise les identifiants de programmes et comptes connus.
- `ks-core` fournit les erreurs et identités transversales minimales.
- `ks-config` charge, résout et valide la configuration.
- `ks-logging` initialise le logging et le tracing.
- `ks-program-ids` centralise les identifiants de programmes et comptes connus.
### 2.2 Noyau métier
`kb-lib` contient quatre familles principales :
`ks-lib` contient quatre familles principales :
- modèles et contrats partagés ;
- décodeurs ;
- exécuteurs ;
- matérialisateurs.
La façade publique est constituée par les réexports de `kb-lib/src/lib.rs`. Les modules internes conservent leurs frontières et leurs conventions de nommage.
La façade publique est constituée par les réexports de `ks-lib/src/lib.rs`. Les modules internes conservent leurs frontières et leurs conventions de nommage.
### 2.3 Acquisition et stockage
- `kb-onchain-transport` fournit les clients HTTP/WebSocket, pools, rôles dendpoints, méthodes RPC standard et contrats liés à lexécution RPC.
- `kb-store` regroupe les contrats store-neutral et limplémentation PostgreSQL.
- `ks-onchain-transport` fournit les clients HTTP/WebSocket, pools, rôles dendpoints, méthodes RPC standard et contrats liés à lexécution RPC.
- `ks-store` regroupe les contrats store-neutral et limplémentation PostgreSQL.
Les transports neffectuent pas la matérialisation métier. Le stockage ne décide pas quelle surface protocolaire doit être décodée.
### 2.4 Orchestration
`kb-pipeline` orchestre :
`ks-pipeline` orchestre :
- backfill ;
- extraction Core ;
@@ -62,14 +62,14 @@ Les transports neffectuent pas la matérialisation métier. Le stockage ne d
- corrélation stateful ;
- préflight et orchestration dexécution pour les surfaces prises en charge.
Il dépend des contrats de `kb-lib`, des données de `kb-store` et des capacités de `kb-onchain-transport` sans absorber leurs responsabilités.
Il dépend des contrats de `ks-lib`, des données de `ks-store` et des capacités de `ks-onchain-transport` sans absorber leurs responsabilités.
### 2.5 Démonstrations et applications
- `kb-pipeline-demo-scenarios` fournit les fixtures et campagnes réseau réutilisables spécifiques aux validations Devnet/Testnet. Les scénarios réutilisables doivent être appelables sans dépendre du desktop.
- Le binaire `kb-pipeline-demo-scenarios-cli` reste un outil ciblé ; son existence nimpose pas dexposer chaque scénario par un CLI.
- `kb-app-demo-desktop` est une crate mixte : bibliothèque Tauri et binaire desktop. Les commandes et projections UI y restent, tandis que la logique de scénario réutilisable doit être déléguée à `kb-pipeline-demo-scenarios`. Le reliquat éventuel de scénarios encore déclarés directement dans le desktop sera audité en `0.5.4`.
- `kb-wallet` fournit actuellement une frontière limitée de wallet temporaire et de signataire. Elle devient `ks-wallet` en `0.5.1`, puis sa restructuration fonctionnelle est planifiée en `0.5.2`.
- `ks-pipeline-demo-scenarios` fournit les fixtures et campagnes réseau réutilisables spécifiques aux validations Devnet/Testnet. Les scénarios réutilisables doivent être appelables sans dépendre du desktop.
- Le binaire `ks-pipeline-demo-scenarios-cli` reste un outil ciblé ; son existence nimpose pas dexposer chaque scénario par un CLI.
- `kb-app-demo-desktop` est une crate mixte : bibliothèque Tauri et binaire desktop. Les commandes et projections UI y restent, tandis que la logique de scénario réutilisable doit être déléguée à `ks-pipeline-demo-scenarios`. Le reliquat éventuel de scénarios encore déclarés directement dans le desktop sera audité en `0.5.4`.
- `ks-wallet` fournit actuellement une frontière limitée de wallet temporaire et de signataire. Elle devient `ks-wallet` en `0.5.1`, puis sa restructuration fonctionnelle est planifiée en `0.5.2`.
## 3. Flux principal de données
@@ -77,18 +77,18 @@ Il dépend des contrats de `kb-lib`, des données de `kb-store` et des capacité
Solana RPC / WebSocket
v
kb-onchain-transport
ks-onchain-transport
v
kb-store (données brutes/canoniques)
ks-store (données brutes/canoniques)
v
kb-pipeline
ks-pipeline
├── extraction Core
├── sélection des décodeurs
├── décodage via kb-lib
├── matérialisation via kb-lib
├── décodage via ks-lib
├── matérialisation via ks-lib
└── stockage des résultats
```
@@ -96,11 +96,11 @@ Lexécution suit un flux séparé : intention typée, construction, préfligh
## 4. Frontières obligatoires
- Les IDs canoniques ne doivent pas être dispersés lorsquils appartiennent au registre de `kb-program-ids`.
- Les APIs publiques de modèles, décodeurs, exécuteurs et matérialisateurs sont exposées par `kb-lib`.
- Les IDs canoniques ne doivent pas être dispersés lorsquils appartiennent au registre de `ks-program-ids`.
- Les APIs publiques de modèles, décodeurs, exécuteurs et matérialisateurs sont exposées par `ks-lib`.
- Les commandes Tauri et payloads frontend spécifiques restent dans `kb-app-demo-desktop`.
- Les scénarios réseau réutilisables spécifiques à Devnet/Testnet appartiennent à `kb-pipeline-demo-scenarios`, future `ks-pipeline-demo-scenarios`. `kb-app-demo-desktop` doit se limiter à ladaptation Tauri, aux payloads UI, à la présentation et à lappel de ces scénarios ; les doublons résiduels seront réconciliés en `0.5.4`.
- Toute primitive ou orchestration réellement généraliste, indépendante de lUI et dune campagne de démonstration précise, appartient à `kb-pipeline` ou à la crate métier propriétaire.
- Les scénarios réseau réutilisables spécifiques à Devnet/Testnet appartiennent à `ks-pipeline-demo-scenarios`, future `ks-pipeline-demo-scenarios`. `kb-app-demo-desktop` doit se limiter à ladaptation Tauri, aux payloads UI, à la présentation et à lappel de ces scénarios ; les doublons résiduels seront réconciliés en `0.5.4`.
- Toute primitive ou orchestration réellement généraliste, indépendante de lUI et dune campagne de démonstration précise, appartient à `ks-pipeline` ou à la crate métier propriétaire.
- Les fixtures contractuelles communes restent sous `test-fixtures/contract-matrices/` lorsquelles sont consommées par plusieurs tests.
- Les archives documentaires ne participent ni au build ni aux décisions normatives.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/CRATE_MAP.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Carte des crates
@@ -7,16 +7,16 @@
| Crate | Type | Responsabilité principale | État documentaire |
|------------------------------|------------------------|--------------------------------------------------------------------|------------------------------------------|
| `kb-core` | bibliothèque | erreurs, résultat et identité de module partagés | README/TODO/USAGE/CHANGELOG présents |
| `kb-config` | bibliothèque | configuration JSON, environnement, validation et profils | migration/restructuration en `0.5.1` |
| `kb-lib` | bibliothèque | modèles, décodeurs, exécuteurs et matérialisateurs consolidés | README/TODO/USAGE/CHANGELOG présents |
| `kb-logging` | bibliothèque | initialisation du logging et du tracing | README/TODO/USAGE/CHANGELOG présents |
| `kb-program-ids` | bibliothèque | registre des programmes et comptes Solana connus | README/TODO/USAGE/CHANGELOG présents |
| `kb-pipeline` | bibliothèque | backfill, extraction, replay, stateful, préflight et orchestration | README/TODO/USAGE/CHANGELOG présents |
| `kb-pipeline-demo-scenarios` | bibliothèque + binaire | scénarios Devnet réutilisables et CLI | renommage `0.5.1`, audit `0.5.4` |
| `kb-onchain-transport` | bibliothèque | transports RPC HTTP/WebSocket et pools dendpoints | README/TODO/USAGE/CHANGELOG présents |
| `kb-store` | bibliothèque | contrats de stockage et adaptateur PostgreSQL | renommage `0.5.1`, normalisation `0.5.3` |
| `kb-wallet` | bibliothèque | wallet temporaire et frontière de signataire | renommage `0.5.1`, refonte `0.5.2` |
| `ks-core` | bibliothèque | erreurs, résultat et identité de module partagés | README/TODO/USAGE/CHANGELOG présents |
| `ks-config` | bibliothèque | configuration JSON, environnement, validation et profils | migration/restructuration en `0.5.1` |
| `ks-lib` | bibliothèque | modèles, décodeurs, exécuteurs et matérialisateurs consolidés | README/TODO/USAGE/CHANGELOG présents |
| `ks-logging` | bibliothèque | initialisation du logging et du tracing | README/TODO/USAGE/CHANGELOG présents |
| `ks-program-ids` | bibliothèque | registre des programmes et comptes Solana connus | README/TODO/USAGE/CHANGELOG présents |
| `ks-pipeline` | bibliothèque | backfill, extraction, replay, stateful, préflight et orchestration | README/TODO/USAGE/CHANGELOG présents |
| `ks-pipeline-demo-scenarios` | bibliothèque + binaire | scénarios Devnet réutilisables et CLI | renommage `0.5.1`, audit `0.5.4` |
| `ks-onchain-transport` | bibliothèque | transports RPC HTTP/WebSocket et pools dendpoints | README/TODO/USAGE/CHANGELOG présents |
| `ks-store` | bibliothèque | contrats de stockage et adaptateur PostgreSQL | renommage `0.5.1`, normalisation `0.5.3` |
| `ks-wallet` | bibliothèque | wallet temporaire et frontière de signataire | renommage `0.5.1`, refonte `0.5.2` |
| `kb-app-demo-desktop` | bibliothèque + binaire | application de démonstration Tauri | documentée ; réconciliation en `0.5.4` |
La table décrit les noms physiques du workspace `0.5.0`. La migration `0.5.1` renomme les dix crates généralistes en `ks-core`, `ks-config`, `ks-lib`, `ks-logging`, `ks-program-ids`, `ks-pipeline`, `ks-pipeline-demo-scenarios`, `ks-onchain-transport`, `ks-store` et `ks-wallet`. `kb-app-demo-desktop` conserve son nom parce quil appartient au domaine applicatif Bot. Voir [`../decisions/KHADHROONY_SOLANA_NAMESPACE_POLICY.md`](../decisions/KHADHROONY_SOLANA_NAMESPACE_POLICY.md).
@@ -25,21 +25,21 @@ La table décrit les noms physiques du workspace `0.5.0`. La migration `0.5.1` r
La migration a regroupé de nombreuses anciennes crates dans des frontières plus larges :
- les modèles et APIs de décodage, matérialisation et exécution ont rejoint `kb-lib` ;
- les implémentations de stockage core et PostgreSQL ont rejoint `kb-store` ;
- les responsabilités de pipeline ont été réunies dans `kb-pipeline` ;
- les transports Solana sont réunis dans `kb-onchain-transport` ;
- les modèles et APIs de décodage, matérialisation et exécution ont rejoint `ks-lib` ;
- les implémentations de stockage core et PostgreSQL ont rejoint `ks-store` ;
- les responsabilités de pipeline ont été réunies dans `ks-pipeline` ;
- les transports Solana sont réunis dans `ks-onchain-transport` ;
- lapplication et sa bibliothèque sont réunies dans `kb-app-demo-desktop` ;
- les scénarios réutilisables ont été extraits dans `kb-pipeline-demo-scenarios`.
- les scénarios réutilisables ont été extraits dans `ks-pipeline-demo-scenarios`.
Cette carte nest pas une table de compatibilité exhaustive des anciennes crates. Les correspondances historiques détaillées seront synthétisées dans la documentation de migration et laudit dalignement.
## 3. Crates mixtes
### 3.1 `kb-pipeline-demo-scenarios`
### 3.1 `ks-pipeline-demo-scenarios`
- bibliothèque Rust : `kb_pipeline_demo_scenarios` ;
- binaire : `kb-pipeline-demo-scenarios-cli` ;
- bibliothèque Rust : `ks_pipeline_demo_scenarios` ;
- binaire : `ks-pipeline-demo-scenarios-cli` ;
- `autobins = false` évite une cible implicite concurrente.
### 3.2 `kb-app-demo-desktop`

View File

@@ -1,11 +1,11 @@
<!-- file: docs/architecture/PIPELINE_ARCHITECTURE.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Architecture du pipeline
## 1. Responsabilité
`kb-pipeline` coordonne des opérations généralistes qui traversent plusieurs crates sans devenir propriétaire de leurs implémentations : transport, stockage, contrats de décodage, matérialisation et exécution. Il ne dépend daucun scénario, wallet ou actif propre à un réseau de démonstration.
`ks-pipeline` coordonne des opérations généralistes qui traversent plusieurs crates sans devenir propriétaire de leurs implémentations : transport, stockage, contrats de décodage, matérialisation et exécution. Il ne dépend daucun scénario, wallet ou actif propre à un réseau de démonstration.
## 2. Familles de traitements
@@ -19,7 +19,7 @@ Lextraction Core transforme les transactions stockées en représentations d
### 2.3 Replay de décodage
Le replay sélectionne des candidats, applique les décodeurs compatibles de `kb-lib`, conserve diagnostics et preuves, puis déclenche les matérialisateurs demandés. La reprise doit préserver lidempotence et les frontières de campagne.
Le replay sélectionne des candidats, applique les décodeurs compatibles de `ks-lib`, conserve diagnostics et preuves, puis déclenche les matérialisateurs demandés. La reprise doit préserver lidempotence et les frontières de campagne.
### 2.4 Traitements stateful
@@ -27,28 +27,28 @@ Les modules stateful corrèlent instructions, comptes, états précédents et r
### 2.5 Préflight et exécution
Le pipeline assemble les contrôles préalables, plans préparés, signataires, preuves, simulation et validation postérieure. Les exécuteurs restent définis dans `kb-lib` ; le pipeline orchestre leur utilisation.
Le pipeline assemble les contrôles préalables, plans préparés, signataires, preuves, simulation et validation postérieure. Les exécuteurs restent définis dans `ks-lib` ; le pipeline orchestre leur utilisation.
## 3. Dépendances fonctionnelles
```text
kb-onchain-transport -> acquisition et appels RPC
kb-store -> lecture/écriture canonique et replay
kb-lib -> contrats et implémentations métier
kb-config -> profils et paramètres opérationnels
kb-logging -> observabilité
kb-wallet -> signataires lorsque requis
ks-onchain-transport -> acquisition et appels RPC
ks-store -> lecture/écriture canonique et replay
ks-lib -> contrats et implémentations métier
ks-config -> profils et paramètres opérationnels
ks-logging -> observabilité
ks-wallet -> signataires lorsque requis
```
## 4. Scénarios de démonstration
`kb-pipeline-demo-scenarios` contient les fixtures, aides de campagne et scénarios réutilisables spécifiques à Devnet ou Testnet. Le desktop doit appeler ces scénarios lorsquils existent plutôt que maintenir une seconde implémentation métier du même parcours.
`ks-pipeline-demo-scenarios` contient les fixtures, aides de campagne et scénarios réutilisables spécifiques à Devnet ou Testnet. Le desktop doit appeler ces scénarios lorsquils existent plutôt que maintenir une seconde implémentation métier du même parcours.
Cette crate peut préparer des wallets temporaires, demander des airdrops, créer des mints ou comptes de test, enchaîner plusieurs opérations et réunir les preuves dune campagne réseau. Ces responsabilités spécifiques aux validations réseau ne doivent pas remonter dans `kb-pipeline`.
Cette crate peut préparer des wallets temporaires, demander des airdrops, créer des mints ou comptes de test, enchaîner plusieurs opérations et réunir les preuves dune campagne réseau. Ces responsabilités spécifiques aux validations réseau ne doivent pas remonter dans `ks-pipeline`.
Le binaire `kb-pipeline-demo-scenarios-cli` est actuellement un outil ciblé de préparation des fixtures SPL Token-2022 réutilisées par les démonstrations Devnet. Son existence ne signifie pas que chaque scénario doit être exposé par un CLI ni que le desktop doit consommer ses scénarios.
Le binaire `ks-pipeline-demo-scenarios-cli` est actuellement un outil ciblé de préparation des fixtures SPL Token-2022 réutilisées par les démonstrations Devnet. Son existence ne signifie pas que chaque scénario doit être exposé par un CLI ni que le desktop doit consommer ses scénarios.
`kb-app-demo-desktop` conserve ses commandes Tauri, états, payloads et parcours de présentation Devnet/Testnet. La logique réutilisable de préparation et dexécution de campagne appartient à `kb-pipeline-demo-scenarios`, renommée `ks-pipeline-demo-scenarios` en `0.5.1`. `0.5.4` auditera les scénarios encore déclarés directement dans le desktop et déplacera ceux qui sont réutilisables. La dépendance inverse de `kb-pipeline` vers les scénarios reste interdite et cette règle se conserve après migration vers `ks-pipeline`.
`kb-app-demo-desktop` conserve ses commandes Tauri, états, payloads et parcours de présentation Devnet/Testnet. La logique réutilisable de préparation et dexécution de campagne appartient à `ks-pipeline-demo-scenarios`, renommée `ks-pipeline-demo-scenarios` en `0.5.1`. `0.5.4` auditera les scénarios encore déclarés directement dans le desktop et déplacera ceux qui sont réutilisables. La dépendance inverse de `ks-pipeline` vers les scénarios reste interdite et cette règle se conserve après migration vers `ks-pipeline`.
## 5. Contrats de preuve

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/PROJECT_OBJECTIVES.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Objectifs du projet Khadhroony Bot3
@@ -29,7 +29,7 @@ Le projet vise à :
### 3.1 Consolidation contrôlée
La consolidation ne signifie pas leffacement des frontières métier. `kb-lib` regroupe les modèles, décodeurs, exécuteurs et matérialisateurs dans des modules dédiés. `kb-store`, `kb-pipeline` et `kb-onchain-transport` restent des crates séparées parce quils représentent des responsabilités opérationnelles différentes.
La consolidation ne signifie pas leffacement des frontières métier. `ks-lib` regroupe les modèles, décodeurs, exécuteurs et matérialisateurs dans des modules dédiés. `ks-store`, `ks-pipeline` et `ks-onchain-transport` restent des crates séparées parce quils représentent des responsabilités opérationnelles différentes.
### 3.2 Contrats explicites

View File

@@ -1,11 +1,11 @@
<!-- file: docs/architecture/STORAGE_ARCHITECTURE.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Architecture du stockage
## 1. Responsabilité de `kb-store`
## 1. Responsabilité de `ks-store`
`kb-store` réunit :
`ks-store` réunit :
- les contrats store-neutral ;
- les DTO et entités persistées ;
@@ -34,7 +34,7 @@ Le module PostgreSQL possède :
### 2.3 Modèles partagés
Les modèles métier communs restent dans `kb-lib` lorsquils dépassent la seule persistance. `kb-store` ne doit pas créer une seconde définition concurrente dun contrat partagé.
Les modèles métier communs restent dans `ks-lib` lorsquils dépassent la seule persistance. `ks-store` ne doit pas créer une seconde définition concurrente dun contrat partagé.
## 3. Catégories de données
@@ -47,7 +47,7 @@ Le stockage couvre plusieurs niveaux :
- états de campagne et candidats de replay ;
- informations opérationnelles et de santé.
Les noms de tables, contrats de replay et APIs publiques sont documentés dans `kb-store/USAGE.md` à partir des exports et migrations actuels.
Les noms de tables, contrats de replay et APIs publiques sont documentés dans `ks-store/USAGE.md` à partir des exports et migrations actuels.
## 4. Propriétés attendues

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/SURFACE_CRATE_MATRIX.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Matrice des responsabilités par surface
@@ -13,7 +13,7 @@
## 2. Matrice
| Surface | `kb-lib` | `kb-pipeline` | `kb-store` | `kb-onchain-transport` | `kb-pipeline-demo-scenarios` | `kb-app-demo-desktop` |
| Surface | `ks-lib` | `ks-pipeline` | `ks-store` | `ks-onchain-transport` | `ks-pipeline-demo-scenarios` | `kb-app-demo-desktop` |
|---------------------------|--------------------------------------------------------------------------------|------------------------------------------------------|-----------------------|-------------------------------|--------------------------------------------------------|-----------------------------------------------------|
| Solana Core | décodeurs, exécuteurs et matérialisateurs | extraction, replay, stateful et exécution | persistance générique | RPC HTTP/WS | validations Devnet | panneaux fonctionnels |
| SPL Memo | décodage v1/v3/v4 ; exécution v4 | replay et exécution v4 | persistance générique | RPC | scénario Memo v4 | panneau Memo v4 |
@@ -29,7 +29,7 @@
Cette matrice décrit les responsabilités observées au niveau architectural. Elle ne déclare pas une couverture exhaustive de chaque instruction ou compte. La couverture détaillée reste démontrée par le code, les tests, les matrices sous `test-fixtures/contract-matrices/` et les rapports de validation actifs ou archivés.
La persistance des surfaces Metadata repose sur les contrats génériques de decode/materialization de `kb-store`. Leur séparation métier est portée notamment par les identités de processeur, les familles matérialisées, les clés de sortie et les payloads versionnés ; `0.4.8` nintroduit donc pas de schéma PostgreSQL spécialisé par protocole Metadata.
La persistance des surfaces Metadata repose sur les contrats génériques de decode/materialization de `ks-store`. Leur séparation métier est portée notamment par les identités de processeur, les familles matérialisées, les clés de sortie et les payloads versionnés ; `0.4.8` nintroduit donc pas de schéma PostgreSQL spécialisé par protocole Metadata.
## 4. Statuts sensibles
@@ -38,4 +38,4 @@ La persistance des surfaces Metadata repose sur les contrats génériques de dec
- Solana Program Metadata est couvert par neuf opérations stables, toutes validées sur Devnet.
- Token-2022 Token Metadata est couvert par cinq opérations dinterface, toutes validées sur Devnet.
- Metaplex Token Metadata est clos pour la matrice courante de `0.4.8` avec 15 opérations `confirmed`, 5 `unavailable` et 0 `not_run` ; les opérations indisponibles ne doivent pas être promues sans nouvelle preuve réseau.
- La priorité trading des versions suivantes naltère pas la vocation généraliste de `kb-lib` : les autres Program IDs restent dans le périmètre de couverture et peuvent être différés selon leur priorité de développement.
- La priorité trading des versions suivantes naltère pas la vocation généraliste de `ks-lib` : les autres Program IDs restent dans le périmètre de couverture et peuvent être différés selon leur priorité de développement.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/decisions/DOCUMENT_ARCHIVE_SELECTION_POLICY.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Politique de sélection des archives documentaires
@@ -61,8 +61,8 @@ kb_app_demo/package.json
kb_app_demo/tauri.conf.json
kb_app_demo/tsconfig.json
kb_rpc/tests/fixtures/*.json
kb_store_core/src/**
kb_store_pg/src/**
ks_store_core/src/**
ks_store_pg/src/**
```
## 7. Évolution de larchive

View File

@@ -1,5 +1,5 @@
<!-- file: docs/decisions/KHADHROONY_SOLANA_NAMESPACE_POLICY.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Politique de namespace Khadhroony Solana
@@ -7,7 +7,7 @@
Cette décision est adoptée pendant la clôture de `0.5.0` et devient la cible normative des migrations de fondation `0.5.1` à `0.5.3`.
Le workspace `0.5.0` conserve encore physiquement les noms `kb-*`, `kb_*`, `KB_*`, `kb-lib.*` et `kb_sol_*` là où ils existent. Leur présence avant migration ne remet pas en cause la cible ci-dessous.
À partir de `0.5.1-pre.002`, les dix crates Solana généralistes sont physiquement nommées `ks-*` et leurs identifiants Rust `ks_*`. Les namespaces historiques `KB_*`, `kb-lib.*` et `kb_sol_*` restent temporairement présents jusqu'aux prereleases dédiées ; leur présence pendant cette migration bornée ne remet pas en cause la cible ci-dessous.
Le renommage des bibliothèques internes ne renomme pas le workspace, le dépôt ni le répertoire racine : ils restent `khadhroony-bot3` pendant toute la série pré-`1.0`. Un éventuel renommage du workspace racine est explicitement hors périmètre de `0.5.x` et ne doit intervenir qu'en `1.0` ou ultérieurement sur décision dédiée.
@@ -23,22 +23,22 @@ Le renommage des bibliothèques internes ne renomme pas le workspace, le dépôt
## 3. Crates Solana généralistes
La migration `0.5.1` doit renommer les dix crates généralistes suivantes :
La migration `0.5.1-pre.002` renomme les dix crates généralistes suivantes :
| Nom `0.5.0` | Nom cible |
|------------------------------|------------------------------|
| `kb-core` | `ks-core` |
| `kb-config` | `ks-config` |
| `kb-lib` | `ks-lib` |
| `kb-logging` | `ks-logging` |
| `kb-program-ids` | `ks-program-ids` |
| `kb-pipeline` | `ks-pipeline` |
| Nom `0.5.0` | Nom cible |
|---|---|
| `kb-core` | `ks-core` |
| `kb-config` | `ks-config` |
| `kb-lib` | `ks-lib` |
| `kb-logging` | `ks-logging` |
| `kb-program-ids` | `ks-program-ids` |
| `kb-pipeline` | `ks-pipeline` |
| `kb-pipeline-demo-scenarios` | `ks-pipeline-demo-scenarios` |
| `kb-onchain-transport` | `ks-onchain-transport` |
| `kb-store` | `ks-store` |
| `kb-wallet` | `ks-wallet` |
| `kb-onchain-transport` | `ks-onchain-transport` |
| `kb-store` | `ks-store` |
| `kb-wallet` | `ks-wallet` |
Les identifiants Rust correspondants migrent vers `ks_*` : par exemple `kb_config` devient `ks_config` et `kb_pipeline_demo_scenarios` devient `ks_pipeline_demo_scenarios`.
Les identifiants Rust correspondants migrent dans le même delta vers `ks_*` : par exemple `kb_config` devient `ks_config` et `kb_pipeline_demo_scenarios` devient `ks_pipeline_demo_scenarios`.
La migration doit couvrir les manifests, chemins de workspace, imports, exports, tests d'API externe, scripts, documentation, targets de build et bindings générés à la source. Les artefacts générés restent régénérés localement selon les règles du workspace et ne sont pas livrés sans nécessité explicite.

View File

@@ -1,11 +1,11 @@
<!-- file: docs/guides/CONFIGURATION.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Guide de configuration
## Objectif
Ce guide décrit le chargement et lutilisation de la configuration bot3. La référence dAPI détaillée reste `kb-config/USAGE.md`.
Ce guide décrit le chargement et lutilisation de la configuration bot3. La référence dAPI détaillée reste `ks-config/USAGE.md`.
## Fichiers actifs
@@ -28,21 +28,21 @@ Le format actif est JSON. Le futur split de configuration prévu en `0.5.x` ne m
## Exemple opérateur
```rust
let environment = match kb_config::load_workspace_environment(
let environment = match ks_config::load_workspace_environment(
std::path::Path::new("."),
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let config = match kb_config::load_config_from_path(
let config = match ks_config::load_config_from_path(
std::path::Path::new("config/example.config.json"),
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let profile = match kb_config::active_profile(&config) {
let profile = match ks_config::active_profile(&config) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -83,8 +83,8 @@ Pour isoler une erreur :
## Références
- `kb-config/README.md` ;
- `kb-config/USAGE.md` ;
- `kb-config/TODO.md` ;
- `ks-config/README.md` ;
- `ks-config/USAGE.md` ;
- `ks-config/TODO.md` ;
- `config/README.md` ;
- `docs/decisions/WINCODE_COMPATIBILITY_POLICY.md`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/guides/DEVNET_VALIDATION.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Guide de validation Devnet
@@ -33,7 +33,7 @@ Le rapport doit indiquer précisément les niveaux réellement exécutés.
## Commandes
Les scénarios peuvent être déclenchés depuis `kb-pipeline-demo-scenarios` ou le desktop. La validation frontend se fait uniquement avec :
Les scénarios peuvent être déclenchés depuis `ks-pipeline-demo-scenarios` ou le desktop. La validation frontend se fait uniquement avec :
```bash
cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json
@@ -61,12 +61,12 @@ Le registre ElGamal ne doit pas être déclaré validé sur Devnet ou Mainnet sa
- `docs/validation/V0_4_7_METAPLEX_TOKEN_METADATA_VALIDATION_REPORT.md` ;
- `docs/DEVNET_EXECUTION_GUIDE.md` ;
- `kb-pipeline-demo-scenarios/USAGE.md` ;
- `ks-pipeline-demo-scenarios/USAGE.md` ;
- `kb-app-demo-desktop/USAGE.md`.
## Metaplex Token Metadata
Les scénarios Metadata utilisent un profil Devnet existant, le runner de `kb-pipeline-demo-scenarios` et le panneau `demo_execution_metadata`. Les PDA dérivables ne doivent pas être saisis manuellement. Chaque parcours prépare sa fixture et dérive automatiquement les PDA et comptes de postcondition nécessaires à létape courante.
Les scénarios Metadata utilisent un profil Devnet existant, le runner de `ks-pipeline-demo-scenarios` et le panneau `demo_execution_metadata`. Les PDA dérivables ne doivent pas être saisis manuellement. Chaque parcours prépare sa fixture et dérive automatiquement les PDA et comptes de postcondition nécessaires à létape courante.
Une liste de profils vide est une erreur de configuration ou de raccordement et doit être signalée explicitement. Une validation réseau exige une simulation RPC réelle ; une soumission exige en plus confirmation opérateur, signature, confirmation et postconditions observées.

View File

@@ -1,28 +1,28 @@
<!-- file: docs/guides/LOGGING.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Guide de logging et tracing
## Objectif
`kb-logging` initialise les routes de tracing définies par la configuration et conserve les guards nécessaires à leur durée de vie.
`ks-logging` initialise les routes de tracing définies par la configuration et conserve les guards nécessaires à leur durée de vie.
## Flux de démarrage
1. charger et valider la configuration avec `kb-config` ;
1. charger et valider la configuration avec `ks-config` ;
2. construire `LoggingConfig` ;
3. appeler `kb_logging::init_logging` une seule fois ;
3. appeler `ks_logging::init_logging` une seule fois ;
4. conserver `LoggingGuard` jusquà la fermeture du processus ;
5. émettre les événements avec des targets canoniques.
```rust
let guard = match kb_logging::init_logging(&config.logging) {
let guard = match ks_logging::init_logging(&config.logging) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
tracing::info!(
target: kb_logging::tracing_target(),
target: ks_logging::tracing_target(),
routes = guard.route_count(),
"logging initialized"
);
@@ -46,9 +46,9 @@ Les routes fichier ne doivent jamais écrire de secrets ou de keypairs.
Les targets suivent les conventions du workspace, par exemple :
```text
kb-pipeline.backfill
kb-pipeline.decode-replay
kb-onchain-transport.http
ks-pipeline.backfill
ks-pipeline.decode-replay
ks-onchain-transport.http
kb-lib.executor.spl.token-2022
kb-lib.materializer.compliance.audit
kb-lib.materializer.token.accounts
@@ -73,7 +73,7 @@ Les fenêtres Tauri utilisent la permission tracing prévue par leurs capabiliti
## Références
- `kb-logging/README.md` ;
- `kb-logging/USAGE.md` ;
- `kb-config/USAGE.md` ;
- `ks-logging/README.md` ;
- `ks-logging/USAGE.md` ;
- `ks-config/USAGE.md` ;
- `docs/architecture/ARCHITECTURE.md`.

View File

@@ -1,16 +1,16 @@
<!-- file: docs/guides/POSTGRES_STORAGE.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Guide PostgreSQL et contrats de stockage
## Objectif
`kb-store` consolide les contrats de stockage Core, raw, decode et PostgreSQL de bot2 dans une crate unique.
`ks-store` consolide les contrats de stockage Core, raw, decode et PostgreSQL de bot2 dans une crate unique.
## Connexion
```rust
let options = match kb_store::PostgresStoreOptions::new(
let options = match ks_store::PostgresStoreOptions::new(
database_url,
10,
10_000,
@@ -20,7 +20,7 @@ let options = match kb_store::PostgresStoreOptions::new(
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let store = match kb_store::PostgresStore::connect(options).await {
let store = match ks_store::PostgresStore::connect(options).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -62,5 +62,5 @@ Les traits publics séparent le contrat de limplémentation PostgreSQL. Les o
## Références
- `docs/architecture/STORAGE_ARCHITECTURE.md` ;
- `kb-store/USAGE.md` ;
- `kb-store/README.md`.
- `ks-store/USAGE.md` ;
- `ks-store/README.md`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/guides/REPLAY_CORE_EXTRACTION_AND_MATERIALIZATION.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Guide extraction Core, replay et matérialisation
@@ -24,7 +24,7 @@ matérialisation optionnelle
Lextraction transforme une transaction canonique persistée en entités Core normalisées. Elle doit conserver les index, comptes, Program IDs, succès ou échec de transaction et contexte nécessaire aux instructions internes.
```rust
let summary = match kb_pipeline::execute_core_extraction(
let summary = match ks_pipeline::execute_core_extraction(
request,
observer,
).await {
@@ -72,6 +72,6 @@ La progression persistée ne doit avancer quaprès clôture cohérente du can
- `docs/architecture/PIPELINE_ARCHITECTURE.md` ;
- `docs/architecture/STORAGE_ARCHITECTURE.md` ;
- `kb-pipeline/USAGE.md` ;
- `kb-lib/USAGE.md` ;
- `kb-store/USAGE.md`.
- `ks-pipeline/USAGE.md` ;
- `ks-lib/USAGE.md` ;
- `ks-store/USAGE.md`.

View File

@@ -1,26 +1,26 @@
<!-- file: docs/guides/RPC_BACKFILL_AND_WEBSOCKET.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Guide RPC, backfill et WebSocket
## Séparation des responsabilités
- `kb-onchain-transport` communique avec les endpoints ;
- `kb-pipeline` orchestre les campagnes ;
- `kb-store` persiste les acquisitions canoniques et la progression ;
- `ks-onchain-transport` communique avec les endpoints ;
- `ks-pipeline` orchestre les campagnes ;
- `ks-store` persiste les acquisitions canoniques et la progression ;
- `kb-app-demo-desktop` fournit une interface opérateur ;
- `kb-pipeline-demo-scenarios` construit et exécute les scénarios réutilisables de démonstration et de validation, notamment sur Devnet.
- `ks-pipeline-demo-scenarios` construit et exécute les scénarios réutilisables de démonstration et de validation, notamment sur Devnet.
## Passage dun scénario validé vers le pipeline
`kb-pipeline-demo-scenarios` nest pas la destination finale dune logique réutilisable en production. Son rôle est de composer des APIs publiques existantes, préparer les fixtures, imposer les garde-fous opérateur et démontrer un parcours complet sur un réseau de validation.
`ks-pipeline-demo-scenarios` nest pas la destination finale dune logique réutilisable en production. Son rôle est de composer des APIs publiques existantes, préparer les fixtures, imposer les garde-fous opérateur et démontrer un parcours complet sur un réseau de validation.
Lorsquun composant dun scénario est validé et quil est générique, déterministe et utilisable indépendamment de la démonstration, il doit résider dans la couche appropriée :
- `kb-lib` pour le décodage, la matérialisation, la construction dinstructions, les préflights et les politiques de sécurité ;
- `kb-onchain-transport` pour les opérations réseau génériques ;
- `kb-store` pour les contrats de persistance ;
- `kb-pipeline` pour lorchestration réutilisable, y compris sur Mainnet lorsque le profil, la politique et lappelant lautorisent.
- `ks-lib` pour le décodage, la matérialisation, la construction dinstructions, les préflights et les politiques de sécurité ;
- `ks-onchain-transport` pour les opérations réseau génériques ;
- `ks-store` pour les contrats de persistance ;
- `ks-pipeline` pour lorchestration réutilisable, y compris sur Mainnet lorsque le profil, la politique et lappelant lautorisent.
La crate de scénarios conserve :
@@ -49,7 +49,7 @@ Avant une campagne :
Le backfill parcourt les signatures, charge les transactions et les adapte vers le contrat canonique avant stockage.
```rust
let summary = match kb_pipeline::execute_http_backfill(
let summary = match ks_pipeline::execute_http_backfill(
request,
observer,
).await {
@@ -96,6 +96,6 @@ Distinguer :
## Références
- `kb-onchain-transport/USAGE.md` ;
- `kb-pipeline/USAGE.md` ;
- `ks-onchain-transport/USAGE.md` ;
- `ks-pipeline/USAGE.md` ;
- `kb-app-demo-desktop/USAGE.md`.

View File

@@ -1,13 +1,13 @@
<!-- file: docs/plans/V0_5_1_KHADHROONY_SOLANA_NAMESPACE_AND_CONFIG_PLAN.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Plan temporaire `0.5.1` — namespace Khadhroony Solana et configuration sûre
## 1. Statut et règle de cette prerelease
Ce document est le plan temporaire de `0.5.1`. `0.5.1-pre.001` reste exclusivement consacrée à l'inventaire, aux contrats de migration et au découpage des prereleases. Aucun répertoire de crate n'est renommé dans `pre.001` et aucun comportement runtime n'est restructuré.
Ce document est le plan temporaire de `0.5.1`. `0.5.1-pre.001` a fermé l'inventaire et les contrats de migration. `0.5.1-pre.002` réalise le premier changement structurel : les dix crates Solana généralistes, leurs packages, identifiants Rust, chemins de workspace, tests externes, scripts et CLI migrent vers `ks-*` / `ks_*`. `kb-app-demo-desktop` et le workspace racine restent nommés comme avant.
La base `0.5.0-pre.004` a été validée par `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --all-targets`, `python3 scripts/audit_rust_workspace_rules.py` et `cargo test --workspace`. Les tests d'API externe passent également.
La base `0.5.0-pre.004` puis `0.5.1-pre.001` ont été validées par `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --all-targets`, `python3 scripts/audit_rust_workspace_rules.py` et `cargo test --workspace`. Les tests d'API externe passent également. Les validations de `pre.002` doivent être rejouées après application du delta, car les noms de packages et de crates constituent une frontière de compilation réelle.
## 2. Invariant du workspace racine
@@ -32,18 +32,18 @@ Les bibliothèques internes Solana migrent vers `ks-*` / `ks_*` et leurs variabl
## 4. Inventaire des crates et ordre de migration
| Package actuel | Identifiant Rust actuel | Package cible | Identifiant Rust cible | Dépendances workspace directes actuelles | Ordre |
|------------------------------|------------------------------|------------------------------|------------------------------|----------------------------------------------------------------------------------------------------|------:|
| `kb-core` | `kb_core` | `ks-core` | `ks_core` | — | 1 |
| `kb-program-ids` | `kb_program_ids` | `ks-program-ids` | `ks_program_ids` | — | 2 |
| `kb-config` | `kb_config` | `ks-config` | `ks_config` | kb-core | 3 |
| `kb-logging` | `kb_logging` | `ks-logging` | `ks_logging` | kb-core | 4 |
| `kb-wallet` | `kb_wallet` | `ks-wallet` | `ks_wallet` | kb-core | 5 |
| `kb-lib` | `kb_lib` | `ks-lib` | `ks_lib` | kb-core, kb-program-ids | 6 |
| `kb-onchain-transport` | `kb_onchain_transport` | `ks-onchain-transport` | `ks_onchain_transport` | kb-config, kb-core, kb-lib | 7 |
| `kb-store` | `kb_store` | `ks-store` | `ks_store` | kb-core, kb-lib | 8 |
| `kb-pipeline` | `kb_pipeline` | `ks-pipeline` | `ks_pipeline` | kb-core, kb-config, kb-lib, kb-onchain-transport, kb-program-ids, kb-store | 9 |
| `kb-pipeline-demo-scenarios` | `kb_pipeline_demo_scenarios` | `ks-pipeline-demo-scenarios` | `ks_pipeline_demo_scenarios` | kb-core, kb-config, kb-lib, kb-onchain-transport, kb-pipeline, kb-program-ids, kb-store, kb-wallet | 10 |
| Package actuel | Identifiant Rust actuel | Package cible | Identifiant Rust cible | Dépendances workspace directes actuelles | Ordre |
|---|---|---|---|---|---:|
| `kb-core` | `kb_core` | `ks-core` | `ks_core` | — | 1 |
| `kb-program-ids` | `kb_program_ids` | `ks-program-ids` | `ks_program_ids` | — | 2 |
| `kb-config` | `kb_config` | `ks-config` | `ks_config` | kb-core | 3 |
| `kb-logging` | `kb_logging` | `ks-logging` | `ks_logging` | kb-core | 4 |
| `kb-wallet` | `kb_wallet` | `ks-wallet` | `ks_wallet` | kb-core | 5 |
| `kb-lib` | `kb_lib` | `ks-lib` | `ks_lib` | kb-core, kb-program-ids | 6 |
| `kb-onchain-transport` | `kb_onchain_transport` | `ks-onchain-transport` | `ks_onchain_transport` | kb-config, kb-core, kb-lib | 7 |
| `kb-store` | `kb_store` | `ks-store` | `ks_store` | kb-core, kb-lib | 8 |
| `kb-pipeline` | `kb_pipeline` | `ks-pipeline` | `ks_pipeline` | kb-core, kb-config, kb-lib, kb-onchain-transport, kb-program-ids, kb-store | 9 |
| `kb-pipeline-demo-scenarios` | `kb_pipeline_demo_scenarios` | `ks-pipeline-demo-scenarios` | `ks_pipeline_demo_scenarios` | kb-core, kb-config, kb-lib, kb-onchain-transport, kb-pipeline, kb-program-ids, kb-store, kb-wallet | 10 |
`kb-app-demo-desktop` est adapté en dernier, mais garde son package, son répertoire et ses identifiants applicatifs.
@@ -58,18 +58,18 @@ bin : kb-pipeline-demo-scenarios-cli -> ks-pipeline-demo-scenarios-cli
Les valeurs suivantes sont des métriques d'orientation sur les fichiers actifs, hors archives et artefacts générés. Elles montrent qu'un renommage massif en une seule opération serait difficile à diagnostiquer.
| Crate | Références package / fichiers | Références identifiant Rust / fichiers |
|------------------------------|------------------------------:|---------------------------------------:|
| `kb-core` | 51 / 32 | 3165 / 407 |
| `kb-config` | 56 / 33 | 201 / 44 |
| `kb-lib` | 3145 / 550 | 2785 / 97 |
| `kb-logging` | 72 / 27 | 22 / 3 |
| `kb-program-ids` | 42 / 28 | 1413 / 334 |
| `kb-pipeline` | 287 / 112 | 436 / 38 |
| `kb-pipeline-demo-scenarios` | 145 / 75 | 173 / 18 |
| `kb-onchain-transport` | 125 / 56 | 530 / 50 |
| `kb-store` | 157 / 81 | 344 / 30 |
| `kb-wallet` | 75 / 30 | 53 / 17 |
| Crate | Références package / fichiers | Références identifiant Rust / fichiers |
|---|---:|---:|
| `kb-core` | 51 / 32 | 3165 / 407 |
| `kb-config` | 56 / 33 | 201 / 44 |
| `kb-lib` | 3145 / 550 | 2785 / 97 |
| `kb-logging` | 72 / 27 | 22 / 3 |
| `kb-program-ids` | 42 / 28 | 1413 / 334 |
| `kb-pipeline` | 287 / 112 | 436 / 38 |
| `kb-pipeline-demo-scenarios` | 145 / 75 | 173 / 18 |
| `kb-onchain-transport` | 125 / 56 | 530 / 50 |
| `kb-store` | 157 / 81 | 344 / 30 |
| `kb-wallet` | 75 / 30 | 53 / 17 |
Le volume `kb-lib` inclut notamment les identités techniques `kb-lib.*`; il ne doit pas être interprété comme autant d'importations Cargo.
@@ -143,264 +143,264 @@ Les targets de tracing de crates génériques doivent également migrer vers `ks
### 6.1 Inventaire exhaustif des identités `kb-lib.*`
| Identité actuelle | Identité cible |
|----------------------------------------------------------------|----------------------------------------------------------------|
| `kb-lib.decoder.adapter.saber_decimal_wrapper` | `ks-lib-decoder.adapter.saber_decimal_wrapper` |
| `kb-lib.decoder.adapter.spl_token_wrap` | `ks-lib-decoder.adapter.spl_token_wrap` |
| `kb-lib.decoder.admin.jupiter_lock` | `ks-lib-decoder.admin.jupiter_lock` |
| `kb-lib.decoder.admin.pump_fees` | `ks-lib-decoder.admin.pump_fees` |
| `kb-lib.decoder.amm.aldrin_v1` | `ks-lib-decoder.amm.aldrin_v1` |
| `kb-lib.decoder.amm.aldrin_v2` | `ks-lib-decoder.amm.aldrin_v2` |
| `kb-lib.decoder.amm.alphaq` | `ks-lib-decoder.amm.alphaq` |
| `kb-lib.decoder.amm.believe` | `ks-lib-decoder.amm.believe` |
| `kb-lib.decoder.amm.bonk_swap` | `ks-lib-decoder.amm.bonk_swap` |
| `kb-lib.decoder.amm.fluxbeam` | `ks-lib-decoder.amm.fluxbeam` |
| `kb-lib.decoder.amm.goon_fi` | `ks-lib-decoder.amm.goon_fi` |
| `kb-lib.decoder.amm.goosefx_gamma` | `ks-lib-decoder.amm.goosefx_gamma` |
| `kb-lib.decoder.amm.goosefx_v2` | `ks-lib-decoder.amm.goosefx_v2` |
| `kb-lib.decoder.amm.guac_swap` | `ks-lib-decoder.amm.guac_swap` |
| `kb-lib.decoder.amm.lifinity_swap_v2` | `ks-lib-decoder.amm.lifinity_swap_v2` |
| `kb-lib.decoder.amm.metadao_futarchy_amm` | `ks-lib-decoder.amm.metadao_futarchy_amm` |
| `kb-lib.decoder.amm.metadao_v0_5` | `ks-lib-decoder.amm.metadao_v0_5` |
| `kb-lib.decoder.amm.meteora_damm_v1` | `ks-lib-decoder.amm.meteora_damm_v1` |
| `kb-lib.decoder.amm.meteora_damm_v2` | `ks-lib-decoder.amm.meteora_damm_v2` |
| `kb-lib.decoder.amm.obric_v2` | `ks-lib-decoder.amm.obric_v2` |
| `kb-lib.decoder.amm.one_dex` | `ks-lib-decoder.amm.one_dex` |
| `kb-lib.decoder.amm.pump_swap` | `ks-lib-decoder.amm.pump_swap` |
| `kb-lib.decoder.amm.raydium_lp_v4` | `ks-lib-decoder.amm.raydium_lp_v4` |
| `kb-lib.decoder.amm.solfi` | `ks-lib-decoder.amm.solfi` |
| `kb-lib.decoder.amm.solfi_v2` | `ks-lib-decoder.amm.solfi_v2` |
| `kb-lib.decoder.amm.vertigo` | `ks-lib-decoder.amm.vertigo` |
| `kb-lib.decoder.amm.virtuals` | `ks-lib-decoder.amm.virtuals` |
| `kb-lib.decoder.amm.woofi` | `ks-lib-decoder.amm.woofi` |
| `kb-lib.decoder.amm.zero_fi` | `ks-lib-decoder.amm.zero_fi` |
| `kb-lib.decoder.amm.zora` | `ks-lib-decoder.amm.zora` |
| `kb-lib.decoder.anchor` | `ks-lib-decoder.anchor` |
| `kb-lib.decoder.api` | `ks-lib-decoder.api` |
| `kb-lib.decoder.bridge.circle_cctp_token_messenger_minter` | `ks-lib-decoder.bridge.circle_cctp_token_messenger_minter` |
| `kb-lib.decoder.bridge.circle_cctp_token_messenger_minter_v2` | `ks-lib-decoder.bridge.circle_cctp_token_messenger_minter_v2` |
| `kb-lib.decoder.bridge.layer_zero_endpoint` | `ks-lib-decoder.bridge.layer_zero_endpoint` |
| `kb-lib.decoder.bridge.layer_zero_executor` | `ks-lib-decoder.bridge.layer_zero_executor` |
| `kb-lib.decoder.clmm.byreal` | `ks-lib-decoder.clmm.byreal` |
| `kb-lib.decoder.clmm.fusion` | `ks-lib-decoder.clmm.fusion` |
| `kb-lib.decoder.clmm.orca_whirlpool` | `ks-lib-decoder.clmm.orca_whirlpool` |
| `kb-lib.decoder.clmm.pancake_swap` | `ks-lib-decoder.clmm.pancake_swap` |
| `kb-lib.decoder.clmm.raydium` | `ks-lib-decoder.clmm.raydium` |
| `kb-lib.decoder.clmm.stabble` | `ks-lib-decoder.clmm.stabble` |
| `kb-lib.decoder.cpmm.raydium` | `ks-lib-decoder.cpmm.raydium` |
| `kb-lib.decoder.dlmm.meteora` | `ks-lib-decoder.dlmm.meteora` |
| `kb-lib.decoder.fees.bags_fee_share_v1` | `ks-lib-decoder.fees.bags_fee_share_v1` |
| `kb-lib.decoder.fees.bags_fee_share_v2` | `ks-lib-decoder.fees.bags_fee_share_v2` |
| `kb-lib.decoder.fees.pump_fees` | `ks-lib-decoder.fees.pump_fees` |
| `kb-lib.decoder.governance.metadao_bid_wall` | `ks-lib-decoder.governance.metadao_bid_wall` |
| `kb-lib.decoder.governance.metadao_futarchy` | `ks-lib-decoder.governance.metadao_futarchy` |
| `kb-lib.decoder.governance.squads_multisig` | `ks-lib-decoder.governance.squads_multisig` |
| `kb-lib.decoder.launchpad.boop_fun` | `ks-lib-decoder.launchpad.boop_fun` |
| `kb-lib.decoder.launchpad.metadao_ico` | `ks-lib-decoder.launchpad.metadao_ico` |
| `kb-lib.decoder.launchpad.meteora_dbc` | `ks-lib-decoder.launchpad.meteora_dbc` |
| `kb-lib.decoder.launchpad.moonit` | `ks-lib-decoder.launchpad.moonit` |
| `kb-lib.decoder.launchpad.orca_wavebreak` | `ks-lib-decoder.launchpad.orca_wavebreak` |
| `kb-lib.decoder.launchpad.printr` | `ks-lib-decoder.launchpad.printr` |
| `kb-lib.decoder.launchpad.pump_fun` | `ks-lib-decoder.launchpad.pump_fun` |
| `kb-lib.decoder.launchpad.pump_pumpup_ai` | `ks-lib-decoder.launchpad.pump_pumpup_ai` |
| `kb-lib.decoder.launchpad.raydium_launchlab` | `ks-lib-decoder.launchpad.raydium_launchlab` |
| `kb-lib.decoder.launchpad.virtuals` | `ks-lib-decoder.launchpad.virtuals` |
| `kb-lib.decoder.lending.clone` | `ks-lib-decoder.lending.clone` |
| `kb-lib.decoder.lending.jupiter_lend_borrow` | `ks-lib-decoder.lending.jupiter_lend_borrow` |
| `kb-lib.decoder.lending.jupiter_lend_earn` | `ks-lib-decoder.lending.jupiter_lend_earn` |
| `kb-lib.decoder.lending.jupiter_lend_flash_loan` | `ks-lib-decoder.lending.jupiter_lend_flash_loan` |
| `kb-lib.decoder.lending.jupiter_lend_liquidity` | `ks-lib-decoder.lending.jupiter_lend_liquidity` |
| `kb-lib.decoder.lending.kamino` | `ks-lib-decoder.lending.kamino` |
| `kb-lib.decoder.lending.marginfi_v2` | `ks-lib-decoder.lending.marginfi_v2` |
| `kb-lib.decoder.lock.raydium_lp` | `ks-lib-decoder.lock.raydium_lp` |
| `kb-lib.decoder.metadata.metaplex_token_metadata` | `ks-lib-decoder.metadata.metaplex_token_metadata` |
| `kb-lib.decoder.metadata.solana_program_metadata` | `ks-lib-decoder.metadata.solana_program_metadata` |
| `kb-lib.decoder.metadata.spl_name_service` | `ks-lib-decoder.metadata.spl_name_service` |
| `kb-lib.decoder.nft.metaplex_bubblegum` | `ks-lib-decoder.nft.metaplex_bubblegum` |
| `kb-lib.decoder.nft.tensor_cnft` | `ks-lib-decoder.nft.tensor_cnft` |
| `kb-lib.decoder.orderbook.jupiter_limit_order` | `ks-lib-decoder.orderbook.jupiter_limit_order` |
| `kb-lib.decoder.orderbook.jupiter_limit_order_v2` | `ks-lib-decoder.orderbook.jupiter_limit_order_v2` |
| `kb-lib.decoder.orderbook.openbook_v2` | `ks-lib-decoder.orderbook.openbook_v2` |
| `kb-lib.decoder.perpetuals.drift_v2` | `ks-lib-decoder.perpetuals.drift_v2` |
| `kb-lib.decoder.perpetuals.jupiter` | `ks-lib-decoder.perpetuals.jupiter` |
| `kb-lib.decoder.perpetuals.phoenix_eternal` | `ks-lib-decoder.perpetuals.phoenix_eternal` |
| `kb-lib.decoder.perpetuals.zeta` | `ks-lib-decoder.perpetuals.zeta` |
| `kb-lib.decoder.router.dflow_aggregator_v4` | `ks-lib-decoder.router.dflow_aggregator_v4` |
| `kb-lib.decoder.router.jupiter_aggregator_v4` | `ks-lib-decoder.router.jupiter_aggregator_v4` |
| `kb-lib.decoder.router.jupiter_aggregator_v6` | `ks-lib-decoder.router.jupiter_aggregator_v6` |
| `kb-lib.decoder.router.jupiter_dca` | `ks-lib-decoder.router.jupiter_dca` |
| `kb-lib.decoder.router.okx_labs_v1` | `ks-lib-decoder.router.okx_labs_v1` |
| `kb-lib.decoder.router.okx_labs_v2` | `ks-lib-decoder.router.okx_labs_v2` |
| `kb-lib.decoder.rwa.ondo_global_markets` | `ks-lib-decoder.rwa.ondo_global_markets` |
| `kb-lib.decoder.solana.core` | `ks-lib-decoder.solana.core` |
| `kb-lib.decoder.spl.account_compression` | `ks-lib-decoder.spl.account_compression` |
| `kb-lib.decoder.spl.associated_token_account` | `ks-lib-decoder.spl.associated_token_account` |
| `kb-lib.decoder.spl.elgamal_registry` | `ks-lib-decoder.spl.elgamal_registry` |
| `kb-lib.decoder.spl.memo` | `ks-lib-decoder.spl.memo` |
| `kb-lib.decoder.spl.noop` | `ks-lib-decoder.spl.noop` |
| `kb-lib.decoder.spl.single_pool` | `ks-lib-decoder.spl.single_pool` |
| `kb-lib.decoder.spl.stake_pool` | `ks-lib-decoder.spl.stake_pool` |
| `kb-lib.decoder.spl.token` | `ks-lib-decoder.spl.token` |
| `kb-lib.decoder.spl.token_2022` | `ks-lib-decoder.spl.token_2022` |
| `kb-lib.decoder.stable.swap_hylo_exchange` | `ks-lib-decoder.stable.swap_hylo_exchange` |
| `kb-lib.decoder.stable.swap_jupiter_stable` | `ks-lib-decoder.stable.swap_jupiter_stable` |
| `kb-lib.decoder.stable.swap_numeraire` | `ks-lib-decoder.stable.swap_numeraire` |
| `kb-lib.decoder.stable.swap_stabble` | `ks-lib-decoder.stable.swap_stabble` |
| `kb-lib.decoder.staking.jito_tip_distribution` | `ks-lib-decoder.staking.jito_tip_distribution` |
| `kb-lib.decoder.staking.kamino_farm` | `ks-lib-decoder.staking.kamino_farm` |
| `kb-lib.decoder.staking.marinade_finance` | `ks-lib-decoder.staking.marinade_finance` |
| `kb-lib.decoder.staking.solayer` | `ks-lib-decoder.staking.solayer` |
| `kb-lib.decoder.storage.solana_record` | `ks-lib-decoder.storage.solana_record` |
| `kb-lib.decoder.strategy.jupiter_dca` | `ks-lib-decoder.strategy.jupiter_dca` |
| `kb-lib.decoder.treasury.helium_treasury_management` | `ks-lib-decoder.treasury.helium_treasury_management` |
| `kb-lib.decoder.vault.carrot_defi` | `ks-lib-decoder.vault.carrot_defi` |
| `kb-lib.decoder.vault.hylo_stability_pool` | `ks-lib-decoder.vault.hylo_stability_pool` |
| `kb-lib.decoder.vault.kamino` | `ks-lib-decoder.vault.kamino` |
| `kb-lib.decoder.vault.kamino_v2` | `ks-lib-decoder.vault.kamino_v2` |
| `kb-lib.decoder.vault.kamino_yvaults` | `ks-lib-decoder.vault.kamino_yvaults` |
| `kb-lib.decoder.vault.meteora` | `ks-lib-decoder.vault.meteora` |
| `kb-lib.decoder.vesting.jupiter_lock` | `ks-lib-decoder.vesting.jupiter_lock` |
| `kb-lib.decoder.vesting.streamflow` | `ks-lib-decoder.vesting.streamflow` |
| `kb-lib.decoder.wallet.jupiter_apepro_smart_wallet` | `ks-lib-decoder.wallet.jupiter_apepro_smart_wallet` |
| `kb-lib.decoder.weighted.swap_stabble` | `ks-lib-decoder.weighted.swap_stabble` |
| `kb-lib.executor.adapter.saber_decimal_wrapper` | `ks-lib-executor.adapter.saber_decimal_wrapper` |
| `kb-lib.executor.adapter.spl_token_wrap` | `ks-lib-executor.adapter.spl_token_wrap` |
| `kb-lib.executor.amm.aldrin_v1` | `ks-lib-executor.amm.aldrin_v1` |
| `kb-lib.executor.amm.aldrin_v2` | `ks-lib-executor.amm.aldrin_v2` |
| `kb-lib.executor.amm.alphaq` | `ks-lib-executor.amm.alphaq` |
| `kb-lib.executor.amm.believe` | `ks-lib-executor.amm.believe` |
| `kb-lib.executor.amm.bonk_swap` | `ks-lib-executor.amm.bonk_swap` |
| `kb-lib.executor.amm.fluxbeam` | `ks-lib-executor.amm.fluxbeam` |
| `kb-lib.executor.amm.goon_fi` | `ks-lib-executor.amm.goon_fi` |
| `kb-lib.executor.amm.goosefx_gamma` | `ks-lib-executor.amm.goosefx_gamma` |
| `kb-lib.executor.amm.goosefx_v2` | `ks-lib-executor.amm.goosefx_v2` |
| `kb-lib.executor.amm.guac_swap` | `ks-lib-executor.amm.guac_swap` |
| `kb-lib.executor.amm.lifinity_swap_v2` | `ks-lib-executor.amm.lifinity_swap_v2` |
| `kb-lib.executor.amm.metadao_v0_5` | `ks-lib-executor.amm.metadao_v0_5` |
| `kb-lib.executor.amm.meteora_damm_v1` | `ks-lib-executor.amm.meteora_damm_v1` |
| `kb-lib.executor.amm.meteora_damm_v2` | `ks-lib-executor.amm.meteora_damm_v2` |
| `kb-lib.executor.amm.obric_v2` | `ks-lib-executor.amm.obric_v2` |
| `kb-lib.executor.amm.one_dex` | `ks-lib-executor.amm.one_dex` |
| `kb-lib.executor.amm.pump_swap` | `ks-lib-executor.amm.pump_swap` |
| `kb-lib.executor.amm.raydium_lp_v4` | `ks-lib-executor.amm.raydium_lp_v4` |
| `kb-lib.executor.amm.solfi` | `ks-lib-executor.amm.solfi` |
| `kb-lib.executor.amm.solfi_v2` | `ks-lib-executor.amm.solfi_v2` |
| `kb-lib.executor.amm.vertigo` | `ks-lib-executor.amm.vertigo` |
| `kb-lib.executor.amm.woofi` | `ks-lib-executor.amm.woofi` |
| `kb-lib.executor.amm.zero_fi` | `ks-lib-executor.amm.zero_fi` |
| `kb-lib.executor.amm.zora` | `ks-lib-executor.amm.zora` |
| `kb-lib.executor.bridge.circle_cctp_token_messenger_minter` | `ks-lib-executor.bridge.circle_cctp_token_messenger_minter` |
| Identité actuelle | Identité cible |
|---|---|
| `kb-lib.decoder.adapter.saber_decimal_wrapper` | `ks-lib-decoder.adapter.saber_decimal_wrapper` |
| `kb-lib.decoder.adapter.spl_token_wrap` | `ks-lib-decoder.adapter.spl_token_wrap` |
| `kb-lib.decoder.admin.jupiter_lock` | `ks-lib-decoder.admin.jupiter_lock` |
| `kb-lib.decoder.admin.pump_fees` | `ks-lib-decoder.admin.pump_fees` |
| `kb-lib.decoder.amm.aldrin_v1` | `ks-lib-decoder.amm.aldrin_v1` |
| `kb-lib.decoder.amm.aldrin_v2` | `ks-lib-decoder.amm.aldrin_v2` |
| `kb-lib.decoder.amm.alphaq` | `ks-lib-decoder.amm.alphaq` |
| `kb-lib.decoder.amm.believe` | `ks-lib-decoder.amm.believe` |
| `kb-lib.decoder.amm.bonk_swap` | `ks-lib-decoder.amm.bonk_swap` |
| `kb-lib.decoder.amm.fluxbeam` | `ks-lib-decoder.amm.fluxbeam` |
| `kb-lib.decoder.amm.goon_fi` | `ks-lib-decoder.amm.goon_fi` |
| `kb-lib.decoder.amm.goosefx_gamma` | `ks-lib-decoder.amm.goosefx_gamma` |
| `kb-lib.decoder.amm.goosefx_v2` | `ks-lib-decoder.amm.goosefx_v2` |
| `kb-lib.decoder.amm.guac_swap` | `ks-lib-decoder.amm.guac_swap` |
| `kb-lib.decoder.amm.lifinity_swap_v2` | `ks-lib-decoder.amm.lifinity_swap_v2` |
| `kb-lib.decoder.amm.metadao_futarchy_amm` | `ks-lib-decoder.amm.metadao_futarchy_amm` |
| `kb-lib.decoder.amm.metadao_v0_5` | `ks-lib-decoder.amm.metadao_v0_5` |
| `kb-lib.decoder.amm.meteora_damm_v1` | `ks-lib-decoder.amm.meteora_damm_v1` |
| `kb-lib.decoder.amm.meteora_damm_v2` | `ks-lib-decoder.amm.meteora_damm_v2` |
| `kb-lib.decoder.amm.obric_v2` | `ks-lib-decoder.amm.obric_v2` |
| `kb-lib.decoder.amm.one_dex` | `ks-lib-decoder.amm.one_dex` |
| `kb-lib.decoder.amm.pump_swap` | `ks-lib-decoder.amm.pump_swap` |
| `kb-lib.decoder.amm.raydium_lp_v4` | `ks-lib-decoder.amm.raydium_lp_v4` |
| `kb-lib.decoder.amm.solfi` | `ks-lib-decoder.amm.solfi` |
| `kb-lib.decoder.amm.solfi_v2` | `ks-lib-decoder.amm.solfi_v2` |
| `kb-lib.decoder.amm.vertigo` | `ks-lib-decoder.amm.vertigo` |
| `kb-lib.decoder.amm.virtuals` | `ks-lib-decoder.amm.virtuals` |
| `kb-lib.decoder.amm.woofi` | `ks-lib-decoder.amm.woofi` |
| `kb-lib.decoder.amm.zero_fi` | `ks-lib-decoder.amm.zero_fi` |
| `kb-lib.decoder.amm.zora` | `ks-lib-decoder.amm.zora` |
| `kb-lib.decoder.anchor` | `ks-lib-decoder.anchor` |
| `kb-lib.decoder.api` | `ks-lib-decoder.api` |
| `kb-lib.decoder.bridge.circle_cctp_token_messenger_minter` | `ks-lib-decoder.bridge.circle_cctp_token_messenger_minter` |
| `kb-lib.decoder.bridge.circle_cctp_token_messenger_minter_v2` | `ks-lib-decoder.bridge.circle_cctp_token_messenger_minter_v2` |
| `kb-lib.decoder.bridge.layer_zero_endpoint` | `ks-lib-decoder.bridge.layer_zero_endpoint` |
| `kb-lib.decoder.bridge.layer_zero_executor` | `ks-lib-decoder.bridge.layer_zero_executor` |
| `kb-lib.decoder.clmm.byreal` | `ks-lib-decoder.clmm.byreal` |
| `kb-lib.decoder.clmm.fusion` | `ks-lib-decoder.clmm.fusion` |
| `kb-lib.decoder.clmm.orca_whirlpool` | `ks-lib-decoder.clmm.orca_whirlpool` |
| `kb-lib.decoder.clmm.pancake_swap` | `ks-lib-decoder.clmm.pancake_swap` |
| `kb-lib.decoder.clmm.raydium` | `ks-lib-decoder.clmm.raydium` |
| `kb-lib.decoder.clmm.stabble` | `ks-lib-decoder.clmm.stabble` |
| `kb-lib.decoder.cpmm.raydium` | `ks-lib-decoder.cpmm.raydium` |
| `kb-lib.decoder.dlmm.meteora` | `ks-lib-decoder.dlmm.meteora` |
| `kb-lib.decoder.fees.bags_fee_share_v1` | `ks-lib-decoder.fees.bags_fee_share_v1` |
| `kb-lib.decoder.fees.bags_fee_share_v2` | `ks-lib-decoder.fees.bags_fee_share_v2` |
| `kb-lib.decoder.fees.pump_fees` | `ks-lib-decoder.fees.pump_fees` |
| `kb-lib.decoder.governance.metadao_bid_wall` | `ks-lib-decoder.governance.metadao_bid_wall` |
| `kb-lib.decoder.governance.metadao_futarchy` | `ks-lib-decoder.governance.metadao_futarchy` |
| `kb-lib.decoder.governance.squads_multisig` | `ks-lib-decoder.governance.squads_multisig` |
| `kb-lib.decoder.launchpad.boop_fun` | `ks-lib-decoder.launchpad.boop_fun` |
| `kb-lib.decoder.launchpad.metadao_ico` | `ks-lib-decoder.launchpad.metadao_ico` |
| `kb-lib.decoder.launchpad.meteora_dbc` | `ks-lib-decoder.launchpad.meteora_dbc` |
| `kb-lib.decoder.launchpad.moonit` | `ks-lib-decoder.launchpad.moonit` |
| `kb-lib.decoder.launchpad.orca_wavebreak` | `ks-lib-decoder.launchpad.orca_wavebreak` |
| `kb-lib.decoder.launchpad.printr` | `ks-lib-decoder.launchpad.printr` |
| `kb-lib.decoder.launchpad.pump_fun` | `ks-lib-decoder.launchpad.pump_fun` |
| `kb-lib.decoder.launchpad.pump_pumpup_ai` | `ks-lib-decoder.launchpad.pump_pumpup_ai` |
| `kb-lib.decoder.launchpad.raydium_launchlab` | `ks-lib-decoder.launchpad.raydium_launchlab` |
| `kb-lib.decoder.launchpad.virtuals` | `ks-lib-decoder.launchpad.virtuals` |
| `kb-lib.decoder.lending.clone` | `ks-lib-decoder.lending.clone` |
| `kb-lib.decoder.lending.jupiter_lend_borrow` | `ks-lib-decoder.lending.jupiter_lend_borrow` |
| `kb-lib.decoder.lending.jupiter_lend_earn` | `ks-lib-decoder.lending.jupiter_lend_earn` |
| `kb-lib.decoder.lending.jupiter_lend_flash_loan` | `ks-lib-decoder.lending.jupiter_lend_flash_loan` |
| `kb-lib.decoder.lending.jupiter_lend_liquidity` | `ks-lib-decoder.lending.jupiter_lend_liquidity` |
| `kb-lib.decoder.lending.kamino` | `ks-lib-decoder.lending.kamino` |
| `kb-lib.decoder.lending.marginfi_v2` | `ks-lib-decoder.lending.marginfi_v2` |
| `kb-lib.decoder.lock.raydium_lp` | `ks-lib-decoder.lock.raydium_lp` |
| `kb-lib.decoder.metadata.metaplex_token_metadata` | `ks-lib-decoder.metadata.metaplex_token_metadata` |
| `kb-lib.decoder.metadata.solana_program_metadata` | `ks-lib-decoder.metadata.solana_program_metadata` |
| `kb-lib.decoder.metadata.spl_name_service` | `ks-lib-decoder.metadata.spl_name_service` |
| `kb-lib.decoder.nft.metaplex_bubblegum` | `ks-lib-decoder.nft.metaplex_bubblegum` |
| `kb-lib.decoder.nft.tensor_cnft` | `ks-lib-decoder.nft.tensor_cnft` |
| `kb-lib.decoder.orderbook.jupiter_limit_order` | `ks-lib-decoder.orderbook.jupiter_limit_order` |
| `kb-lib.decoder.orderbook.jupiter_limit_order_v2` | `ks-lib-decoder.orderbook.jupiter_limit_order_v2` |
| `kb-lib.decoder.orderbook.openbook_v2` | `ks-lib-decoder.orderbook.openbook_v2` |
| `kb-lib.decoder.perpetuals.drift_v2` | `ks-lib-decoder.perpetuals.drift_v2` |
| `kb-lib.decoder.perpetuals.jupiter` | `ks-lib-decoder.perpetuals.jupiter` |
| `kb-lib.decoder.perpetuals.phoenix_eternal` | `ks-lib-decoder.perpetuals.phoenix_eternal` |
| `kb-lib.decoder.perpetuals.zeta` | `ks-lib-decoder.perpetuals.zeta` |
| `kb-lib.decoder.router.dflow_aggregator_v4` | `ks-lib-decoder.router.dflow_aggregator_v4` |
| `kb-lib.decoder.router.jupiter_aggregator_v4` | `ks-lib-decoder.router.jupiter_aggregator_v4` |
| `kb-lib.decoder.router.jupiter_aggregator_v6` | `ks-lib-decoder.router.jupiter_aggregator_v6` |
| `kb-lib.decoder.router.jupiter_dca` | `ks-lib-decoder.router.jupiter_dca` |
| `kb-lib.decoder.router.okx_labs_v1` | `ks-lib-decoder.router.okx_labs_v1` |
| `kb-lib.decoder.router.okx_labs_v2` | `ks-lib-decoder.router.okx_labs_v2` |
| `kb-lib.decoder.rwa.ondo_global_markets` | `ks-lib-decoder.rwa.ondo_global_markets` |
| `kb-lib.decoder.solana.core` | `ks-lib-decoder.solana.core` |
| `kb-lib.decoder.spl.account_compression` | `ks-lib-decoder.spl.account_compression` |
| `kb-lib.decoder.spl.associated_token_account` | `ks-lib-decoder.spl.associated_token_account` |
| `kb-lib.decoder.spl.elgamal_registry` | `ks-lib-decoder.spl.elgamal_registry` |
| `kb-lib.decoder.spl.memo` | `ks-lib-decoder.spl.memo` |
| `kb-lib.decoder.spl.noop` | `ks-lib-decoder.spl.noop` |
| `kb-lib.decoder.spl.single_pool` | `ks-lib-decoder.spl.single_pool` |
| `kb-lib.decoder.spl.stake_pool` | `ks-lib-decoder.spl.stake_pool` |
| `kb-lib.decoder.spl.token` | `ks-lib-decoder.spl.token` |
| `kb-lib.decoder.spl.token_2022` | `ks-lib-decoder.spl.token_2022` |
| `kb-lib.decoder.stable.swap_hylo_exchange` | `ks-lib-decoder.stable.swap_hylo_exchange` |
| `kb-lib.decoder.stable.swap_jupiter_stable` | `ks-lib-decoder.stable.swap_jupiter_stable` |
| `kb-lib.decoder.stable.swap_numeraire` | `ks-lib-decoder.stable.swap_numeraire` |
| `kb-lib.decoder.stable.swap_stabble` | `ks-lib-decoder.stable.swap_stabble` |
| `kb-lib.decoder.staking.jito_tip_distribution` | `ks-lib-decoder.staking.jito_tip_distribution` |
| `kb-lib.decoder.staking.kamino_farm` | `ks-lib-decoder.staking.kamino_farm` |
| `kb-lib.decoder.staking.marinade_finance` | `ks-lib-decoder.staking.marinade_finance` |
| `kb-lib.decoder.staking.solayer` | `ks-lib-decoder.staking.solayer` |
| `kb-lib.decoder.storage.solana_record` | `ks-lib-decoder.storage.solana_record` |
| `kb-lib.decoder.strategy.jupiter_dca` | `ks-lib-decoder.strategy.jupiter_dca` |
| `kb-lib.decoder.treasury.helium_treasury_management` | `ks-lib-decoder.treasury.helium_treasury_management` |
| `kb-lib.decoder.vault.carrot_defi` | `ks-lib-decoder.vault.carrot_defi` |
| `kb-lib.decoder.vault.hylo_stability_pool` | `ks-lib-decoder.vault.hylo_stability_pool` |
| `kb-lib.decoder.vault.kamino` | `ks-lib-decoder.vault.kamino` |
| `kb-lib.decoder.vault.kamino_v2` | `ks-lib-decoder.vault.kamino_v2` |
| `kb-lib.decoder.vault.kamino_yvaults` | `ks-lib-decoder.vault.kamino_yvaults` |
| `kb-lib.decoder.vault.meteora` | `ks-lib-decoder.vault.meteora` |
| `kb-lib.decoder.vesting.jupiter_lock` | `ks-lib-decoder.vesting.jupiter_lock` |
| `kb-lib.decoder.vesting.streamflow` | `ks-lib-decoder.vesting.streamflow` |
| `kb-lib.decoder.wallet.jupiter_apepro_smart_wallet` | `ks-lib-decoder.wallet.jupiter_apepro_smart_wallet` |
| `kb-lib.decoder.weighted.swap_stabble` | `ks-lib-decoder.weighted.swap_stabble` |
| `kb-lib.executor.adapter.saber_decimal_wrapper` | `ks-lib-executor.adapter.saber_decimal_wrapper` |
| `kb-lib.executor.adapter.spl_token_wrap` | `ks-lib-executor.adapter.spl_token_wrap` |
| `kb-lib.executor.amm.aldrin_v1` | `ks-lib-executor.amm.aldrin_v1` |
| `kb-lib.executor.amm.aldrin_v2` | `ks-lib-executor.amm.aldrin_v2` |
| `kb-lib.executor.amm.alphaq` | `ks-lib-executor.amm.alphaq` |
| `kb-lib.executor.amm.believe` | `ks-lib-executor.amm.believe` |
| `kb-lib.executor.amm.bonk_swap` | `ks-lib-executor.amm.bonk_swap` |
| `kb-lib.executor.amm.fluxbeam` | `ks-lib-executor.amm.fluxbeam` |
| `kb-lib.executor.amm.goon_fi` | `ks-lib-executor.amm.goon_fi` |
| `kb-lib.executor.amm.goosefx_gamma` | `ks-lib-executor.amm.goosefx_gamma` |
| `kb-lib.executor.amm.goosefx_v2` | `ks-lib-executor.amm.goosefx_v2` |
| `kb-lib.executor.amm.guac_swap` | `ks-lib-executor.amm.guac_swap` |
| `kb-lib.executor.amm.lifinity_swap_v2` | `ks-lib-executor.amm.lifinity_swap_v2` |
| `kb-lib.executor.amm.metadao_v0_5` | `ks-lib-executor.amm.metadao_v0_5` |
| `kb-lib.executor.amm.meteora_damm_v1` | `ks-lib-executor.amm.meteora_damm_v1` |
| `kb-lib.executor.amm.meteora_damm_v2` | `ks-lib-executor.amm.meteora_damm_v2` |
| `kb-lib.executor.amm.obric_v2` | `ks-lib-executor.amm.obric_v2` |
| `kb-lib.executor.amm.one_dex` | `ks-lib-executor.amm.one_dex` |
| `kb-lib.executor.amm.pump_swap` | `ks-lib-executor.amm.pump_swap` |
| `kb-lib.executor.amm.raydium_lp_v4` | `ks-lib-executor.amm.raydium_lp_v4` |
| `kb-lib.executor.amm.solfi` | `ks-lib-executor.amm.solfi` |
| `kb-lib.executor.amm.solfi_v2` | `ks-lib-executor.amm.solfi_v2` |
| `kb-lib.executor.amm.vertigo` | `ks-lib-executor.amm.vertigo` |
| `kb-lib.executor.amm.woofi` | `ks-lib-executor.amm.woofi` |
| `kb-lib.executor.amm.zero_fi` | `ks-lib-executor.amm.zero_fi` |
| `kb-lib.executor.amm.zora` | `ks-lib-executor.amm.zora` |
| `kb-lib.executor.bridge.circle_cctp_token_messenger_minter` | `ks-lib-executor.bridge.circle_cctp_token_messenger_minter` |
| `kb-lib.executor.bridge.circle_cctp_token_messenger_minter_v2` | `ks-lib-executor.bridge.circle_cctp_token_messenger_minter_v2` |
| `kb-lib.executor.bridge.layer_zero_endpoint` | `ks-lib-executor.bridge.layer_zero_endpoint` |
| `kb-lib.executor.bridge.layer_zero_executor` | `ks-lib-executor.bridge.layer_zero_executor` |
| `kb-lib.executor.clmm.byreal` | `ks-lib-executor.clmm.byreal` |
| `kb-lib.executor.clmm.fusion` | `ks-lib-executor.clmm.fusion` |
| `kb-lib.executor.clmm.orca_whirlpool` | `ks-lib-executor.clmm.orca_whirlpool` |
| `kb-lib.executor.clmm.pancake_swap` | `ks-lib-executor.clmm.pancake_swap` |
| `kb-lib.executor.clmm.raydium` | `ks-lib-executor.clmm.raydium` |
| `kb-lib.executor.clmm.stabble` | `ks-lib-executor.clmm.stabble` |
| `kb-lib.executor.cpmm.raydium` | `ks-lib-executor.cpmm.raydium` |
| `kb-lib.executor.dlmm.meteora` | `ks-lib-executor.dlmm.meteora` |
| `kb-lib.executor.fees.bags_fee_share_v1` | `ks-lib-executor.fees.bags_fee_share_v1` |
| `kb-lib.executor.fees.bags_fee_share_v2` | `ks-lib-executor.fees.bags_fee_share_v2` |
| `kb-lib.executor.fees.pump_fees` | `ks-lib-executor.fees.pump_fees` |
| `kb-lib.executor.governance.metadao_bid_wall` | `ks-lib-executor.governance.metadao_bid_wall` |
| `kb-lib.executor.governance.metadao_futarchy` | `ks-lib-executor.governance.metadao_futarchy` |
| `kb-lib.executor.governance.squads_multisig` | `ks-lib-executor.governance.squads_multisig` |
| `kb-lib.executor.launchpad.boop_fun` | `ks-lib-executor.launchpad.boop_fun` |
| `kb-lib.executor.launchpad.metadao_ico` | `ks-lib-executor.launchpad.metadao_ico` |
| `kb-lib.executor.launchpad.meteora_dbc` | `ks-lib-executor.launchpad.meteora_dbc` |
| `kb-lib.executor.launchpad.moonit` | `ks-lib-executor.launchpad.moonit` |
| `kb-lib.executor.launchpad.orca_wavebreak` | `ks-lib-executor.launchpad.orca_wavebreak` |
| `kb-lib.executor.launchpad.printr` | `ks-lib-executor.launchpad.printr` |
| `kb-lib.executor.launchpad.pump_fun` | `ks-lib-executor.launchpad.pump_fun` |
| `kb-lib.executor.launchpad.pump_pumpup_ai` | `ks-lib-executor.launchpad.pump_pumpup_ai` |
| `kb-lib.executor.launchpad.raydium_launchlab` | `ks-lib-executor.launchpad.raydium_launchlab` |
| `kb-lib.executor.launchpad.virtuals` | `ks-lib-executor.launchpad.virtuals` |
| `kb-lib.executor.lending.clone` | `ks-lib-executor.lending.clone` |
| `kb-lib.executor.lending.jupiter_lend_borrow` | `ks-lib-executor.lending.jupiter_lend_borrow` |
| `kb-lib.executor.lending.jupiter_lend_earn` | `ks-lib-executor.lending.jupiter_lend_earn` |
| `kb-lib.executor.lending.jupiter_lend_flash_loan` | `ks-lib-executor.lending.jupiter_lend_flash_loan` |
| `kb-lib.executor.lending.jupiter_lend_liquidity` | `ks-lib-executor.lending.jupiter_lend_liquidity` |
| `kb-lib.executor.lending.kamino` | `ks-lib-executor.lending.kamino` |
| `kb-lib.executor.lending.marginfi_v2` | `ks-lib-executor.lending.marginfi_v2` |
| `kb-lib.executor.lock.raydium_lp` | `ks-lib-executor.lock.raydium_lp` |
| `kb-lib.executor.metadata.metaplex_token_metadata` | `ks-lib-executor.metadata.metaplex_token_metadata` |
| `kb-lib.executor.metadata.solana_program_metadata` | `ks-lib-executor.metadata.solana_program_metadata` |
| `kb-lib.executor.metadata.spl_name_service` | `ks-lib-executor.metadata.spl_name_service` |
| `kb-lib.executor.nft.metaplex_bubblegum` | `ks-lib-executor.nft.metaplex_bubblegum` |
| `kb-lib.executor.nft.tensor_cnft` | `ks-lib-executor.nft.tensor_cnft` |
| `kb-lib.executor.orderbook.jupiter_limit_order` | `ks-lib-executor.orderbook.jupiter_limit_order` |
| `kb-lib.executor.orderbook.jupiter_limit_order_v2` | `ks-lib-executor.orderbook.jupiter_limit_order_v2` |
| `kb-lib.executor.orderbook.openbook_v2` | `ks-lib-executor.orderbook.openbook_v2` |
| `kb-lib.executor.perpetuals.drift_v2` | `ks-lib-executor.perpetuals.drift_v2` |
| `kb-lib.executor.perpetuals.jupiter` | `ks-lib-executor.perpetuals.jupiter` |
| `kb-lib.executor.perpetuals.phoenix_eternal` | `ks-lib-executor.perpetuals.phoenix_eternal` |
| `kb-lib.executor.perpetuals.zeta` | `ks-lib-executor.perpetuals.zeta` |
| `kb-lib.executor.router.dflow_aggregator_v4` | `ks-lib-executor.router.dflow_aggregator_v4` |
| `kb-lib.executor.router.jupiter_aggregator_v4` | `ks-lib-executor.router.jupiter_aggregator_v4` |
| `kb-lib.executor.router.jupiter_aggregator_v6` | `ks-lib-executor.router.jupiter_aggregator_v6` |
| `kb-lib.executor.router.okx_labs_v1` | `ks-lib-executor.router.okx_labs_v1` |
| `kb-lib.executor.router.okx_labs_v2` | `ks-lib-executor.router.okx_labs_v2` |
| `kb-lib.executor.rwa.ondo_global_markets` | `ks-lib-executor.rwa.ondo_global_markets` |
| `kb-lib.executor.solana.core` | `ks-lib-executor.solana.core` |
| `kb-lib.executor.solana.transaction` | `ks-lib-executor.solana.transaction` |
| `kb-lib.executor.spl.account_compression` | `ks-lib-executor.spl.account_compression` |
| `kb-lib.executor.spl.associated_token_account` | `ks-lib-executor.spl.associated_token_account` |
| `kb-lib.executor.spl.elgamal_registry` | `ks-lib-executor.spl.elgamal_registry` |
| `kb-lib.executor.spl.memo` | `ks-lib-executor.spl.memo` |
| `kb-lib.executor.spl.noop` | `ks-lib-executor.spl.noop` |
| `kb-lib.executor.spl.single_pool` | `ks-lib-executor.spl.single_pool` |
| `kb-lib.executor.spl.stake_pool` | `ks-lib-executor.spl.stake_pool` |
| `kb-lib.executor.spl.token` | `ks-lib-executor.spl.token` |
| `kb-lib.executor.spl.token-2022` | `ks-lib-executor.spl.token-2022` |
| `kb-lib.executor.spl.token_2022` | `ks-lib-executor.spl.token_2022` |
| `kb-lib.executor.stable.swap_hylo_exchange` | `ks-lib-executor.stable.swap_hylo_exchange` |
| `kb-lib.executor.stable.swap_jupiter_stable` | `ks-lib-executor.stable.swap_jupiter_stable` |
| `kb-lib.executor.stable.swap_numeraire` | `ks-lib-executor.stable.swap_numeraire` |
| `kb-lib.executor.stable.swap_stabble` | `ks-lib-executor.stable.swap_stabble` |
| `kb-lib.executor.staking.jito_tip_distribution` | `ks-lib-executor.staking.jito_tip_distribution` |
| `kb-lib.executor.staking.kamino_farm` | `ks-lib-executor.staking.kamino_farm` |
| `kb-lib.executor.staking.marinade_finance` | `ks-lib-executor.staking.marinade_finance` |
| `kb-lib.executor.staking.solayer` | `ks-lib-executor.staking.solayer` |
| `kb-lib.executor.storage.solana_record` | `ks-lib-executor.storage.solana_record` |
| `kb-lib.executor.strategy.jupiter_dca` | `ks-lib-executor.strategy.jupiter_dca` |
| `kb-lib.executor.treasury.helium_treasury_management` | `ks-lib-executor.treasury.helium_treasury_management` |
| `kb-lib.executor.vault.carrot_defi` | `ks-lib-executor.vault.carrot_defi` |
| `kb-lib.executor.vault.hylo_stability_pool` | `ks-lib-executor.vault.hylo_stability_pool` |
| `kb-lib.executor.vault.kamino` | `ks-lib-executor.vault.kamino` |
| `kb-lib.executor.vault.kamino_v2` | `ks-lib-executor.vault.kamino_v2` |
| `kb-lib.executor.vault.kamino_yvaults` | `ks-lib-executor.vault.kamino_yvaults` |
| `kb-lib.executor.vault.meteora` | `ks-lib-executor.vault.meteora` |
| `kb-lib.executor.vesting.jupiter_lock` | `ks-lib-executor.vesting.jupiter_lock` |
| `kb-lib.executor.vesting.streamflow` | `ks-lib-executor.vesting.streamflow` |
| `kb-lib.executor.wallet.jupiter_apepro_smart_wallet` | `ks-lib-executor.wallet.jupiter_apepro_smart_wallet` |
| `kb-lib.executor.weighted.swap_stabble` | `ks-lib-executor.weighted.swap_stabble` |
| `kb-lib.materializer.admin` | `ks-lib-materializer.admin` |
| `kb-lib.materializer.bridge` | `ks-lib-materializer.bridge` |
| `kb-lib.materializer.compliance.audit` | `ks-lib-materializer.compliance.audit` |
| `kb-lib.materializer.fees` | `ks-lib-materializer.fees` |
| `kb-lib.materializer.governance` | `ks-lib-materializer.governance` |
| `kb-lib.materializer.lending` | `ks-lib-materializer.lending` |
| `kb-lib.materializer.lifecycle` | `ks-lib-materializer.lifecycle` |
| `kb-lib.materializer.liquidity` | `ks-lib-materializer.liquidity` |
| `kb-lib.materializer.metadata.metaplex_token_metadata` | `ks-lib-materializer.metadata.metaplex_token_metadata` |
| `kb-lib.materializer.metadata.solana_program_metadata` | `ks-lib-materializer.metadata.solana_program_metadata` |
| `kb-lib.materializer.metadata.token_2022` | `ks-lib-materializer.metadata.token_2022` |
| `kb-lib.materializer.nft` | `ks-lib-materializer.nft` |
| `kb-lib.materializer.oracle` | `ks-lib-materializer.oracle` |
| `kb-lib.materializer.orderbook` | `ks-lib-materializer.orderbook` |
| `kb-lib.materializer.perpetuals` | `ks-lib-materializer.perpetuals` |
| `kb-lib.materializer.pool.state` | `ks-lib-materializer.pool.state` |
| `kb-lib.materializer.rewards` | `ks-lib-materializer.rewards` |
| `kb-lib.materializer.risk` | `ks-lib-materializer.risk` |
| `kb-lib.materializer.routing` | `ks-lib-materializer.routing` |
| `kb-lib.materializer.staking` | `ks-lib-materializer.staking` |
| `kb-lib.materializer.token.accounts` | `ks-lib-materializer.token.accounts` |
| `kb-lib.materializer.token.metadata_risk` | `ks-lib-materializer.token.metadata_risk` |
| `kb-lib.materializer.trades` | `ks-lib-materializer.trades` |
| `kb-lib.materializer.transaction.annotations` | `ks-lib-materializer.transaction.annotations` |
| `kb-lib.materializer.vault` | `ks-lib-materializer.vault` |
| `kb-lib.executor.bridge.layer_zero_endpoint` | `ks-lib-executor.bridge.layer_zero_endpoint` |
| `kb-lib.executor.bridge.layer_zero_executor` | `ks-lib-executor.bridge.layer_zero_executor` |
| `kb-lib.executor.clmm.byreal` | `ks-lib-executor.clmm.byreal` |
| `kb-lib.executor.clmm.fusion` | `ks-lib-executor.clmm.fusion` |
| `kb-lib.executor.clmm.orca_whirlpool` | `ks-lib-executor.clmm.orca_whirlpool` |
| `kb-lib.executor.clmm.pancake_swap` | `ks-lib-executor.clmm.pancake_swap` |
| `kb-lib.executor.clmm.raydium` | `ks-lib-executor.clmm.raydium` |
| `kb-lib.executor.clmm.stabble` | `ks-lib-executor.clmm.stabble` |
| `kb-lib.executor.cpmm.raydium` | `ks-lib-executor.cpmm.raydium` |
| `kb-lib.executor.dlmm.meteora` | `ks-lib-executor.dlmm.meteora` |
| `kb-lib.executor.fees.bags_fee_share_v1` | `ks-lib-executor.fees.bags_fee_share_v1` |
| `kb-lib.executor.fees.bags_fee_share_v2` | `ks-lib-executor.fees.bags_fee_share_v2` |
| `kb-lib.executor.fees.pump_fees` | `ks-lib-executor.fees.pump_fees` |
| `kb-lib.executor.governance.metadao_bid_wall` | `ks-lib-executor.governance.metadao_bid_wall` |
| `kb-lib.executor.governance.metadao_futarchy` | `ks-lib-executor.governance.metadao_futarchy` |
| `kb-lib.executor.governance.squads_multisig` | `ks-lib-executor.governance.squads_multisig` |
| `kb-lib.executor.launchpad.boop_fun` | `ks-lib-executor.launchpad.boop_fun` |
| `kb-lib.executor.launchpad.metadao_ico` | `ks-lib-executor.launchpad.metadao_ico` |
| `kb-lib.executor.launchpad.meteora_dbc` | `ks-lib-executor.launchpad.meteora_dbc` |
| `kb-lib.executor.launchpad.moonit` | `ks-lib-executor.launchpad.moonit` |
| `kb-lib.executor.launchpad.orca_wavebreak` | `ks-lib-executor.launchpad.orca_wavebreak` |
| `kb-lib.executor.launchpad.printr` | `ks-lib-executor.launchpad.printr` |
| `kb-lib.executor.launchpad.pump_fun` | `ks-lib-executor.launchpad.pump_fun` |
| `kb-lib.executor.launchpad.pump_pumpup_ai` | `ks-lib-executor.launchpad.pump_pumpup_ai` |
| `kb-lib.executor.launchpad.raydium_launchlab` | `ks-lib-executor.launchpad.raydium_launchlab` |
| `kb-lib.executor.launchpad.virtuals` | `ks-lib-executor.launchpad.virtuals` |
| `kb-lib.executor.lending.clone` | `ks-lib-executor.lending.clone` |
| `kb-lib.executor.lending.jupiter_lend_borrow` | `ks-lib-executor.lending.jupiter_lend_borrow` |
| `kb-lib.executor.lending.jupiter_lend_earn` | `ks-lib-executor.lending.jupiter_lend_earn` |
| `kb-lib.executor.lending.jupiter_lend_flash_loan` | `ks-lib-executor.lending.jupiter_lend_flash_loan` |
| `kb-lib.executor.lending.jupiter_lend_liquidity` | `ks-lib-executor.lending.jupiter_lend_liquidity` |
| `kb-lib.executor.lending.kamino` | `ks-lib-executor.lending.kamino` |
| `kb-lib.executor.lending.marginfi_v2` | `ks-lib-executor.lending.marginfi_v2` |
| `kb-lib.executor.lock.raydium_lp` | `ks-lib-executor.lock.raydium_lp` |
| `kb-lib.executor.metadata.metaplex_token_metadata` | `ks-lib-executor.metadata.metaplex_token_metadata` |
| `kb-lib.executor.metadata.solana_program_metadata` | `ks-lib-executor.metadata.solana_program_metadata` |
| `kb-lib.executor.metadata.spl_name_service` | `ks-lib-executor.metadata.spl_name_service` |
| `kb-lib.executor.nft.metaplex_bubblegum` | `ks-lib-executor.nft.metaplex_bubblegum` |
| `kb-lib.executor.nft.tensor_cnft` | `ks-lib-executor.nft.tensor_cnft` |
| `kb-lib.executor.orderbook.jupiter_limit_order` | `ks-lib-executor.orderbook.jupiter_limit_order` |
| `kb-lib.executor.orderbook.jupiter_limit_order_v2` | `ks-lib-executor.orderbook.jupiter_limit_order_v2` |
| `kb-lib.executor.orderbook.openbook_v2` | `ks-lib-executor.orderbook.openbook_v2` |
| `kb-lib.executor.perpetuals.drift_v2` | `ks-lib-executor.perpetuals.drift_v2` |
| `kb-lib.executor.perpetuals.jupiter` | `ks-lib-executor.perpetuals.jupiter` |
| `kb-lib.executor.perpetuals.phoenix_eternal` | `ks-lib-executor.perpetuals.phoenix_eternal` |
| `kb-lib.executor.perpetuals.zeta` | `ks-lib-executor.perpetuals.zeta` |
| `kb-lib.executor.router.dflow_aggregator_v4` | `ks-lib-executor.router.dflow_aggregator_v4` |
| `kb-lib.executor.router.jupiter_aggregator_v4` | `ks-lib-executor.router.jupiter_aggregator_v4` |
| `kb-lib.executor.router.jupiter_aggregator_v6` | `ks-lib-executor.router.jupiter_aggregator_v6` |
| `kb-lib.executor.router.okx_labs_v1` | `ks-lib-executor.router.okx_labs_v1` |
| `kb-lib.executor.router.okx_labs_v2` | `ks-lib-executor.router.okx_labs_v2` |
| `kb-lib.executor.rwa.ondo_global_markets` | `ks-lib-executor.rwa.ondo_global_markets` |
| `kb-lib.executor.solana.core` | `ks-lib-executor.solana.core` |
| `kb-lib.executor.solana.transaction` | `ks-lib-executor.solana.transaction` |
| `kb-lib.executor.spl.account_compression` | `ks-lib-executor.spl.account_compression` |
| `kb-lib.executor.spl.associated_token_account` | `ks-lib-executor.spl.associated_token_account` |
| `kb-lib.executor.spl.elgamal_registry` | `ks-lib-executor.spl.elgamal_registry` |
| `kb-lib.executor.spl.memo` | `ks-lib-executor.spl.memo` |
| `kb-lib.executor.spl.noop` | `ks-lib-executor.spl.noop` |
| `kb-lib.executor.spl.single_pool` | `ks-lib-executor.spl.single_pool` |
| `kb-lib.executor.spl.stake_pool` | `ks-lib-executor.spl.stake_pool` |
| `kb-lib.executor.spl.token` | `ks-lib-executor.spl.token` |
| `kb-lib.executor.spl.token-2022` | `ks-lib-executor.spl.token-2022` |
| `kb-lib.executor.spl.token_2022` | `ks-lib-executor.spl.token_2022` |
| `kb-lib.executor.stable.swap_hylo_exchange` | `ks-lib-executor.stable.swap_hylo_exchange` |
| `kb-lib.executor.stable.swap_jupiter_stable` | `ks-lib-executor.stable.swap_jupiter_stable` |
| `kb-lib.executor.stable.swap_numeraire` | `ks-lib-executor.stable.swap_numeraire` |
| `kb-lib.executor.stable.swap_stabble` | `ks-lib-executor.stable.swap_stabble` |
| `kb-lib.executor.staking.jito_tip_distribution` | `ks-lib-executor.staking.jito_tip_distribution` |
| `kb-lib.executor.staking.kamino_farm` | `ks-lib-executor.staking.kamino_farm` |
| `kb-lib.executor.staking.marinade_finance` | `ks-lib-executor.staking.marinade_finance` |
| `kb-lib.executor.staking.solayer` | `ks-lib-executor.staking.solayer` |
| `kb-lib.executor.storage.solana_record` | `ks-lib-executor.storage.solana_record` |
| `kb-lib.executor.strategy.jupiter_dca` | `ks-lib-executor.strategy.jupiter_dca` |
| `kb-lib.executor.treasury.helium_treasury_management` | `ks-lib-executor.treasury.helium_treasury_management` |
| `kb-lib.executor.vault.carrot_defi` | `ks-lib-executor.vault.carrot_defi` |
| `kb-lib.executor.vault.hylo_stability_pool` | `ks-lib-executor.vault.hylo_stability_pool` |
| `kb-lib.executor.vault.kamino` | `ks-lib-executor.vault.kamino` |
| `kb-lib.executor.vault.kamino_v2` | `ks-lib-executor.vault.kamino_v2` |
| `kb-lib.executor.vault.kamino_yvaults` | `ks-lib-executor.vault.kamino_yvaults` |
| `kb-lib.executor.vault.meteora` | `ks-lib-executor.vault.meteora` |
| `kb-lib.executor.vesting.jupiter_lock` | `ks-lib-executor.vesting.jupiter_lock` |
| `kb-lib.executor.vesting.streamflow` | `ks-lib-executor.vesting.streamflow` |
| `kb-lib.executor.wallet.jupiter_apepro_smart_wallet` | `ks-lib-executor.wallet.jupiter_apepro_smart_wallet` |
| `kb-lib.executor.weighted.swap_stabble` | `ks-lib-executor.weighted.swap_stabble` |
| `kb-lib.materializer.admin` | `ks-lib-materializer.admin` |
| `kb-lib.materializer.bridge` | `ks-lib-materializer.bridge` |
| `kb-lib.materializer.compliance.audit` | `ks-lib-materializer.compliance.audit` |
| `kb-lib.materializer.fees` | `ks-lib-materializer.fees` |
| `kb-lib.materializer.governance` | `ks-lib-materializer.governance` |
| `kb-lib.materializer.lending` | `ks-lib-materializer.lending` |
| `kb-lib.materializer.lifecycle` | `ks-lib-materializer.lifecycle` |
| `kb-lib.materializer.liquidity` | `ks-lib-materializer.liquidity` |
| `kb-lib.materializer.metadata.metaplex_token_metadata` | `ks-lib-materializer.metadata.metaplex_token_metadata` |
| `kb-lib.materializer.metadata.solana_program_metadata` | `ks-lib-materializer.metadata.solana_program_metadata` |
| `kb-lib.materializer.metadata.token_2022` | `ks-lib-materializer.metadata.token_2022` |
| `kb-lib.materializer.nft` | `ks-lib-materializer.nft` |
| `kb-lib.materializer.oracle` | `ks-lib-materializer.oracle` |
| `kb-lib.materializer.orderbook` | `ks-lib-materializer.orderbook` |
| `kb-lib.materializer.perpetuals` | `ks-lib-materializer.perpetuals` |
| `kb-lib.materializer.pool.state` | `ks-lib-materializer.pool.state` |
| `kb-lib.materializer.rewards` | `ks-lib-materializer.rewards` |
| `kb-lib.materializer.risk` | `ks-lib-materializer.risk` |
| `kb-lib.materializer.routing` | `ks-lib-materializer.routing` |
| `kb-lib.materializer.staking` | `ks-lib-materializer.staking` |
| `kb-lib.materializer.token.accounts` | `ks-lib-materializer.token.accounts` |
| `kb-lib.materializer.token.metadata_risk` | `ks-lib-materializer.token.metadata_risk` |
| `kb-lib.materializer.trades` | `ks-lib-materializer.trades` |
| `kb-lib.materializer.transaction.annotations` | `ks-lib-materializer.transaction.annotations` |
| `kb-lib.materializer.vault` | `ks-lib-materializer.vault` |
## 7. Inventaire des variables d'environnement
@@ -440,112 +440,112 @@ Les treize variables historiques `TOKEN_2022_*` sont des fixtures Devnet et conv
### 7.2 Mapping code/config/tests — 82 noms
| Nom actuel | Nom cible | Classe |
|--------------------------------------------------------------|--------------------------------------------------------------|------------|
| `HELIUS_API_KEY` | `KS_SECRET_HELIUS_API_KEY` | `secret` |
| `KB_CONFIG_PATH` | `KS_CONFIG_PATH` | `internal` |
| `KB_CONFIG_TEST_MISSING` | `KS_CONFIG_TEST_MISSING` | `internal` |
| `KB_DEVNET_AIRDROP_LAMPORTS` | `KS_DEVNET_AIRDROP_LAMPORTS` | `internal` |
| `KB_DEVNET_CONFIG_PATH` | `KS_DEVNET_CONFIG_PATH` | `internal` |
| `KB_DEVNET_EXECUTION_TEST` | `KS_DEVNET_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_MEMO_EXECUTION_TEST` | `KS_DEVNET_MEMO_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_MEMO_SUBMIT` | `KS_DEVNET_MEMO_SUBMIT` | `internal` |
| `KB_DEVNET_METAPLEX_COLLECTION_VERIFY_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_COLLECTION_VERIFY_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_CREATE_MINT_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_CREATE_MINT_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_CREATE_MINT_FAMILY` | `KS_DEVNET_METAPLEX_CREATE_MINT_FAMILY` | `internal` |
| `KB_DEVNET_METAPLEX_ESCROW_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_ESCROW_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_EXECUTION_TEST` | `KS_DEVNET_METAPLEX_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_MAINTENANCE_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_MAINTENANCE_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_MATERIALIZE_AFTER_CONFIRMATION` | `KS_DEVNET_METAPLEX_MATERIALIZE_AFTER_CONFIRMATION` | `internal` |
| `KB_DEVNET_METAPLEX_OPERATION_JSON` | `KS_DEVNET_METAPLEX_OPERATION_JSON` | `internal` |
| `KB_DEVNET_METAPLEX_OPERATOR_CONFIRMED` | `KS_DEVNET_METAPLEX_OPERATOR_CONFIRMED` | `internal` |
| `KB_DEVNET_METAPLEX_PNFT_LIFECYCLE_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_PNFT_LIFECYCLE_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_POSTCONDITION_READS_JSON` | `KS_DEVNET_METAPLEX_POSTCONDITION_READS_JSON` | `internal` |
| `KB_DEVNET_METAPLEX_PREFLIGHT_READS_JSON` | `KS_DEVNET_METAPLEX_PREFLIGHT_READS_JSON` | `internal` |
| `KB_DEVNET_METAPLEX_PRINT_BURN_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_PRINT_BURN_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_SUBMIT` | `KS_DEVNET_METAPLEX_SUBMIT` | `internal` |
| `KB_DEVNET_METAPLEX_USE_PROBE_TEST` | `KS_DEVNET_METAPLEX_USE_PROBE_TEST` | `internal` |
| `KB_DEVNET_PROFILE` | `KS_DEVNET_PROFILE` | `internal` |
| `KB_DEVNET_RPC_URL` | `KS_DEVNET_RPC_URL` | `internal` |
| `KB_DEVNET_SPL_ATA_EXECUTION_TEST` | `KS_DEVNET_SPL_ATA_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_SPL_ATA_MINT` | `KS_DEVNET_SPL_ATA_MINT` | `internal` |
| `KB_DEVNET_SPL_ATA_NESTED_MINT` | `KS_DEVNET_SPL_ATA_NESTED_MINT` | `internal` |
| `KB_DEVNET_SPL_ATA_OPERATION` | `KS_DEVNET_SPL_ATA_OPERATION` | `internal` |
| `KB_DEVNET_SPL_ATA_OWNER_MINT` | `KS_DEVNET_SPL_ATA_OWNER_MINT` | `internal` |
| `KB_DEVNET_SPL_ATA_SUBMIT` | `KS_DEVNET_SPL_ATA_SUBMIT` | `internal` |
| `KB_DEVNET_SPL_ATA_TOKEN_PROGRAM` | `KS_DEVNET_SPL_ATA_TOKEN_PROGRAM` | `internal` |
| `KB_DEVNET_SPL_TOKEN_AMOUNT` | `KS_DEVNET_SPL_TOKEN_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_AUTHORITY` | `KS_DEVNET_SPL_TOKEN_AUTHORITY` | `internal` |
| `KB_DEVNET_SPL_TOKEN_DECIMALS` | `KS_DEVNET_SPL_TOKEN_DECIMALS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_DESTINATION` | `KS_DEVNET_SPL_TOKEN_DESTINATION` | `internal` |
| `KB_DEVNET_SPL_TOKEN_EXECUTION_TEST` | `KS_DEVNET_SPL_TOKEN_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_APPROVE_AMOUNT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_APPROVE_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_AUTHORITY` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_AUTHORITY` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_DECIMALS` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_DECIMALS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_DELEGATE` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_DELEGATE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_DESTINATION` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_DESTINATION` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_FIRST_STEP_INDEX` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_FIRST_STEP_INDEX` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_INTER_STEP_DELAY_MS` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_INTER_STEP_DELAY_MS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_MINT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_MINT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_MINT_AMOUNT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_MINT_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARATION_SETTLE_DELAY_MS` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARATION_SETTLE_DELAY_MS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARE` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARE` | `internal` |
| Nom actuel | Nom cible | Classe |
|---|---|---|
| `HELIUS_API_KEY` | `KS_SECRET_HELIUS_API_KEY` | `secret` |
| `KB_CONFIG_PATH` | `KS_CONFIG_PATH` | `internal` |
| `KB_CONFIG_TEST_MISSING` | `KS_CONFIG_TEST_MISSING` | `internal` |
| `KB_DEVNET_AIRDROP_LAMPORTS` | `KS_DEVNET_AIRDROP_LAMPORTS` | `internal` |
| `KB_DEVNET_CONFIG_PATH` | `KS_DEVNET_CONFIG_PATH` | `internal` |
| `KB_DEVNET_EXECUTION_TEST` | `KS_DEVNET_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_MEMO_EXECUTION_TEST` | `KS_DEVNET_MEMO_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_MEMO_SUBMIT` | `KS_DEVNET_MEMO_SUBMIT` | `internal` |
| `KB_DEVNET_METAPLEX_COLLECTION_VERIFY_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_COLLECTION_VERIFY_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_CREATE_MINT_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_CREATE_MINT_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_CREATE_MINT_FAMILY` | `KS_DEVNET_METAPLEX_CREATE_MINT_FAMILY` | `internal` |
| `KB_DEVNET_METAPLEX_ESCROW_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_ESCROW_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_EXECUTION_TEST` | `KS_DEVNET_METAPLEX_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_MAINTENANCE_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_MAINTENANCE_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_MATERIALIZE_AFTER_CONFIRMATION` | `KS_DEVNET_METAPLEX_MATERIALIZE_AFTER_CONFIRMATION` | `internal` |
| `KB_DEVNET_METAPLEX_OPERATION_JSON` | `KS_DEVNET_METAPLEX_OPERATION_JSON` | `internal` |
| `KB_DEVNET_METAPLEX_OPERATOR_CONFIRMED` | `KS_DEVNET_METAPLEX_OPERATOR_CONFIRMED` | `internal` |
| `KB_DEVNET_METAPLEX_PNFT_LIFECYCLE_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_PNFT_LIFECYCLE_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_POSTCONDITION_READS_JSON` | `KS_DEVNET_METAPLEX_POSTCONDITION_READS_JSON` | `internal` |
| `KB_DEVNET_METAPLEX_PREFLIGHT_READS_JSON` | `KS_DEVNET_METAPLEX_PREFLIGHT_READS_JSON` | `internal` |
| `KB_DEVNET_METAPLEX_PRINT_BURN_CAMPAIGN_TEST` | `KS_DEVNET_METAPLEX_PRINT_BURN_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_METAPLEX_SUBMIT` | `KS_DEVNET_METAPLEX_SUBMIT` | `internal` |
| `KB_DEVNET_METAPLEX_USE_PROBE_TEST` | `KS_DEVNET_METAPLEX_USE_PROBE_TEST` | `internal` |
| `KB_DEVNET_PROFILE` | `KS_DEVNET_PROFILE` | `internal` |
| `KB_DEVNET_RPC_URL` | `KS_DEVNET_RPC_URL` | `internal` |
| `KB_DEVNET_SPL_ATA_EXECUTION_TEST` | `KS_DEVNET_SPL_ATA_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_SPL_ATA_MINT` | `KS_DEVNET_SPL_ATA_MINT` | `internal` |
| `KB_DEVNET_SPL_ATA_NESTED_MINT` | `KS_DEVNET_SPL_ATA_NESTED_MINT` | `internal` |
| `KB_DEVNET_SPL_ATA_OPERATION` | `KS_DEVNET_SPL_ATA_OPERATION` | `internal` |
| `KB_DEVNET_SPL_ATA_OWNER_MINT` | `KS_DEVNET_SPL_ATA_OWNER_MINT` | `internal` |
| `KB_DEVNET_SPL_ATA_SUBMIT` | `KS_DEVNET_SPL_ATA_SUBMIT` | `internal` |
| `KB_DEVNET_SPL_ATA_TOKEN_PROGRAM` | `KS_DEVNET_SPL_ATA_TOKEN_PROGRAM` | `internal` |
| `KB_DEVNET_SPL_TOKEN_AMOUNT` | `KS_DEVNET_SPL_TOKEN_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_AUTHORITY` | `KS_DEVNET_SPL_TOKEN_AUTHORITY` | `internal` |
| `KB_DEVNET_SPL_TOKEN_DECIMALS` | `KS_DEVNET_SPL_TOKEN_DECIMALS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_DESTINATION` | `KS_DEVNET_SPL_TOKEN_DESTINATION` | `internal` |
| `KB_DEVNET_SPL_TOKEN_EXECUTION_TEST` | `KS_DEVNET_SPL_TOKEN_EXECUTION_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_APPROVE_AMOUNT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_APPROVE_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_AUTHORITY` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_AUTHORITY` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_DECIMALS` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_DECIMALS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_DELEGATE` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_DELEGATE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_DESTINATION` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_DESTINATION` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_FIRST_STEP_INDEX` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_FIRST_STEP_INDEX` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_INTER_STEP_DELAY_MS` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_INTER_STEP_DELAY_MS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_MINT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_MINT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_MINT_AMOUNT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_MINT_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARATION_SETTLE_DELAY_MS` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARATION_SETTLE_DELAY_MS` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARE` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_RESUME_PREDECESSOR_SIGNATURE` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_RESUME_PREDECESSOR_SIGNATURE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_SOURCE` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_SOURCE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_SUBMIT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_SUBMIT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_TEST` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_TRANSFER_AMOUNT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_TRANSFER_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_MINT` | `KS_DEVNET_SPL_TOKEN_MINT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_NATIVE_ACCOUNT` | `KS_DEVNET_SPL_TOKEN_NATIVE_ACCOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_PREFLIGHT_TEST` | `KS_DEVNET_SPL_TOKEN_PREFLIGHT_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_RECENT_PROBE_TEST` | `KS_DEVNET_SPL_TOKEN_RECENT_PROBE_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_SOURCE` | `KS_DEVNET_SPL_TOKEN_SOURCE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_SUBMIT` | `KS_DEVNET_SPL_TOKEN_SUBMIT` | `internal` |
| `KB_DEVNET_TOKEN_2022_METADATA_CAMPAIGN_TEST` | `KS_DEVNET_TOKEN_2022_METADATA_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_TOKEN_2022_METADATA_OPERATOR_CONFIRMED` | `KS_DEVNET_TOKEN_2022_METADATA_OPERATOR_CONFIRMED` | `internal` |
| `KB_DEVNET_TRANSFER_LAMPORTS` | `KS_DEVNET_TRANSFER_LAMPORTS` | `internal` |
| `KB_DEVNET_WALLET` | `KS_DEVNET_WALLET` | `internal` |
| `KB_DEVNET_WALLET_ADDRESS` | `KS_DEVNET_WALLET_ADDRESS` | `internal` |
| `KB_DEVNET_WALLET_DIR` | `KS_DEVNET_WALLET_DIR` | `internal` |
| `KB_ENV_FILE` | `KS_ENV_FILE` | `internal` |
| `KB_POSTGRES_DEVNET_URL` | `KS_SECRET_POSTGRES_DEVNET_URL` | `secret` |
| `KB_POSTGRES_MAINNET_URL` | `KS_SECRET_POSTGRES_MAINNET_URL` | `secret` |
| `KB_POSTGRES_TEST_URL` | `KS_SECRET_POSTGRES_TEST_URL` | `secret` |
| `TOKEN_2022_APPROVE_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_APPROVE_AMOUNT_RAW` | `internal` |
| `TOKEN_2022_AUTHORITY` | `KS_DEVNET_TOKEN_2022_AUTHORITY` | `internal` |
| `TOKEN_2022_BURN_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_BURN_AMOUNT_RAW` | `internal` |
| `TOKEN_2022_CLOSE_ACCOUNT` | `KS_DEVNET_TOKEN_2022_CLOSE_ACCOUNT` | `internal` |
| `TOKEN_2022_DECIMALS` | `KS_DEVNET_TOKEN_2022_DECIMALS` | `internal` |
| `TOKEN_2022_DELEGATE` | `KS_DEVNET_TOKEN_2022_DELEGATE` | `internal` |
| `TOKEN_2022_DESTINATION` | `KS_DEVNET_TOKEN_2022_DESTINATION` | `internal` |
| `TOKEN_2022_FREEZE_AUTHORITY` | `KS_DEVNET_TOKEN_2022_FREEZE_AUTHORITY` | `internal` |
| `TOKEN_2022_MINT` | `KS_DEVNET_TOKEN_2022_MINT` | `internal` |
| `TOKEN_2022_MINT_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_MINT_AMOUNT_RAW` | `internal` |
| `TOKEN_2022_PROGRAM` | `KS_DEVNET_TOKEN_2022_PROGRAM` | `internal` |
| `TOKEN_2022_SOURCE` | `KS_DEVNET_TOKEN_2022_SOURCE` | `internal` |
| `TOKEN_2022_TRANSFER_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_TRANSFER_AMOUNT_RAW` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_SOURCE` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_SOURCE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_SUBMIT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_SUBMIT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_TEST` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_LIFECYCLE_TRANSFER_AMOUNT` | `KS_DEVNET_SPL_TOKEN_LIFECYCLE_TRANSFER_AMOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_MINT` | `KS_DEVNET_SPL_TOKEN_MINT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_NATIVE_ACCOUNT` | `KS_DEVNET_SPL_TOKEN_NATIVE_ACCOUNT` | `internal` |
| `KB_DEVNET_SPL_TOKEN_PREFLIGHT_TEST` | `KS_DEVNET_SPL_TOKEN_PREFLIGHT_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_RECENT_PROBE_TEST` | `KS_DEVNET_SPL_TOKEN_RECENT_PROBE_TEST` | `internal` |
| `KB_DEVNET_SPL_TOKEN_SOURCE` | `KS_DEVNET_SPL_TOKEN_SOURCE` | `internal` |
| `KB_DEVNET_SPL_TOKEN_SUBMIT` | `KS_DEVNET_SPL_TOKEN_SUBMIT` | `internal` |
| `KB_DEVNET_TOKEN_2022_METADATA_CAMPAIGN_TEST` | `KS_DEVNET_TOKEN_2022_METADATA_CAMPAIGN_TEST` | `internal` |
| `KB_DEVNET_TOKEN_2022_METADATA_OPERATOR_CONFIRMED` | `KS_DEVNET_TOKEN_2022_METADATA_OPERATOR_CONFIRMED` | `internal` |
| `KB_DEVNET_TRANSFER_LAMPORTS` | `KS_DEVNET_TRANSFER_LAMPORTS` | `internal` |
| `KB_DEVNET_WALLET` | `KS_DEVNET_WALLET` | `internal` |
| `KB_DEVNET_WALLET_ADDRESS` | `KS_DEVNET_WALLET_ADDRESS` | `internal` |
| `KB_DEVNET_WALLET_DIR` | `KS_DEVNET_WALLET_DIR` | `internal` |
| `KB_ENV_FILE` | `KS_ENV_FILE` | `internal` |
| `KB_POSTGRES_DEVNET_URL` | `KS_SECRET_POSTGRES_DEVNET_URL` | `secret` |
| `KB_POSTGRES_MAINNET_URL` | `KS_SECRET_POSTGRES_MAINNET_URL` | `secret` |
| `KB_POSTGRES_TEST_URL` | `KS_SECRET_POSTGRES_TEST_URL` | `secret` |
| `TOKEN_2022_APPROVE_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_APPROVE_AMOUNT_RAW` | `internal` |
| `TOKEN_2022_AUTHORITY` | `KS_DEVNET_TOKEN_2022_AUTHORITY` | `internal` |
| `TOKEN_2022_BURN_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_BURN_AMOUNT_RAW` | `internal` |
| `TOKEN_2022_CLOSE_ACCOUNT` | `KS_DEVNET_TOKEN_2022_CLOSE_ACCOUNT` | `internal` |
| `TOKEN_2022_DECIMALS` | `KS_DEVNET_TOKEN_2022_DECIMALS` | `internal` |
| `TOKEN_2022_DELEGATE` | `KS_DEVNET_TOKEN_2022_DELEGATE` | `internal` |
| `TOKEN_2022_DESTINATION` | `KS_DEVNET_TOKEN_2022_DESTINATION` | `internal` |
| `TOKEN_2022_FREEZE_AUTHORITY` | `KS_DEVNET_TOKEN_2022_FREEZE_AUTHORITY` | `internal` |
| `TOKEN_2022_MINT` | `KS_DEVNET_TOKEN_2022_MINT` | `internal` |
| `TOKEN_2022_MINT_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_MINT_AMOUNT_RAW` | `internal` |
| `TOKEN_2022_PROGRAM` | `KS_DEVNET_TOKEN_2022_PROGRAM` | `internal` |
| `TOKEN_2022_SOURCE` | `KS_DEVNET_TOKEN_2022_SOURCE` | `internal` |
| `TOKEN_2022_TRANSFER_AMOUNT_RAW` | `KS_DEVNET_TOKEN_2022_TRANSFER_AMOUNT_RAW` | `internal` |
### 7.3 Mapping guide opérateur Devnet — 17 noms
| Nom actuel | Nom cible | Classe |
|---------------------------------------|---------------------------------------|------------|
| `KB_CONFIRM_DEVNET_DATABASE_RESET` | `KS_CONFIRM_DEVNET_DATABASE_RESET` | `internal` |
| `KB_DEVNET_CLASSIC_DESTINATION_ATA` | `KS_DEVNET_CLASSIC_DESTINATION_ATA` | `internal` |
| `KB_DEVNET_CLASSIC_MINT` | `KS_DEVNET_CLASSIC_MINT` | `internal` |
| `KB_DEVNET_CLASSIC_MINT_KEYPAIR` | `KS_DEVNET_CLASSIC_MINT_KEYPAIR` | `internal` |
| `KB_DEVNET_CLASSIC_RECIPIENT` | `KS_DEVNET_CLASSIC_RECIPIENT` | `internal` |
| Nom actuel | Nom cible | Classe |
|---|---|---|
| `KB_CONFIRM_DEVNET_DATABASE_RESET` | `KS_CONFIRM_DEVNET_DATABASE_RESET` | `internal` |
| `KB_DEVNET_CLASSIC_DESTINATION_ATA` | `KS_DEVNET_CLASSIC_DESTINATION_ATA` | `internal` |
| `KB_DEVNET_CLASSIC_MINT` | `KS_DEVNET_CLASSIC_MINT` | `internal` |
| `KB_DEVNET_CLASSIC_MINT_KEYPAIR` | `KS_DEVNET_CLASSIC_MINT_KEYPAIR` | `internal` |
| `KB_DEVNET_CLASSIC_RECIPIENT` | `KS_DEVNET_CLASSIC_RECIPIENT` | `internal` |
| `KB_DEVNET_CLASSIC_RECIPIENT_KEYPAIR` | `KS_DEVNET_CLASSIC_RECIPIENT_KEYPAIR` | `internal` |
| `KB_DEVNET_CLASSIC_SOURCE_ATA` | `KS_DEVNET_CLASSIC_SOURCE_ATA` | `internal` |
| `KB_DEVNET_RECIPIENT` | `KS_DEVNET_RECIPIENT` | `internal` |
| `KB_DEVNET_SCENARIO` | `KS_DEVNET_SCENARIO` | `internal` |
| `KB_DEVNET_SIGNATURE` | `KS_DEVNET_SIGNATURE` | `internal` |
| `KB_DEVNET_TOKEN_2022_FIXTURE` | `KS_DEVNET_TOKEN_2022_FIXTURE` | `internal` |
| `KB_DEVNET_TOKEN_2022_MINT` | `KS_DEVNET_TOKEN_2022_MINT` | `internal` |
| `KB_DEVNET_TOKEN_2022_MINT_KEYPAIR` | `KS_DEVNET_TOKEN_2022_MINT_KEYPAIR` | `internal` |
| `KB_DEVNET_VALIDATION_DIR` | `KS_DEVNET_VALIDATION_DIR` | `internal` |
| `KB_DEVNET_WALLET_PUBKEY` | `KS_DEVNET_WALLET_PUBKEY` | `internal` |
| `KB_SPL_TOKEN_2022_PROGRAM_ID` | `KS_SPL_TOKEN_2022_PROGRAM_ID` | `internal` |
| `KB_SPL_TOKEN_PROGRAM_ID` | `KS_SPL_TOKEN_PROGRAM_ID` | `internal` |
| `KB_DEVNET_CLASSIC_SOURCE_ATA` | `KS_DEVNET_CLASSIC_SOURCE_ATA` | `internal` |
| `KB_DEVNET_RECIPIENT` | `KS_DEVNET_RECIPIENT` | `internal` |
| `KB_DEVNET_SCENARIO` | `KS_DEVNET_SCENARIO` | `internal` |
| `KB_DEVNET_SIGNATURE` | `KS_DEVNET_SIGNATURE` | `internal` |
| `KB_DEVNET_TOKEN_2022_FIXTURE` | `KS_DEVNET_TOKEN_2022_FIXTURE` | `internal` |
| `KB_DEVNET_TOKEN_2022_MINT` | `KS_DEVNET_TOKEN_2022_MINT` | `internal` |
| `KB_DEVNET_TOKEN_2022_MINT_KEYPAIR` | `KS_DEVNET_TOKEN_2022_MINT_KEYPAIR` | `internal` |
| `KB_DEVNET_VALIDATION_DIR` | `KS_DEVNET_VALIDATION_DIR` | `internal` |
| `KB_DEVNET_WALLET_PUBKEY` | `KS_DEVNET_WALLET_PUBKEY` | `internal` |
| `KB_SPL_TOKEN_2022_PROGRAM_ID` | `KS_SPL_TOKEN_2022_PROGRAM_ID` | `internal` |
| `KB_SPL_TOKEN_PROGRAM_ID` | `KS_SPL_TOKEN_PROGRAM_ID` | `internal` |
## 8. Split configuration / logging
@@ -566,7 +566,7 @@ Le code duplique actuellement dans `kb-config` et `kb-logging` les concepts :
- `LogTargetConfig` ;
- `LogTargetFilterConfig`.
`kb-app-demo-desktop` contient en plus une conversion manuelle de `kb_config::LoggingConfig` vers `kb_logging::LoggingConfig`. `0.5.1` doit supprimer cette duplication en donnant au logging un contrat possédé par `ks-logging`, tout en laissant `ks-config` charger/valider/composer les documents sans réinventer les types runtime du logging.
`kb-app-demo-desktop` contient en plus une conversion manuelle de `ks_config::LoggingConfig` vers `ks_logging::LoggingConfig`. `0.5.1` doit supprimer cette duplication en donnant au logging un contrat possédé par `ks-logging`, tout en laissant `ks-config` charger/valider/composer les documents sans réinventer les types runtime du logging.
Aucun troisième document spécialisé n'est créé dans `0.5.1` sans bénéfice de découplage démontré.
@@ -640,12 +640,14 @@ Les tests ne doivent pas figer comme comportement légitime la fuite actuelle de
- renommer physiquement les dix crates selon l'ordre de dépendance ;
- migrer packages, paths, imports, exports, tests externes, scripts et CLI ;
- adapter `kb-app-demo-desktop` sans le renommer ;
- conserver encore les changements sémantiques de config hors de ce delta.
- migrer les targets de tracing **racine** dont le contrat est couplé au nom Cargo (`ks-logging`, `ks-pipeline`, `ks-pipeline-demo-scenarios`, `ks-onchain-transport`, `ks-store`, `ks-wallet`) et réaligner les routes de logging qui utilisent les noms de crates ;
- régénérer localement les bindings TS-RS de `ks-config` plutôt que livrer des bindings générés à la main ;
- conserver encore les variables d'environnement, les identités `kb-lib.*` et les tables `kb_sol_*` hors de ce delta.
### `0.5.1-pre.003` — identités techniques et tracing
### `0.5.1-pre.003` — identités techniques et tracing hiérarchique `ks-lib-*`
- migrer les 256 identités `kb-lib.*` vers `ks-lib-*` ;
- migrer targets de tracing génériques vers `ks-*` ;
- migrer les subtargets et identités de composants hiérarchiques qui ne pouvaient pas être changés par le simple renommage Cargo ;
- synchroniser routes de logging, matrices, diagnostics, tests et provenance/replay ;
- ne pas renommer encore les tables SQL `kb_sol_*`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_SPECIFIC_KHADHROONY.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# Règles spécifiques à `khadhroony-bot3`
@@ -13,10 +13,10 @@ Toute divergence avec une règle générale doit être explicitement documentée
- Les noms de fichiers et de répertoires ne doivent contenir aucun accent, espace ou caractère spécial inutile.
- Les noms internes doivent utiliser le format `snake_case` lorsque c'est applicable.
- Les packages Rust utilisent le préfixe `kb-` ; leur identifiant Rust correspondant utilise automatiquement `kb_`.
- Les décodeurs, matérialisateurs et exécuteurs sont des modules de `kb-lib`, pas des crates séparées.
- Le crate de journalisation s'appelle `kb-logging`.
- Les décodeurs, matérialisateurs et exécuteurs sont des modules de `ks-lib`, pas des crates séparées.
- Le crate de journalisation s'appelle `ks-logging`.
- Les réexports sont regroupés par visibilité : le bloc `pub use` précède le bloc séparé `pub(crate) use`, sans ligne vide interne à un bloc ; leur ordre naturel doit rester compatible avec `cargo fmt`.
- Les familles de symboles consolidées dans `kb-lib` utilisent les préfixes `DC_`/`Dc`/`decoder_` pour les décodeurs, `MT_`/`Mt`/`materializer_` pour les matérialisateurs, `EX_`/`Ex`/`executor_` pour les exécuteurs et `MD_`/`Md`/`model_` pour les modèles.
- Les familles de symboles consolidées dans `ks-lib` utilisent les préfixes `DC_`/`Dc`/`decoder_` pour les décodeurs, `MT_`/`Mt`/`materializer_` pour les matérialisateurs, `EX_`/`Ex`/`executor_` pour les exécuteurs et `MD_`/`Md`/`model_` pour les modèles.
- Les méthodes inhérentes et helpers strictement privés peuvent conserver un nom local court ; les préfixes sappliquent aux constantes, types, traits et fonctions libres exposés à la crate ou hors de la crate.
- Les constantes temporaires `*_LEGACY_CRATE`, `*_MIGRATION_STATUS` et `*_MIGRATION_BOUNDARIES` doivent disparaître dune famille dès que ses squelettes typés sont restaurés ; elles ne constituent jamais une API durable.
@@ -55,7 +55,7 @@ Toute divergence avec une règle générale doit être explicitement documentée
- Toute absence volontaire de projection doit être documentée avec une justification technique précise. Un matérialisateur ne doit inventer ni état final, ni montant, ni autorité, ni frais, ni agrégation que l'observation ne prouve pas.
- Chaque matérialisateur concret possède un composant structuré avec une façade limitée aux déclarations de sous-modules et réexports, un `constants.rs` et un `materializer.rs`. Les fichiers spécialisés `state.rs`, `account.rs` ou équivalents sont ajoutés seulement lorsque leur responsabilité est distincte.
- Lidentité runtime suit `kb-lib.materializer.<domain>[.<subsystem>]`. Le `processorName` persisté suit `materializer.<domain>[.<subsystem>]` et doit être exactement lidentité runtime sans le préfixe `kb-lib.`. Le tracing target dun composant actif est identique à son identité runtime.
- Les constantes dun composant utilisent le préfixe `MT_<COMPONENT>_`, résident dans son `constants.rs`, sont réexportées par chaque façade jusquà `kb-lib/src/lib.rs` et sont consommées par `crate::`, y compris dans les tests lorsquelles sont `pub` ou `pub(crate)`.
- Les constantes dun composant utilisent le préfixe `MT_<COMPONENT>_`, résident dans son `constants.rs`, sont réexportées par chaque façade jusquà `ks-lib/src/lib.rs` et sont consommées par `crate::`, y compris dans les tests lorsquelles sont `pub` ou `pub(crate)`.
- Toute sortie persistée contient un `processorName` issu de la constante du composant et une `projectionVersion` explicite. Une correction de provenance persistée impose une nouvelle version de projection.
- Une coquille réservée implémente `MtMaterializer` et `MtApiEventMaterializer`, expose une constante `MT_*_ACCEPTED_FAMILIES` vide, refuse tous les événements, retourne une liste legacy vide et un résultat contextuel `Ignored`. Elle ne doit jamais créer un faux événement de transition.
- Un composant state-only peut exposer uniquement des APIs de snapshots sans implémenter `MtApiEventMaterializer`; ce statut doit être explicite et ne crée pas artificiellement un matérialisateur instructionnel.
@@ -77,24 +77,24 @@ Toute divergence avec une règle générale doit être explicitement documentée
### Frontière des pipelines
- `kb-pipeline` est le pipeline généraliste, réutilisable et indépendant d'un environnement de démonstration. Ses contrats doivent pouvoir être appelés depuis une application, un service, un worker, un CLI, des tests ou une autre orchestration, sur tout cluster compatible autorisé par la configuration.
- `kb-pipeline` possède l'orchestration générique du backfill, de l'extraction Core, du replay, des corrélations stateful, du préflight, de la préparation, de la simulation, de la soumission autorisée, de la confirmation, de la postvalidation et de la matérialisation idempotente.
- `kb-pipeline` ne doit contenir ni wallet, mint, compte, airdrop, autorité, adresse, séquence ou hypothèse codée en dur pour une démonstration Devnet ou Testnet.
- `kb-pipeline-demo-scenarios` contient les fixtures, aides de campagne et tests automatisés spécifiques aux réseaux de test, actuellement Devnet ou Testnet.
- Les fixtures, séquences, simulations/soumissions, postconditions et qualifications Devnet/Testnet réutilisables appartiennent à `kb-pipeline-demo-scenarios`, y compris lorsqu'elles sont déclenchées depuis le desktop.
- `ks-pipeline` est le pipeline généraliste, réutilisable et indépendant d'un environnement de démonstration. Ses contrats doivent pouvoir être appelés depuis une application, un service, un worker, un CLI, des tests ou une autre orchestration, sur tout cluster compatible autorisé par la configuration.
- `ks-pipeline` possède l'orchestration générique du backfill, de l'extraction Core, du replay, des corrélations stateful, du préflight, de la préparation, de la simulation, de la soumission autorisée, de la confirmation, de la postvalidation et de la matérialisation idempotente.
- `ks-pipeline` ne doit contenir ni wallet, mint, compte, airdrop, autorité, adresse, séquence ou hypothèse codée en dur pour une démonstration Devnet ou Testnet.
- `ks-pipeline-demo-scenarios` contient les fixtures, aides de campagne et tests automatisés spécifiques aux réseaux de test, actuellement Devnet ou Testnet.
- Les fixtures, séquences, simulations/soumissions, postconditions et qualifications Devnet/Testnet réutilisables appartiennent à `ks-pipeline-demo-scenarios`, y compris lorsqu'elles sont déclenchées depuis le desktop.
- `kb-app-demo-desktop` conserve l'adaptation UI/Tauri, l'état applicatif, la sélection opérateur, la progression/annulation et la présentation. Il ne doit pas maintenir une seconde implémentation d'une campagne réutilisable.
- `kb-pipeline-demo-scenarios` peut préparer des wallets temporaires, demander des airdrops, créer des actifs de test, enchaîner plusieurs appels du pipeline généraliste et produire des preuves de validation réseau.
- Le binaire `kb-pipeline-demo-scenarios-cli` reste un outil ciblé tant que son contrat public ne prévoit pas explicitement d'autres commandes. Son usage historique de préparation des fixtures SPL Token-2022 ne doit pas être généralisé implicitement à tous les scénarios.
- `kb-pipeline-demo-scenarios` dépend de `kb-pipeline` ; la dépendance inverse est interdite.
- Une primitive ou orchestration réellement réutilisable hors d'une campagne de validation précise doit être placée dans `kb-pipeline`, `kb-pipeline-demo-scenarios` ou la crate métier propriétaire selon sa responsabilité. Seuls les adaptateurs, états et séquences strictement propres à l'interaction UI restent dans le desktop.
- `ks-pipeline-demo-scenarios` peut préparer des wallets temporaires, demander des airdrops, créer des actifs de test, enchaîner plusieurs appels du pipeline généraliste et produire des preuves de validation réseau.
- Le binaire `ks-pipeline-demo-scenarios-cli` reste un outil ciblé tant que son contrat public ne prévoit pas explicitement d'autres commandes. Son usage historique de préparation des fixtures SPL Token-2022 ne doit pas être généralisé implicitement à tous les scénarios.
- `ks-pipeline-demo-scenarios` dépend de `ks-pipeline` ; la dépendance inverse est interdite.
- Une primitive ou orchestration réellement réutilisable hors d'une campagne de validation précise doit être placée dans `ks-pipeline`, `ks-pipeline-demo-scenarios` ou la crate métier propriétaire selon sa responsabilité. Seuls les adaptateurs, états et séquences strictement propres à l'interaction UI restent dans le desktop.
- Les scénarios Mainnet sans écriture, par exemple les validations de backfill ou de replay, relèvent du pipeline généraliste et de documents de validation dédiés ; ils ne justifient pas l'introduction d'une logique Mainnet spécifique dans la crate de scénarios Devnet/Testnet.
### Autres frontières
- `kb-store` possède les contrats de persistance neutres et les adaptateurs de base de données.
- PostgreSQL est l'adaptateur de production de `kb-store`.
- Un futur adaptateur SQLite doit rester interne à `kb-store` et limité aux tests, imports et corpus locaux.
- `kb-wallet` reste isolé du reste du système.
- `ks-store` possède les contrats de persistance neutres et les adaptateurs de base de données.
- PostgreSQL est l'adaptateur de production de `ks-store`.
- Un futur adaptateur SQLite doit rester interne à `ks-store` et limité aux tests, imports et corpus locaux.
- `ks-wallet` reste isolé du reste du système.
- Les transactions raw sont immuables et restent la source d'audit.
- Les replays doivent être ciblés par module, version, programme, surface, discriminator, slot ou signatures.
- La documentation active du projet ne doit pas présenter l'ancien workspace comme architecture courante. Les documents de migration et copies de référence peuvent le nommer explicitement.
@@ -124,20 +124,20 @@ Les nouvelles surfaces de programmes doivent utiliser un nom canonique basé sur
Les modules internes de décodage doivent utiliser la hiérarchie de fichiers :
```text
kb-lib/src/decoder/<function_code>/<family_code>_<identifier_code>[_vN].rs
ks-lib/src/decoder/<function_code>/<family_code>_<identifier_code>[_vN].rs
```
Exemples :
- `kb-lib/src/decoder/amm/raydium_cpmm.rs` ;
- `kb-lib/src/decoder/clmm/raydium.rs` ;
- `kb-lib/src/decoder/dlmm/meteora.rs` ;
- `kb-lib/src/decoder/router/jupiter_aggregator_v6.rs` ;
- `kb-lib/src/decoder/orderbook/openbook_v2.rs` ;
- `kb-lib/src/decoder/metadata/metaplex_token_metadata.rs` ;
- `kb-lib/src/decoder/nft/metaplex_bubblegum.rs`.
- `ks-lib/src/decoder/amm/raydium_cpmm.rs` ;
- `ks-lib/src/decoder/clmm/raydium.rs` ;
- `ks-lib/src/decoder/dlmm/meteora.rs` ;
- `ks-lib/src/decoder/router/jupiter_aggregator_v6.rs` ;
- `ks-lib/src/decoder/orderbook/openbook_v2.rs` ;
- `ks-lib/src/decoder/metadata/metaplex_token_metadata.rs` ;
- `ks-lib/src/decoder/nft/metaplex_bubblegum.rs`.
Ces modules restent privés. Les consommateurs externes utilisent exclusivement les types et fonctions réexportés directement par `kb_lib`.
Ces modules restent privés. Les consommateurs externes utilisent exclusivement les types et fonctions réexportés directement par `ks_lib`.
Les noms historiques ou issus d'IDL doivent être conservés dans le registre, mais ne doivent pas créer de nouveau module si un module canonique existe déjà.
@@ -178,13 +178,13 @@ Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédi
## Règles de tracing
- Une crate ou un composant de `kb-lib` est opérationnel lorsquil effectue des I/O, orchestre un pipeline, décode, matérialise, exécute, applique une politique runtime ou prend une décision mutable observable.
- Une crate ou un composant de `ks-lib` est opérationnel lorsquil effectue des I/O, orchestre un pipeline, décode, matérialise, exécute, applique une politique runtime ou prend une décision mutable observable.
- Toute crate opérationnelle ajoutée ou modifiée doit dépendre de `tracing` depuis le workspace et déclarer exactement un `pub(crate) const TRACING_TARGET` dans `src/constants.rs`.
- Hors `kb-lib`, la valeur canonique de `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` est le nom exact du package Cargo.
- Dans `kb-lib`, chaque composant opérationnel possède son propre `constants.rs` et un target hiérarchique stable fondé sur son identifiant de décodeur, matérialiseur ou exécuteur ; un target unique `kb-lib` ne doit pas effacer l'identité du composant.
- Hors `ks-lib`, la valeur canonique de `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` est le nom exact du package Cargo.
- Dans `ks-lib`, chaque composant opérationnel possède son propre `constants.rs` et un target hiérarchique stable fondé sur son identifiant de décodeur, matérialiseur ou exécuteur ; un target unique `ks-lib` ne doit pas effacer l'identité du composant.
- Les targets historiques `khbot.*` et les targets de fenêtre sont interdits dans les nouvelles modifications.
- Les macros `tracing` doivent utiliser `target: crate::TRACING_TARGET` et des champs structurés stables. La granularité interne passe par `action`, `stage`, `window`, `campaign_id`, `signature`, `instruction_path`, `program_id`, `processor_name`, `processor_version`, `status` et `error_code`.
- Les crates passives de types, contrats, DTO, API sans exécution, registres ou constantes restent sans dépendance `tracing`. `kb-config` reste une exception de bootstrap tant que sa validation précède linstallation du subscriber.
- Les crates passives de types, contrats, DTO, API sans exécution, registres ou constantes restent sans dépendance `tracing`. `ks-config` reste une exception de bootstrap tant que sa validation précède linstallation du subscriber.
- Il est interdit dajouter `tracing` sans événement réel, de conserver un tracing target déclaré mais inutilisé ou de consommer artificiellement un target avec `let _target`.
- Une décision interne doit être journalisée par la crate responsable ; `kb-app-demo-desktop` ne journalise que les frontières Tauri/UI, les actions utilisateur et les résumés dorchestration.
- Tout input sélectionné sans décodeur compatible, tout résultat de décodage `failed` ou `unsupported`, tout résultat de matérialisation `failed`, toute validation de résultat invalide et toute erreur de persistance doivent émettre un événement `error` avant le retour ou la persistance terminale.
@@ -201,14 +201,14 @@ Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédi
- Les dépendances déclarées dans `[workspace.dependencies]` forment un catalogue de versions et de features autorisées ; elles ne doivent être ajoutées à une crate consommatrice que lorsquun type, un encodeur, un décodeur ou un identifiant officiel est réellement utilisé.
- Dans un `Cargo.toml`, placer dans `[dependencies]` toute crate référencée par le code de bibliothèque compilé en production. Réserver `[dev-dependencies]` aux références contenues exclusivement dans `#[cfg(test)]`, les tests dintégration, benches ou exemples. Une dépendance de test vers un décodeur ou matérialiseur concret est légitime lorsquelle sert uniquement à éprouver une orchestration générique fondée sur les traits API ; elle ne prouve pas quune capacité de production manque. Toute promotion de `dev-dependencies` vers `dependencies` doit être motivée par un appel runtime réel, et toute dépendance runtime inutilisée doit être supprimée.
- Les registres de composition runtime des applications doivent énumérer explicitement chaque décodeur et matérialiseur concret activé. Toute nouvelle surface instructionnelle dotée dun `MtApiEventMaterializer` doit être ajoutée au registre applicatif et couverte par un test dinventaire ordonné ; une crate présente dans le workspace ou dans `kb_pipeline` nest pas activée automatiquement. Les matérialiseurs exclusivement stateful qui nimplémentent pas `MtApiEventMaterializer` restent routés par leurs APIs de snapshots dédiées.
- Les registres de composition runtime des applications doivent énumérer explicitement chaque décodeur et matérialiseur concret activé. Toute nouvelle surface instructionnelle dotée dun `MtApiEventMaterializer` doit être ajoutée au registre applicatif et couverte par un test dinventaire ordonné ; une crate présente dans le workspace ou dans `ks_pipeline` nest pas activée automatiquement. Les matérialiseurs exclusivement stateful qui nimplémentent pas `MtApiEventMaterializer` restent routés par leurs APIs de snapshots dédiées.
- Les corrélations instruction/état doivent produire une issue explicite (`confirmed`, `contradicted` ou `not_applicable`) et ne doivent jamais transformer automatiquement une configuration observée en violation, score ou conclusion métier.
- Une interface officielle Solana ou SPL étroite doit être préférée à `solana-sdk` lorsque son contrat suffit.
- Lordre de préférence des formats est : schéma officiel `wincode`, schéma officiel Borsh, puis parseur local borné reproduisant exactement le runtime lorsque linterface officielle nexpose que `bincode`.
- Aucun nouveau code ne doit dépendre directement de `bincode`. Une interface officielle uniquement disponible derrière une feature `bincode` ne justifie pas lactivation de cette feature ; le layout doit alors être prouvé depuis les sources officielles et implémenté localement avec des bornes et des tests.
- Les exécuteurs doivent utiliser les builders officiels disponibles, préserver lordre exact des metas, borner toute liste de comptes variable avant lappel au builder et refuser les doublons lorsque leur répétition na pas de sémantique publiée.
- Les features des interfaces doivent rester minimales et explicites. Une feature `serde`, `wincode`, `borsh`, `std`, `alloc` ou équivalente nest activée que si la crate consommatrice lutilise réellement.
- Les crates applicatives ne doivent pas dépendre dinterfaces RPC ou transactionnelles uniquement pour relayer des types ; ces dépendances appartiennent à `kb_onchain_transport`, aux modèles communs justifiés ou à la crate opérationnelle propriétaire.
- Les crates applicatives ne doivent pas dépendre dinterfaces RPC ou transactionnelles uniquement pour relayer des types ; ces dépendances appartiennent à `ks_onchain_transport`, aux modèles communs justifiés ou à la crate opérationnelle propriétaire.
- Toute exception et toute implémentation locale doivent être documentées dans `docs/SOLANA_INTERFACE_DEPENDENCIES.md` avec la raison, la source officielle et la stratégie de test.
- Tant que les types Solana consommés implémentent les traits de `wincode 0.5.x`, le catalogue
workspace conserve `wincode = "^0.5"`. Le `Cargo.lock` local du workspace doit résoudre exactement
@@ -221,13 +221,13 @@ Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédi
## Règles des exécuteurs
- Les exécuteurs résident dans `kb_lib::executor`.
- Une surface classifiée peut avoir un module décodeur et un module exécuteur distincts dans `kb-lib`.
- Les exécuteurs résident dans `ks_lib::executor`.
- Une surface classifiée peut avoir un module décodeur et un module exécuteur distincts dans `ks-lib`.
- Les exécuteurs ne doivent pas dépendre des décodeurs.
- Les exécuteurs utilisent les contrats `ExApi*` réexportés directement par la façade `kb_lib`.
- Un squelette dexécuteur doit exposer un type `Ex*Executor`, référencer uniquement des Program IDs de `kb-program-ids`, annoncer `Maybe` pour sa surface et construire exclusivement un plan réservé à zéro instruction.
- Les exécuteurs utilisent les contrats `ExApi*` réexportés directement par la façade `ks_lib`.
- Un squelette dexécuteur doit exposer un type `Ex*Executor`, référencer uniquement des Program IDs de `ks-program-ids`, annoncer `Maybe` pour sa surface et construire exclusivement un plan réservé à zéro instruction.
- La migration fonctionnelle dun exécuteur doit remplacer ce comportement réservé par des capacités exactes `Supported` ou `Unsupported(reason)` ; aucun statut temporaire `LEGACY_CRATE` ou `MIGRATION_STATUS` ne doit subsister.
- Les garde-fous communs doivent être placés dans les modules de sécurité partagés de `kb-lib`.
- Les garde-fous communs doivent être placés dans les modules de sécurité partagés de `ks-lib`.
- Aucun exécuteur ne doit envoyer de transaction sans simulation et validation explicite.
- Les surfaces non classifiées ne doivent pas avoir de crate exécuteur.
- La section « Couverture des exécuteurs » ci-dessus est normative pour chaque surface : la migration fonctionnelle doit fermer linventaire complet et ne peut pas sélectionner arbitrairement un sous-ensemble dopérations officiellement constructibles.
@@ -237,7 +237,7 @@ Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédi
## Règles de configuration
- La configuration applicative commune doit passer par `kb-config`.
- La configuration applicative commune doit passer par `ks-config`.
- Les fichiers JSON de configuration ne doivent pas contenir de commentaires.
- Les secrets ne doivent pas être écrits en clair dans le dépôt.
- Les valeurs sensibles doivent utiliser des variables d'environnement ou un stockage chiffré dédié.
@@ -245,23 +245,23 @@ Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédi
## Ordre de développement cible
- `kb-logging` doit être stabilisé avant les logs avancés des autres crates.
- `kb-config` doit être stabilisé avant les stores, RPC, wallet et applications.
- `ks-logging` doit être stabilisé avant les logs avancés des autres crates.
- `ks-config` doit être stabilisé avant les stores, RPC, wallet et applications.
- Les contrats SQL et de matérialisation doivent être définis avant les gros décodeurs DEX.
- Les implémentations détaillées des matérialisateurs doivent suivre les sorties réelles des décodeurs correspondants.
- `kb-app-demo-desktop` doit fournir des validations live après chaque capacité majeure, sans créer une application Tauri séparée par crate.
## Constantes des composants de `kb-lib`
## Constantes des composants de `ks-lib`
- Chaque composant classifié avec un `program_id` doit avoir son propre fichier `constants.rs`.
- `constants.rs` contient les discriminators, sélecteurs, opcodes, constantes Borsh et constantes de décodage quand elles sont connues.
- Le module parent puis `kb-lib/src/lib.rs` réexportent les constantes publiques nécessaires.
- Les fichiers d'implémentation utilisent le chemin public le plus court réexporté par `kb-lib`.
- Le module parent puis `ks-lib/src/lib.rs` réexportent les constantes publiques nécessaires.
- Les fichiers d'implémentation utilisent le chemin public le plus court réexporté par `ks-lib`.
- Les literals de `program_id` ne doivent pas rester dans `program_ids()`, sauf dans un fichier `constants.rs`.
## Identifiants de programmes
Les `program_id` connus doivent être définis une seule fois dans `kb-program-ids`. Les composants de décodeur, dexécuteur, de store, dapplication ou doutil doivent référencer directement `kb_program_ids::XXX_PROGRAM_ID`. Les fichiers `constants.rs` locaux ne doivent pas redéfinir ces chaînes ; ils restent réservés aux constantes internes du module, par exemple discriminators, opcodes, seeds, index de comptes ou layouts.
Les `program_id` connus doivent être définis une seule fois dans `ks-program-ids`. Les composants de décodeur, dexécuteur, de store, dapplication ou doutil doivent référencer directement `ks_program_ids::XXX_PROGRAM_ID`. Les fichiers `constants.rs` locaux ne doivent pas redéfinir ces chaînes ; ils restent réservés aux constantes internes du module, par exemple discriminators, opcodes, seeds, index de comptes ou layouts.
## Validation frontend Tauri
@@ -274,14 +274,14 @@ Les `program_id` connus doivent être définis une seule fois dans `kb-program-i
## Architecture `khadhroony-bot3`
- Les décodeurs, exécuteurs et matérialisateurs résident exclusivement dans `kb-lib`.
- Les décodeurs, exécuteurs et matérialisateurs résident exclusivement dans `ks-lib`.
- Les modules peuvent posséder leur propre fichier de constantes.
- Toute API publique portée depuis une ancienne crate doit être réexportée au crate root de `kb-lib`.
- `kb-store` regroupe les contrats store-neutral et les adaptateurs de persistance, avec PostgreSQL comme adaptateur de production initial.
- `kb-store/src/lib.rs` reste une façade : les DTO, entités, traits, requêtes et implémentations résident dans des modules privés dédiés et toute API publique est réexportée au crate root.
- Les modèles source-neutral partagés avec les décodeurs, notamment `MdCoreInstructionReplayInput`, appartiennent à `kb-lib`; `kb-store` les consomme et les réexporte sans les dupliquer.
- `kb-lib` ne dépend jamais de `kb-store`. Cette direction de dépendance évite tout cycle entre modèles, décodage et persistance.
- `kb-store` ne dépend pas de `kb-config`. La frontière applicative transforme une configuration résolue en options de store explicitement validées.
- Toute API publique portée depuis une ancienne crate doit être réexportée au crate root de `ks-lib`.
- `ks-store` regroupe les contrats store-neutral et les adaptateurs de persistance, avec PostgreSQL comme adaptateur de production initial.
- `ks-store/src/lib.rs` reste une façade : les DTO, entités, traits, requêtes et implémentations résident dans des modules privés dédiés et toute API publique est réexportée au crate root.
- Les modèles source-neutral partagés avec les décodeurs, notamment `MdCoreInstructionReplayInput`, appartiennent à `ks-lib`; `ks-store` les consomme et les réexporte sans les dupliquer.
- `ks-lib` ne dépend jamais de `ks-store`. Cette direction de dépendance évite tout cycle entre modèles, décodage et persistance.
- `ks-store` ne dépend pas de `ks-config`. La frontière applicative transforme une configuration résolue en options de store explicitement validées.
- Les adaptateurs concrets implémentent les mêmes traits neutres et ne font pas fuiter leurs types de connexion dans les contrats.
- Seul `kb-app-demo-desktop` est conservé comme binaire pendant la migration initiale.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/V0_4_8_METADATA_VALIDATION_REPORT.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Validation fonctionnelle — Metadata on-chain et clôture 0.4.8
@@ -41,7 +41,7 @@ Les cinq opérations indisponibles restent explicitement bornées par les observ
## Desktop Metadata
`kb-app-demo-desktop` sépare les trois domaines Metadata et appelle les scénarios réutilisables de `kb-pipeline-demo-scenarios`.
`kb-app-demo-desktop` sépare les trois domaines Metadata et appelle les scénarios réutilisables de `ks-pipeline-demo-scenarios`.
La validation finale couvre notamment :
@@ -67,16 +67,16 @@ La campagne finale du 9 août 2026 est conforme :
Les principales cibles unitaires observées comprennent :
- `kb-app-demo-desktop` : 144 tests ;
- `kb-config` : 46 tests ;
- `kb-core` : 2 tests ;
- `kb-lib` : 706 tests, plus 9 tests dintégration ;
- `kb-logging` : 17 tests ;
- `kb-onchain-transport` : 118 tests ;
- `kb-pipeline` : 109 tests, plus 3 tests dintégration Metadata ;
- `kb-pipeline-demo-scenarios` : 105 tests bibliothèque, 1 test CLI et 1 test API externe ;
- `kb-program-ids` : 6 tests ;
- `kb-store` : 84 tests ;
- `kb-wallet` : 6 tests.
- `ks-config` : 46 tests ;
- `ks-core` : 2 tests ;
- `ks-lib` : 706 tests, plus 9 tests dintégration ;
- `ks-logging` : 17 tests ;
- `ks-onchain-transport` : 118 tests ;
- `ks-pipeline` : 109 tests, plus 3 tests dintégration Metadata ;
- `ks-pipeline-demo-scenarios` : 105 tests bibliothèque, 1 test CLI et 1 test API externe ;
- `ks-program-ids` : 6 tests ;
- `ks-store` : 84 tests ;
- `ks-wallet` : 6 tests.
## Build desktop de release

View File

@@ -1,5 +1,5 @@
<!-- file: idls/001.README.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Répertoire IDL v3
@@ -9,10 +9,10 @@ Le contenu brut des JSON n'a pas été modifié ; seuls les noms de fichiers ont
## Convention
```text
<famille-kb-lib>.<program-id>.<chemin-module>[.<génération-ou-sous-système>].V<version-idl>.from_<source>.json
<famille-ks-lib>.<program-id>.<chemin-module>[.<génération-ou-sous-système>].V<version-idl>.from_<source>.json
```
- `famille-kb-lib` correspond au premier niveau fonctionnel de `kb-lib` : `solana`, `spl`,
- `famille-ks-lib` correspond au premier niveau fonctionnel de `ks-lib` : `solana`, `spl`,
`metadata`, `launchpad`, `fees`, `strategy`, etc.
- `program-id` est l'identifiant canonique du programme.
- `chemin-module` correspond au module fonctionnel cible sans les rôles `decoder` ou `executor`.
@@ -24,7 +24,7 @@ Le contenu brut des JSON n'a pas été modifié ; seuls les noms de fichiers ont
- `../docs/IDL_AUDIT.md` : inventaire, validation JSON, versions et empreintes.
- `../docs/MISSING_PROGRAM_IDLS.md` : programmes connus sans IDL présente ou sans IDL officielle identifiée.
- `../docs/IDL_TO_KB_LIB_NOMENCLATURE.md` : correspondance entre chaque IDL et le module `kb-lib`.
- `../docs/IDL_TO_KB_LIB_NOMENCLATURE.md` : correspondance entre chaque IDL et le module `ks-lib`.
## Décisions architecturales intégrées
@@ -36,4 +36,4 @@ Le contenu brut des JSON n'a pas été modifié ; seuls les noms de fichiers ont
- une famille `storage` est proposée pour `storage/solana_record`.
Ces changements de modules ne sont pas appliqués au code Rust dans cette archive ; ils servent de cible
pour la prochaine refactorisation de `kb-lib`.
pour la prochaine refactorisation de `ks-lib`.

View File

@@ -1,8 +1,14 @@
<!-- file: kb-app-demo-desktop/CHANGELOG.md -->
<!-- version: 42 -->
<!-- version: 43 -->
# CHANGELOG — kb-app-demo-desktop
## `0.5.1-pre.002`
- adapte les dépendances Rust et tous les appels de crates Solana vers `ks_*` sans renommer l'application ;
- conserve `kb-app-demo-desktop` comme banc de validation et future surface de démonstrations propres au bot ;
- laisse les bindings TS-RS générés être régénérés par les tests après migration de `kb_config` vers `ks_config`.
## `0.5.1-pre.001`
### Documentation
@@ -14,7 +20,7 @@
### Documentation
- réaligne la frontière desktop/scénarios : les campagnes réutilisables appartiennent à `kb-pipeline-demo-scenarios`, tandis que le desktop conserve ladaptation UI/Tauri, létat applicatif et la présentation ;
- réaligne la frontière desktop/scénarios : les campagnes réutilisables appartiennent à `ks-pipeline-demo-scenarios`, tandis que le desktop conserve ladaptation UI/Tauri, létat applicatif et la présentation ;
- identifie pour `0.5.4` les dispatchs, critères de complétion et projections de preuves encore réutilisables à sortir du desktop ; aucun parcours runtime nest modifié dans cette prerelease.
## 0.5.0-pre.001
@@ -39,11 +45,11 @@
- `pre.014-delta-fix-002` réaligne le test de contrôles Metaplex sur la nouvelle UI qualifiée (`metadataMetaplexCampaignSelect` + confirmation + exécution) et retire les assertions sur les anciens contrôles Devnet supprimés par `fix-001` ;
- après deux crashs reproductibles du desktop pendant `Create -> Mint — NFT`, les logs montrent `Create` simulé, soumis et confirmé, puis un arrêt brutal pendant le `getTransaction` de l'hydratation canonique, sans panic Rust ni erreur JSONL ;
- boxe explicitement le futur volumineux du dispatch des 11 campagnes Metaplex avant son exécution dans le runtime Tauri afin de réduire l'état async conservé par la commande desktop et ajoute des marqueurs backend `campaign_start`, `campaign_completed` et `campaign_failed` ; cette correction reste volontairement limitée à l'adaptateur desktop et ne modifie aucune campagne Devnet déjà qualifiée ;
- `pre.014-delta-fix-001` remplace le chemin Devnet Metaplex générique du panneau par 11 campagnes qualifiées réutilisant directement les runners spécialisés de `kb-pipeline-demo-scenarios` : cinq `Create -> Mint`, collection, Print/Burn, lifecycle pNFT, escrow, maintenance et probe Use ;
- `pre.014-delta-fix-001` remplace le chemin Devnet Metaplex générique du panneau par 11 campagnes qualifiées réutilisant directement les runners spécialisés de `ks-pipeline-demo-scenarios` : cinq `Create -> Mint`, collection, Print/Burn, lifecycle pNFT, escrow, maintenance et probe Use ;
- conserve les scénarios Metaplex synthétiques pour linspection de contrats, mais ne présente plus `scenario + step + intent JSON` comme parcours Devnet principal ;
- confine `Use`, `Resize`, `Migrate`, `Collect` et `CloseAccounts` aux probes simulation-only de leurs campagnes qualifiées et ne les expose jamais comme soumissions isolées ;
- déplace la carte **Exigences** en bas de la colonne droite, après les postconditions, tout en conservant le journal dexécution en pleine largeur sous la grille ;
- enregistre la première validation Tauri de `pre.014` : `cargo check --workspace`, Clippy et laudit workspace sont propres, `kb-pipeline-demo-scenarios` réussit 105 tests unitaires + 1 CLI + 1 API externe, et `kb-app-demo-desktop` réussit 139 tests unitaires ;
- enregistre la première validation Tauri de `pre.014` : `cargo check --workspace`, Clippy et laudit workspace sont propres, `ks-pipeline-demo-scenarios` réussit 105 tests unitaires + 1 CLI + 1 API externe, et `kb-app-demo-desktop` réussit 139 tests unitaires ;
- les logs fournis confirment lexécution desktop complète de Token-2022 Token Metadata et Solana Program Metadata sur Devnet, tandis que lancien parcours Metaplex sarrêtait après la seule préparation de fixture, défaut de câblage corrigé par ce delta ;
- ajoute le troisième sous-panneau **Token-2022 Token Metadata** dans `demo_execution_metadata` ;
- appelle directement la campagne réutilisable de cinq opérations `Initialize -> UpdateField -> Emit -> RemoveKey -> UpdateAuthority` sur un mint Token-2022 frais ;
@@ -57,7 +63,7 @@
- `pre.013-delta-fix-022` restaure la compatibilité `Future + Send` de la commande Tauri Metaplex en corrigeant le runner partagé : l'effacement temporaire `Signer + Sync -> &dyn Signer` est limité à un helper synchrone de signature et n'est plus conservé au travers des `await` ; aucun assouplissement de la commande desktop n'est nécessaire ;
- `pre.013-delta-fix-002` retire la réécriture locale du JSON `Create` par famille et consomme désormais directement la fixture Metaplex réutilisable, afin déviter quun parcours `Fungible` annonce un token standard incompatible avec le mint réellement préparé ;
- conserve laction Create autonome sur une fixture NFT par défaut, tandis que les parcours de scénario sélectionnent explicitement leur famille lors de la préparation.
- `pre.013-delta-fix-001` sérialise explicitement les summaries de backfill, extraction Core et replay dans l'evidence JSON au lieu d'exiger `serde::Serialize` sur les contrats internes de `kb-pipeline` ;
- `pre.013-delta-fix-001` sérialise explicitement les summaries de backfill, extraction Core et replay dans l'evidence JSON au lieu d'exiger `serde::Serialize` sur les contrats internes de `ks-pipeline` ;
- adapte lappel Metaplex au runner Devnet renforcé sans ajouter encore de nouveau parcours UI ;
- initialise le store PostgreSQL avant une exécution Metaplex réelle et fournit le décodeur ainsi que les matérialiseurs runtime ;
- conserve dans levidence JSON le backfill canonique, lextraction Core, le replay, la seconde passe didempotence, les matérialisations instructionnelles et le diagnostic post-exécution.
@@ -68,11 +74,11 @@
- renomme les contrats et commandes Tauri Metaplex afin de rendre leur domaine explicite ;
- remplace la réutilisation erronée de lobserver Solana Core par un observer Metadata ciblant exclusivement `demo_execution_metadata` ;
- déplace le garde de lexécution Devnet partagée dans `demo_devnet_common` sous le nom générique `DemoExecutionRunGuard` ;
- consomme la borne RPC complète de `65536` octets exposée par `kb-onchain-transport` pour les lectures Solana Program Metadata ;
- consomme la borne RPC complète de `65536` octets exposée par `ks-onchain-transport` pour les lectures Solana Program Metadata ;
- ajoute un adaptateur desktop séparé pour les deux parcours Solana Program Metadata ;
- expose linventaire exact des neuf opérations et leurs états attendus ;
- synchronise le profil Devnet entre les sections Metaplex et Solana Program Metadata ;
- appelle directement la campagne réutilisable de `kb-pipeline-demo-scenarios` sans dupliquer la logique réseau ;
- appelle directement la campagne réutilisable de `ks-pipeline-demo-scenarios` sans dupliquer la logique réseau ;
- affiche la fixture, les deux signatures de préfinancement, les neuf simulations, confirmations, postconditions et snapshots matérialisés ;
- exige une confirmation explicite unique couvrant les deux préfinancements et les neuf mutations ;
- conserve les parcours Metaplex existants inchangés.
@@ -125,7 +131,7 @@
- remplace la préparation Metaplex fondée sur `solana-keygen`, `solana` et `spl-token` par une transaction Rust native ;
- crée le mint par `SystemCreateAccount` puis `SPL Token InitializeMint2` dans un même message simulé, signé et confirmé ;
- utilise explicitement le wallet du profil comme mint authority et freeze authority ;
- conserve le keypair du mint dans `kb-wallet` sans exposer ni déléguer ses secrets à une CLI externe.
- conserve le keypair du mint dans `ks-wallet` sans exposer ni déléguer ses secrets à une CLI externe.
## 0.4.7-pre.013-fix-009

View File

@@ -1,5 +1,5 @@
# file: kb-app-demo-desktop/Cargo.toml
# version: 6
# version: 7
[package]
name = "kb-app-demo-desktop"
@@ -23,16 +23,16 @@ tauri-build.workspace = true
[dependencies]
chrono.workspace = true
fs2.workspace = true
kb-config = { path = "../kb-config" }
kb-core = { path = "../kb-core" }
kb-logging = { path = "../kb-logging" }
kb-lib = { path = "../kb-lib" }
kb-program-ids = { path = "../kb-program-ids" }
kb-store = { path = "../kb-store" }
kb-wallet = { path = "../kb-wallet" }
kb-pipeline = { path = "../kb-pipeline" }
kb-pipeline-demo-scenarios = { path = "../kb-pipeline-demo-scenarios" }
kb-onchain-transport = { path = "../kb-onchain-transport" }
ks-config = { path = "../ks-config" }
ks-core = { path = "../ks-core" }
ks-logging = { path = "../ks-logging" }
ks-lib = { path = "../ks-lib" }
ks-program-ids = { path = "../ks-program-ids" }
ks-store = { path = "../ks-store" }
ks-wallet = { path = "../ks-wallet" }
ks-pipeline = { path = "../ks-pipeline" }
ks-pipeline-demo-scenarios = { path = "../ks-pipeline-demo-scenarios" }
ks-onchain-transport = { path = "../ks-onchain-transport" }
serde.workspace = true
serde_json.workspace = true
spl-associated-token-account-interface.workspace = true

View File

@@ -1,5 +1,5 @@
<!-- file: kb-app-demo-desktop/README.md -->
<!-- version: 13 -->
<!-- version: 14 -->
# kb-app-demo-desktop
@@ -17,21 +17,21 @@
## Frontière architecturale
Les commandes Tauri sont des adaptateurs minces. La logique réutilisable appartient à `kb-pipeline`, `kb-pipeline-demo-scenarios`, `kb-lib`, `kb-store` et `kb-onchain-transport`.
Les commandes Tauri sont des adaptateurs minces. La logique réutilisable appartient à `ks-pipeline`, `ks-pipeline-demo-scenarios`, `ks-lib`, `ks-store` et `ks-onchain-transport`.
Les campagnes Devnet/Testnet réutilisables appartiennent à `kb-pipeline-demo-scenarios`. Le desktop conserve leurs adaptateurs UI/Tauri, la sélection opérateur, la progression, les payloads TS-RS et la présentation ; `0.5.4` doit retirer les orchestrations réutilisables qui subsistent encore localement.
Les campagnes Devnet/Testnet réutilisables appartiennent à `ks-pipeline-demo-scenarios`. Le desktop conserve leurs adaptateurs UI/Tauri, la sélection opérateur, la progression, les payloads TS-RS et la présentation ; `0.5.4` doit retirer les orchestrations réutilisables qui subsistent encore localement.
## Exécution Metaplex Token Metadata
Le panneau conserve les scénarios synthétiques pour inspecter les contrats, mais son parcours Devnet principal expose désormais 11 campagnes qualifiées de `pre.013` et appelle directement leurs runners spécialisés de `kb-pipeline-demo-scenarios`. Les cinq variantes `Create -> Mint`, collection, Print/Burn, lifecycle pNFT et escrow soumettent uniquement les opérations autorisées ; Maintenance et Use conservent les opérations `unavailable` dans des probes simulation-only. Le desktop ne reconstruit pas les builders ; il conserve encore une partie du dispatch, des critères de complétion et de la projection de preuves, à centraliser en `0.5.4` lorsque cette logique est réutilisable.
Le panneau conserve les scénarios synthétiques pour inspecter les contrats, mais son parcours Devnet principal expose désormais 11 campagnes qualifiées de `pre.013` et appelle directement leurs runners spécialisés de `ks-pipeline-demo-scenarios`. Les cinq variantes `Create -> Mint`, collection, Print/Burn, lifecycle pNFT et escrow soumettent uniquement les opérations autorisées ; Maintenance et Use conservent les opérations `unavailable` dans des probes simulation-only. Le desktop ne reconstruit pas les builders ; il conserve encore une partie du dispatch, des critères de complétion et de la projection de preuves, à centraliser en `0.5.4` lorsque cette logique est réutilisable.
## Exécution Token-2022 Token Metadata
Le sous-panneau dédié appelle directement la campagne réutilisable de `kb-pipeline-demo-scenarios`; son parcours desktop complet a été confirmé sur Devnet pendant `pre.014`. Il crée un mint Token-2022 frais avec Metadata Pointer auto-référencé puis exécute, dans lordre, `Initialize`, `UpdateField`, `Emit`, `RemoveKey` et `UpdateAuthority`. Chaque étape passe par simulation, confirmation, replay canonique, matérialisation lorsque requise, lecture stateful et postcondition ; `Emit` conserve en plus sa return data validée.
Le sous-panneau dédié appelle directement la campagne réutilisable de `ks-pipeline-demo-scenarios`; son parcours desktop complet a été confirmé sur Devnet pendant `pre.014`. Il crée un mint Token-2022 frais avec Metadata Pointer auto-référencé puis exécute, dans lordre, `Initialize`, `UpdateField`, `Emit`, `RemoveKey` et `UpdateAuthority`. Chaque étape passe par simulation, confirmation, replay canonique, matérialisation lorsque requise, lecture stateful et postcondition ; `Emit` conserve en plus sa return data validée.
## Exécution Solana Program Metadata
Le même panneau expose séparément les deux parcours `Buffer` et `Metadata` de `ProgM6…`; sa campagne desktop complète a été confirmée sur Devnet pendant `pre.014`. La campagne complète crée deux PDA frais, confirme leurs préfinancements, exécute les neuf opérations stables, vérifie les lectures avant/après et affiche les snapshots matérialisés. La logique réseau reste entièrement dans `kb-pipeline-demo-scenarios` ; le desktop ne fait que sélectionner le profil, demander la confirmation et présenter les preuves.
Le même panneau expose séparément les deux parcours `Buffer` et `Metadata` de `ProgM6…`; sa campagne desktop complète a été confirmée sur Devnet pendant `pre.014`. La campagne complète crée deux PDA frais, confirme leurs préfinancements, exécute les neuf opérations stables, vérifie les lectures avant/après et affiche les snapshots matérialisés. La logique réseau reste entièrement dans `ks-pipeline-demo-scenarios` ; le desktop ne fait que sélectionner le profil, demander la confirmation et présenter les preuves.
## Documentation

View File

@@ -1,11 +1,11 @@
<!-- file: kb-app-demo-desktop/TODO.md -->
<!-- version: 15 -->
<!-- version: 16 -->
# TODO — kb-app-demo-desktop
## Évolutions générales
- [ ] `0.5.4` — réduire les panneaux d'exécution à l'adaptation UI/Tauri en déplaçant toute orchestration de campagne encore réutilisable vers `kb-pipeline-demo-scenarios`.
- [ ] `0.5.4` — réduire les panneaux d'exécution à l'adaptation UI/Tauri en déplaçant toute orchestration de campagne encore réutilisable vers `ks-pipeline-demo-scenarios`.
- [ ] UX — empêcher les doubles déclenchements pendant une préparation, simulation ou soumission active.
- [ ] Observabilité — afficher explicitement les comptes relus et les projections matérialisées.

View File

@@ -1,5 +1,5 @@
<!-- file: kb-app-demo-desktop/USAGE.md -->
<!-- version: 14 -->
<!-- version: 15 -->
# Utilisation de kb-app-demo-desktop
@@ -32,7 +32,7 @@ Ne pas lancer `npm run build` directement. Tauri exécute le `beforeBuildCommand
La bibliothèque expose uniquement `run()` :
```rust
fn launch_desktop() -> kb_core::Result<()> {
fn launch_desktop() -> ks_core::Result<()> {
return kb_app_demo_desktop_lib::run();
}
```
@@ -170,7 +170,7 @@ Avant les scénarios Devnet, utiliser les fenêtres généralistes dans cet ordr
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`.
Ce parcours ne dépend pas de `ks-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

View File

@@ -1,5 +1,5 @@
<!-- file: kb-app-demo-desktop/frontend/demo_sql_replay_candidates.html -->
<!-- version: 10 -->
<!-- version: 11 -->
<!DOCTYPE html>
<html lang="fr">
@@ -194,7 +194,7 @@
<div class="card-body">
<div class="row g-3 align-items-end">
<div class="col-12 col-lg-5">
<label for="knownProgramSelect" class="form-label">Programme connu (kb_program_ids)</label>
<label for="knownProgramSelect" class="form-label">Programme connu (ks_program_ids)</label>
<select id="knownProgramSelect" class="form-select">
<option value="">Tous les programmes connus</option>
</select>

View File

@@ -1,19 +1,19 @@
// file: kb-app-demo-desktop/src/app_state.rs
// version: 10
// version: 11
//! Shared Tauri application state and startup initialization.
/// Shared state managed by Tauri for the desktop demo application.
pub(crate) struct AppState {
config_path: std::string::String,
app_config: kb_config::AppConfig,
active_profile: kb_config::ProfileConfig,
logging_guard: std::sync::Mutex<kb_logging::LoggingGuard>,
http_pool: kb_onchain_transport::HttpEndpointPool,
app_config: ks_config::AppConfig,
active_profile: ks_config::ProfileConfig,
logging_guard: std::sync::Mutex<ks_logging::LoggingGuard>,
http_pool: ks_onchain_transport::HttpEndpointPool,
ws_pool:
std::sync::Mutex<std::option::Option<std::sync::Arc<kb_onchain_transport::WsEndpointPool>>>,
std::sync::Mutex<std::option::Option<std::sync::Arc<ks_onchain_transport::WsEndpointPool>>>,
demo_ws_session:
tokio::sync::Mutex<std::option::Option<std::sync::Arc<kb_onchain_transport::WsSession>>>,
tokio::sync::Mutex<std::option::Option<std::sync::Arc<ks_onchain_transport::WsSession>>>,
demo_backfill_running: std::sync::atomic::AtomicBool,
demo_backfill_cancel_requested: std::sync::atomic::AtomicBool,
demo_core_extraction_running: std::sync::atomic::AtomicBool,
@@ -28,26 +28,26 @@ pub(crate) struct AppState {
impl crate::AppState {
/// Initializes configuration, logging and shared runtime state.
pub(crate) fn initialize() -> kb_core::Result<crate::AppState> {
pub(crate) fn initialize() -> ks_core::Result<crate::AppState> {
let config_path = resolve_config_path();
let workspace_root = crate::workspace_root_dir();
let app_config = match kb_config::read_config_json_file_with_environment(
let app_config = match ks_config::read_config_json_file_with_environment(
&config_path,
&workspace_root,
) {
std::result::Result::Ok(config) => config,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let active_profile = match kb_config::active_profile(&app_config) {
let active_profile = match ks_config::active_profile(&app_config) {
std::result::Result::Ok(profile) => profile.clone(),
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let logging_config = convert_logging_config(&active_profile.logging);
let logging_guard = match kb_logging::init_logging(&logging_config) {
let logging_guard = match ks_logging::init_logging(&logging_config) {
std::result::Result::Ok(guard) => guard,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&active_profile)
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&active_profile)
{
std::result::Result::Ok(pool) => pool,
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -79,29 +79,29 @@ impl crate::AppState {
}
/// Returns the complete parsed application configuration.
pub(crate) fn app_config(&self) -> &kb_config::AppConfig {
pub(crate) fn app_config(&self) -> &ks_config::AppConfig {
return &self.app_config;
}
/// Returns the active profile selected from the configuration.
pub(crate) fn active_profile(&self) -> &kb_config::ProfileConfig {
pub(crate) fn active_profile(&self) -> &ks_config::ProfileConfig {
return &self.active_profile;
}
/// Returns the configured HTTP endpoint pool.
pub(crate) fn http_pool(&self) -> &kb_onchain_transport::HttpEndpointPool {
pub(crate) fn http_pool(&self) -> &ks_onchain_transport::HttpEndpointPool {
return &self.http_pool;
}
/// Returns the lazily initialized WebSocket endpoint pool.
pub(crate) fn demo_ws_pool(
&self,
) -> kb_core::Result<std::sync::Arc<kb_onchain_transport::WsEndpointPool>> {
) -> ks_core::Result<std::sync::Arc<ks_onchain_transport::WsEndpointPool>> {
let lock_result = self.ws_pool.lock();
let mut guard = match lock_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => {
return std::result::Result::Err(kb_core::Error::invalid_state(
return std::result::Result::Err(ks_core::Error::invalid_state(
"demo WebSocket pool lock is poisoned",
));
},
@@ -109,7 +109,7 @@ impl crate::AppState {
if let std::option::Option::Some(pool) = guard.as_ref() {
return std::result::Result::Ok(std::sync::Arc::clone(pool));
}
let pool = match kb_onchain_transport::WsEndpointPool::from_profile(&self.active_profile) {
let pool = match ks_onchain_transport::WsEndpointPool::from_profile(&self.active_profile) {
std::result::Result::Ok(value) => std::sync::Arc::new(value),
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -120,7 +120,7 @@ impl crate::AppState {
/// Returns the persistent WebSocket demo session slot.
pub(crate) fn demo_ws_session(
&self,
) -> &tokio::sync::Mutex<std::option::Option<std::sync::Arc<kb_onchain_transport::WsSession>>>
) -> &tokio::sync::Mutex<std::option::Option<std::sync::Arc<ks_onchain_transport::WsSession>>>
{
return &self.demo_ws_session;
}
@@ -198,10 +198,10 @@ impl crate::AppState {
}
}
fn convert_logging_config(config: &kb_config::LoggingConfig) -> kb_logging::LoggingConfig {
let mut targets = std::vec::Vec::<kb_logging::LogTargetConfig>::new();
fn convert_logging_config(config: &ks_config::LoggingConfig) -> ks_logging::LoggingConfig {
let mut targets = std::vec::Vec::<ks_logging::LogTargetConfig>::new();
for target in &config.targets {
targets.push(kb_logging::LogTargetConfig {
targets.push(ks_logging::LogTargetConfig {
name: target.name.clone(),
enabled: target.enabled,
sink: target.sink.clone(),
@@ -213,14 +213,14 @@ fn convert_logging_config(config: &kb_config::LoggingConfig) -> kb_logging::Logg
targets: target.targets.clone(),
});
}
let mut target_filters = std::vec::Vec::<kb_logging::LogTargetFilterConfig>::new();
let mut target_filters = std::vec::Vec::<ks_logging::LogTargetFilterConfig>::new();
for filter in &config.target_filters {
target_filters.push(kb_logging::LogTargetFilterConfig {
target_filters.push(ks_logging::LogTargetFilterConfig {
target: filter.target.clone(),
level: filter.level.clone(),
});
}
return kb_logging::LoggingConfig {
return ks_logging::LoggingConfig {
default_level: config.default_level.clone(),
targets,
target_filters,

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_backfill.rs
// version: 15
// version: 16
//! Tauri commands and UI payloads for bounded HTTP transaction backfills.
@@ -193,8 +193,8 @@ pub(crate) struct DemoBackfillObserver<'a> {
pub(crate) cancel_requested: &'a std::sync::atomic::AtomicBool,
}
impl kb_pipeline::BackfillObserver for crate::DemoBackfillObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::BackfillProgressEvent) {
impl ks_pipeline::BackfillObserver for crate::DemoBackfillObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::BackfillProgressEvent) {
let payload = crate::DemoBackfillProgressPayload {
timestamp: event.timestamp.clone(),
level: event.level.code().to_string(),
@@ -244,7 +244,7 @@ pub(crate) fn demo_backfill_options(
} else {
roles.first().map(|item| return item.role.clone())
};
let programs = kb_program_ids::registered_program_ids()
let programs = ks_program_ids::registered_program_ids()
.iter()
.map(|entry| {
return crate::DemoBackfillProgramOption {
@@ -289,7 +289,7 @@ pub(crate) async fn demo_backfill_execute(
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let profile = state.active_profile();
let store_options = match kb_store::PostgresStoreOptions::new(
let store_options = match ks_store::PostgresStoreOptions::new(
profile.database.postgres.url.clone(),
profile.database.postgres.max_connections,
profile.database.postgres.connect_timeout_ms,
@@ -298,7 +298,7 @@ pub(crate) async fn demo_backfill_execute(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let store = match kb_store::PostgresStore::connect(store_options).await {
let store = match ks_store::PostgresStore::connect(store_options).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -309,7 +309,7 @@ pub(crate) async fn demo_backfill_execute(
app_handle,
cancel_requested: state.demo_backfill_cancel_requested(),
};
let summary = match kb_pipeline::execute_http_backfill(
let summary = match ks_pipeline::execute_http_backfill(
state.http_pool(),
&store,
&pipeline_request,
@@ -324,7 +324,7 @@ pub(crate) async fn demo_backfill_execute(
}
fn build_role_options(
snapshots: std::vec::Vec<kb_onchain_transport::HttpPoolClientSnapshot>,
snapshots: std::vec::Vec<ks_onchain_transport::HttpPoolClientSnapshot>,
) -> std::vec::Vec<crate::DemoBackfillRoleOption> {
let mut role_methods = std::collections::BTreeMap::<
std::string::String,
@@ -364,25 +364,25 @@ fn build_role_options(
fn build_pipeline_request(
request: DemoBackfillRequest,
) -> std::result::Result<kb_pipeline::BackfillRequest, std::string::String> {
) -> std::result::Result<ks_pipeline::BackfillRequest, std::string::String> {
let source_result = match request.mode.trim() {
"explicit_signatures" => explicit_source(request.signatures_text.as_deref()),
"program" => address_source(
kb_pipeline::BackfillAddressKind::Program,
ks_pipeline::BackfillAddressKind::Program,
request.address.as_deref(),
request.anchor_signature.as_deref(),
request.direction.as_deref(),
request.limit,
),
"token" => address_source(
kb_pipeline::BackfillAddressKind::Token,
ks_pipeline::BackfillAddressKind::Token,
request.address.as_deref(),
request.anchor_signature.as_deref(),
request.direction.as_deref(),
request.limit,
),
"pool" => address_source(
kb_pipeline::BackfillAddressKind::Pool,
ks_pipeline::BackfillAddressKind::Pool,
request.address.as_deref(),
request.anchor_signature.as_deref(),
request.direction.as_deref(),
@@ -394,7 +394,7 @@ fn build_pipeline_request(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let pipeline_request = kb_pipeline::BackfillRequest {
let pipeline_request = ks_pipeline::BackfillRequest {
role: request.role,
commitment: request.commitment,
source,
@@ -412,7 +412,7 @@ fn build_pipeline_request(
fn explicit_source(
signatures_text: std::option::Option<&str>,
) -> std::result::Result<kb_pipeline::BackfillSource, std::string::String> {
) -> std::result::Result<ks_pipeline::BackfillSource, std::string::String> {
let text = match signatures_text {
std::option::Option::Some(value) => value,
std::option::Option::None => "",
@@ -428,16 +428,16 @@ fn explicit_source(
"the signatures textarea must contain at least one signature".to_string(),
);
}
return std::result::Result::Ok(kb_pipeline::BackfillSource::ExplicitSignatures(signatures));
return std::result::Result::Ok(ks_pipeline::BackfillSource::ExplicitSignatures(signatures));
}
fn address_source(
kind: kb_pipeline::BackfillAddressKind,
kind: ks_pipeline::BackfillAddressKind,
address: std::option::Option<&str>,
anchor_signature: std::option::Option<&str>,
direction: std::option::Option<&str>,
limit: u32,
) -> std::result::Result<kb_pipeline::BackfillSource, std::string::String> {
) -> std::result::Result<ks_pipeline::BackfillSource, std::string::String> {
let address_text = match address {
std::option::Option::Some(value) => value,
std::option::Option::None => "",
@@ -451,8 +451,8 @@ fn address_source(
std::option::Option::None => "",
};
let direction_value = match direction_text.trim() {
"before" => kb_pipeline::BackfillDirection::Before,
"after" => kb_pipeline::BackfillDirection::After,
"before" => ks_pipeline::BackfillDirection::Before,
"after" => ks_pipeline::BackfillDirection::After,
_ => {
return std::result::Result::Err("direction must be before or after".to_string());
},
@@ -461,7 +461,7 @@ fn address_source(
.map(str::trim)
.filter(|value| return !value.is_empty())
.map(str::to_string);
if direction_value == kb_pipeline::BackfillDirection::After && anchor_value.is_none() {
if direction_value == ks_pipeline::BackfillDirection::After && anchor_value.is_none() {
return std::result::Result::Err(
"anchor signature is required for newer-history backfill".to_string(),
);
@@ -472,7 +472,7 @@ fn address_source(
return std::result::Result::Err(format!("signature limit conversion failed: {error}"));
},
};
return std::result::Result::Ok(kb_pipeline::BackfillSource::AddressHistory {
return std::result::Result::Ok(ks_pipeline::BackfillSource::AddressHistory {
kind,
address: address_value.to_string(),
anchor_signature: anchor_value,
@@ -481,7 +481,7 @@ fn address_source(
});
}
fn summary_payload(summary: kb_pipeline::BackfillSummary) -> DemoBackfillSummaryPayload {
fn summary_payload(summary: ks_pipeline::BackfillSummary) -> DemoBackfillSummaryPayload {
return crate::DemoBackfillSummaryPayload {
capture_session_id: summary.capture_session_id,
filter_code: summary.filter_code,
@@ -520,7 +520,7 @@ mod tests {
};
assert_eq!(
source,
kb_pipeline::BackfillSource::ExplicitSignatures(std::vec![
ks_pipeline::BackfillSource::ExplicitSignatures(std::vec![
"first".to_string(),
"second".to_string(),
])
@@ -530,7 +530,7 @@ mod tests {
#[test]
fn older_history_accepts_missing_anchor_and_uses_latest_filter() {
let source_result = super::address_source(
kb_pipeline::BackfillAddressKind::Program,
ks_pipeline::BackfillAddressKind::Program,
std::option::Option::Some("11111111111111111111111111111111"),
std::option::Option::Some(" "),
std::option::Option::Some("before"),
@@ -540,7 +540,7 @@ mod tests {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("source failed: {error}"),
};
let request = kb_pipeline::BackfillRequest {
let request = ks_pipeline::BackfillRequest {
role: "history_backfill".to_string(),
commitment: "confirmed".to_string(),
source,
@@ -556,7 +556,7 @@ mod tests {
#[test]
fn newer_history_rejects_missing_anchor() {
let source_result = super::address_source(
kb_pipeline::BackfillAddressKind::Program,
ks_pipeline::BackfillAddressKind::Program,
std::option::Option::Some("11111111111111111111111111111111"),
std::option::Option::None,
std::option::Option::Some("after"),

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_config.rs
// version: 2
// version: 3
//! Configuration demo payload and state projection.
@@ -19,9 +19,9 @@ pub(crate) struct DemoConfigPayload {
/// Active profile environment.
pub(crate) environment: std::string::String,
/// Entire parsed configuration.
pub(crate) app_config: kb_config::AppConfig,
pub(crate) app_config: ks_config::AppConfig,
/// Active profile configuration.
pub(crate) active_profile: kb_config::ProfileConfig,
pub(crate) active_profile: ks_config::ProfileConfig,
/// Embedded JSON Schema text used during loading.
pub(crate) schema_json: std::string::String,
}
@@ -34,7 +34,7 @@ pub(crate) fn demo_config_payload(state: &crate::AppState) -> crate::DemoConfigP
environment: state.active_profile().app.environment.clone(),
app_config: state.app_config().clone(),
active_profile: state.active_profile().clone(),
schema_json: kb_config::config_json_schema_text().to_owned(),
schema_json: ks_config::config_json_schema_text().to_owned(),
};
}

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_core_extraction.rs
// version: 13
// version: 14
//! Tauri commands and UI payloads for canonical transaction to core extraction.
@@ -137,8 +137,8 @@ pub(crate) struct DemoCoreExtractionObserver<'a> {
pub(crate) cancel_requested: &'a std::sync::atomic::AtomicBool,
}
impl kb_pipeline::CoreExtractionObserver for crate::DemoCoreExtractionObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::CoreExtractionProgressEvent) {
impl ks_pipeline::CoreExtractionObserver for crate::DemoCoreExtractionObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::CoreExtractionProgressEvent) {
let payload = crate::DemoCoreExtractionProgressPayload {
timestamp: event.timestamp.clone(),
level: event.level.code().to_string(),
@@ -178,11 +178,11 @@ pub(crate) fn demo_core_extraction_options_payload(
state: &crate::AppState,
) -> crate::DemoCoreExtractionOptionsPayload {
return crate::DemoCoreExtractionOptionsPayload {
processor_version: kb_pipeline::CORE_EXTRACTION_PROCESSOR_VERSION.to_string(),
processor_version: ks_pipeline::CORE_EXTRACTION_PROCESSOR_VERSION.to_string(),
default_limit: 100,
default_max_concurrent_extractions: 4,
running: state.demo_core_extraction_running().load(std::sync::atomic::Ordering::Acquire),
programs: kb_program_ids::registered_program_ids()
programs: ks_program_ids::registered_program_ids()
.iter()
.map(|entry| {
return crate::DemoCoreExtractionProgramOption {
@@ -231,7 +231,7 @@ pub(crate) async fn demo_core_extraction_execute(
cancel_requested: state.demo_core_extraction_cancel_requested(),
};
let summary_result =
kb_pipeline::execute_core_extraction(&store, &pipeline_request, &observer).await;
ks_pipeline::execute_core_extraction(&store, &pipeline_request, &observer).await;
let summary = match summary_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
@@ -249,13 +249,13 @@ pub(crate) fn demo_core_extraction_cancel(state: &crate::AppState) -> bool {
fn build_pipeline_request(
request: crate::DemoCoreExtractionRequest,
) -> std::result::Result<kb_pipeline::CoreExtractionRequest, std::string::String> {
) -> std::result::Result<ks_pipeline::CoreExtractionRequest, std::string::String> {
let source_result = match request.mode.trim() {
"signatures" => {
let signatures = split_signatures(request.signatures_text.as_deref());
std::result::Result::Ok(kb_pipeline::CoreExtractionSource::Signatures(signatures))
std::result::Result::Ok(ks_pipeline::CoreExtractionSource::Signatures(signatures))
},
"pending" => std::result::Result::Ok(kb_pipeline::CoreExtractionSource::Pending),
"pending" => std::result::Result::Ok(ks_pipeline::CoreExtractionSource::Pending),
"program_id" => {
let program_id = match request.program_id {
std::option::Option::Some(value) if !value.trim().is_empty() => value,
@@ -265,7 +265,7 @@ fn build_pipeline_request(
);
},
};
std::result::Result::Ok(kb_pipeline::CoreExtractionSource::ProgramId { program_id })
std::result::Result::Ok(ks_pipeline::CoreExtractionSource::ProgramId { program_id })
},
"slot_range" => {
let min_slot = match request.min_slot {
@@ -284,7 +284,7 @@ fn build_pipeline_request(
);
},
};
std::result::Result::Ok(kb_pipeline::CoreExtractionSource::SlotRange {
std::result::Result::Ok(ks_pipeline::CoreExtractionSource::SlotRange {
min_slot,
max_slot,
})
@@ -295,7 +295,7 @@ fn build_pipeline_request(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let pipeline_request = kb_pipeline::CoreExtractionRequest {
let pipeline_request = ks_pipeline::CoreExtractionRequest {
source,
limit: request.limit,
max_concurrent_extractions: request.max_concurrent_extractions,
@@ -309,7 +309,7 @@ fn build_pipeline_request(
}
fn summary_payload(
summary: kb_pipeline::CoreExtractionSummary,
summary: ks_pipeline::CoreExtractionSummary,
) -> crate::DemoCoreExtractionSummaryPayload {
return crate::DemoCoreExtractionSummaryPayload {
processor_version: summary.processor_version,

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_decode_replay.rs
// version: 39
// version: 40
//! Tauri commands and UI payloads for contextual instruction decode replay.
@@ -319,8 +319,8 @@ pub(crate) struct DemoDecodeReplayObserver<'a> {
pub(crate) cancel_requested: &'a std::sync::atomic::AtomicBool,
}
impl kb_pipeline::DecodeReplayObserver for crate::DemoDecodeReplayObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::DecodeReplayProgressEvent) {
impl ks_pipeline::DecodeReplayObserver for crate::DemoDecodeReplayObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::DecodeReplayProgressEvent) {
let payload = crate::DemoDecodeReplayProgressPayload {
campaign_id: self.campaign_id.clone(),
timestamp: event.timestamp.clone(),
@@ -385,7 +385,7 @@ pub(crate) fn demo_decode_replay_options(
return format!("{}@{}", identity.name, identity.version);
})
.collect::<std::vec::Vec<_>>();
let programs = kb_program_ids::registered_program_ids()
let programs = ks_program_ids::registered_program_ids()
.iter()
.map(|entry| {
return crate::DemoDecodeReplayProgramOption {
@@ -398,7 +398,7 @@ pub(crate) fn demo_decode_replay_options(
tracing::debug!(
target: crate::TRACING_TARGET,
action = "load_options",
pipeline_version = kb_pipeline::DECODE_PIPELINE_VERSION,
pipeline_version = ks_pipeline::DECODE_PIPELINE_VERSION,
decoder_count = decoder_options.len(),
materializer_names = ?materializer_names,
default_limit = 100_u32,
@@ -407,7 +407,7 @@ pub(crate) fn demo_decode_replay_options(
"return contextual decode replay options"
);
return crate::DemoDecodeReplayOptionsPayload {
pipeline_version: kb_pipeline::DECODE_PIPELINE_VERSION.to_string(),
pipeline_version: ks_pipeline::DECODE_PIPELINE_VERSION.to_string(),
decoders: decoder_options,
materializer_names,
programs,
@@ -423,7 +423,7 @@ pub(crate) async fn demo_decode_replay_execute(
state: tauri::State<'_, crate::AppState>,
request: crate::DemoDecodeReplayRequest,
) -> std::result::Result<crate::DemoDecodeReplaySummaryPayload, std::string::String> {
let campaign_id = kb_pipeline::new_decode_campaign_id();
let campaign_id = ks_pipeline::new_decode_campaign_id();
tracing::debug!(
target: crate::TRACING_TARGET,
action = "execute",
@@ -510,7 +510,7 @@ pub(crate) async fn demo_decode_replay_execute(
campaign_id: pipeline_request.campaign_id.clone(),
cancel_requested: state.demo_decode_replay_cancel_requested(),
};
let summary_result = kb_pipeline::execute_decode_replay(
let summary_result = ks_pipeline::execute_decode_replay(
&store,
&pipeline_request,
decoders.as_slice(),
@@ -582,7 +582,7 @@ pub(crate) async fn demo_decode_replay_diagnostics(
})
.map(crate::table_snapshot_from_pg)
.collect();
let coverage_result = kb_store::DecodePipelineStore::list_decode_coverage_summary(
let coverage_result = ks_store::DecodePipelineStore::list_decode_coverage_summary(
&store,
std::option::Option::None,
std::option::Option::None,
@@ -605,7 +605,7 @@ pub(crate) async fn demo_decode_replay_annotations(
state: tauri::State<'_, crate::AppState>,
request: crate::DemoTransactionAnnotationRequest,
) -> std::result::Result<std::vec::Vec<crate::DemoTransactionAnnotationRow>, std::string::String> {
let filter_result = kb_store::MaterializedEventFilter::new(
let filter_result = ks_store::MaterializedEventFilter::new(
std::option::Option::Some("materializer.transaction.annotations".to_string()),
std::option::Option::Some("transaction_annotation".to_string()),
request.signature_contains,
@@ -622,7 +622,7 @@ pub(crate) async fn demo_decode_replay_annotations(
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let rows_result =
kb_store::DecodePipelineStore::list_materialized_events(&store, &filter).await;
ks_store::DecodePipelineStore::list_materialized_events(&store, &filter).await;
let rows = match rows_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
@@ -656,39 +656,39 @@ fn register_active_campaign(
return std::result::Result::Ok(());
}
fn available_materializers() -> std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> {
fn available_materializers() -> std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> {
return std::vec![
std::sync::Arc::new(kb_lib::MtAdminMaterializer),
std::sync::Arc::new(kb_lib::MtComplianceAuditMaterializer),
std::sync::Arc::new(kb_lib::MtFeesMaterializer),
std::sync::Arc::new(kb_lib::MtLifecycleMaterializer),
std::sync::Arc::new(kb_lib::MtMetadataMetaplexTokenMetadataMaterializer),
std::sync::Arc::new(kb_lib::MtMetadataSolanaProgramMaterializer),
std::sync::Arc::new(kb_lib::MtMetadataToken2022Materializer),
std::sync::Arc::new(kb_lib::MtStakingMaterializer),
std::sync::Arc::new(kb_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(kb_lib::MtRiskMaterializer),
std::sync::Arc::new(kb_lib::MtTransactionAnnotationMaterializer),
std::sync::Arc::new(ks_lib::MtAdminMaterializer),
std::sync::Arc::new(ks_lib::MtComplianceAuditMaterializer),
std::sync::Arc::new(ks_lib::MtFeesMaterializer),
std::sync::Arc::new(ks_lib::MtLifecycleMaterializer),
std::sync::Arc::new(ks_lib::MtMetadataMetaplexTokenMetadataMaterializer),
std::sync::Arc::new(ks_lib::MtMetadataSolanaProgramMaterializer),
std::sync::Arc::new(ks_lib::MtMetadataToken2022Materializer),
std::sync::Arc::new(ks_lib::MtStakingMaterializer),
std::sync::Arc::new(ks_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(ks_lib::MtRiskMaterializer),
std::sync::Arc::new(ks_lib::MtTransactionAnnotationMaterializer),
];
}
fn available_decoders() -> std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> {
fn available_decoders() -> std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> {
return std::vec![
std::sync::Arc::new(kb_lib::DcSolanaCoreDecoder),
std::sync::Arc::new(kb_lib::DcMetadataMetaplexTokenMetadataDecoder),
std::sync::Arc::new(kb_lib::DcMetadataSolanaProgramMetadataDecoder),
std::sync::Arc::new(kb_lib::DcSplAssociatedTokenAccountDecoder),
std::sync::Arc::new(kb_lib::DcSplElgamalRegistryDecoder),
std::sync::Arc::new(kb_lib::DcSplMemoDecoder),
std::sync::Arc::new(kb_lib::DcSplTokenDecoder),
std::sync::Arc::new(kb_lib::DcSplToken2022Decoder),
std::sync::Arc::new(ks_lib::DcSolanaCoreDecoder),
std::sync::Arc::new(ks_lib::DcMetadataMetaplexTokenMetadataDecoder),
std::sync::Arc::new(ks_lib::DcMetadataSolanaProgramMetadataDecoder),
std::sync::Arc::new(ks_lib::DcSplAssociatedTokenAccountDecoder),
std::sync::Arc::new(ks_lib::DcSplElgamalRegistryDecoder),
std::sync::Arc::new(ks_lib::DcSplMemoDecoder),
std::sync::Arc::new(ks_lib::DcSplTokenDecoder),
std::sync::Arc::new(ks_lib::DcSplToken2022Decoder),
];
}
fn build_pipeline_request(
request: crate::DemoDecodeReplayRequest,
campaign_id: std::string::String,
) -> std::result::Result<kb_pipeline::DecodeReplayRequest, std::string::String> {
) -> std::result::Result<ks_pipeline::DecodeReplayRequest, std::string::String> {
let states_result = processing_states(request.instruction_state.as_str());
let states = match states_result {
std::result::Result::Ok(value) => value,
@@ -703,7 +703,7 @@ fn build_pipeline_request(
},
_ => std::vec::Vec::new(),
};
let selection_result = kb_store::DecodeSelectionFilter::new(
let selection_result = ks_store::DecodeSelectionFilter::new(
signatures,
states,
std::option::Option::None,
@@ -718,11 +718,11 @@ fn build_pipeline_request(
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let dispatch_policy = if request.all_compatible {
kb_pipeline::DecodeDispatchPolicy::AllCompatible
ks_pipeline::DecodeDispatchPolicy::AllCompatible
} else {
kb_pipeline::DecodeDispatchPolicy::HighestPriority
ks_pipeline::DecodeDispatchPolicy::HighestPriority
};
let pipeline_request = kb_pipeline::DecodeReplayRequest {
let pipeline_request = ks_pipeline::DecodeReplayRequest {
campaign_id,
selection,
decoder_names: request.decoder_names,
@@ -773,31 +773,31 @@ fn text_sample(values: &[std::string::String], limit: usize) -> std::vec::Vec<&s
fn processing_states(
value: &str,
) -> std::result::Result<std::vec::Vec<kb_store::CoreInstructionProcessingState>, std::string::String>
) -> std::result::Result<std::vec::Vec<ks_store::CoreInstructionProcessingState>, std::string::String>
{
return match value.trim() {
"incomplete_signatures" | "actionable" => std::result::Result::Ok(std::vec![
kb_store::CoreInstructionProcessingState::Pending,
kb_store::CoreInstructionProcessingState::Failed,
kb_store::CoreInstructionProcessingState::ReplayRequested,
ks_store::CoreInstructionProcessingState::Pending,
ks_store::CoreInstructionProcessingState::Failed,
ks_store::CoreInstructionProcessingState::ReplayRequested,
]),
"pending" => {
std::result::Result::Ok(std::vec![kb_store::CoreInstructionProcessingState::Pending])
std::result::Result::Ok(std::vec![ks_store::CoreInstructionProcessingState::Pending])
},
"failed" => {
std::result::Result::Ok(std::vec![kb_store::CoreInstructionProcessingState::Failed])
std::result::Result::Ok(std::vec![ks_store::CoreInstructionProcessingState::Failed])
},
"replay_requested" => std::result::Result::Ok(std::vec![
kb_store::CoreInstructionProcessingState::ReplayRequested
ks_store::CoreInstructionProcessingState::ReplayRequested
]),
"decoded" => {
std::result::Result::Ok(std::vec![kb_store::CoreInstructionProcessingState::Decoded])
std::result::Result::Ok(std::vec![ks_store::CoreInstructionProcessingState::Decoded])
},
"ignored" => {
std::result::Result::Ok(std::vec![kb_store::CoreInstructionProcessingState::Ignored])
std::result::Result::Ok(std::vec![ks_store::CoreInstructionProcessingState::Ignored])
},
"materialized" => std::result::Result::Ok(std::vec![
kb_store::CoreInstructionProcessingState::Materialized
ks_store::CoreInstructionProcessingState::Materialized
]),
_ => std::result::Result::Err("unsupported instruction processing state".to_string()),
};
@@ -823,7 +823,7 @@ fn split_lines(text: std::option::Option<&str>) -> std::vec::Vec<std::string::St
}
fn summary_payload(
summary: kb_pipeline::DecodeReplaySummary,
summary: ks_pipeline::DecodeReplaySummary,
) -> crate::DemoDecodeReplaySummaryPayload {
return crate::DemoDecodeReplaySummaryPayload {
campaign_id: summary.campaign_id,
@@ -861,7 +861,7 @@ fn summary_payload(
}
fn coverage_payload(
value: kb_store::DecodeCoverageSummaryRow,
value: ks_store::DecodeCoverageSummaryRow,
) -> crate::DemoDecodeCoverageSummaryPayload {
return crate::DemoDecodeCoverageSummaryPayload {
processor_name: value.processor_name,
@@ -882,7 +882,7 @@ fn coverage_payload(
}
fn annotation_payload(
row: kb_store::MaterializedEventQueryRow,
row: ks_store::MaterializedEventQueryRow,
) -> std::result::Result<crate::DemoTransactionAnnotationRow, std::string::String> {
if row.processor_name != "materializer.transaction.annotations"
|| row.materialized_family != "transaction_annotation"
@@ -994,31 +994,31 @@ fn required_annotation_text(
#[cfg(test)]
mod tests {
fn ata_observation(entry: &str) -> kb_lib::DcApiDecodedObservation {
return kb_lib::DcApiDecodedObservation {
fn ata_observation(entry: &str) -> ks_lib::DcApiDecodedObservation {
return ks_lib::DcApiDecodedObservation {
event_key: format!("ata:{entry}:0"),
event: kb_lib::MdDecodedProtocolEvent {
signature: kb_lib::MdSignature("signature".to_string()),
slot: kb_lib::MdSlot(1),
instruction_path: kb_lib::MdInstructionPath("0".to_string()),
program_id: kb_lib::MdProgramId(
kb_program_ids::ASSOCIATED_TOKEN_PROGRAM_ID.to_string(),
event: ks_lib::MdDecodedProtocolEvent {
signature: ks_lib::MdSignature("signature".to_string()),
slot: ks_lib::MdSlot(1),
instruction_path: ks_lib::MdInstructionPath("0".to_string()),
program_id: ks_lib::MdProgramId(
ks_program_ids::ASSOCIATED_TOKEN_PROGRAM_ID.to_string(),
),
protocol_code: kb_lib::MdProtocolCode("spl.associated_token_account".to_string()),
surface_code: kb_lib::MdSurfaceCode("spl.associated_token_account".to_string()),
event_code: kb_lib::MdEventCode(format!("spl.associated_token_account.{entry}")),
event_name: kb_lib::MdEventName(entry.to_string()),
event_family: kb_lib::MdEventFamily::Lifecycle,
source_kind: kb_lib::MdEventSourceKind::Instruction,
confidence: kb_lib::MdDecoderConfidence::ManualExact,
protocol_code: ks_lib::MdProtocolCode("spl.associated_token_account".to_string()),
surface_code: ks_lib::MdSurfaceCode("spl.associated_token_account".to_string()),
event_code: ks_lib::MdEventCode(format!("spl.associated_token_account.{entry}")),
event_name: ks_lib::MdEventName(entry.to_string()),
event_family: ks_lib::MdEventFamily::Lifecycle,
source_kind: ks_lib::MdEventSourceKind::Instruction,
confidence: ks_lib::MdDecoderConfidence::ManualExact,
},
payload_json: serde_json::json!({}),
transaction_failed: false,
transaction_error: std::option::Option::None,
observation_committed: true,
proof: kb_lib::DcApiDecoderProof {
kind: kb_lib::DcApiDecoderProofKind::Manual,
confidence: kb_lib::MdDecoderConfidence::ManualExact,
proof: ks_lib::DcApiDecoderProof {
kind: ks_lib::DcApiDecoderProofKind::Manual,
confidence: ks_lib::MdDecoderConfidence::ManualExact,
evidence: std::vec!["fixture".to_string()],
},
};
@@ -1028,21 +1028,21 @@ mod tests {
program_id: &str,
surface: &str,
entry: &str,
) -> kb_lib::DcApiDecodedObservation {
return kb_lib::DcApiDecodedObservation {
) -> ks_lib::DcApiDecodedObservation {
return ks_lib::DcApiDecodedObservation {
event_key: format!("{surface}:{entry}:0"),
event: kb_lib::MdDecodedProtocolEvent {
signature: kb_lib::MdSignature("signature".to_string()),
slot: kb_lib::MdSlot(1),
instruction_path: kb_lib::MdInstructionPath("0".to_string()),
program_id: kb_lib::MdProgramId(program_id.to_string()),
protocol_code: kb_lib::MdProtocolCode(surface.to_string()),
surface_code: kb_lib::MdSurfaceCode(surface.to_string()),
event_code: kb_lib::MdEventCode(format!("{surface}.{entry}")),
event_name: kb_lib::MdEventName(entry.to_string()),
event_family: kb_lib::MdEventFamily::Metadata,
source_kind: kb_lib::MdEventSourceKind::Instruction,
confidence: kb_lib::MdDecoderConfidence::ManualExact,
event: ks_lib::MdDecodedProtocolEvent {
signature: ks_lib::MdSignature("signature".to_string()),
slot: ks_lib::MdSlot(1),
instruction_path: ks_lib::MdInstructionPath("0".to_string()),
program_id: ks_lib::MdProgramId(program_id.to_string()),
protocol_code: ks_lib::MdProtocolCode(surface.to_string()),
surface_code: ks_lib::MdSurfaceCode(surface.to_string()),
event_code: ks_lib::MdEventCode(format!("{surface}.{entry}")),
event_name: ks_lib::MdEventName(entry.to_string()),
event_family: ks_lib::MdEventFamily::Metadata,
source_kind: ks_lib::MdEventSourceKind::Instruction,
confidence: ks_lib::MdDecoderConfidence::ManualExact,
},
payload_json: serde_json::json!({
"programId": program_id,
@@ -1053,9 +1053,9 @@ mod tests {
transaction_failed: false,
transaction_error: std::option::Option::None,
observation_committed: true,
proof: kb_lib::DcApiDecoderProof {
kind: kb_lib::DcApiDecoderProofKind::Manual,
confidence: kb_lib::MdDecoderConfidence::ManualExact,
proof: ks_lib::DcApiDecoderProof {
kind: ks_lib::DcApiDecoderProofKind::Manual,
confidence: ks_lib::MdDecoderConfidence::ManualExact,
evidence: std::vec!["fixture".to_string()],
},
};
@@ -1114,19 +1114,19 @@ mod tests {
fn metadata_materializer_ownership_is_exact_in_the_runtime_registry() {
for (program_id, surface, entry, expected) in [
(
kb_program_ids::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID,
ks_program_ids::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID,
"metadata.metaplex_token_metadata",
"create_metadata_account_v3",
"materializer.metadata.metaplex_token_metadata",
),
(
kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID,
ks_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID,
"metadata.solana_program_metadata",
"initialize",
"materializer.metadata.solana_program_metadata",
),
(
kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
ks_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
"spl.token_2022",
"initialize_token_metadata",
"materializer.metadata.token_2022",
@@ -1274,7 +1274,7 @@ mod tests {
#[test]
fn committed_annotation_row_is_mapped_to_ui_safe_contract() {
let row = kb_store::MaterializedEventQueryRow {
let row = ks_store::MaterializedEventQueryRow {
processor_name: "materializer.transaction.annotations".to_string(),
processor_version: "0.4.3".to_string(),
input_key: "input".to_string(),
@@ -1288,7 +1288,7 @@ mod tests {
payload_json: serde_json::json!({
"instructionPath": "1/0",
"generation": "v4",
"programId": kb_program_ids::SPL_MEMO_V4_PROGRAM_ID,
"programId": ks_program_ids::SPL_MEMO_V4_PROGRAM_ID,
"text": "annotation",
"payloadLengthBytes": 10,
"payloadSha256": "11",
@@ -1310,7 +1310,7 @@ mod tests {
#[test]
fn malformed_annotation_payload_fails_closed() {
let row = kb_store::MaterializedEventQueryRow {
let row = ks_store::MaterializedEventQueryRow {
processor_name: "materializer.transaction.annotations".to_string(),
processor_version: "0.4.3".to_string(),
input_key: "input".to_string(),

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_devnet_common.rs
// version: 3
// version: 4
//! Shared Devnet demo UI contracts.
@@ -29,7 +29,7 @@ pub(crate) struct DemoExecutionDevnetStoreReadinessPayload {
/// Converts the reusable scenario readiness report to the desktop TS-RS payload.
pub(crate) fn devnet_store_readiness_payload(
readiness: kb_pipeline_demo_scenarios::DevnetProfileStoreReadiness,
readiness: ks_pipeline_demo_scenarios::DevnetProfileStoreReadiness,
) -> DemoExecutionDevnetStoreReadinessPayload {
return DemoExecutionDevnetStoreReadinessPayload {
profile_name: readiness.profile_name,

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_execution_metadata.rs
// version: 15
// version: 16
//! Shared desktop contracts for metadata execution demos.
@@ -69,8 +69,8 @@ impl crate::DemoExecutionMetadataObserver<'_> {
}
}
impl kb_pipeline::BackfillObserver for crate::DemoExecutionMetadataObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::BackfillProgressEvent) {
impl ks_pipeline::BackfillObserver for crate::DemoExecutionMetadataObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::BackfillProgressEvent) {
self.emit(
event.timestamp.clone(),
event.level.code(),
@@ -85,8 +85,8 @@ impl kb_pipeline::BackfillObserver for crate::DemoExecutionMetadataObserver<'_>
}
}
impl kb_pipeline::CoreExtractionObserver for crate::DemoExecutionMetadataObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::CoreExtractionProgressEvent) {
impl ks_pipeline::CoreExtractionObserver for crate::DemoExecutionMetadataObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::CoreExtractionProgressEvent) {
self.emit(
event.timestamp.clone(),
event.level.code(),
@@ -101,8 +101,8 @@ impl kb_pipeline::CoreExtractionObserver for crate::DemoExecutionMetadataObserve
}
}
impl kb_pipeline::DecodeReplayObserver for crate::DemoExecutionMetadataObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::DecodeReplayProgressEvent) {
impl ks_pipeline::DecodeReplayObserver for crate::DemoExecutionMetadataObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::DecodeReplayProgressEvent) {
self.emit(
event.timestamp.clone(),
event.level.code(),
@@ -117,12 +117,12 @@ impl kb_pipeline::DecodeReplayObserver for crate::DemoExecutionMetadataObserver<
}
}
impl kb_pipeline_demo_scenarios::SolanaExecutionObserver
impl ks_pipeline_demo_scenarios::SolanaExecutionObserver
for crate::DemoExecutionMetadataObserver<'_>
{
fn on_execution_progress(
&self,
event: &kb_pipeline_demo_scenarios::SolanaExecutionProgressEvent,
event: &ks_pipeline_demo_scenarios::SolanaExecutionProgressEvent,
) {
self.emit(
event.timestamp.clone(),

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_execution_metadata_metaplex_token_metadata.rs
// version: 6
// version: 7
//! Desktop adapters for generic and qualified Metaplex Token Metadata execution workflows.
@@ -186,7 +186,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -197,7 +197,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
return std::result::Result::Err(error.to_string());
}
let mut execution_request = match kb_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionRequest::from_operation_json(
let mut execution_request = match ks_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionRequest::from_operation_json(
request.intent_id,
request.operation_json.as_str(),
) {
@@ -222,21 +222,21 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
if let std::result::Result::Err(error) = execution_request.validate() {
return std::result::Result::Err(error.to_string());
}
let decoders: std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(kb_lib::DcMetadataMetaplexTokenMetadataDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(kb_lib::MtAdminMaterializer),
std::sync::Arc::new(kb_lib::MtComplianceAuditMaterializer),
std::sync::Arc::new(kb_lib::MtLifecycleMaterializer),
std::sync::Arc::new(kb_lib::MtMetadataMetaplexTokenMetadataMaterializer),
std::sync::Arc::new(kb_lib::MtRiskMaterializer),
let decoders: std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(ks_lib::DcMetadataMetaplexTokenMetadataDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(ks_lib::MtAdminMaterializer),
std::sync::Arc::new(ks_lib::MtComplianceAuditMaterializer),
std::sync::Arc::new(ks_lib::MtLifecycleMaterializer),
std::sync::Arc::new(ks_lib::MtMetadataMetaplexTokenMetadataMaterializer),
std::sync::Arc::new(ks_lib::MtRiskMaterializer),
];
let observer = crate::DemoExecutionMetadataObserver {
app_handle,
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let workspace_root = crate::workspace_root_dir();
let summary = match kb_pipeline_demo_scenarios::execute_devnet_metaplex_token_metadata(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_metaplex_token_metadata(
&http_pool,
&store,
&profile,
@@ -290,7 +290,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
);
}
fn backfill_summary_json(summary: &kb_pipeline::BackfillSummary) -> serde_json::Value {
fn backfill_summary_json(summary: &ks_pipeline::BackfillSummary) -> serde_json::Value {
return serde_json::json!({
"captureSessionId": summary.capture_session_id,
"filterCode": summary.filter_code,
@@ -318,7 +318,7 @@ fn backfill_summary_json(summary: &kb_pipeline::BackfillSummary) -> serde_json::
});
}
fn core_extraction_summary_json(summary: &kb_pipeline::CoreExtractionSummary) -> serde_json::Value {
fn core_extraction_summary_json(summary: &ks_pipeline::CoreExtractionSummary) -> serde_json::Value {
return serde_json::json!({
"processorVersion": summary.processor_version,
"selected": summary.selected,
@@ -335,7 +335,7 @@ fn core_extraction_summary_json(summary: &kb_pipeline::CoreExtractionSummary) ->
});
}
fn decode_replay_summary_json(summary: &kb_pipeline::DecodeReplaySummary) -> serde_json::Value {
fn decode_replay_summary_json(summary: &ks_pipeline::DecodeReplaySummary) -> serde_json::Value {
let processors = summary
.processors
.iter()
@@ -375,7 +375,7 @@ fn decode_replay_summary_json(summary: &kb_pipeline::DecodeReplaySummary) -> ser
fn parse_stateful_reads(
value: &str,
) -> std::result::Result<
std::vec::Vec<kb_pipeline::MetaplexTokenMetadataStatefulReadRequest>,
std::vec::Vec<ks_pipeline::MetaplexTokenMetadataStatefulReadRequest>,
std::string::String,
> {
if value.trim().is_empty() {
@@ -400,7 +400,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_crea
return prepare_create_fixture_for_family(
state,
profile_name,
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
)
.await;
}
@@ -408,7 +408,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_crea
async fn prepare_create_fixture_for_family(
state: tauri::State<'_, crate::AppState>,
profile_name: std::string::String,
asset_family: kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily,
asset_family: ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily,
) -> std::result::Result<
crate::DemoExecutionMetadataMetaplexTokenMetadataCreateFixturePayload,
std::string::String,
@@ -423,15 +423,15 @@ async fn prepare_create_fixture_for_family(
} else {
crate::workspace_root_dir().join(configured)
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let workspace_root = crate::workspace_root_dir();
let options =
kb_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions::new(wallet_dir)
ks_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions::new(wallet_dir)
.with_asset_family(asset_family);
let summary = match kb_pipeline_demo_scenarios::prepare_metaplex_create_fixture(
let summary = match ks_pipeline_demo_scenarios::prepare_metaplex_create_fixture(
&http_pool,
&profile,
workspace_root.as_path(),
@@ -465,7 +465,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_step
crate::DemoExecutionMetadataMetaplexTokenMetadataPreparedStepPayload,
std::string::String,
> {
let scenario = kb_pipeline_demo_scenarios::metaplex_token_metadata_devnet_scenarios()
let scenario = ks_pipeline_demo_scenarios::metaplex_token_metadata_devnet_scenarios()
.into_iter()
.find(|candidate| return candidate.id == scenario_id);
let scenario = match scenario {
@@ -566,7 +566,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_step
std::option::Option::None => std::string::String::new(),
};
let immutable_transition = scenario.asset_family
== kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft
== ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft
&& step_index == 2;
let value = serde_json::json!({
"operation": "update_as_update_authority_v2",
@@ -633,9 +633,9 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_step
};
let create_reads_edition = matches!(
scenario.asset_family,
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft
| kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Collection
| kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft
| ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Collection
| ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft
);
let postcondition_reads = if operation == "create" && create_reads_edition {
serde_json::json!([metadata_read, edition_read])
@@ -648,7 +648,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_step
step_index,
operation: operation.clone(),
label: if scenario.asset_family
== kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft
== ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft
&& step_index == 2
{
"Étape 3 — rendre les metadata immutables".to_string()
@@ -668,7 +668,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_step
/// Returns current operation names accepted by automatic Devnet campaigns.
pub(crate) fn demo_execution_metadata_metaplex_token_metadata_current_operations()
-> std::vec::Vec<std::string::String> {
return kb_pipeline_demo_scenarios::metaplex_token_metadata_current_operation_names()
return ks_pipeline_demo_scenarios::metaplex_token_metadata_current_operation_names()
.iter()
.map(|value| return (*value).to_string())
.collect();
@@ -678,7 +678,7 @@ pub(crate) fn demo_execution_metadata_metaplex_token_metadata_current_operations
pub(crate) fn demo_execution_metadata_metaplex_token_metadata_operation_template(
operation: std::string::String,
) -> std::result::Result<std::string::String, std::string::String> {
return match kb_pipeline_demo_scenarios::metaplex_token_metadata_current_operation_json_template(
return match ks_pipeline_demo_scenarios::metaplex_token_metadata_current_operation_json_template(
operation.as_str(),
) {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
@@ -691,7 +691,7 @@ pub(crate) fn demo_execution_metadata_metaplex_token_metadata_scenarios() -> std
std::vec::Vec<crate::DemoExecutionMetadataMetaplexTokenMetadataScenarioPayload>,
std::string::String,
> {
let matrix = match kb_pipeline_demo_scenarios::load_metaplex_token_metadata_validation_matrix()
let matrix = match ks_pipeline_demo_scenarios::load_metaplex_token_metadata_validation_matrix()
{
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
@@ -703,14 +703,14 @@ pub(crate) fn demo_execution_metadata_metaplex_token_metadata_scenarios() -> std
.collect::<std::collections::BTreeMap<
std::string::String,
(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus,
std::vec::Vec<std::string::String>,
),
>>();
let mut payloads = std::vec::Vec::new();
for scenario in kb_pipeline_demo_scenarios::metaplex_token_metadata_synthetic_scenarios()
for scenario in ks_pipeline_demo_scenarios::metaplex_token_metadata_synthetic_scenarios()
.into_iter()
.chain(kb_pipeline_demo_scenarios::metaplex_token_metadata_devnet_scenarios())
.chain(ks_pipeline_demo_scenarios::metaplex_token_metadata_devnet_scenarios())
{
let status = statuses.get(scenario.id.as_str());
let validation_status = match status {
@@ -742,74 +742,74 @@ pub(crate) fn demo_execution_metadata_metaplex_token_metadata_scenarios() -> std
}
fn asset_family_code(
value: kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily,
value: ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily,
) -> std::string::String {
return match value {
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft => "nft".to_string(),
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Sft => "sft".to_string(),
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Fungible => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft => "nft".to_string(),
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Sft => "sft".to_string(),
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Fungible => {
"fungible".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Collection => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Collection => {
"collection".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft => {
"programmable_nft".to_string()
},
};
}
fn fixture_kind_code(
value: kb_pipeline_demo_scenarios::MetaplexTokenMetadataFixtureKind,
value: ks_pipeline_demo_scenarios::MetaplexTokenMetadataFixtureKind,
) -> std::string::String {
return format!("{value:?}").to_lowercase();
}
fn fixture_state_code(
value: kb_pipeline_demo_scenarios::MetaplexTokenMetadataFixtureState,
value: ks_pipeline_demo_scenarios::MetaplexTokenMetadataFixtureState,
) -> std::string::String {
return format!("{value:?}").to_lowercase();
}
fn scenario_mode_code(
value: kb_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode,
value: ks_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode,
) -> std::string::String {
return match value {
kb_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode::Synthetic => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode::Synthetic => {
"synthetic".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode::NetworkSimulation => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode::NetworkSimulation => {
"network_simulation".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode::NetworkSubmission => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataScenarioMode::NetworkSubmission => {
"network_submission".to_string()
},
};
}
fn validation_status_code(
value: kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus,
value: ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus,
) -> std::string::String {
return match value {
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::NotRun => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::NotRun => {
"not_run".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::SyntheticValidated => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::SyntheticValidated => {
"synthetic_validated".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Simulated => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Simulated => {
"simulated".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Submitted => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Submitted => {
"submitted".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Confirmed => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Confirmed => {
"confirmed".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Unavailable => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Unavailable => {
"unavailable".to_string()
},
kb_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Failed => {
ks_pipeline_demo_scenarios::MetaplexTokenMetadataValidationStatus::Failed => {
"failed".to_string()
},
};
@@ -895,7 +895,7 @@ struct CampaignProjection {
type CampaignProjectionFuture<'a> = std::pin::Pin<
std::boxed::Box<
dyn std::future::Future<Output = kb_core::Result<CampaignProjection>>
dyn std::future::Future<Output = ks_core::Result<CampaignProjection>>
+ std::marker::Send
+ 'a,
>,
@@ -917,7 +917,7 @@ pub(crate) fn demo_execution_metadata_metaplex_campaigns()
label: label.to_string(),
asset_family: family.to_string(),
operation_names:
kb_pipeline_demo_scenarios::metaplex_create_mint_campaign_operation_names()
ks_pipeline_demo_scenarios::metaplex_create_mint_campaign_operation_names()
.iter()
.map(|value| return (*value).to_string())
.collect(),
@@ -930,7 +930,7 @@ pub(crate) fn demo_execution_metadata_metaplex_campaigns()
"collection_verify",
"Collection — Verify → Unverify",
"collection",
kb_pipeline_demo_scenarios::metaplex_collection_verify_campaign_operation_names(),
ks_pipeline_demo_scenarios::metaplex_collection_verify_campaign_operation_names(),
"confirmed",
"fresh collection parent + fresh unverified member",
),
@@ -938,7 +938,7 @@ pub(crate) fn demo_execution_metadata_metaplex_campaigns()
"print_burn",
"NFT imprimable — Print → Burn",
"nft",
kb_pipeline_demo_scenarios::metaplex_print_burn_campaign_operation_names(),
ks_pipeline_demo_scenarios::metaplex_print_burn_campaign_operation_names(),
"confirmed",
"fresh limited-supply master NFT + fresh printed edition",
),
@@ -946,7 +946,7 @@ pub(crate) fn demo_execution_metadata_metaplex_campaigns()
"pnft_lifecycle",
"pNFT — Delegate → Lock → Unlock → Revoke → Delegate → Transfer",
"programmable_nft",
kb_pipeline_demo_scenarios::metaplex_pnft_lifecycle_campaign_operation_names(),
ks_pipeline_demo_scenarios::metaplex_pnft_lifecycle_campaign_operation_names(),
"confirmed",
"fresh pNFT + delegate wallet + destination owner",
),
@@ -954,7 +954,7 @@ pub(crate) fn demo_execution_metadata_metaplex_campaigns()
"escrow",
"Token Owned Escrow — Create → TransferOut → Close",
"nft",
kb_pipeline_demo_scenarios::metaplex_escrow_campaign_operation_names(),
ks_pipeline_demo_scenarios::metaplex_escrow_campaign_operation_names(),
"confirmed",
"fresh NFT parent + fresh fungible attribute + escrow ATA deposit",
),
@@ -962,7 +962,7 @@ pub(crate) fn demo_execution_metadata_metaplex_campaigns()
"maintenance",
"Maintenance — Update + probes réservés/legacy",
"nft",
kb_pipeline_demo_scenarios::metaplex_maintenance_campaign_operation_names(),
ks_pipeline_demo_scenarios::metaplex_maintenance_campaign_operation_names(),
"mixed_confirmed_unavailable",
"fresh NFT; Update submitted; Resize/Migrate/Collect/CloseAccounts simulation-only probes",
),
@@ -970,7 +970,7 @@ pub(crate) fn demo_execution_metadata_metaplex_campaigns()
"use_probe",
"Use — probe runtime",
"nft",
kb_pipeline_demo_scenarios::metaplex_use_probe_operation_names(),
ks_pipeline_demo_scenarios::metaplex_use_probe_operation_names(),
"runtime_unavailable_probe",
"fresh NFT with two bounded Multiple uses; Use is simulation-only when rejected",
),
@@ -1036,7 +1036,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_execute_campaign(
.to_string(),
);
}
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -1131,19 +1131,19 @@ pub(crate) async fn demo_execution_metadata_metaplex_execute_campaign(
fn execute_campaign_projection<'a, S, O>(
campaign_id: &'a str,
wallet_dir: std::path::PathBuf,
http_pool: &'a kb_onchain_transport::HttpEndpointPool,
http_pool: &'a ks_onchain_transport::HttpEndpointPool,
store: &'a S,
profile: &'a kb_config::ProfileConfig,
profile: &'a ks_config::ProfileConfig,
workspace_root: &'a std::path::Path,
observer: &'a O,
) -> CampaignProjectionFuture<'a>
where
S: kb_store::RawTransactionStore
+ kb_store::CoreExtractionStore
+ kb_store::DecodePipelineStore
S: ks_store::RawTransactionStore
+ ks_store::CoreExtractionStore
+ ks_store::DecodePipelineStore
+ Sync
+ 'a,
O: kb_pipeline_demo_scenarios::SolanaExecutionObserver + 'a,
O: ks_pipeline_demo_scenarios::SolanaExecutionObserver + 'a,
{
return std::boxed::Box::pin(execute_campaign_projection_unboxed(
campaign_id,
@@ -1159,27 +1159,27 @@ where
async fn execute_campaign_projection_unboxed<S, O>(
campaign_id: &str,
wallet_dir: std::path::PathBuf,
http_pool: &kb_onchain_transport::HttpEndpointPool,
http_pool: &ks_onchain_transport::HttpEndpointPool,
store: &S,
profile: &kb_config::ProfileConfig,
profile: &ks_config::ProfileConfig,
workspace_root: &std::path::Path,
observer: &O,
) -> kb_core::Result<CampaignProjection>
) -> ks_core::Result<CampaignProjection>
where
S: kb_store::RawTransactionStore
+ kb_store::CoreExtractionStore
+ kb_store::DecodePipelineStore
S: ks_store::RawTransactionStore
+ ks_store::CoreExtractionStore
+ ks_store::DecodePipelineStore
+ Sync,
O: kb_pipeline_demo_scenarios::SolanaExecutionObserver,
O: ks_pipeline_demo_scenarios::SolanaExecutionObserver,
{
let base_options =
kb_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions::new(wallet_dir);
ks_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions::new(wallet_dir);
return match campaign_id {
"create_mint_nft" => {
execute_create_mint_projection(
"Create → Mint — NFT",
base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
),
http_pool,
store,
@@ -1193,7 +1193,7 @@ where
execute_create_mint_projection(
"Create → Mint — SFT",
base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Sft,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Sft,
),
http_pool,
store,
@@ -1207,7 +1207,7 @@ where
execute_create_mint_projection(
"Create → Mint — Fungible",
base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Fungible,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Fungible,
),
http_pool,
store,
@@ -1221,7 +1221,7 @@ where
execute_create_mint_projection(
"Create → Mint — Collection",
base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Collection,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Collection,
),
http_pool,
store,
@@ -1235,7 +1235,7 @@ where
execute_create_mint_projection(
"Create → Mint — pNFT",
base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft,
),
http_pool,
store,
@@ -1246,7 +1246,7 @@ where
.await
},
"collection_verify" => {
let summary = match kb_pipeline_demo_scenarios::execute_devnet_metaplex_collection_verify_campaign(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_metaplex_collection_verify_campaign(
http_pool,
store,
profile,
@@ -1285,7 +1285,7 @@ where
},
"print_burn" => {
let summary =
match kb_pipeline_demo_scenarios::execute_devnet_metaplex_print_burn_campaign(
match ks_pipeline_demo_scenarios::execute_devnet_metaplex_print_burn_campaign(
http_pool,
store,
profile,
@@ -1324,10 +1324,10 @@ where
},
"pnft_lifecycle" => {
let options = base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft,
);
let summary =
match kb_pipeline_demo_scenarios::execute_devnet_metaplex_pnft_lifecycle_campaign(
match ks_pipeline_demo_scenarios::execute_devnet_metaplex_pnft_lifecycle_campaign(
http_pool,
store,
profile,
@@ -1361,7 +1361,7 @@ where
})
},
"escrow" => {
let summary = match kb_pipeline_demo_scenarios::execute_devnet_metaplex_escrow_campaign(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_metaplex_escrow_campaign(
http_pool,
store,
profile,
@@ -1407,10 +1407,10 @@ where
},
"maintenance" => {
let options = base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
);
let summary =
match kb_pipeline_demo_scenarios::execute_devnet_metaplex_maintenance_campaign(
match ks_pipeline_demo_scenarios::execute_devnet_metaplex_maintenance_campaign(
http_pool,
store,
profile,
@@ -1463,9 +1463,9 @@ where
},
"use_probe" => {
let options = base_options.clone().with_asset_family(
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
ks_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
);
let summary = match kb_pipeline_demo_scenarios::execute_devnet_metaplex_use_probe(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_metaplex_use_probe(
http_pool,
store,
profile,
@@ -1501,7 +1501,7 @@ where
}),
})
},
_ => std::result::Result::Err(kb_core::Error::config(format!(
_ => std::result::Result::Err(ks_core::Error::config(format!(
"unknown qualified Metaplex desktop campaign `{campaign_id}`"
))),
};
@@ -1509,21 +1509,21 @@ where
async fn execute_create_mint_projection<S, O>(
label: &str,
options: kb_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions,
http_pool: &kb_onchain_transport::HttpEndpointPool,
options: ks_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions,
http_pool: &ks_onchain_transport::HttpEndpointPool,
store: &S,
profile: &kb_config::ProfileConfig,
profile: &ks_config::ProfileConfig,
workspace_root: &std::path::Path,
observer: &O,
) -> kb_core::Result<CampaignProjection>
) -> ks_core::Result<CampaignProjection>
where
S: kb_store::RawTransactionStore
+ kb_store::CoreExtractionStore
+ kb_store::DecodePipelineStore
S: ks_store::RawTransactionStore
+ ks_store::CoreExtractionStore
+ ks_store::DecodePipelineStore
+ Sync,
O: kb_pipeline_demo_scenarios::SolanaExecutionObserver,
O: ks_pipeline_demo_scenarios::SolanaExecutionObserver,
{
let summary = match kb_pipeline_demo_scenarios::execute_devnet_metaplex_create_mint_campaign(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_metaplex_create_mint_campaign(
http_pool,
store,
profile,
@@ -1554,7 +1554,7 @@ where
fn metaplex_execution_json(
label: &str,
summary: &kb_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionSummary,
summary: &ks_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionSummary,
) -> serde_json::Value {
let classification = if execution_confirmation_is_confirmed(&summary.confirmation) {
"confirmed"
@@ -1594,13 +1594,13 @@ fn metaplex_execution_json(
}
fn execution_confirmation_is_confirmed(
confirmation: &std::option::Option<kb_lib::ExApiExecutionConfirmationResult>,
confirmation: &std::option::Option<ks_lib::ExApiExecutionConfirmationResult>,
) -> bool {
return confirmation.as_ref().is_some_and(|value| {
return matches!(
value.status,
kb_lib::ExApiExecutionConfirmationStatus::Confirmed
| kb_lib::ExApiExecutionConfirmationStatus::Finalized
ks_lib::ExApiExecutionConfirmationStatus::Confirmed
| ks_lib::ExApiExecutionConfirmationStatus::Finalized
);
});
}
@@ -1611,7 +1611,7 @@ fn execution_is_confirmed_json(value: &serde_json::Value) -> bool {
}
fn create_mint_state_json(
state: &kb_pipeline_demo_scenarios::DevnetMetaplexCreateMintTokenState,
state: &ks_pipeline_demo_scenarios::DevnetMetaplexCreateMintTokenState,
) -> serde_json::Value {
return serde_json::json!({
"expectedAmountRaw": state.expected_amount_raw,
@@ -1625,7 +1625,7 @@ fn create_mint_state_json(
}
fn print_burn_state_json(
state: &kb_pipeline_demo_scenarios::DevnetMetaplexPrintBurnState,
state: &ks_pipeline_demo_scenarios::DevnetMetaplexPrintBurnState,
) -> serde_json::Value {
return serde_json::json!({
"editionNumber": state.edition_number,
@@ -1648,7 +1648,7 @@ fn print_burn_state_json(
}
fn pnft_state_json(
state: &kb_pipeline_demo_scenarios::DevnetMetaplexPnftLifecycleState,
state: &ks_pipeline_demo_scenarios::DevnetMetaplexPnftLifecycleState,
) -> serde_json::Value {
return serde_json::json!({
"delegate": &state.delegate,
@@ -1671,7 +1671,7 @@ fn pnft_state_json(
}
fn escrow_state_json(
state: &kb_pipeline_demo_scenarios::DevnetMetaplexEscrowCampaignState,
state: &ks_pipeline_demo_scenarios::DevnetMetaplexEscrowCampaignState,
) -> serde_json::Value {
return serde_json::json!({
"depositAmountRaw": state.deposit_amount_raw,
@@ -1697,8 +1697,8 @@ mod tests {
},
};
let expected_count =
kb_pipeline_demo_scenarios::metaplex_token_metadata_synthetic_scenarios().len()
+ kb_pipeline_demo_scenarios::metaplex_token_metadata_devnet_scenarios().len();
ks_pipeline_demo_scenarios::metaplex_token_metadata_synthetic_scenarios().len()
+ ks_pipeline_demo_scenarios::metaplex_token_metadata_devnet_scenarios().len();
assert_eq!(payloads.len(), expected_count);
assert!(payloads.iter().all(|payload| return !payload.operation_codes.is_empty()));
assert!(payloads.iter().all(|payload| return payload.requires_postcondition));

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_execution_metadata_solana_program.rs
// version: 2
// version: 3
//! Thin desktop adapter for complete Solana Program Metadata Devnet campaigns.
@@ -98,7 +98,7 @@ pub(crate) struct DemoExecutionMetadataSolanaProgramCampaignSummaryPayload {
/// Returns the two canonical Solana Program Metadata Devnet journeys.
pub(crate) fn demo_execution_metadata_solana_program_scenarios()
-> std::vec::Vec<crate::DemoExecutionMetadataSolanaProgramScenarioPayload> {
return kb_pipeline_demo_scenarios::solana_program_metadata_devnet_scenarios()
return ks_pipeline_demo_scenarios::solana_program_metadata_devnet_scenarios()
.into_iter()
.map(|scenario| {
return crate::DemoExecutionMetadataSolanaProgramScenarioPayload {
@@ -159,19 +159,19 @@ pub(crate) async fn demo_execution_metadata_solana_program_execute_campaign(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let mut options =
kb_pipeline_demo_scenarios::SolanaProgramMetadataFixturePreparationOptions::new();
ks_pipeline_demo_scenarios::SolanaProgramMetadataFixturePreparationOptions::new();
options.operator_confirmed = true;
let observer = crate::DemoExecutionMetadataObserver {
app_handle,
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let workspace_root = crate::workspace_root_dir();
let summary = match kb_pipeline_demo_scenarios::execute_devnet_solana_program_metadata_campaign(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_solana_program_metadata_campaign(
&http_pool,
&profile,
workspace_root.as_path(),
@@ -187,7 +187,7 @@ pub(crate) async fn demo_execution_metadata_solana_program_execute_campaign(
}
fn campaign_summary_payload(
summary: kb_pipeline_demo_scenarios::DevnetSolanaProgramMetadataCampaignSummary,
summary: ks_pipeline_demo_scenarios::DevnetSolanaProgramMetadataCampaignSummary,
) -> crate::DemoExecutionMetadataSolanaProgramCampaignSummaryPayload {
let mut confirmed_step_count = 0_usize;
let mut materialized_snapshot_count = 0_usize;
@@ -201,8 +201,8 @@ fn campaign_summary_payload(
let confirmed = match step.execution.confirmation.as_ref() {
std::option::Option::Some(value) => matches!(
value.status,
kb_lib::ExApiExecutionConfirmationStatus::Confirmed
| kb_lib::ExApiExecutionConfirmationStatus::Finalized
ks_lib::ExApiExecutionConfirmationStatus::Confirmed
| ks_lib::ExApiExecutionConfirmationStatus::Finalized
),
std::option::Option::None => false,
};
@@ -235,7 +235,7 @@ fn campaign_summary_payload(
"materializedSnapshots": &step.execution.materialized_snapshots
}));
}
let expected_step_count = kb_lib::EX_METADATA_SPM_SUPPORTED_OPERATION_CODES.len();
let expected_step_count = ks_lib::EX_METADATA_SPM_SUPPORTED_OPERATION_CODES.len();
let completed = summary.steps.len() == expected_step_count
&& confirmed_step_count == expected_step_count
&& summary.steps.iter().all(|step| {
@@ -246,7 +246,7 @@ fn campaign_summary_payload(
.find(|prepared| return prepared.step_id == step.step_id)
{
std::option::Option::Some(prepared) => {
prepared.operation.operation_code() == kb_lib::EX_METADATA_SPM_CLOSE_OPERATION
prepared.operation.operation_code() == ks_lib::EX_METADATA_SPM_CLOSE_OPERATION
},
std::option::Option::None => false,
};
@@ -285,22 +285,22 @@ fn campaign_summary_payload(
}
fn fixture_state_code(
value: kb_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState,
value: ks_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState,
) -> std::string::String {
return match value {
kb_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::Prefunded => {
ks_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::Prefunded => {
"prefunded".to_string()
},
kb_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::Buffer => {
ks_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::Buffer => {
"buffer".to_string()
},
kb_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::MutableMetadata => {
ks_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::MutableMetadata => {
"mutable_metadata".to_string()
},
kb_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::ImmutableMetadata => {
ks_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::ImmutableMetadata => {
"immutable_metadata".to_string()
},
kb_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::Closed => {
ks_pipeline_demo_scenarios::SolanaProgramMetadataFixtureState::Closed => {
"closed".to_string()
},
};
@@ -314,11 +314,11 @@ mod tests {
assert_eq!(payloads.len(), 2);
assert_eq!(
payloads.iter().map(|scenario| return scenario.steps.len()).sum::<usize>(),
kb_lib::EX_METADATA_SPM_SUPPORTED_OPERATION_CODES.len()
ks_lib::EX_METADATA_SPM_SUPPORTED_OPERATION_CODES.len()
);
assert!(payloads.iter().flat_map(|scenario| return scenario.steps.iter()).all(|step| {
return !step.required_evidence.is_empty()
&& kb_lib::EX_METADATA_SPM_SUPPORTED_OPERATION_CODES
&& ks_lib::EX_METADATA_SPM_SUPPORTED_OPERATION_CODES
.contains(&step.operation_code.as_str());
}));
}

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_execution_metadata_token_2022.rs
// version: 1
// version: 2
//! Thin desktop adapter for the complete Token-2022 Token Metadata Devnet campaign.
@@ -84,7 +84,7 @@ pub(crate) async fn demo_execution_metadata_token_2022_execute_campaign(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -103,13 +103,13 @@ pub(crate) async fn demo_execution_metadata_token_2022_execute_campaign(
workspace_root.join(configured_wallet_dir)
};
let mut options =
kb_pipeline_demo_scenarios::Token2022MetadataFixturePreparationOptions::new(wallet_dir);
ks_pipeline_demo_scenarios::Token2022MetadataFixturePreparationOptions::new(wallet_dir);
options.operator_confirmed = true;
let observer = crate::DemoExecutionMetadataObserver {
app_handle,
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let summary = match kb_pipeline_demo_scenarios::execute_devnet_token_2022_metadata_campaign(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_token_2022_metadata_campaign(
&http_pool,
&store,
&profile,
@@ -127,7 +127,7 @@ pub(crate) async fn demo_execution_metadata_token_2022_execute_campaign(
fn campaign_summary_payload(
profile_name: std::string::String,
summary: kb_pipeline_demo_scenarios::DevnetToken2022MetadataCampaignSummary,
summary: ks_pipeline_demo_scenarios::DevnetToken2022MetadataCampaignSummary,
) -> crate::DemoExecutionMetadataToken2022CampaignSummaryPayload {
let mut confirmed_step_count = 0_usize;
let mut materialization_count = 0_usize;
@@ -136,8 +136,8 @@ fn campaign_summary_payload(
let confirmed = match step.execution.confirmation.as_ref() {
std::option::Option::Some(value) => matches!(
value.status,
kb_lib::ExApiExecutionConfirmationStatus::Confirmed
| kb_lib::ExApiExecutionConfirmationStatus::Finalized
ks_lib::ExApiExecutionConfirmationStatus::Confirmed
| ks_lib::ExApiExecutionConfirmationStatus::Finalized
),
std::option::Option::None => false,
};
@@ -161,12 +161,12 @@ fn campaign_summary_payload(
}));
}
let expected_step_count =
kb_pipeline_demo_scenarios::token_2022_metadata_campaign_operation_names().len();
ks_pipeline_demo_scenarios::token_2022_metadata_campaign_operation_names().len();
let completed = summary.steps.len() == expected_step_count
&& confirmed_step_count == expected_step_count
&& summary.steps.iter().all(|step| {
return step.postcondition.status
== kb_pipeline::Token2022ExecutionPostconditionStatus::Confirmed;
== ks_pipeline::Token2022ExecutionPostconditionStatus::Confirmed;
});
let fixture_json = crate::pretty_json(&serde_json::json!({
"mint": &summary.fixture.mint,
@@ -198,7 +198,7 @@ mod tests {
#[test]
fn desktop_campaign_exposes_the_exact_five_token_metadata_operations() {
assert_eq!(
kb_pipeline_demo_scenarios::token_2022_metadata_campaign_operation_names(),
ks_pipeline_demo_scenarios::token_2022_metadata_campaign_operation_names(),
&[
"initialize_token_metadata",
"update_token_metadata_field",

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_execution_solana_core.rs
// version: 13
// version: 14
//! Tauri adapter for bounded Solana Core execution on Devnet.
@@ -290,8 +290,8 @@ impl crate::DemoExecutionSolanaCoreObserver<'_> {
}
}
impl kb_pipeline::BackfillObserver for crate::DemoExecutionSolanaCoreObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::BackfillProgressEvent) {
impl ks_pipeline::BackfillObserver for crate::DemoExecutionSolanaCoreObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::BackfillProgressEvent) {
self.emit(
event.timestamp.clone(),
event.level.code(),
@@ -306,8 +306,8 @@ impl kb_pipeline::BackfillObserver for crate::DemoExecutionSolanaCoreObserver<'_
}
}
impl kb_pipeline::CoreExtractionObserver for crate::DemoExecutionSolanaCoreObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::CoreExtractionProgressEvent) {
impl ks_pipeline::CoreExtractionObserver for crate::DemoExecutionSolanaCoreObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::CoreExtractionProgressEvent) {
self.emit(
event.timestamp.clone(),
event.level.code(),
@@ -322,8 +322,8 @@ impl kb_pipeline::CoreExtractionObserver for crate::DemoExecutionSolanaCoreObser
}
}
impl kb_pipeline::DecodeReplayObserver for crate::DemoExecutionSolanaCoreObserver<'_> {
fn on_progress(&self, event: &kb_pipeline::DecodeReplayProgressEvent) {
impl ks_pipeline::DecodeReplayObserver for crate::DemoExecutionSolanaCoreObserver<'_> {
fn on_progress(&self, event: &ks_pipeline::DecodeReplayProgressEvent) {
self.emit(
event.timestamp.clone(),
event.level.code(),
@@ -338,12 +338,12 @@ impl kb_pipeline::DecodeReplayObserver for crate::DemoExecutionSolanaCoreObserve
}
}
impl kb_pipeline_demo_scenarios::SolanaExecutionObserver
impl ks_pipeline_demo_scenarios::SolanaExecutionObserver
for crate::DemoExecutionSolanaCoreObserver<'_>
{
fn on_execution_progress(
&self,
event: &kb_pipeline_demo_scenarios::SolanaExecutionProgressEvent,
event: &ks_pipeline_demo_scenarios::SolanaExecutionProgressEvent,
) {
self.emit(
event.timestamp.clone(),
@@ -360,10 +360,10 @@ impl kb_pipeline_demo_scenarios::SolanaExecutionObserver
}
pub(crate) fn select_devnet_profile(
config: &kb_config::AppConfig,
config: &ks_config::AppConfig,
profile_name: &str,
) -> std::result::Result<kb_config::ProfileConfig, std::string::String> {
return kb_pipeline_demo_scenarios::resolve_demo_devnet_profile(
) -> std::result::Result<ks_config::ProfileConfig, std::string::String> {
return ks_pipeline_demo_scenarios::resolve_demo_devnet_profile(
config,
std::option::Option::Some(profile_name),
)
@@ -371,26 +371,26 @@ pub(crate) fn select_devnet_profile(
}
pub(crate) fn execution_cluster_code(
cluster: kb_lib::ExApiExecutionCluster,
cluster: ks_lib::ExApiExecutionCluster,
) -> std::string::String {
return match cluster {
kb_lib::ExApiExecutionCluster::Localnet => "localnet".to_string(),
kb_lib::ExApiExecutionCluster::Devnet => "devnet".to_string(),
kb_lib::ExApiExecutionCluster::Testnet => "testnet".to_string(),
kb_lib::ExApiExecutionCluster::Mainnet => "mainnet".to_string(),
ks_lib::ExApiExecutionCluster::Localnet => "localnet".to_string(),
ks_lib::ExApiExecutionCluster::Devnet => "devnet".to_string(),
ks_lib::ExApiExecutionCluster::Testnet => "testnet".to_string(),
ks_lib::ExApiExecutionCluster::Mainnet => "mainnet".to_string(),
};
}
pub(crate) fn confirmation_status_code(
status: kb_lib::ExApiExecutionConfirmationStatus,
status: ks_lib::ExApiExecutionConfirmationStatus,
) -> std::string::String {
return match status {
kb_lib::ExApiExecutionConfirmationStatus::Processed => "processed".to_string(),
kb_lib::ExApiExecutionConfirmationStatus::Confirmed => "confirmed".to_string(),
kb_lib::ExApiExecutionConfirmationStatus::Finalized => "finalized".to_string(),
kb_lib::ExApiExecutionConfirmationStatus::Failed => "failed".to_string(),
kb_lib::ExApiExecutionConfirmationStatus::Expired => "expired".to_string(),
kb_lib::ExApiExecutionConfirmationStatus::TimedOut => "timed_out".to_string(),
ks_lib::ExApiExecutionConfirmationStatus::Processed => "processed".to_string(),
ks_lib::ExApiExecutionConfirmationStatus::Confirmed => "confirmed".to_string(),
ks_lib::ExApiExecutionConfirmationStatus::Finalized => "finalized".to_string(),
ks_lib::ExApiExecutionConfirmationStatus::Failed => "failed".to_string(),
ks_lib::ExApiExecutionConfirmationStatus::Expired => "expired".to_string(),
ks_lib::ExApiExecutionConfirmationStatus::TimedOut => "timed_out".to_string(),
};
}
@@ -404,7 +404,7 @@ pub(crate) async fn demo_execution_devnet_prepare_profile(
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let readiness =
match kb_pipeline_demo_scenarios::prepare_demo_devnet_profile_store(&profile).await {
match ks_pipeline_demo_scenarios::prepare_demo_devnet_profile_store(&profile).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(error.to_string());
@@ -433,11 +433,11 @@ pub(crate) fn demo_execution_solana_core_options(
pub(crate) fn demo_execution_solana_core_generate_recipient()
-> std::result::Result<crate::DemoExecutionSolanaCoreGeneratedRecipientPayload, std::string::String>
{
let alias = match kb_wallet::WalletAlias::parse("demo-devnet-recipient") {
let alias = match ks_wallet::WalletAlias::parse("demo-devnet-recipient") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let wallet = kb_wallet::TemporaryWallet::generate(alias);
let wallet = ks_wallet::TemporaryWallet::generate(alias);
return std::result::Result::Ok(crate::DemoExecutionSolanaCoreGeneratedRecipientPayload {
public_key: wallet.public_key(),
});
@@ -469,7 +469,7 @@ pub(crate) async fn demo_execution_solana_core_execute(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -481,9 +481,9 @@ pub(crate) async fn demo_execution_solana_core_execute(
if let std::result::Result::Err(error) = initialize_result {
return std::result::Result::Err(error.to_string());
}
let mut pipeline_request = kb_pipeline_demo_scenarios::DevnetSystemTransferRequest::new(
let mut pipeline_request = ks_pipeline_demo_scenarios::DevnetSystemTransferRequest::new(
format!("demo-execution-{}", chrono::Utc::now().timestamp_micros()),
kb_lib::MdPubkey(request.recipient.trim().to_string()),
ks_lib::MdPubkey(request.recipient.trim().to_string()),
request.lamports,
);
pipeline_request.airdrop_lamports = request.airdrop_lamports;
@@ -492,15 +492,15 @@ pub(crate) async fn demo_execution_solana_core_execute(
pipeline_request.post_validation_max_retries = 20;
pipeline_request.force_post_validation_replay = request.force_post_validation_replay;
pipeline_request.materialize_after_decode = request.materialize_after_decode;
let decoders: std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(kb_lib::DcSolanaCoreDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> =
let decoders: std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(ks_lib::DcSolanaCoreDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> =
if request.materialize_after_decode {
std::vec![
std::sync::Arc::new(kb_lib::MtAdminMaterializer),
std::sync::Arc::new(kb_lib::MtComplianceAuditMaterializer,),
std::sync::Arc::new(kb_lib::MtLifecycleMaterializer),
std::sync::Arc::new(kb_lib::MtStakingMaterializer),
std::sync::Arc::new(ks_lib::MtAdminMaterializer),
std::sync::Arc::new(ks_lib::MtComplianceAuditMaterializer,),
std::sync::Arc::new(ks_lib::MtLifecycleMaterializer),
std::sync::Arc::new(ks_lib::MtStakingMaterializer),
]
} else {
std::vec::Vec::new()
@@ -510,7 +510,7 @@ pub(crate) async fn demo_execution_solana_core_execute(
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let workspace_root = crate::workspace_root_dir();
let summary = match kb_pipeline_demo_scenarios::execute_devnet_system_transfer(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_system_transfer(
&http_pool,
&store,
&profile,
@@ -554,7 +554,7 @@ pub(crate) async fn demo_execution_spl_memo_execute(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -565,7 +565,7 @@ pub(crate) async fn demo_execution_spl_memo_execute(
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
return std::result::Result::Err(error.to_string());
}
let mut pipeline_request = kb_pipeline_demo_scenarios::DevnetMemoExecutionRequest::new(
let mut pipeline_request = ks_pipeline_demo_scenarios::DevnetMemoExecutionRequest::new(
format!("demo-memo-execution-{}", chrono::Utc::now().timestamp_micros()),
request.message,
);
@@ -574,16 +574,16 @@ pub(crate) async fn demo_execution_spl_memo_execute(
pipeline_request.operator_confirmed = request.operator_confirmed;
pipeline_request.post_validation_max_retries = 20;
pipeline_request.force_post_validation_replay = request.force_post_validation_replay;
let decoders: std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(kb_lib::DcSplMemoDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> =
std::vec![std::sync::Arc::new(kb_lib::MtTransactionAnnotationMaterializer,)];
let decoders: std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(ks_lib::DcSplMemoDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> =
std::vec![std::sync::Arc::new(ks_lib::MtTransactionAnnotationMaterializer,)];
let observer = crate::DemoExecutionSolanaCoreObserver {
app_handle,
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let workspace_root = crate::workspace_root_dir();
let summary = match kb_pipeline_demo_scenarios::execute_devnet_memo(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_memo(
&http_pool,
&store,
&profile,
@@ -616,7 +616,7 @@ pub(crate) fn demo_execution_solana_core_cancel(state: tauri::State<'_, crate::A
}
fn devnet_profile_options(
config: &kb_config::AppConfig,
config: &ks_config::AppConfig,
) -> std::vec::Vec<crate::DemoExecutionSolanaCoreProfileOption> {
let mut output = std::vec::Vec::new();
for profile in &config.profiles {
@@ -639,7 +639,7 @@ fn devnet_profile_options(
}
fn summary_payload(
summary: kb_pipeline_demo_scenarios::DevnetSystemTransferSummary,
summary: ks_pipeline_demo_scenarios::DevnetSystemTransferSummary,
) -> crate::DemoExecutionSolanaCoreSummaryPayload {
let plan_json = crate::pretty_json(&summary.plan);
let simulation_json = crate::pretty_json(&summary.simulation);
@@ -720,7 +720,7 @@ fn summary_payload(
}
fn memo_summary_payload(
summary: kb_pipeline_demo_scenarios::DevnetMemoExecutionSummary,
summary: ks_pipeline_demo_scenarios::DevnetMemoExecutionSummary,
) -> crate::DemoExecutionMemoSummaryPayload {
let plan_json = crate::pretty_json(&summary.plan);
let simulation_json = crate::pretty_json(&summary.simulation);
@@ -851,7 +851,7 @@ mod tests {
#[test]
fn example_config_exposes_one_devnet_execution_profile() {
let config =
match kb_config::parse_config_json(include_str!("../../config/example.config.json")) {
match ks_config::parse_config_json(include_str!("../../config/example.config.json")) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("example config parse failed: {error}"),
};
@@ -865,7 +865,7 @@ mod tests {
#[test]
fn profile_selection_rejects_mainnet_profiles() {
let config =
match kb_config::parse_config_json(include_str!("../../config/example.config.json")) {
match ks_config::parse_config_json(include_str!("../../config/example.config.json")) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("example config parse failed: {error}"),
};

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_execution_spl.rs
// version: 5
// version: 6
//! Dedicated Tauri window for bounded SPL execution on Devnet.
@@ -30,32 +30,32 @@ pub(crate) struct DevnetSplValidationScenarioPayload {
/// Returns the complete ordered Devnet SPL validation inventory for milestone 0.4.6.
pub(crate) fn demo_execution_spl_validation_scenarios()
-> std::vec::Vec<crate::DevnetSplValidationScenarioPayload> {
return kb_pipeline_demo_scenarios::devnet_spl_validation_scenarios()
return ks_pipeline_demo_scenarios::devnet_spl_validation_scenarios()
.into_iter()
.map(|scenario| {
return crate::DevnetSplValidationScenarioPayload {
id: scenario.id,
label: scenario.label,
family: match scenario.family {
kb_pipeline_demo_scenarios::DevnetSplValidationFamily::Token2022Public => {
ks_pipeline_demo_scenarios::DevnetSplValidationFamily::Token2022Public => {
"token_2022_public".to_string()
},
kb_pipeline_demo_scenarios::DevnetSplValidationFamily::ElGamalRegistry => {
ks_pipeline_demo_scenarios::DevnetSplValidationFamily::ElGamalRegistry => {
"elgamal_registry".to_string()
},
kb_pipeline_demo_scenarios::DevnetSplValidationFamily::Token2022Confidential => {
ks_pipeline_demo_scenarios::DevnetSplValidationFamily::Token2022Confidential => {
"token_2022_confidential".to_string()
},
},
operation_code: scenario.operation_code,
implementation_status: match scenario.implementation_status {
kb_pipeline_demo_scenarios::DevnetSplValidationImplementationStatus::Executable => {
ks_pipeline_demo_scenarios::DevnetSplValidationImplementationStatus::Executable => {
"executable".to_string()
},
kb_pipeline_demo_scenarios::DevnetSplValidationImplementationStatus::BackendReady => {
ks_pipeline_demo_scenarios::DevnetSplValidationImplementationStatus::BackendReady => {
"backend_ready".to_string()
},
kb_pipeline_demo_scenarios::DevnetSplValidationImplementationStatus::ProofFixtureRequired => {
ks_pipeline_demo_scenarios::DevnetSplValidationImplementationStatus::ProofFixtureRequired => {
"proof_fixture_required".to_string()
},
},
@@ -75,7 +75,7 @@ mod tests {
profile_name: "local_devnet".to_string(),
cluster: "devnet".to_string(),
genesis_hash: "EtWTRABZaYq6iMfeYKouRu166VU2xqa1".to_string(),
wallet_public_key: kb_program_ids::SYSTEM_PROGRAM_ID.to_string(),
wallet_public_key: ks_program_ids::SYSTEM_PROGRAM_ID.to_string(),
balance_lamports: u64::MAX.to_string(),
fee_lamports: std::option::Option::Some(u64::MAX.to_string()),
simulation_success: true,

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_http.rs
// version: 13
// version: 14
//! HTTP JSON-RPC demo commands.
@@ -142,13 +142,13 @@ pub(crate) async fn demo_http_execute_request(
std::result::Result::Ok(text) => text,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let method_class = kb_onchain_transport::HttpClient::classify_method(&method);
let method_class = ks_onchain_transport::HttpClient::classify_method(&method);
return std::result::Result::Ok(crate::DemoHttpExecutionPayload {
endpoint_name: selected_client.endpoint_name().to_string(),
provider: selected_client.provider().to_string(),
endpoint_url: selected_client.endpoint_url().to_string(),
role,
request_kind: kb_onchain_transport::request_kind_from_method(&method),
request_kind: ks_onchain_transport::request_kind_from_method(&method),
method,
method_class: method_class_to_string(method_class).to_string(),
response_json,
@@ -157,7 +157,7 @@ pub(crate) async fn demo_http_execute_request(
pub(crate) fn demo_http_list_pool_clients(
state: tauri::State<'_, crate::AppState>,
) -> std::vec::Vec<kb_onchain_transport::HttpPoolClientSnapshot> {
) -> std::vec::Vec<ks_onchain_transport::HttpPoolClientSnapshot> {
return state.http_pool().snapshot();
}
@@ -171,7 +171,7 @@ pub(crate) fn demo_http_options(
}
fn build_http_role_options(
snapshots: std::vec::Vec<kb_onchain_transport::HttpPoolClientSnapshot>,
snapshots: std::vec::Vec<ks_onchain_transport::HttpPoolClientSnapshot>,
) -> std::vec::Vec<crate::DemoHttpRoleOption> {
let mut roles = std::collections::BTreeMap::<
std::string::String,
@@ -256,7 +256,7 @@ fn build_http_method_options() -> std::vec::Vec<crate::DemoHttpMethodOption> {
for (method, label, requires_first_arg, supports_config_json) in methods {
options.push(crate::DemoHttpMethodOption {
method: method.to_string(),
request_kind: kb_onchain_transport::request_kind_from_method(method),
request_kind: ks_onchain_transport::request_kind_from_method(method),
label: label.to_string(),
requires_first_arg,
supports_config_json,
@@ -367,11 +367,11 @@ fn parse_optional_params_json(
return std::result::Result::Ok(std::option::Option::Some(array));
}
fn method_class_to_string(method_class: kb_onchain_transport::HttpMethodClass) -> &'static str {
fn method_class_to_string(method_class: ks_onchain_transport::HttpMethodClass) -> &'static str {
return match method_class {
kb_onchain_transport::HttpMethodClass::GeneralRpc => "GeneralRpc",
kb_onchain_transport::HttpMethodClass::SendTransaction => "SendTransaction",
kb_onchain_transport::HttpMethodClass::HeavyRead => "HeavyRead",
ks_onchain_transport::HttpMethodClass::GeneralRpc => "GeneralRpc",
ks_onchain_transport::HttpMethodClass::SendTransaction => "SendTransaction",
ks_onchain_transport::HttpMethodClass::HeavyRead => "HeavyRead",
};
}
@@ -407,7 +407,7 @@ mod tests {
assert!(names.insert(option.method.as_str()));
assert_eq!(
option.request_kind,
kb_onchain_transport::request_kind_from_method(option.method.as_str())
ks_onchain_transport::request_kind_from_method(option.method.as_str())
);
}
assert!(!options.is_empty());

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_spl_ata.rs
// version: 12
// version: 13
//! Thin Tauri adapter for ATA execution, derivation and lifecycle journal reads.
@@ -228,15 +228,15 @@ pub(crate) async fn demo_execution_spl_ata_execute(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let wallet_owner = kb_lib::MdPubkey(request.wallet_owner.trim().to_string());
let mint = kb_lib::MdPubkey(request.mint.trim().to_string());
let wallet_owner = ks_lib::MdPubkey(request.wallet_owner.trim().to_string());
let mint = ks_lib::MdPubkey(request.mint.trim().to_string());
let operation = match request.mode.as_str() {
"create" => kb_lib::ExSplAssociatedTokenAccountOperation::Create {
"create" => ks_lib::ExSplAssociatedTokenAccountOperation::Create {
wallet_owner,
mint,
token_program,
},
"create_idempotent" => kb_lib::ExSplAssociatedTokenAccountOperation::CreateIdempotent {
"create_idempotent" => ks_lib::ExSplAssociatedTokenAccountOperation::CreateIdempotent {
wallet_owner,
mint,
token_program,
@@ -248,7 +248,7 @@ pub(crate) async fn demo_execution_spl_ata_execute(
},
};
let mut pipeline_request =
kb_pipeline_demo_scenarios::DevnetSplAssociatedTokenAccountExecutionRequest::new(
ks_pipeline_demo_scenarios::DevnetSplAssociatedTokenAccountExecutionRequest::new(
format!("demo-spl-ata-execution-{}", chrono::Utc::now().timestamp_micros()),
operation,
);
@@ -256,7 +256,7 @@ pub(crate) async fn demo_execution_spl_ata_execute(
pipeline_request.operator_confirmed = request.operator_confirmed;
pipeline_request.post_validation_max_retries = 20;
pipeline_request.force_post_validation_replay = request.force_post_validation_replay;
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -267,19 +267,19 @@ pub(crate) async fn demo_execution_spl_ata_execute(
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
return std::result::Result::Err(error.to_string());
}
let decoders: std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> = std::vec![
std::sync::Arc::new(kb_lib::DcSplAssociatedTokenAccountDecoder),
std::sync::Arc::new(kb_lib::DcSplTokenDecoder),
let decoders: std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> = std::vec![
std::sync::Arc::new(ks_lib::DcSplAssociatedTokenAccountDecoder),
std::sync::Arc::new(ks_lib::DcSplTokenDecoder),
];
let materializers: std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(kb_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(kb_lib::MtRiskMaterializer),
let materializers: std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(ks_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(ks_lib::MtRiskMaterializer),
];
let observer = crate::DemoExecutionSolanaCoreObserver {
app_handle,
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let summary = match kb_pipeline_demo_scenarios::execute_devnet_spl_associated_token_account(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_spl_associated_token_account(
&http_pool,
&store,
&profile,
@@ -314,7 +314,7 @@ pub(crate) async fn demo_spl_ata_journal(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let filter = match kb_store::MaterializedEventFilter::new(
let filter = match ks_store::MaterializedEventFilter::new(
std::option::Option::Some("materializer.token.accounts".to_string()),
std::option::Option::None,
request.signature_contains.clone(),
@@ -323,7 +323,7 @@ pub(crate) async fn demo_spl_ata_journal(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let rows = match kb_store::DecodePipelineStore::list_materialized_events(&store, &filter).await
let rows = match ks_store::DecodePipelineStore::list_materialized_events(&store, &filter).await
{
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
@@ -344,19 +344,19 @@ pub(crate) async fn demo_spl_ata_journal(
}
async fn load_profile_wallet(
profile: &kb_config::ProfileConfig,
) -> std::result::Result<kb_wallet::TemporaryWallet, std::string::String> {
profile: &ks_config::ProfileConfig,
) -> std::result::Result<ks_wallet::TemporaryWallet, std::string::String> {
let configured = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
let directory = if configured.is_absolute() {
configured
} else {
crate::workspace_root_dir().join(configured)
};
let store = match kb_wallet::TemporaryWalletStore::new(directory) {
let store = match ks_wallet::TemporaryWalletStore::new(directory) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let alias = match kb_wallet::WalletAlias::parse(profile.wallet.temporary_wallet_alias.clone()) {
let alias = match ks_wallet::WalletAlias::parse(profile.wallet.temporary_wallet_alias.clone()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -368,10 +368,10 @@ async fn load_profile_wallet(
fn parse_token_program(
value: &str,
) -> std::result::Result<kb_lib::ExSplAssociatedTokenProgram, std::string::String> {
) -> std::result::Result<ks_lib::ExSplAssociatedTokenProgram, std::string::String> {
return match value.trim() {
"classic" => std::result::Result::Ok(kb_lib::ExSplAssociatedTokenProgram::Classic),
"token_2022" => std::result::Result::Ok(kb_lib::ExSplAssociatedTokenProgram::Token2022),
"classic" => std::result::Result::Ok(ks_lib::ExSplAssociatedTokenProgram::Classic),
"token_2022" => std::result::Result::Ok(ks_lib::ExSplAssociatedTokenProgram::Token2022),
_ => std::result::Result::Err("Token Program must be classic or token_2022".to_string()),
};
}
@@ -410,7 +410,7 @@ fn derive_ata(
}
fn summary_payload(
summary: kb_pipeline_demo_scenarios::DevnetSplAssociatedTokenAccountExecutionSummary,
summary: ks_pipeline_demo_scenarios::DevnetSplAssociatedTokenAccountExecutionSummary,
) -> crate::DemoExecutionSplAtaSummaryPayload {
let (associated_token_account, token_program_id) = match summary.plan.instructions.first() {
std::option::Option::Some(instruction) => {
@@ -522,10 +522,10 @@ fn summary_payload(
balance_lamports: summary.balance_lamports.to_string(),
fee_lamports: summary.fee.fee_lamports.map(|value| return value.to_string()),
readiness_status: match summary.stateful_readiness.status {
kb_pipeline::SplAssociatedTokenAccountStatefulReadinessStatus::Ready => {
ks_pipeline::SplAssociatedTokenAccountStatefulReadinessStatus::Ready => {
"ready".to_string()
},
kb_pipeline::SplAssociatedTokenAccountStatefulReadinessStatus::Blocked => {
ks_pipeline::SplAssociatedTokenAccountStatefulReadinessStatus::Blocked => {
"blocked".to_string()
},
},
@@ -558,7 +558,7 @@ fn journal_matches(payload: &serde_json::Value, request: &crate::DemoSplAtaJourn
return true;
}
fn journal_row(row: kb_store::MaterializedEventQueryRow) -> crate::DemoSplAtaJournalRow {
fn journal_row(row: ks_store::MaterializedEventQueryRow) -> crate::DemoSplAtaJournalRow {
let text = |key: &str| {
return row
.payload_json
@@ -585,11 +585,11 @@ fn journal_row(row: kb_store::MaterializedEventQueryRow) -> crate::DemoSplAtaJou
mod tests {
#[test]
fn classic_and_token_2022_derivations_are_distinct_and_canonical() {
let wallet = kb_program_ids::SYSTEM_PROGRAM_ID;
let wallet = ks_program_ids::SYSTEM_PROGRAM_ID;
let mint = "So11111111111111111111111111111111111111112";
let classic = super::derive_ata(wallet, mint, kb_program_ids::SPL_TOKEN_PROGRAM_ID)
let classic = super::derive_ata(wallet, mint, ks_program_ids::SPL_TOKEN_PROGRAM_ID)
.unwrap_or_else(|error| panic!("classic derivation failed: {error}"));
let token_2022 = super::derive_ata(wallet, mint, kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID)
let token_2022 = super::derive_ata(wallet, mint, ks_program_ids::SPL_TOKEN_2022_PROGRAM_ID)
.unwrap_or_else(|error| panic!("Token-2022 derivation failed: {error}"));
assert_eq!(classic, "aqxoAhCwpy3oB1BpNw9hL1HdLYLgPpbPjzxDrrQj3Fs");
assert_eq!(token_2022, "2sZUUBGq1i6aE47ZoxCaCW89jmYm2EXLPPmNMgMDXHMS");

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_spl_token.rs
// version: 9
// version: 10
//! Thin Tauri adapter for classic SPL Token execution and materialized journals.
@@ -179,7 +179,7 @@ pub(crate) async fn demo_execution_spl_token_execute(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -191,20 +191,20 @@ pub(crate) async fn demo_execution_spl_token_execute(
return std::result::Result::Err(error.to_string());
}
let amount_raw = request.amount_raw.trim().to_string();
let operation = kb_lib::ExSplClassicTokenOperation::Instruction {
value: kb_lib::ExSplClassicTokenSingleOperation::TransferChecked {
source: kb_lib::MdPubkey(request.source.trim().to_string()),
mint: kb_lib::MdPubkey(request.mint.trim().to_string()),
destination: kb_lib::MdPubkey(request.destination.trim().to_string()),
authority: kb_lib::ExSplClassicTokenAuthority {
authority: kb_lib::MdPubkey(request.authority.trim().to_string()),
let operation = ks_lib::ExSplClassicTokenOperation::Instruction {
value: ks_lib::ExSplClassicTokenSingleOperation::TransferChecked {
source: ks_lib::MdPubkey(request.source.trim().to_string()),
mint: ks_lib::MdPubkey(request.mint.trim().to_string()),
destination: ks_lib::MdPubkey(request.destination.trim().to_string()),
authority: ks_lib::ExSplClassicTokenAuthority {
authority: ks_lib::MdPubkey(request.authority.trim().to_string()),
multisig_signers: std::vec::Vec::new(),
},
amount: kb_lib::ExSplClassicTokenAmount(amount_raw.clone()),
amount: ks_lib::ExSplClassicTokenAmount(amount_raw.clone()),
decimals: request.decimals,
},
};
let mut pipeline_request = kb_pipeline_demo_scenarios::DevnetSplTokenExecutionRequest::new(
let mut pipeline_request = ks_pipeline_demo_scenarios::DevnetSplTokenExecutionRequest::new(
format!("demo-spl-token-execution-{}", chrono::Utc::now().timestamp_micros()),
operation,
);
@@ -212,19 +212,19 @@ pub(crate) async fn demo_execution_spl_token_execute(
pipeline_request.operator_confirmed = request.operator_confirmed;
pipeline_request.post_validation_max_retries = 20;
pipeline_request.force_post_validation_replay = request.force_post_validation_replay;
let decoders: std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(kb_lib::DcSplTokenDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(kb_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(kb_lib::MtAdminMaterializer),
std::sync::Arc::new(kb_lib::MtRiskMaterializer),
let decoders: std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(ks_lib::DcSplTokenDecoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(ks_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(ks_lib::MtAdminMaterializer),
std::sync::Arc::new(ks_lib::MtRiskMaterializer),
];
let observer = crate::DemoExecutionSolanaCoreObserver {
app_handle,
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let workspace_root = crate::workspace_root_dir();
let summary = match kb_pipeline_demo_scenarios::execute_devnet_spl_token(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_spl_token(
&http_pool,
&store,
&profile,
@@ -266,11 +266,11 @@ pub(crate) async fn demo_spl_token_journal(
let needs_payload_filter =
validated.mint.is_some() || validated.account.is_some() || validated.operation.is_some();
let query_limit = if needs_payload_filter {
kb_store::MAX_MATERIALIZED_EVENT_QUERY_ROWS
ks_store::MAX_MATERIALIZED_EVENT_QUERY_ROWS
} else {
validated.limit
};
let filter = match kb_store::MaterializedEventFilter::new(
let filter = match ks_store::MaterializedEventFilter::new(
std::option::Option::None,
validated.family.clone(),
validated.signature_contains.clone(),
@@ -279,7 +279,7 @@ pub(crate) async fn demo_spl_token_journal(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let rows = match kb_store::DecodePipelineStore::list_materialized_events(&store, &filter).await
let rows = match ks_store::DecodePipelineStore::list_materialized_events(&store, &filter).await
{
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
@@ -299,7 +299,7 @@ pub(crate) async fn demo_spl_token_journal(
}
fn summary_payload(
summary: kb_pipeline_demo_scenarios::DevnetSplTokenExecutionSummary,
summary: ks_pipeline_demo_scenarios::DevnetSplTokenExecutionSummary,
amount_raw: std::string::String,
decimals: u8,
) -> crate::DemoExecutionSplTokenSummaryPayload {
@@ -370,8 +370,8 @@ fn summary_payload(
amount_raw,
decimals,
readiness_status: match summary.stateful_readiness.status {
kb_pipeline::SplTokenStatefulReadinessStatus::Ready => "ready".to_string(),
kb_pipeline::SplTokenStatefulReadinessStatus::Blocked => "blocked".to_string(),
ks_pipeline::SplTokenStatefulReadinessStatus::Ready => "ready".to_string(),
ks_pipeline::SplTokenStatefulReadinessStatus::Blocked => "blocked".to_string(),
},
simulation_success: summary.simulation.success,
simulation_error: summary.simulation.error,
@@ -389,7 +389,7 @@ fn summary_payload(
};
}
fn replay_diagnostics(summary: &kb_pipeline::DecodeReplaySummary) -> serde_json::Value {
fn replay_diagnostics(summary: &ks_pipeline::DecodeReplaySummary) -> serde_json::Value {
return serde_json::json!({
"campaignId": summary.campaign_id,
"selected": summary.selected,
@@ -415,10 +415,10 @@ fn replay_diagnostics(summary: &kb_pipeline::DecodeReplaySummary) -> serde_json:
fn validate_journal_request(
request: crate::DemoSplTokenJournalRequest,
) -> std::result::Result<crate::DemoSplTokenJournalRequest, std::string::String> {
if request.limit == 0 || request.limit > kb_store::MAX_MATERIALIZED_EVENT_QUERY_ROWS {
if request.limit == 0 || request.limit > ks_store::MAX_MATERIALIZED_EVENT_QUERY_ROWS {
return std::result::Result::Err(format!(
"journal limit must be between 1 and {}",
kb_store::MAX_MATERIALIZED_EVENT_QUERY_ROWS
ks_store::MAX_MATERIALIZED_EVENT_QUERY_ROWS
));
}
if request.profile_name.trim().is_empty() {
@@ -499,7 +499,7 @@ fn payload_matches(
return true;
}
fn journal_row(row: kb_store::MaterializedEventQueryRow) -> DemoSplTokenJournalRow {
fn journal_row(row: ks_store::MaterializedEventQueryRow) -> DemoSplTokenJournalRow {
let operation = row
.payload_json
.get("operation")
@@ -605,7 +605,7 @@ mod tests {
payload.get("amountRaw").and_then(serde_json::Value::as_str),
std::option::Option::Some("18446744073709551615")
);
let row = super::journal_row(kb_store::MaterializedEventQueryRow {
let row = super::journal_row(ks_store::MaterializedEventQueryRow {
processor_name: "materializer.token.accounts".to_string(),
processor_version: "0.4.4".to_string(),
input_key: "input".to_string(),

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_spl_token_2022.rs
// version: 12
// version: 13
//! Thin Tauri adapter for independent public Token-2022 Devnet validation scenarios.
@@ -157,7 +157,7 @@ pub(crate) async fn demo_execution_spl_token_2022_execute(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let http_pool = match kb_onchain_transport::HttpEndpointPool::from_profile(&profile) {
let http_pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
@@ -173,7 +173,7 @@ pub(crate) async fn demo_execution_spl_token_2022_execute(
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let operation_code = operation.operation_code().to_string();
let mut pipeline_request = kb_pipeline_demo_scenarios::DevnetSplToken2022ExecutionRequest::new(
let mut pipeline_request = ks_pipeline_demo_scenarios::DevnetSplToken2022ExecutionRequest::new(
format!("demo-spl-token-2022-execution-{}", chrono::Utc::now().timestamp_micros()),
operation,
);
@@ -181,21 +181,21 @@ pub(crate) async fn demo_execution_spl_token_2022_execute(
pipeline_request.operator_confirmed = request.operator_confirmed;
pipeline_request.post_validation_max_retries = 20;
pipeline_request.force_post_validation_replay = request.force_post_validation_replay;
let decoders: std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(kb_lib::DcSplToken2022Decoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(kb_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(kb_lib::MtAdminMaterializer),
std::sync::Arc::new(kb_lib::MtRiskMaterializer),
std::sync::Arc::new(kb_lib::MtFeesMaterializer),
std::sync::Arc::new(kb_lib::MtComplianceAuditMaterializer),
let decoders: std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> =
std::vec![std::sync::Arc::new(ks_lib::DcSplToken2022Decoder)];
let materializers: std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> = std::vec![
std::sync::Arc::new(ks_lib::MtTokenAccountsMaterializer),
std::sync::Arc::new(ks_lib::MtAdminMaterializer),
std::sync::Arc::new(ks_lib::MtRiskMaterializer),
std::sync::Arc::new(ks_lib::MtFeesMaterializer),
std::sync::Arc::new(ks_lib::MtComplianceAuditMaterializer),
];
let observer = crate::DemoExecutionSolanaCoreObserver {
app_handle,
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
};
let workspace_root = crate::workspace_root_dir();
let summary = match kb_pipeline_demo_scenarios::execute_devnet_spl_token_2022(
let summary = match ks_pipeline_demo_scenarios::execute_devnet_spl_token_2022(
&http_pool,
&store,
&profile,
@@ -321,63 +321,63 @@ pub(crate) fn demo_spl_token_2022_fixture(
fn operation_from_request(
request: &crate::DemoExecutionSplToken2022Request,
) -> std::result::Result<kb_lib::ExSplToken2022Operation, std::string::String> {
let authority = kb_lib::ExSplTokenAuthority {
authority: kb_lib::MdPubkey(request.authority.trim().to_string()),
) -> std::result::Result<ks_lib::ExSplToken2022Operation, std::string::String> {
let authority = ks_lib::ExSplTokenAuthority {
authority: ks_lib::MdPubkey(request.authority.trim().to_string()),
multisig_signers: std::vec::Vec::new(),
};
let freeze_authority = kb_lib::ExSplTokenAuthority {
authority: kb_lib::MdPubkey(request.freeze_authority.trim().to_string()),
let freeze_authority = ks_lib::ExSplTokenAuthority {
authority: ks_lib::MdPubkey(request.freeze_authority.trim().to_string()),
multisig_signers: std::vec::Vec::new(),
};
let value = match request.scenario_id.trim() {
"token_2022_mint_to_checked" => kb_lib::ExSplTokenSingleOperation::MintToChecked {
mint: kb_lib::MdPubkey(request.mint.trim().to_string()),
destination: kb_lib::MdPubkey(request.source.trim().to_string()),
"token_2022_mint_to_checked" => ks_lib::ExSplTokenSingleOperation::MintToChecked {
mint: ks_lib::MdPubkey(request.mint.trim().to_string()),
destination: ks_lib::MdPubkey(request.source.trim().to_string()),
authority,
amount: kb_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
amount: ks_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
decimals: request.decimals,
},
"token_2022_transfer_checked" => kb_lib::ExSplTokenSingleOperation::TransferChecked {
source: kb_lib::MdPubkey(request.source.trim().to_string()),
mint: kb_lib::MdPubkey(request.mint.trim().to_string()),
destination: kb_lib::MdPubkey(request.destination.trim().to_string()),
"token_2022_transfer_checked" => ks_lib::ExSplTokenSingleOperation::TransferChecked {
source: ks_lib::MdPubkey(request.source.trim().to_string()),
mint: ks_lib::MdPubkey(request.mint.trim().to_string()),
destination: ks_lib::MdPubkey(request.destination.trim().to_string()),
authority,
amount: kb_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
amount: ks_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
decimals: request.decimals,
},
"token_2022_approve_checked" => kb_lib::ExSplTokenSingleOperation::ApproveChecked {
source: kb_lib::MdPubkey(request.source.trim().to_string()),
mint: kb_lib::MdPubkey(request.mint.trim().to_string()),
delegate: kb_lib::MdPubkey(request.delegate.trim().to_string()),
"token_2022_approve_checked" => ks_lib::ExSplTokenSingleOperation::ApproveChecked {
source: ks_lib::MdPubkey(request.source.trim().to_string()),
mint: ks_lib::MdPubkey(request.mint.trim().to_string()),
delegate: ks_lib::MdPubkey(request.delegate.trim().to_string()),
authority,
amount: kb_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
amount: ks_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
decimals: request.decimals,
},
"token_2022_revoke" => kb_lib::ExSplTokenSingleOperation::Revoke {
source: kb_lib::MdPubkey(request.source.trim().to_string()),
"token_2022_revoke" => ks_lib::ExSplTokenSingleOperation::Revoke {
source: ks_lib::MdPubkey(request.source.trim().to_string()),
authority,
},
"token_2022_burn_checked" => kb_lib::ExSplTokenSingleOperation::BurnChecked {
source: kb_lib::MdPubkey(request.source.trim().to_string()),
mint: kb_lib::MdPubkey(request.mint.trim().to_string()),
"token_2022_burn_checked" => ks_lib::ExSplTokenSingleOperation::BurnChecked {
source: ks_lib::MdPubkey(request.source.trim().to_string()),
mint: ks_lib::MdPubkey(request.mint.trim().to_string()),
authority,
amount: kb_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
amount: ks_lib::ExSplTokenAmount(request.amount_raw.trim().to_string()),
decimals: request.decimals,
},
"token_2022_freeze_account" => kb_lib::ExSplTokenSingleOperation::FreezeAccount {
account: kb_lib::MdPubkey(request.source.trim().to_string()),
mint: kb_lib::MdPubkey(request.mint.trim().to_string()),
"token_2022_freeze_account" => ks_lib::ExSplTokenSingleOperation::FreezeAccount {
account: ks_lib::MdPubkey(request.source.trim().to_string()),
mint: ks_lib::MdPubkey(request.mint.trim().to_string()),
authority: freeze_authority,
},
"token_2022_thaw_account" => kb_lib::ExSplTokenSingleOperation::ThawAccount {
account: kb_lib::MdPubkey(request.source.trim().to_string()),
mint: kb_lib::MdPubkey(request.mint.trim().to_string()),
"token_2022_thaw_account" => ks_lib::ExSplTokenSingleOperation::ThawAccount {
account: ks_lib::MdPubkey(request.source.trim().to_string()),
mint: ks_lib::MdPubkey(request.mint.trim().to_string()),
authority: freeze_authority,
},
"token_2022_close_destination" => kb_lib::ExSplTokenSingleOperation::CloseAccount {
account: kb_lib::MdPubkey(request.source.trim().to_string()),
destination: kb_lib::MdPubkey(request.destination.trim().to_string()),
"token_2022_close_destination" => ks_lib::ExSplTokenSingleOperation::CloseAccount {
account: ks_lib::MdPubkey(request.source.trim().to_string()),
destination: ks_lib::MdPubkey(request.destination.trim().to_string()),
authority,
},
other => {
@@ -386,7 +386,7 @@ fn operation_from_request(
));
},
};
return std::result::Result::Ok(kb_lib::ExSplToken2022Operation::Instruction {
return std::result::Result::Ok(ks_lib::ExSplToken2022Operation::Instruction {
value: std::boxed::Box::new(value),
});
}
@@ -394,7 +394,7 @@ fn operation_from_request(
fn summary_payload(
scenario_id: std::string::String,
operation: std::string::String,
summary: kb_pipeline_demo_scenarios::DevnetSplToken2022ExecutionSummary,
summary: ks_pipeline_demo_scenarios::DevnetSplToken2022ExecutionSummary,
) -> crate::DemoExecutionSplToken2022SummaryPayload {
let plan_json = crate::pretty_json(&summary.plan);
let preflight_json = crate::pretty_json(&summary.stateful_preflight);
@@ -477,7 +477,7 @@ fn parse_fixture(
return values;
}
fn backfill_summary_json(summary: &kb_pipeline::BackfillSummary) -> serde_json::Value {
fn backfill_summary_json(summary: &ks_pipeline::BackfillSummary) -> serde_json::Value {
return serde_json::json!({
"captureSessionId": summary.capture_session_id,
"filterCode": summary.filter_code,
@@ -505,7 +505,7 @@ fn backfill_summary_json(summary: &kb_pipeline::BackfillSummary) -> serde_json::
});
}
fn core_extraction_summary_json(summary: &kb_pipeline::CoreExtractionSummary) -> serde_json::Value {
fn core_extraction_summary_json(summary: &ks_pipeline::CoreExtractionSummary) -> serde_json::Value {
return serde_json::json!({
"processorVersion": summary.processor_version,
"selected": summary.selected,
@@ -522,7 +522,7 @@ fn core_extraction_summary_json(summary: &kb_pipeline::CoreExtractionSummary) ->
});
}
fn decode_replay_summary_json(summary: &kb_pipeline::DecodeReplaySummary) -> serde_json::Value {
fn decode_replay_summary_json(summary: &ks_pipeline::DecodeReplaySummary) -> serde_json::Value {
let processors = summary
.processors
.iter()

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_sql_common.rs
// version: 12
// version: 13
//! Shared SQL demo helpers and serializable payloads.
@@ -34,12 +34,12 @@ pub(crate) struct DemoSqlTableSnapshot {
pub(crate) latest_created_at: std::option::Option<std::string::String>,
}
/// Builds PostgreSQL options from the active profile without coupling kb-store to kb-config.
/// Builds PostgreSQL options from the active profile without coupling ks-store to ks-config.
pub(crate) fn postgres_store_options_from_profile(
profile: &kb_config::ProfileConfig,
profile: &ks_config::ProfileConfig,
auto_initialize_schema: bool,
) -> kb_core::Result<kb_store::PostgresStoreOptions> {
return kb_store::PostgresStoreOptions::new(
) -> ks_core::Result<ks_store::PostgresStoreOptions> {
return ks_store::PostgresStoreOptions::new(
profile.database.postgres.url.clone(),
profile.database.postgres.max_connections,
profile.database.postgres.connect_timeout_ms,
@@ -49,8 +49,8 @@ pub(crate) fn postgres_store_options_from_profile(
/// Connects to PostgreSQL without reapplying schemas initialized at application startup.
pub(crate) async fn connect_postgres_store(
profile: &kb_config::ProfileConfig,
) -> std::result::Result<kb_store::PostgresStore, std::string::String> {
profile: &ks_config::ProfileConfig,
) -> std::result::Result<ks_store::PostgresStore, std::string::String> {
if !profile.database.enabled {
return std::result::Result::Err(std::string::String::from(
"database configuration is disabled in the active profile",
@@ -62,7 +62,7 @@ pub(crate) async fn connect_postgres_store(
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
options.auto_initialize_schema = false;
let store_result = kb_store::PostgresStore::connect(options).await;
let store_result = ks_store::PostgresStore::connect(options).await;
return match store_result {
std::result::Result::Ok(store) => std::result::Result::Ok(store),
std::result::Result::Err(error) => std::result::Result::Err(error.to_string()),
@@ -71,7 +71,7 @@ pub(crate) async fn connect_postgres_store(
/// Converts store table diagnostics to the UI payload shape.
pub(crate) fn table_snapshot_from_pg(
value: &kb_store::PostgresTableDiagnostics,
value: &ks_store::PostgresTableDiagnostics,
) -> crate::DemoSqlTableSnapshot {
let row_count = match &value.statistics {
std::option::Option::Some(statistics) => std::option::Option::Some(statistics.row_count),
@@ -103,7 +103,7 @@ pub(crate) fn table_snapshot_from_pg(
/// Converts many table diagnostics to UI payloads.
pub(crate) fn table_snapshots_from_pg(
values: &[kb_store::PostgresTableDiagnostics],
values: &[ks_store::PostgresTableDiagnostics],
) -> std::vec::Vec<crate::DemoSqlTableSnapshot> {
let mut output = std::vec::Vec::new();
for value in values {
@@ -169,7 +169,7 @@ pub(crate) async fn initialize_postgres_schema_for_startup(
);
}
tracing::debug!(target: crate::TRACING_TARGET, dsn = masked_dsn.as_str(), "start PostgreSQL schema initialization");
let store_result = kb_store::PostgresStore::connect(options).await;
let store_result = ks_store::PostgresStore::connect(options).await;
let store = match store_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
@@ -218,8 +218,8 @@ pub(crate) fn debug_status<T: std::fmt::Debug>(value: T) -> std::string::String
fn emit_sql_startup_table_report(
splash_window: &tauri::WebviewWindow,
before_tables: &[kb_store::PostgresTableDiagnostics],
after_tables: &[kb_store::PostgresTableDiagnostics],
before_tables: &[ks_store::PostgresTableDiagnostics],
after_tables: &[ks_store::PostgresTableDiagnostics],
) {
let mut created_count = 0_u32;
let mut existing_count = 0_u32;
@@ -268,7 +268,7 @@ fn emit_sql_startup_table_report(
}
fn table_exists_in(
tables: &[kb_store::PostgresTableDiagnostics],
tables: &[ks_store::PostgresTableDiagnostics],
table_name: &str,
) -> std::option::Option<bool> {
for table in tables {

View File

@@ -1,11 +1,11 @@
// file: kb-app-demo-desktop/src/demo_sql_replay_candidates.rs
// version: 12
// version: 13
//! Read-only SQL replay candidate browser commands.
use ts_rs::TS; // rust-rules: derive-import
/// One program identifier exposed by the runtime `kb_program_ids` registry.
/// One program identifier exposed by the runtime `ks_program_ids` registry.
#[derive(Clone, Debug, serde::Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(
@@ -33,7 +33,7 @@ pub(crate) struct DemoSqlReplayOptionsPayload {
pub(crate) masked_dsn: std::string::String,
/// Maximum rows accepted by one query.
pub(crate) maximum_limit: u32,
/// Program identifiers enumerable from `kb_program_ids`.
/// Program identifiers enumerable from `ks_program_ids`.
pub(crate) known_programs: std::vec::Vec<crate::DemoSqlReplayKnownProgramOption>,
}
@@ -136,7 +136,7 @@ pub(crate) struct DemoSqlReplayProgramRequest {
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_sql_replay_candidates/DemoSqlReplayProgramRow.ts"
)]
pub(crate) struct DemoSqlReplayProgramRow {
/// Optional stable code from `kb_program_ids`.
/// Optional stable code from `ks_program_ids`.
pub(crate) program_code: std::option::Option<std::string::String>,
/// Program id.
pub(crate) program_id: std::string::String,
@@ -251,8 +251,8 @@ pub(crate) async fn demo_sql_replay_options(
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let mut known_programs =
std::vec::Vec::with_capacity(kb_program_ids::registered_program_ids().len());
for entry in kb_program_ids::registered_program_ids() {
std::vec::Vec::with_capacity(ks_program_ids::registered_program_ids().len());
for entry in ks_program_ids::registered_program_ids() {
known_programs.push(crate::DemoSqlReplayKnownProgramOption {
code: entry.code().to_owned(),
program_id: entry.program_id().to_owned(),
@@ -261,7 +261,7 @@ pub(crate) async fn demo_sql_replay_options(
return std::result::Result::Ok(crate::DemoSqlReplayOptionsPayload {
active_profile_name: profile.name,
masked_dsn: options.masked_dsn(),
maximum_limit: kb_store::MAX_REPLAY_CANDIDATE_ROWS,
maximum_limit: ks_store::MAX_REPLAY_CANDIDATE_ROWS,
known_programs,
});
}
@@ -281,7 +281,7 @@ pub(crate) async fn load_demo_sql_replay_transactions(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let filter_result = kb_store::PostgresReplayTransactionFilter::new(
let filter_result = ks_store::PostgresReplayTransactionFilter::new(
request.signature_contains,
request.min_slot,
request.max_slot,
@@ -322,7 +322,7 @@ pub(crate) async fn load_demo_sql_replay_programs(
request: crate::DemoSqlReplayProgramRequest,
) -> std::result::Result<std::vec::Vec<crate::DemoSqlReplayProgramRow>, std::string::String> {
let filter_result =
kb_store::PostgresReplayProgramFilter::new(request.program_id_contains, request.limit);
ks_store::PostgresReplayProgramFilter::new(request.program_id_contains, request.limit);
let filter = match filter_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
@@ -355,7 +355,7 @@ pub(crate) async fn load_demo_sql_replay_entities(
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let filter_result = kb_store::PostgresReplayEntityFilter::new(
let filter_result = ks_store::PostgresReplayEntityFilter::new(
entity_kind,
request.entity_value_contains,
request.limit,
@@ -383,7 +383,7 @@ pub(crate) async fn load_demo_sql_replay_entities(
}
fn transaction_row_from_pg(
row: kb_store::PostgresReplayTransactionCandidate,
row: ks_store::PostgresReplayTransactionCandidate,
) -> crate::DemoSqlReplayTransactionRow {
return crate::DemoSqlReplayTransactionRow {
signature: row.signature,
@@ -404,9 +404,9 @@ fn transaction_row_from_pg(
}
fn program_row_from_pg(
row: kb_store::PostgresReplayProgramSummary,
row: ks_store::PostgresReplayProgramSummary,
) -> crate::DemoSqlReplayProgramRow {
let program_code = kb_program_ids::find_registered_program_id(&row.program_id)
let program_code = ks_program_ids::find_registered_program_id(&row.program_id)
.map(|entry| return entry.code().to_owned());
return crate::DemoSqlReplayProgramRow {
program_code,
@@ -420,7 +420,7 @@ fn program_row_from_pg(
};
}
fn entity_row_from_pg(row: kb_store::PostgresReplayEntitySummary) -> crate::DemoSqlReplayEntityRow {
fn entity_row_from_pg(row: ks_store::PostgresReplayEntitySummary) -> crate::DemoSqlReplayEntityRow {
return crate::DemoSqlReplayEntityRow {
entity_kind: row.entity_kind,
entity_value: row.entity_value,
@@ -480,19 +480,19 @@ async fn available_csv_export_path(
fn program_scope_from_code(
code: &str,
) -> std::result::Result<kb_store::PostgresReplayProgramScope, std::string::String> {
) -> std::result::Result<ks_store::PostgresReplayProgramScope, std::string::String> {
return match code {
"any" => std::result::Result::Ok(kb_store::PostgresReplayProgramScope::Any),
"outer" => std::result::Result::Ok(kb_store::PostgresReplayProgramScope::Outer),
"inner" => std::result::Result::Ok(kb_store::PostgresReplayProgramScope::Inner),
"logs" => std::result::Result::Ok(kb_store::PostgresReplayProgramScope::Logs),
"any" => std::result::Result::Ok(ks_store::PostgresReplayProgramScope::Any),
"outer" => std::result::Result::Ok(ks_store::PostgresReplayProgramScope::Outer),
"inner" => std::result::Result::Ok(ks_store::PostgresReplayProgramScope::Inner),
"logs" => std::result::Result::Ok(ks_store::PostgresReplayProgramScope::Logs),
_ => std::result::Result::Err(format!("unsupported replay program scope: {code}")),
};
}
fn optional_entity_kind_from_code(
code: std::option::Option<&str>,
) -> std::result::Result<std::option::Option<kb_store::PostgresReplayEntityKind>, std::string::String>
) -> std::result::Result<std::option::Option<ks_store::PostgresReplayEntityKind>, std::string::String>
{
return match code {
std::option::Option::Some(value) => {
@@ -510,11 +510,11 @@ fn optional_entity_kind_from_code(
fn entity_kind_from_code(
code: &str,
) -> std::result::Result<kb_store::PostgresReplayEntityKind, std::string::String> {
) -> std::result::Result<ks_store::PostgresReplayEntityKind, std::string::String> {
return match code {
"mint" => std::result::Result::Ok(kb_store::PostgresReplayEntityKind::Mint),
"owner" => std::result::Result::Ok(kb_store::PostgresReplayEntityKind::Owner),
"account_key" => std::result::Result::Ok(kb_store::PostgresReplayEntityKind::AccountKey),
"mint" => std::result::Result::Ok(ks_store::PostgresReplayEntityKind::Mint),
"owner" => std::result::Result::Ok(ks_store::PostgresReplayEntityKind::Owner),
"account_key" => std::result::Result::Ok(ks_store::PostgresReplayEntityKind::AccountKey),
_ => std::result::Result::Err(format!("unsupported replay entity kind: {code}")),
};
}
@@ -524,7 +524,7 @@ mod tests {
#[test]
fn program_scope_parser_accepts_logs() {
let result = super::program_scope_from_code("logs");
assert_eq!(result, std::result::Result::Ok(kb_store::PostgresReplayProgramScope::Logs));
assert_eq!(result, std::result::Result::Ok(ks_store::PostgresReplayProgramScope::Logs));
}
#[test]
@@ -551,8 +551,8 @@ mod tests {
#[test]
fn program_row_exposes_registered_code() {
let row = kb_store::PostgresReplayProgramSummary {
program_id: kb_program_ids::SYSTEM_PROGRAM_ID.to_owned(),
let row = ks_store::PostgresReplayProgramSummary {
program_id: ks_program_ids::SYSTEM_PROGRAM_ID.to_owned(),
transaction_count: 1,
outer_instruction_count: 1,
inner_instruction_count: 0,

View File

@@ -1,7 +1,7 @@
// file: kb-app-demo-desktop/src/demo_ws.rs
// version: 19
// version: 20
//! Standard Solana WebSocket demo commands backed by `kb_onchain_transport::WsSession`.
//! Standard Solana WebSocket demo commands backed by `ks_onchain_transport::WsSession`.
use tauri::Emitter; // rust-rules: trait-import
use tauri::Manager; // rust-rules: trait-import
@@ -179,7 +179,7 @@ pub(crate) struct DemoWsMessagePayload {
pub(crate) payload_json: std::string::String,
}
/// Connects if needed, then subscribes through `kb_onchain_transport::WsSession`.
/// Connects if needed, then subscribes through `ks_onchain_transport::WsSession`.
pub(crate) async fn demo_ws_connect(
app_handle: tauri::AppHandle,
state: &crate::AppState,
@@ -233,7 +233,7 @@ pub(crate) async fn demo_ws_connect(
endpoint_url: selected_client.endpoint_url().to_string(),
role,
method: method.clone(),
request_kind: kb_onchain_transport::request_kind_from_method(&method),
request_kind: ks_onchain_transport::request_kind_from_method(&method),
response_kind: acknowledgement.response.kind_name().to_string(),
subscription_id: acknowledgement.subscription.remote_subscription_id,
response_json,
@@ -260,7 +260,7 @@ pub(crate) async fn demo_ws_status(
pub(crate) fn demo_ws_list_pool_clients(
state: tauri::State<'_, crate::AppState>,
) -> std::result::Result<
std::vec::Vec<kb_onchain_transport::WsPoolClientSnapshot>,
std::vec::Vec<ks_onchain_transport::WsPoolClientSnapshot>,
std::string::String,
> {
let pool = match state.demo_ws_pool() {
@@ -384,15 +384,15 @@ impl DemoWsUiRateLimiter {
async fn ensure_session(
app_handle: &tauri::AppHandle,
state: &crate::AppState,
selected_client: kb_onchain_transport::WsClient,
) -> std::result::Result<std::sync::Arc<kb_onchain_transport::WsSession>, std::string::String> {
selected_client: ks_onchain_transport::WsClient,
) -> std::result::Result<std::sync::Arc<ks_onchain_transport::WsSession>, std::string::String> {
let existing = {
let guard = state.demo_ws_session().lock().await;
guard.clone()
};
if let std::option::Option::Some(session) = existing {
let snapshot = session.snapshot().await;
if snapshot.state != kb_onchain_transport::WsSessionState::Disconnected {
if snapshot.state != ks_onchain_transport::WsSessionState::Disconnected {
if snapshot.endpoint_url != selected_client.endpoint_url() {
return std::result::Result::Err(format!(
"demo WebSocket session already uses endpoint '{}'; disconnect before selecting '{}'",
@@ -404,7 +404,7 @@ async fn ensure_session(
}
}
let reconnect_policy = if selected_client.endpoint_config().auto_reconnect {
match kb_onchain_transport::WsReconnectPolicy::bounded(
match ks_onchain_transport::WsReconnectPolicy::bounded(
DEMO_WS_RECONNECT_ATTEMPTS,
DEMO_WS_RECONNECT_INITIAL_DELAY_MS,
DEMO_WS_RECONNECT_MAX_DELAY_MS,
@@ -413,12 +413,12 @@ async fn ensure_session(
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
}
} else {
kb_onchain_transport::WsReconnectPolicy::disabled()
ks_onchain_transport::WsReconnectPolicy::disabled()
};
let capabilities = kb_onchain_transport::StandardWsCapabilities::from_endpoint(
let capabilities = ks_onchain_transport::StandardWsCapabilities::from_endpoint(
selected_client.endpoint_config(),
);
let session = match kb_onchain_transport::WsSession::connect(
let session = match ks_onchain_transport::WsSession::connect(
selected_client,
capabilities,
reconnect_policy,
@@ -438,7 +438,7 @@ async fn ensure_session(
fn spawn_event_bridge(
app_handle: tauri::AppHandle,
session: std::sync::Arc<kb_onchain_transport::WsSession>,
session: std::sync::Arc<ks_onchain_transport::WsSession>,
) {
let mut receiver = session.subscribe_events();
tauri::async_runtime::spawn(async move {
@@ -460,7 +460,7 @@ fn spawn_event_bridge(
std::result::Result::Err(tokio::sync::broadcast::error::RecvError::Closed) => break,
};
match event {
kb_onchain_transport::WsSessionEvent::Notification { notification, .. } => {
ks_onchain_transport::WsSessionEvent::Notification { notification, .. } => {
let compact_payload = match serde_json::to_string(&notification) {
std::result::Result::Ok(payload) => payload,
std::result::Result::Err(error) => {
@@ -480,10 +480,10 @@ fn spawn_event_bridge(
emit_message(&app_handle, "notification", truncate_payload(ui_payload));
}
},
kb_onchain_transport::WsSessionEvent::Diagnostic { code, message } => {
ks_onchain_transport::WsSessionEvent::Diagnostic { code, message } => {
emit_message(&app_handle, &code, truncate_payload(message));
},
kb_onchain_transport::WsSessionEvent::Reconnecting {
ks_onchain_transport::WsSessionEvent::Reconnecting {
attempt,
maximum_attempts,
} => {
@@ -494,7 +494,7 @@ fn spawn_event_bridge(
);
emit_status(&app_handle, session.snapshot().await);
},
kb_onchain_transport::WsSessionEvent::Reconnected { reconnect_count } => {
ks_onchain_transport::WsSessionEvent::Reconnected { reconnect_count } => {
emit_message(
&app_handle,
"reconnected",
@@ -502,13 +502,13 @@ fn spawn_event_bridge(
);
emit_status(&app_handle, session.snapshot().await);
},
kb_onchain_transport::WsSessionEvent::Connected
| kb_onchain_transport::WsSessionEvent::SubscriptionAdded(_)
| kb_onchain_transport::WsSessionEvent::SubscriptionRemapped { .. }
| kb_onchain_transport::WsSessionEvent::SubscriptionRemoved(_) => {
ks_onchain_transport::WsSessionEvent::Connected
| ks_onchain_transport::WsSessionEvent::SubscriptionAdded(_)
| ks_onchain_transport::WsSessionEvent::SubscriptionRemapped { .. }
| ks_onchain_transport::WsSessionEvent::SubscriptionRemoved(_) => {
emit_status(&app_handle, session.snapshot().await);
},
kb_onchain_transport::WsSessionEvent::Disconnected => {
ks_onchain_transport::WsSessionEvent::Disconnected => {
emit_status(&app_handle, session.snapshot().await);
break;
},
@@ -517,7 +517,7 @@ fn spawn_event_bridge(
});
}
fn emit_status(app_handle: &tauri::AppHandle, snapshot: kb_onchain_transport::WsSessionSnapshot) {
fn emit_status(app_handle: &tauri::AppHandle, snapshot: ks_onchain_transport::WsSessionSnapshot) {
let window = match app_handle.get_webview_window("demo_ws") {
std::option::Option::Some(window) => window,
std::option::Option::None => return,
@@ -542,7 +542,7 @@ fn emit_message(app_handle: &tauri::AppHandle, kind: &str, payload_json: std::st
}
fn status_from_snapshot(
snapshot: kb_onchain_transport::WsSessionSnapshot,
snapshot: ks_onchain_transport::WsSessionSnapshot,
) -> crate::DemoWsStatusPayload {
let mut subscriptions = std::vec::Vec::new();
for subscription in &snapshot.subscriptions {
@@ -567,7 +567,7 @@ fn status_from_snapshot(
},
};
return crate::DemoWsStatusPayload {
connected: snapshot.state != kb_onchain_transport::WsSessionState::Disconnected,
connected: snapshot.state != ks_onchain_transport::WsSessionState::Disconnected,
endpoint_name: std::option::Option::Some(snapshot.endpoint_name),
endpoint_url: std::option::Option::Some(snapshot.endpoint_url),
method,
@@ -595,7 +595,7 @@ fn disconnected_status() -> crate::DemoWsStatusPayload {
}
fn build_ws_role_options(
snapshots: std::vec::Vec<kb_onchain_transport::WsPoolClientSnapshot>,
snapshots: std::vec::Vec<ks_onchain_transport::WsPoolClientSnapshot>,
) -> std::vec::Vec<crate::DemoWsRoleOption> {
let mut roles = std::collections::BTreeMap::<
std::string::String,
@@ -635,7 +635,7 @@ fn build_ws_method_options() -> std::vec::Vec<crate::DemoWsMethodOption> {
("voteSubscribe", ("Votes", false, false, false)),
]);
let mut options = std::vec::Vec::new();
for specification in &kb_onchain_transport::STANDARD_WS_SUBSCRIPTIONS {
for specification in &ks_onchain_transport::STANDARD_WS_SUBSCRIPTIONS {
let metadata = labels.get(specification.subscribe_method);
let (label, requires_target, requires_filter_json, supports_config_json) = match metadata {
std::option::Option::Some(metadata) => *metadata,
@@ -644,7 +644,7 @@ fn build_ws_method_options() -> std::vec::Vec<crate::DemoWsMethodOption> {
options.push(crate::DemoWsMethodOption {
method: specification.subscribe_method.to_string(),
unsubscribe_method: specification.unsubscribe_method.to_string(),
request_kind: kb_onchain_transport::request_kind_from_method(
request_kind: ks_onchain_transport::request_kind_from_method(
specification.subscribe_method,
),
label: label.to_string(),
@@ -661,7 +661,7 @@ fn build_standard_ws_request(
target: std::option::Option<std::string::String>,
filter_json: std::option::Option<std::string::String>,
config_json: std::option::Option<std::string::String>,
) -> std::result::Result<kb_onchain_transport::StandardWsRequest, std::string::String> {
) -> std::result::Result<ks_onchain_transport::StandardWsRequest, std::string::String> {
return match method {
"accountSubscribe" => {
let target = match required_target(target, method) {
@@ -669,7 +669,7 @@ fn build_standard_ws_request(
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let mut config = match parse_optional_json_as::<
kb_onchain_transport::WsAccountSubscribeConfig,
ks_onchain_transport::WsAccountSubscribeConfig,
>(config_json, "configJson")
{
std::result::Result::Ok(config) => config.unwrap_or_default(),
@@ -677,15 +677,15 @@ fn build_standard_ws_request(
};
if config.encoding.is_none() {
config.encoding =
std::option::Option::Some(kb_onchain_transport::RpcAccountEncoding::Base64);
std::option::Option::Some(ks_onchain_transport::RpcAccountEncoding::Base64);
}
if let std::result::Result::Err(error) =
reject_present(filter_json, "filterJson", method)
{
return std::result::Result::Err(error);
}
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Account(
kb_onchain_transport::AccountSubscribeRequest {
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Account(
ks_onchain_transport::AccountSubscribeRequest {
pubkey: target,
config: std::option::Option::Some(config),
},
@@ -695,44 +695,44 @@ fn build_standard_ws_request(
if let std::result::Result::Err(error) = reject_present(target, "target", method) {
return std::result::Result::Err(error);
}
let filter = match parse_required_json_as::<kb_onchain_transport::WsBlockFilter>(
let filter = match parse_required_json_as::<ks_onchain_transport::WsBlockFilter>(
filter_json,
"filterJson",
) {
std::result::Result::Ok(filter) => filter,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let config = match parse_optional_json_as::<kb_onchain_transport::WsBlockSubscribeConfig>(
let config = match parse_optional_json_as::<ks_onchain_transport::WsBlockSubscribeConfig>(
config_json,
"configJson",
) {
std::result::Result::Ok(config) => config,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Block(
kb_onchain_transport::BlockSubscribeRequest { filter, config },
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Block(
ks_onchain_transport::BlockSubscribeRequest { filter, config },
))
},
"logsSubscribe" => {
if let std::result::Result::Err(error) = reject_present(target, "target", method) {
return std::result::Result::Err(error);
}
let filter = match parse_required_json_as::<kb_onchain_transport::WsLogsFilter>(
let filter = match parse_required_json_as::<ks_onchain_transport::WsLogsFilter>(
filter_json,
"filterJson",
) {
std::result::Result::Ok(filter) => filter,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let config = match parse_optional_json_as::<kb_onchain_transport::WsLogsSubscribeConfig>(
let config = match parse_optional_json_as::<ks_onchain_transport::WsLogsSubscribeConfig>(
config_json,
"configJson",
) {
std::result::Result::Ok(config) => config,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Logs(
kb_onchain_transport::LogsSubscribeRequest { filter, config },
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Logs(
ks_onchain_transport::LogsSubscribeRequest { filter, config },
))
},
"programSubscribe" => {
@@ -746,7 +746,7 @@ fn build_standard_ws_request(
return std::result::Result::Err(error);
}
let mut config = match parse_optional_json_as::<
kb_onchain_transport::WsProgramSubscribeConfig,
ks_onchain_transport::WsProgramSubscribeConfig,
>(config_json, "configJson")
{
std::result::Result::Ok(config) => config.unwrap_or_default(),
@@ -754,10 +754,10 @@ fn build_standard_ws_request(
};
if config.encoding.is_none() {
config.encoding =
std::option::Option::Some(kb_onchain_transport::RpcAccountEncoding::Base64);
std::option::Option::Some(ks_onchain_transport::RpcAccountEncoding::Base64);
}
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Program(
kb_onchain_transport::ProgramSubscribeRequest {
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Program(
ks_onchain_transport::ProgramSubscribeRequest {
program_id: target,
config: std::option::Option::Some(config),
},
@@ -774,14 +774,14 @@ fn build_standard_ws_request(
return std::result::Result::Err(error);
}
let config = match parse_optional_json_as::<
kb_onchain_transport::WsSignatureSubscribeConfig,
ks_onchain_transport::WsSignatureSubscribeConfig,
>(config_json, "configJson")
{
std::result::Result::Ok(config) => config,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Signature(
kb_onchain_transport::SignatureSubscribeRequest { signature: target, config },
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Signature(
ks_onchain_transport::SignatureSubscribeRequest { signature: target, config },
))
},
"rootSubscribe" => {
@@ -790,8 +790,8 @@ fn build_standard_ws_request(
{
return std::result::Result::Err(error);
}
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Root(
kb_onchain_transport::RootSubscribeRequest,
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Root(
ks_onchain_transport::RootSubscribeRequest,
))
},
"slotSubscribe" => {
@@ -800,8 +800,8 @@ fn build_standard_ws_request(
{
return std::result::Result::Err(error);
}
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Slot(
kb_onchain_transport::SlotSubscribeRequest,
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Slot(
ks_onchain_transport::SlotSubscribeRequest,
))
},
"slotsUpdatesSubscribe" => {
@@ -810,8 +810,8 @@ fn build_standard_ws_request(
{
return std::result::Result::Err(error);
}
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::SlotsUpdates(
kb_onchain_transport::SlotsUpdatesSubscribeRequest,
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::SlotsUpdates(
ks_onchain_transport::SlotsUpdatesSubscribeRequest,
))
},
"voteSubscribe" => {
@@ -820,8 +820,8 @@ fn build_standard_ws_request(
{
return std::result::Result::Err(error);
}
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Vote(
kb_onchain_transport::VoteSubscribeRequest,
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Vote(
ks_onchain_transport::VoteSubscribeRequest,
))
},
_ => std::result::Result::Err(format!("unsupported standard WebSocket method '{method}'")),
@@ -930,30 +930,30 @@ mod tests {
std::option::Option::None,
);
let account = match account {
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Account(value)) => {
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Account(value)) => {
value
},
_ => panic!("accountSubscribe request was not built"),
};
assert_eq!(
account.config.and_then(|value| return value.encoding),
std::option::Option::Some(kb_onchain_transport::RpcAccountEncoding::Base64)
std::option::Option::Some(ks_onchain_transport::RpcAccountEncoding::Base64)
);
let program = super::build_standard_ws_request(
"programSubscribe",
std::option::Option::Some(kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID.to_string()),
std::option::Option::Some(ks_program_ids::SPL_TOKEN_2022_PROGRAM_ID.to_string()),
std::option::Option::None,
std::option::Option::Some(r#"{"encoding":"jsonParsed"}"#.to_string()),
);
let program = match program {
std::result::Result::Ok(kb_onchain_transport::StandardWsRequest::Program(value)) => {
std::result::Result::Ok(ks_onchain_transport::StandardWsRequest::Program(value)) => {
value
},
_ => panic!("programSubscribe request was not built"),
};
assert_eq!(
program.config.and_then(|value| return value.encoding),
std::option::Option::Some(kb_onchain_transport::RpcAccountEncoding::JsonParsed)
std::option::Option::Some(ks_onchain_transport::RpcAccountEncoding::JsonParsed)
);
}

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/main_window.rs
// version: 1
// version: 2
//! Main-window helpers and workspace README loading.
@@ -11,12 +11,12 @@ pub(crate) fn workspace_root_dir() -> std::path::PathBuf {
};
}
pub(crate) fn load_project_readme() -> kb_core::Result<std::string::String> {
pub(crate) fn load_project_readme() -> ks_core::Result<std::string::String> {
let path = crate::workspace_root_dir().join("README.md");
let content = match std::fs::read_to_string(&path) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::io(format!(
return std::result::Result::Err(ks_core::Error::io(format!(
"cannot read project README '{}': {error}",
path.display()
)));

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/tauri.rs
// version: 34
// version: 35
//! Tauri runtime assembly and private command wrappers.
@@ -9,7 +9,7 @@ use tauri::Manager; // rust-rules: trait-import
#[cfg_attr(mobile, tauri::mobile_entry_point)]
#[allow(clippy::question_mark_used)]
#[allow(clippy::question_mark)]
pub fn run() -> kb_core::Result<()> {
pub fn run() -> ks_core::Result<()> {
let rustls_result = install_default_rustls_provider();
if let std::result::Result::Err(error) = rustls_result {
return std::result::Result::Err(error);
@@ -131,20 +131,20 @@ pub fn run() -> kb_core::Result<()> {
let run_result = builder.run(tauri::generate_context!());
return match run_result {
std::result::Result::Ok(()) => std::result::Result::Ok(()),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::tauri(
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::tauri(
format!("cannot run desktop demo application: {error:?}"),
)),
};
}
fn install_default_rustls_provider() -> kb_core::Result<()> {
fn install_default_rustls_provider() -> ks_core::Result<()> {
if rustls::crypto::CryptoProvider::get_default().is_some() {
return std::result::Result::Ok(());
}
let provider_result = rustls::crypto::aws_lc_rs::default_provider().install_default();
return match provider_result {
std::result::Result::Ok(()) => std::result::Result::Ok(()),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::invalid_state(
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::invalid_state(
format!("cannot install default rustls crypto provider: {error:?}"),
)),
};
@@ -160,12 +160,12 @@ fn open_or_focus_demo_window(
if let std::option::Option::Some(window) = app_handle.get_webview_window(label) {
if let std::result::Result::Err(error) = window.show() {
return std::result::Result::Err(
kb_core::Error::tauri(format!("cannot show {label} window: {error}")).to_string(),
ks_core::Error::tauri(format!("cannot show {label} window: {error}")).to_string(),
);
}
if let std::result::Result::Err(error) = window.set_focus() {
return std::result::Result::Err(
kb_core::Error::tauri(format!("cannot focus {label} window: {error}")).to_string(),
ks_core::Error::tauri(format!("cannot focus {label} window: {error}")).to_string(),
);
}
return std::result::Result::Ok(());
@@ -185,12 +185,12 @@ fn open_or_focus_demo_window(
std::result::Result::Ok(window) => match window.set_focus() {
std::result::Result::Ok(()) => std::result::Result::Ok(()),
std::result::Result::Err(error) => std::result::Result::Err(
kb_core::Error::tauri(format!("cannot focus created {label} window: {error}"))
ks_core::Error::tauri(format!("cannot focus created {label} window: {error}"))
.to_string(),
),
},
std::result::Result::Err(error) => std::result::Result::Err(
kb_core::Error::tauri(format!("cannot create {label} window: {error}")).to_string(),
ks_core::Error::tauri(format!("cannot create {label} window: {error}")).to_string(),
),
};
}
@@ -256,7 +256,7 @@ fn open_demo_http_window(
#[tauri::command]
fn demo_http_list_pool_clients(
state: tauri::State<'_, crate::AppState>,
) -> std::vec::Vec<kb_onchain_transport::HttpPoolClientSnapshot> {
) -> std::vec::Vec<ks_onchain_transport::HttpPoolClientSnapshot> {
return crate::demo_http_list_pool_clients(state);
}
@@ -284,7 +284,7 @@ fn open_demo_ws_window(
fn demo_ws_list_pool_clients(
state: tauri::State<'_, crate::AppState>,
) -> std::result::Result<
std::vec::Vec<kb_onchain_transport::WsPoolClientSnapshot>,
std::vec::Vec<ks_onchain_transport::WsPoolClientSnapshot>,
std::string::String,
> {
return crate::demo_ws_list_pool_clients(state);

View File

@@ -1,98 +0,0 @@
// file: kb-lib/tests/external_materializer_api.rs
// version: 8
//! Downstream-style compilation contract for externally implemented materializers.
const ACCEPTED_FAMILIES: &[kb_lib::MdEventFamily] = &[kb_lib::MdEventFamily::Audit];
struct ExternalAuditMaterializer;
fn assert_event_materializer<Materializer: kb_lib::MtApiEventMaterializer>() {}
fn assert_legacy_materializer<Materializer: kb_lib::MtMaterializer>() {}
impl kb_lib::MtApiEventMaterializer for ExternalAuditMaterializer {
fn identity(&self) -> kb_lib::MtApiMaterializerIdentity {
return kb_lib::MtApiMaterializerIdentity {
name: "materializer.external.audit".to_string(),
version: "1".to_string(),
};
}
fn accepted_families(&self) -> &'static [kb_lib::MdEventFamily] {
return ACCEPTED_FAMILIES;
}
fn transaction_policy(
&self,
_family: kb_lib::MdEventFamily,
) -> kb_lib::MtApiMaterializationTransactionPolicy {
return kb_lib::MtApiMaterializationTransactionPolicy::SuccessfulOrFailedAudit;
}
fn materialize(
&self,
_observation: &kb_lib::DcApiDecodedObservation,
) -> kb_lib::MtApiMaterializerExecutionResult {
return kb_lib::MtApiMaterializerExecutionResult::ignored();
}
}
#[test]
fn external_materializer_uses_only_the_public_kb_lib_contract() {
let materializer: &dyn kb_lib::MtApiEventMaterializer = &ExternalAuditMaterializer;
assert_eq!(materializer.identity().name, "materializer.external.audit");
assert_eq!(materializer.accepted_families(), ACCEPTED_FAMILIES);
assert_event_materializer::<kb_lib::MtAdminMaterializer>();
assert_event_materializer::<kb_lib::MtBridgeMaterializer>();
assert_event_materializer::<kb_lib::MtComplianceAuditMaterializer>();
assert_event_materializer::<kb_lib::MtFeesMaterializer>();
assert_event_materializer::<kb_lib::MtGovernanceMaterializer>();
assert_event_materializer::<kb_lib::MtLendingMaterializer>();
assert_event_materializer::<kb_lib::MtLifecycleMaterializer>();
assert_event_materializer::<kb_lib::MtMetadataMetaplexTokenMetadataMaterializer>();
assert_event_materializer::<kb_lib::MtMetadataSolanaProgramMaterializer>();
assert_event_materializer::<kb_lib::MtMetadataToken2022Materializer>();
assert_event_materializer::<kb_lib::MtLiquidityMaterializer>();
assert_event_materializer::<kb_lib::MtNftMaterializer>();
assert_event_materializer::<kb_lib::MtOracleMaterializer>();
assert_event_materializer::<kb_lib::MtOrderbookMaterializer>();
assert_event_materializer::<kb_lib::MtPerpetualsMaterializer>();
assert_event_materializer::<kb_lib::MtPoolStateMaterializer>();
assert_event_materializer::<kb_lib::MtRewardsMaterializer>();
assert_event_materializer::<kb_lib::MtRiskMaterializer>();
assert_event_materializer::<kb_lib::MtRoutingMaterializer>();
assert_event_materializer::<kb_lib::MtStakingMaterializer>();
assert_event_materializer::<kb_lib::MtTokenAccountsMaterializer>();
assert_event_materializer::<kb_lib::MtTokenMetadataRiskMaterializer>();
assert_event_materializer::<kb_lib::MtTradesMaterializer>();
assert_event_materializer::<kb_lib::MtTransactionAnnotationMaterializer>();
assert_event_materializer::<kb_lib::MtVaultMaterializer>();
assert_legacy_materializer::<kb_lib::MtBridgeMaterializer>();
assert_legacy_materializer::<kb_lib::MtGovernanceMaterializer>();
assert_legacy_materializer::<kb_lib::MtLendingMaterializer>();
assert_legacy_materializer::<kb_lib::MtLiquidityMaterializer>();
assert_legacy_materializer::<kb_lib::MtMetadataMetaplexTokenMetadataMaterializer>();
assert_legacy_materializer::<kb_lib::MtMetadataSolanaProgramMaterializer>();
assert_legacy_materializer::<kb_lib::MtMetadataToken2022Materializer>();
assert_legacy_materializer::<kb_lib::MtNftMaterializer>();
assert_legacy_materializer::<kb_lib::MtOracleMaterializer>();
assert_legacy_materializer::<kb_lib::MtOrderbookMaterializer>();
assert_legacy_materializer::<kb_lib::MtPerpetualsMaterializer>();
assert_legacy_materializer::<kb_lib::MtPoolStateMaterializer>();
assert_legacy_materializer::<kb_lib::MtRewardsMaterializer>();
assert_legacy_materializer::<kb_lib::MtRoutingMaterializer>();
assert_legacy_materializer::<kb_lib::MtTokenMetadataRiskMaterializer>();
assert_legacy_materializer::<kb_lib::MtTradesMaterializer>();
assert_legacy_materializer::<kb_lib::MtVaultMaterializer>();
let _ = kb_lib::materializer_admin_materialize_elgamal_registry_state_snapshot;
let _ = kb_lib::materializer_metadata_materialize_metaplex_account_snapshot;
let _ = kb_lib::materializer_metadata_materialize_metaplex_metadata_snapshot;
let _ = kb_lib::materializer_metadata_materialize_solana_program_metadata_account_snapshot;
let _ = kb_lib::materializer_metadata_materialize_solana_program_metadata_buffer_snapshot;
let _ = kb_lib::materializer_metadata_materialize_solana_program_metadata_metadata_snapshot;
let _ = kb_lib::materializer_admin_materialize_token_2022_state_snapshots;
let _ = kb_lib::materializer_fees_materialize_token_2022_state_snapshots;
let _ = kb_lib::materializer_metadata_materialize_token_2022_snapshot;
let _ = kb_lib::materializer_token_materialize_token_2022_state_snapshot;
}

View File

@@ -1,34 +0,0 @@
// file: kb-lib/tests/external_metaplex_token_metadata_executor_api.rs
// version: 1
//! Downstream-style compilation contract for the Metaplex Token Metadata executor.
#[test]
fn external_consumers_inspect_metaplex_executor_capabilities_only_through_crate_root_exports() {
let executor = kb_lib::ExMetadataMetaplexTokenMetadataExecutor;
let program_id = kb_lib::MdProgramId(
kb_program_ids::METADATA_METAPLEX_TOKEN_METADATA_PROGRAM_ID.to_string(),
);
assert_eq!(kb_lib::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES.len(), 35);
assert_eq!(kb_lib::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES.len(), 15);
for operation_code in kb_lib::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES {
let capability = kb_lib::ExApiTypedInstructionExecutor::capability(
&executor,
&program_id,
operation_code,
);
assert!(capability.is_supported());
}
for operation_code in kb_lib::EX_METAPLEX_TOKEN_METADATA_DEPRECATED_OPERATION_CODES {
assert!(
kb_lib::EX_METAPLEX_TOKEN_METADATA_SUPPORTED_OPERATION_CODES.contains(operation_code)
);
}
let foreign_program_id = kb_lib::MdProgramId(kb_program_ids::SYSTEM_PROGRAM_ID.to_string());
let foreign_capability = kb_lib::ExApiTypedInstructionExecutor::capability(
&executor,
&foreign_program_id,
kb_lib::EX_METAPLEX_TOKEN_METADATA_CREATE_OPERATION,
);
assert!(!foreign_capability.is_supported());
}

View File

@@ -1,30 +0,0 @@
// file: kb-lib/tests/external_solana_program_metadata_model_api.rs
// version: 1
//! Downstream-style compilation contract for Solana Program Metadata models.
#[test]
fn external_consumers_use_only_crate_root_model_exports() {
let seed_result = kb_lib::DcMetadataSpmSeed::from_utf8("idl");
assert!(seed_result.is_ok());
let seed;
if let std::result::Result::Ok(value) = seed_result {
seed = value;
} else {
return;
}
assert_eq!(seed.trimmed_utf8(), std::result::Result::Ok("idl"));
assert_eq!(seed.as_bytes().len(), kb_lib::DC_METADATA_SPM_SEED_BYTES);
let external = kb_lib::DcMetadataSpmExternalData::from_zeroable_length(
solana_pubkey::Pubkey::new_from_array([9_u8; 32]),
4,
8,
);
let data = kb_lib::DcMetadataSpmData::External(external);
assert_eq!(data.source(), kb_lib::DcMetadataSpmDataSource::External);
assert_eq!(data.wire_length_u32(), std::result::Result::Ok(40),);
assert_eq!(kb_lib::DcMetadataSpmProgramError::InvalidDataLength.code(), 4);
assert_eq!(kb_lib::DC_METADATA_SPM_BUFFER_HEADER_BYTES, 96);
assert_eq!(kb_lib::DC_METADATA_SPM_METADATA_HEADER_BYTES, 96);
assert_eq!(kb_lib::DC_METADATA_SPM_EXTERNAL_DATA_BYTES, 40);
}

View File

@@ -1,5 +0,0 @@
// file: kb-logging/src/constants.rs
// version: 2
/// Canonical tracing target for this crate.
pub(crate) const TRACING_TARGET: &str = "kb-logging";

View File

@@ -1,7 +0,0 @@
// file: kb-pipeline/src/constants.rs
// version: 2
//! Pipeline constants.
/// Canonical tracing target for pipeline orchestration.
pub(crate) const TRACING_TARGET: &str = "kb-pipeline";

View File

@@ -1,42 +0,0 @@
// file: kb-pipeline/tests/external_metadata_token_2022_pipeline_api.rs
// version: 1
//! External-only coverage for the public Token-2022 Token Metadata pipeline contract.
#[test]
fn external_consumers_use_only_public_token_2022_metadata_pipeline_exports() {
let account = kb_lib::MdPubkey(solana_pubkey::Pubkey::new_from_array([9_u8; 32]).to_string());
let request = kb_pipeline::Token2022StatefulReadRequest {
query_role: "rpc".to_string(),
account: account.clone(),
kind: kb_lib::DcToken2022StateKind::Mint,
min_context_slot: std::option::Option::Some(42),
max_data_bytes: kb_pipeline::MAX_TOKEN_2022_STATEFUL_ACCOUNT_BYTES,
context: kb_pipeline::Token2022StatefulContext::default(),
};
assert_eq!(request.account, account);
assert_eq!(request.kind, kb_lib::DcToken2022StateKind::Mint);
assert!(
kb_pipeline::validate_token_2022_metadata_emit_range(
std::option::Option::Some(0),
std::option::Option::Some(32),
)
.is_ok()
);
let _emit_inspector: fn(
&kb_lib::ExApiExecutionSimulationResult,
std::option::Option<u64>,
std::option::Option<u64>,
) -> kb_core::Result<kb_pipeline::Token2022MetadataEmitEvidence> =
kb_pipeline::inspect_token_2022_metadata_emit_simulation;
let _authority_inspector: fn(
&kb_lib::MdPubkey,
std::option::Option<&kb_lib::MdPubkey>,
&kb_pipeline::Token2022StatefulSnapshotBundle,
) -> kb_pipeline::Token2022ExecutionPostcondition =
kb_pipeline::inspect_token_2022_metadata_authority_postcondition;
const {
assert!(kb_pipeline::MAX_TOKEN_2022_METADATA_EMIT_BYTES > 0);
assert!(kb_pipeline::MAX_TOKEN_2022_STATEFUL_ACCOUNT_BYTES > 0);
}
}

View File

@@ -1,7 +0,0 @@
// file: kb-store/src/constants.rs
// version: 1
//! Local constants for the `kb-store` crate.
/// Canonical tracing target for this crate.
pub(crate) const TRACING_TARGET: &str = "kb-store";

View File

@@ -1,7 +1,13 @@
<!-- file: kb-config/CHANGELOG.md -->
<!-- version: 11 -->
<!-- file: ks-config/CHANGELOG.md -->
<!-- version: 12 -->
# CHANGELOG — kb-config
# CHANGELOG — ks-config
## `0.5.1-pre.002`
- renomme `kb-config` en `ks-config` et l'identifiant Rust `kb_config` en `ks_config` ;
- met à jour les chemins TS-RS source vers `frontend/ts/bindings/ks_config` sans livrer les bindings générés ;
- conserve le format de configuration et les variables d'environnement historiques jusqu'aux prereleases dédiées.
## `0.5.0-pre.002`
@@ -17,7 +23,7 @@
## 0.1.0-pre.075
- validation statique que `kb-config` reste lunique propriétaire direct de `dotenvy` ;
- validation statique que `ks-config` reste lunique propriétaire direct de `dotenvy` ;
## 0.1.0-pre.073
@@ -47,14 +53,14 @@
### Migré
- migration et consolidation de la configuration typée bot2 dans `kb-config` ;
- migration et consolidation de la configuration typée bot2 dans `ks-config` ;
- conservation du schéma JSON, des profils, endpoints, listeners, paramètres de stockage, logging, wallet et exécution.
### Modifié
- adoption des règles Rust 2024 et Khadhroony ;
- export TypeScript contrôlé des types destinés au frontend ;
- validation structurée par `kb_core::Error`.
- validation structurée par `ks_core::Error`.
### Validation

View File

@@ -1,8 +1,8 @@
# file: kb-config/Cargo.toml
# version: 3
# file: ks-config/Cargo.toml
# version: 4
[package]
name = "kb-config"
name = "ks-config"
version.workspace = true
edition.workspace = true
license.workspace = true
@@ -10,7 +10,7 @@ publish.workspace = true
[dependencies]
dotenvy.workspace = true
kb-core = { path = "../kb-core" }
ks-core = { path = "../ks-core" }
jsonschema.workspace = true
serde.workspace = true
serde_json.workspace = true

View File

@@ -1,9 +1,9 @@
<!-- file: kb-config/README.md -->
<!-- version: 5 -->
<!-- file: ks-config/README.md -->
<!-- version: 6 -->
# kb-config
# ks-config
`kb-config` définit le contrat de configuration typé du workspace, son schéma JSON embarqué et les fonctions de chargement, résolution denvironnement, validation et sérialisation.
`ks-config` définit le contrat de configuration typé du workspace, son schéma JSON embarqué et les fonctions de chargement, résolution denvironnement, validation et sérialisation.
## Responsabilités
@@ -25,8 +25,8 @@ Les principales fonctions sont `read_config_json_file_with_environment`, `parse_
## Relations
- dépend de `kb-core` pour les erreurs structurées ;
- alimente `kb-logging`, `kb-store`, `kb-onchain-transport`, `kb-pipeline`, `kb-wallet` et les applications ;
- dépend de `ks-core` pour les erreurs structurées ;
- alimente `ks-logging`, `ks-store`, `ks-onchain-transport`, `ks-pipeline`, `ks-wallet` et les applications ;
- utilise [`../config/example.config.json`](../config/example.config.json) et [`../config/schema.config.json`](../config/schema.config.json) comme exemple utilisateur et contrat de schéma actifs.
## Statut

View File

@@ -1,7 +1,7 @@
<!-- file: kb-config/TODO.md -->
<!-- version: 4 -->
<!-- file: ks-config/TODO.md -->
<!-- version: 5 -->
# TODO — kb-config
# TODO — ks-config
## Série `0.5.x`

View File

@@ -1,12 +1,12 @@
<!-- file: kb-config/USAGE.md -->
<!-- version: 4 -->
<!-- file: ks-config/USAGE.md -->
<!-- version: 5 -->
# Utilisation de kb-config
# Utilisation de ks-config
## Chargement recommandé
```rust
let config_result = kb_config::read_config_json_file_with_environment(
let config_result = ks_config::read_config_json_file_with_environment(
std::path::Path::new("config/example.config.json"),
std::path::Path::new("."),
);
@@ -14,7 +14,7 @@ let config = match config_result {
Ok(value) => value,
Err(error) => return Err(error),
};
let profile = match kb_config::active_profile(&config) {
let profile = match ks_config::active_profile(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
@@ -25,7 +25,7 @@ Cette fonction charge lenvironnement du workspace, résout les placeholders p
## Chargement de lenvironnement
```rust
let report = match kb_config::load_workspace_environment(std::path::Path::new(".")) {
let report = match ks_config::load_workspace_environment(std::path::Path::new(".")) {
Ok(value) => value,
Err(error) => return Err(error),
};
@@ -41,7 +41,7 @@ for path in report.loaded_files {
```rust
let raw = r#"{"databaseUrl":"${KB_DATABASE_URL:-postgres://localhost/kb}"}"#;
let resolved = kb_config::resolve_environment_placeholders(raw);
let resolved = ks_config::resolve_environment_placeholders(raw);
assert!(resolved.contains("databaseUrl"));
```
@@ -51,14 +51,14 @@ Cette API retourne actuellement une chaîne résolue ordinaire et peut donc cont
## Validation et parsing
```rust
if let Err(error) = kb_config::validate_config_json_schema(raw_json) {
if let Err(error) = ks_config::validate_config_json_schema(raw_json) {
return Err(error);
}
let config = match kb_config::parse_config_json(raw_json) {
let config = match ks_config::parse_config_json(raw_json) {
Ok(value) => value,
Err(error) => return Err(error),
};
if let Err(error) = kb_config::validate_config(&config) {
if let Err(error) = ks_config::validate_config(&config) {
return Err(error);
}
```
@@ -68,18 +68,18 @@ if let Err(error) = kb_config::validate_config(&config) {
## Sérialisation
```rust
let compact = match kb_config::serialize_config_json(&config) {
let compact = match ks_config::serialize_config_json(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
let pretty = match kb_config::serialize_config_json_pretty(&config) {
let pretty = match ks_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(
return Err(ks_core::Error::new(
"config_write_failed",
format!("cannot write generated configuration: {error}"),
));
@@ -91,8 +91,8 @@ La configuration est validée avant sérialisation.
## Schéma embarqué
```rust
let schema_text = kb_config::config_json_schema_text();
let schema_value = match kb_config::config_json_schema_value() {
let schema_text = ks_config::config_json_schema_text();
let schema_value = match ks_config::config_json_schema_value() {
Ok(value) => value,
Err(error) => return Err(error),
};
@@ -110,7 +110,7 @@ Le schéma actif est aussi disponible sous [`../config/schema.config.json`](../c
## Sélection du profil actif
```rust
let profile = match kb_config::active_profile(&config) {
let profile = match ks_config::active_profile(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
@@ -131,7 +131,7 @@ println!("websocket endpoints: {}", profile.solana.ws_endpoints.len());
## Erreurs et invariants
Les erreurs utilisent `kb_core::Error` avec un code stable. Les validations couvrent notamment lunicité des profils, lexistence du profil actif, les URLs, les rôles dendpoints, les limites dexécution, les routes de logging et les contraintes wallet.
Les erreurs utilisent `ks_core::Error` avec un code stable. Les validations couvrent notamment lunicité des profils, lexistence du profil actif, les URLs, les rôles dendpoints, les limites dexécution, les routes de logging et les contraintes wallet.
## Tests instructifs

View File

@@ -1,5 +1,5 @@
// file: kb-config/src/environment.rs
// version: 3
// file: ks-config/src/environment.rs
// version: 4
//! Environment-file loading and configuration placeholder resolution.
@@ -16,7 +16,7 @@ pub struct EnvironmentLoadReport {
/// fallback text declared with `${NAME:-fallback}` placeholders.
pub fn load_workspace_environment(
workspace_root: &std::path::Path,
) -> kb_core::Result<EnvironmentLoadReport> {
) -> ks_core::Result<EnvironmentLoadReport> {
let explicit_path = std::env::var("KB_ENV_FILE").ok();
let selected_path = match explicit_path {
std::option::Option::Some(path) if !path.trim().is_empty() => {
@@ -32,7 +32,7 @@ pub fn load_workspace_environment(
std::result::Result::Ok(()) => std::result::Result::Ok(EnvironmentLoadReport {
loaded_path: std::option::Option::Some(selected_path),
}),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new(
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::new(
"config_env_file_load_failed",
format!("{}: {error}", selected_path.display()),
)),

View File

@@ -1,5 +1,5 @@
// file: kb-config/src/lib.rs
// version: 4
// file: ks-config/src/lib.rs
// version: 5
//! Khadhroony Bot3 workspace configuration contract and loading helpers.
#![warn(missing_docs)]

View File

@@ -1,5 +1,5 @@
// file: kb-config/src/settings.rs
// version: 17
// file: ks-config/src/settings.rs
// version: 18
//! Typed configuration models shared by applications and workers.
@@ -9,7 +9,7 @@ const CONFIG_JSON_SCHEMA: &str = include_str!("../../config/schema.config.json")
/// Root configuration containing every named profile.
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(export, export_to = "../frontend/ts/bindings/kb_config/settings/AppConfig.ts")]
#[ts(export, export_to = "../frontend/ts/bindings/ks_config/settings/AppConfig.ts")]
pub struct AppConfig {
/// Active profile name.
pub active_profile: std::string::String,
@@ -21,7 +21,7 @@ pub struct AppConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/ProfileConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/ProfileConfig.ts"
)]
pub struct ProfileConfig {
/// Profile code.
@@ -48,7 +48,7 @@ pub struct ProfileConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/AppSectionConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/AppSectionConfig.ts"
)]
pub struct AppSectionConfig {
/// Application name.
@@ -63,7 +63,7 @@ pub struct AppSectionConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/LoggingConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/LoggingConfig.ts"
)]
pub struct LoggingConfig {
/// Default log level.
@@ -78,7 +78,7 @@ pub struct LoggingConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/LogTargetConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/LogTargetConfig.ts"
)]
pub struct LogTargetConfig {
/// Output target name.
@@ -105,7 +105,7 @@ pub struct LogTargetConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/LogTargetFilterConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/LogTargetFilterConfig.ts"
)]
pub struct LogTargetFilterConfig {
/// Tracing target or crate prefix.
@@ -118,7 +118,7 @@ pub struct LogTargetFilterConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/DatabaseConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/DatabaseConfig.ts"
)]
pub struct DatabaseConfig {
/// Enables database storage.
@@ -135,7 +135,7 @@ pub struct DatabaseConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/PostgresConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/PostgresConfig.ts"
)]
pub struct PostgresConfig {
/// PostgreSQL URL or local placeholder.
@@ -151,7 +151,7 @@ pub struct PostgresConfig {
/// SQLite backend configuration.
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(export, export_to = "../frontend/ts/bindings/kb_config/settings/SqliteConfig.ts")]
#[ts(export, export_to = "../frontend/ts/bindings/ks_config/settings/SqliteConfig.ts")]
pub struct SqliteConfig {
/// SQLite database path.
pub path: std::string::String,
@@ -170,7 +170,7 @@ pub struct SqliteConfig {
/// Local data directory configuration.
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(export, export_to = "../frontend/ts/bindings/kb_config/settings/DataConfig.ts")]
#[ts(export, export_to = "../frontend/ts/bindings/ks_config/settings/DataConfig.ts")]
pub struct DataConfig {
/// Wallet directory path.
pub wallets_directory: std::string::String,
@@ -180,7 +180,7 @@ pub struct DataConfig {
/// Solana endpoints and listener configuration.
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(export, export_to = "../frontend/ts/bindings/kb_config/settings/SolanaConfig.ts")]
#[ts(export, export_to = "../frontend/ts/bindings/ks_config/settings/SolanaConfig.ts")]
pub struct SolanaConfig {
/// HTTP JSON-RPC endpoints.
pub http_endpoints: std::vec::Vec<HttpEndpointConfig>,
@@ -194,7 +194,7 @@ pub struct SolanaConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/HttpEndpointConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/HttpEndpointConfig.ts"
)]
pub struct HttpEndpointConfig {
/// Endpoint name.
@@ -223,7 +223,7 @@ pub struct HttpEndpointConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/WsEndpointConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/WsEndpointConfig.ts"
)]
pub struct WsEndpointConfig {
/// Endpoint name.
@@ -259,7 +259,7 @@ pub struct WsEndpointConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/EndpointRoleConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/EndpointRoleConfig.ts"
)]
pub struct EndpointRoleConfig {
/// Role code used by endpoint pools.
@@ -287,7 +287,7 @@ pub struct EndpointRoleConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/ListenerConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/ListenerConfig.ts"
)]
pub struct ListenerConfig {
/// Enables listener creation.
@@ -306,7 +306,7 @@ pub struct ListenerConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/LogListenerConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/LogListenerConfig.ts"
)]
pub struct LogListenerConfig {
/// Listener name.
@@ -325,7 +325,7 @@ pub struct LogListenerConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/ProgramListenerConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/ProgramListenerConfig.ts"
)]
pub struct ProgramListenerConfig {
/// Listener name.
@@ -344,7 +344,7 @@ pub struct ProgramListenerConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/AccountListenerConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/AccountListenerConfig.ts"
)]
pub struct AccountListenerConfig {
/// Listener name.
@@ -361,7 +361,7 @@ pub struct AccountListenerConfig {
/// Wallet configuration.
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(export, export_to = "../frontend/ts/bindings/kb_config/settings/WalletConfig.ts")]
#[ts(export, export_to = "../frontend/ts/bindings/ks_config/settings/WalletConfig.ts")]
pub struct WalletConfig {
/// Wallet directory path.
pub wallet_dir: std::string::String,
@@ -387,7 +387,7 @@ pub struct WalletConfig {
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/kb_config/settings/ExecutionConfig.ts"
export_to = "../frontend/ts/bindings/ks_config/settings/ExecutionConfig.ts"
)]
pub struct ExecutionConfig {
/// Enables dry-run for newly prepared execution policies.
@@ -431,7 +431,7 @@ pub struct ExecutionConfig {
/// Demo application configuration.
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, TS)]
#[ts(export, export_to = "../frontend/ts/bindings/kb_config/settings/DemoConfig.ts")]
#[ts(export, export_to = "../frontend/ts/bindings/ks_config/settings/DemoConfig.ts")]
pub struct DemoConfig {
/// Enables live demo pages.
pub live_demo_enabled: bool,
@@ -445,11 +445,11 @@ pub fn config_json_schema_text() -> &'static str {
}
/// Parses the embedded JSON Schema into a JSON value.
pub fn config_json_schema_value() -> kb_core::Result<serde_json::Value> {
pub fn config_json_schema_value() -> ks_core::Result<serde_json::Value> {
let schema_result = serde_json::from_str::<serde_json::Value>(CONFIG_JSON_SCHEMA);
return match schema_result {
std::result::Result::Ok(schema) => std::result::Result::Ok(schema),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new(
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::new(
"config_schema_parse_failed",
error.to_string(),
)),
@@ -457,7 +457,7 @@ pub fn config_json_schema_value() -> kb_core::Result<serde_json::Value> {
}
/// Validates a raw JSON configuration string against the embedded JSON Schema.
pub fn validate_config_json_schema(raw_json: &str) -> kb_core::Result<()> {
pub fn validate_config_json_schema(raw_json: &str) -> ks_core::Result<()> {
let schema = match config_json_schema_value() {
std::result::Result::Ok(schema) => schema,
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -465,7 +465,7 @@ pub fn validate_config_json_schema(raw_json: &str) -> kb_core::Result<()> {
let instance = match serde_json::from_str::<serde_json::Value>(raw_json) {
std::result::Result::Ok(instance) => instance,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"config_json_parse_failed",
error.to_string(),
));
@@ -474,7 +474,7 @@ pub fn validate_config_json_schema(raw_json: &str) -> kb_core::Result<()> {
let validator = match jsonschema::validator_for(&schema) {
std::result::Result::Ok(validator) => validator,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"config_schema_compile_failed",
error.to_string(),
));
@@ -483,7 +483,7 @@ pub fn validate_config_json_schema(raw_json: &str) -> kb_core::Result<()> {
let validation_result = validator.validate(&instance);
return match validation_result {
std::result::Result::Ok(()) => std::result::Result::Ok(()),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new(
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::new(
"config_json_schema_validation_failed",
error.to_string(),
)),
@@ -491,7 +491,7 @@ pub fn validate_config_json_schema(raw_json: &str) -> kb_core::Result<()> {
}
/// Parses the application configuration from a JSON string and validates it.
pub fn parse_config_json(raw_json: &str) -> kb_core::Result<AppConfig> {
pub fn parse_config_json(raw_json: &str) -> ks_core::Result<AppConfig> {
match validate_config_json_schema(raw_json) {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -499,7 +499,7 @@ pub fn parse_config_json(raw_json: &str) -> kb_core::Result<AppConfig> {
let config = match serde_json::from_str::<AppConfig>(raw_json) {
std::result::Result::Ok(config) => config,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"config_json_decode_failed",
error.to_string(),
));
@@ -512,11 +512,11 @@ pub fn parse_config_json(raw_json: &str) -> kb_core::Result<AppConfig> {
}
/// Reads and parses the application configuration from a filesystem path.
pub fn read_config_json_file(path: &std::path::Path) -> kb_core::Result<AppConfig> {
pub fn read_config_json_file(path: &std::path::Path) -> ks_core::Result<AppConfig> {
let raw_json = match std::fs::read_to_string(path) {
std::result::Result::Ok(content) => content,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"config_file_read_failed",
error.to_string(),
));
@@ -529,7 +529,7 @@ pub fn read_config_json_file(path: &std::path::Path) -> kb_core::Result<AppConfi
pub fn read_config_json_file_with_environment(
path: &std::path::Path,
workspace_root: &std::path::Path,
) -> kb_core::Result<AppConfig> {
) -> ks_core::Result<AppConfig> {
match crate::load_workspace_environment(workspace_root) {
std::result::Result::Ok(_) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -537,7 +537,7 @@ pub fn read_config_json_file_with_environment(
let raw_json = match std::fs::read_to_string(path) {
std::result::Result::Ok(content) => content,
std::result::Result::Err(error) => {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"config_file_read_failed",
error.to_string(),
));
@@ -548,14 +548,14 @@ pub fn read_config_json_file_with_environment(
}
/// Serializes a configuration value to compact JSON.
pub fn serialize_config_json(config: &AppConfig) -> kb_core::Result<std::string::String> {
pub fn serialize_config_json(config: &AppConfig) -> ks_core::Result<std::string::String> {
match validate_config(config) {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
return match serde_json::to_string(config) {
std::result::Result::Ok(serialized) => std::result::Result::Ok(serialized),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new(
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::new(
"config_json_serialize_failed",
error.to_string(),
)),
@@ -563,14 +563,14 @@ pub fn serialize_config_json(config: &AppConfig) -> kb_core::Result<std::string:
}
/// Serializes a configuration value to pretty JSON.
pub fn serialize_config_json_pretty(config: &AppConfig) -> kb_core::Result<std::string::String> {
pub fn serialize_config_json_pretty(config: &AppConfig) -> ks_core::Result<std::string::String> {
match validate_config(config) {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
return match serde_json::to_string_pretty(config) {
std::result::Result::Ok(serialized) => std::result::Result::Ok(serialized),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::new(
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::new(
"config_json_pretty_serialize_failed",
error.to_string(),
)),
@@ -578,20 +578,20 @@ pub fn serialize_config_json_pretty(config: &AppConfig) -> kb_core::Result<std::
}
/// Returns the active profile declared by the root configuration.
pub fn active_profile(config: &AppConfig) -> kb_core::Result<&ProfileConfig> {
pub fn active_profile(config: &AppConfig) -> ks_core::Result<&ProfileConfig> {
for profile in &config.profiles {
if profile.name == config.active_profile {
return std::result::Result::Ok(profile);
}
}
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"active_profile_not_found",
config.active_profile.clone(),
));
}
/// Validates a typed configuration after JSON Schema validation and deserialization.
pub fn validate_config(config: &AppConfig) -> kb_core::Result<()> {
pub fn validate_config(config: &AppConfig) -> ks_core::Result<()> {
match validate_root_config(config) {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -608,13 +608,13 @@ pub fn validate_config(config: &AppConfig) -> kb_core::Result<()> {
};
}
fn validate_root_config(config: &AppConfig) -> kb_core::Result<()> {
fn validate_root_config(config: &AppConfig) -> ks_core::Result<()> {
match require_non_empty(&config.active_profile, "active_profile") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if config.profiles.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"config_profiles_empty",
"at least one profile is required",
));
@@ -627,7 +627,7 @@ fn validate_root_config(config: &AppConfig) -> kb_core::Result<()> {
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if !names.insert(profile.name.clone()) {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"profile_name_duplicate",
profile.name.clone(),
));
@@ -637,7 +637,7 @@ fn validate_root_config(config: &AppConfig) -> kb_core::Result<()> {
}
}
if active_count != 1 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"active_profile_count_invalid",
format!("active profile '{}' must match exactly one profile", config.active_profile),
));
@@ -645,7 +645,7 @@ fn validate_root_config(config: &AppConfig) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_profile(profile: &ProfileConfig) -> kb_core::Result<()> {
fn validate_profile(profile: &ProfileConfig) -> ks_core::Result<()> {
match validate_app_section(&profile.app) {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -677,7 +677,7 @@ fn validate_profile(profile: &ProfileConfig) -> kb_core::Result<()> {
return validate_wallet_execution_pair(&profile.wallet, &profile.execution);
}
fn validate_app_section(config: &AppSectionConfig) -> kb_core::Result<()> {
fn validate_app_section(config: &AppSectionConfig) -> ks_core::Result<()> {
match require_non_empty(&config.name, "app.name") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -685,13 +685,13 @@ fn validate_app_section(config: &AppSectionConfig) -> kb_core::Result<()> {
return require_non_empty(&config.environment, "app.environment");
}
fn validate_logging(config: &LoggingConfig) -> kb_core::Result<()> {
fn validate_logging(config: &LoggingConfig) -> ks_core::Result<()> {
match validate_log_level(&config.default_level, "logging.default_level") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if config.targets.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_targets_empty",
"at least one logging target is required",
));
@@ -703,7 +703,7 @@ fn validate_logging(config: &LoggingConfig) -> kb_core::Result<()> {
enabled_count += 1;
}
if !names.insert(target.name.clone()) {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_target_duplicate",
target.name.clone(),
));
@@ -724,7 +724,7 @@ fn validate_logging(config: &LoggingConfig) -> kb_core::Result<()> {
}
}
if enabled_count == 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_no_enabled_targets",
"at least one logging target must be enabled",
));
@@ -732,7 +732,7 @@ fn validate_logging(config: &LoggingConfig) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_log_target(config: &LogTargetConfig) -> kb_core::Result<()> {
fn validate_log_target(config: &LogTargetConfig) -> ks_core::Result<()> {
match require_non_empty(&config.name, "logging.targets.name") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -742,7 +742,7 @@ fn validate_log_target(config: &LogTargetConfig) -> kb_core::Result<()> {
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if config.sink != "console" && config.sink != "file" {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_sink_invalid",
config.sink.clone(),
));
@@ -752,7 +752,7 @@ fn validate_log_target(config: &LogTargetConfig) -> kb_core::Result<()> {
&& config.rotation != "daily"
&& config.rotation != "hourly"
{
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_rotation_invalid",
config.rotation.clone(),
));
@@ -762,19 +762,19 @@ fn validate_log_target(config: &LogTargetConfig) -> kb_core::Result<()> {
&& config.format != "pretty"
&& config.format != "json"
{
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_format_invalid",
config.format.clone(),
));
}
if config.sink == "file" && config.path.trim().is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_file_path_empty",
config.name.clone(),
));
}
if config.sink == "console" && !config.path.trim().is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"logging_console_path_not_empty",
config.name.clone(),
));
@@ -788,9 +788,9 @@ fn validate_log_target(config: &LogTargetConfig) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_database(config: &DatabaseConfig) -> kb_core::Result<()> {
fn validate_database(config: &DatabaseConfig) -> ks_core::Result<()> {
if config.backend != "postgres" && config.backend != "sqlite" {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"database_backend_invalid",
config.backend.clone(),
));
@@ -800,13 +800,13 @@ fn validate_database(config: &DatabaseConfig) -> kb_core::Result<()> {
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if config.postgres.max_connections == 0 || config.sqlite.max_connections == 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"database_max_connections_zero",
"database connection limits must be greater than zero",
));
}
if config.postgres.connect_timeout_ms == 0 || config.sqlite.busy_timeout_ms == 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"database_timeout_zero",
"database timeouts must be greater than zero",
));
@@ -814,7 +814,7 @@ fn validate_database(config: &DatabaseConfig) -> kb_core::Result<()> {
return require_non_empty(&config.sqlite.path, "database.sqlite.path");
}
fn validate_data(config: &DataConfig) -> kb_core::Result<()> {
fn validate_data(config: &DataConfig) -> ks_core::Result<()> {
match require_non_empty(&config.wallets_directory, "data.wallets_directory") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -822,15 +822,15 @@ fn validate_data(config: &DataConfig) -> kb_core::Result<()> {
return require_non_empty(&config.logs_directory, "data.logs_directory");
}
fn validate_solana(config: &SolanaConfig) -> kb_core::Result<()> {
fn validate_solana(config: &SolanaConfig) -> ks_core::Result<()> {
if config.http_endpoints.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"http_endpoints_empty",
"at least one HTTP JSON-RPC endpoint is required",
));
}
if config.ws_endpoints.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"ws_endpoints_empty",
"at least one standard Solana WebSocket endpoint is required",
));
@@ -838,7 +838,7 @@ fn validate_solana(config: &SolanaConfig) -> kb_core::Result<()> {
let mut http_names = std::collections::BTreeSet::<std::string::String>::new();
for endpoint in &config.http_endpoints {
if !http_names.insert(endpoint.name.clone()) {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"http_endpoint_duplicate",
endpoint.name.clone(),
));
@@ -851,7 +851,7 @@ fn validate_solana(config: &SolanaConfig) -> kb_core::Result<()> {
let mut ws_names = std::collections::BTreeSet::<std::string::String>::new();
for endpoint in &config.ws_endpoints {
if !ws_names.insert(endpoint.name.clone()) {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"ws_endpoint_duplicate",
endpoint.name.clone(),
));
@@ -864,13 +864,13 @@ fn validate_solana(config: &SolanaConfig) -> kb_core::Result<()> {
return validate_listeners(&config.listeners);
}
fn validate_http_endpoint(config: &HttpEndpointConfig) -> kb_core::Result<()> {
fn validate_http_endpoint(config: &HttpEndpointConfig) -> ks_core::Result<()> {
match validate_endpoint_common(&config.name, &config.provider, &config.cluster, &config.roles) {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if !config.url.starts_with("http://") && !config.url.starts_with("https://") {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"http_endpoint_url_invalid",
config.url.clone(),
));
@@ -879,14 +879,14 @@ fn validate_http_endpoint(config: &HttpEndpointConfig) -> kb_core::Result<()> {
|| config.request_timeout_ms == 0
|| config.max_idle_connections_per_host == 0
{
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"http_endpoint_limit_zero",
config.name.clone(),
));
}
for role in &config.roles {
if role.max_subscriptions != 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"http_endpoint_subscriptions_invalid",
role.role.clone(),
));
@@ -895,13 +895,13 @@ fn validate_http_endpoint(config: &HttpEndpointConfig) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_ws_endpoint(config: &WsEndpointConfig) -> kb_core::Result<()> {
fn validate_ws_endpoint(config: &WsEndpointConfig) -> ks_core::Result<()> {
match validate_endpoint_common(&config.name, &config.provider, &config.cluster, &config.roles) {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if !config.url.starts_with("ws://") && !config.url.starts_with("wss://") {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"ws_endpoint_url_invalid",
config.url.clone(),
));
@@ -912,7 +912,7 @@ fn validate_ws_endpoint(config: &WsEndpointConfig) -> kb_core::Result<()> {
|| config.write_channel_capacity == 0
|| config.event_channel_capacity == 0
{
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"ws_endpoint_limit_zero",
config.name.clone(),
));
@@ -925,7 +925,7 @@ fn validate_endpoint_common(
provider: &str,
cluster: &str,
roles: &[EndpointRoleConfig],
) -> kb_core::Result<()> {
) -> ks_core::Result<()> {
match require_non_empty(name, "endpoint.name") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -939,7 +939,7 @@ fn validate_endpoint_common(
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if roles.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"endpoint_roles_empty",
name.to_string(),
));
@@ -947,7 +947,7 @@ fn validate_endpoint_common(
let mut role_names = std::collections::BTreeSet::<std::string::String>::new();
for role in roles {
if !role_names.insert(role.role.clone()) {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"endpoint_role_duplicate",
role.role.clone(),
));
@@ -960,13 +960,13 @@ fn validate_endpoint_common(
return std::result::Result::Ok(());
}
fn validate_endpoint_role(config: &EndpointRoleConfig) -> kb_core::Result<()> {
fn validate_endpoint_role(config: &EndpointRoleConfig) -> ks_core::Result<()> {
match require_non_empty(&config.role, "endpoint.roles.role") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if config.request_kinds.is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"endpoint_role_request_kinds_empty",
config.role.clone(),
));
@@ -982,7 +982,7 @@ fn validate_endpoint_role(config: &EndpointRoleConfig) -> kb_core::Result<()> {
|| config.max_concurrent_requests == 0
|| config.pause_after_rate_limit_ms == 0
{
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"endpoint_role_limit_zero",
config.role.clone(),
));
@@ -990,7 +990,7 @@ fn validate_endpoint_role(config: &EndpointRoleConfig) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_listeners(config: &ListenerConfig) -> kb_core::Result<()> {
fn validate_listeners(config: &ListenerConfig) -> ks_core::Result<()> {
match require_non_empty(&config.default_commitment, "solana.listeners.default_commitment") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -1016,7 +1016,7 @@ fn validate_listeners(config: &ListenerConfig) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_log_listener(config: &LogListenerConfig) -> kb_core::Result<()> {
fn validate_log_listener(config: &LogListenerConfig) -> ks_core::Result<()> {
match require_non_empty(&config.name, "log_listener.name") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -1028,7 +1028,7 @@ fn validate_log_listener(config: &LogListenerConfig) -> kb_core::Result<()> {
return require_non_empty(&config.program_id, "log_listener.program_id");
}
fn validate_program_listener(config: &ProgramListenerConfig) -> kb_core::Result<()> {
fn validate_program_listener(config: &ProgramListenerConfig) -> ks_core::Result<()> {
match require_non_empty(&config.name, "program_listener.name") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -1040,7 +1040,7 @@ fn validate_program_listener(config: &ProgramListenerConfig) -> kb_core::Result<
return require_non_empty(&config.program_id, "program_listener.program_id");
}
fn validate_account_listener(config: &AccountListenerConfig) -> kb_core::Result<()> {
fn validate_account_listener(config: &AccountListenerConfig) -> ks_core::Result<()> {
match require_non_empty(&config.name, "account_listener.name") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -1052,7 +1052,7 @@ fn validate_account_listener(config: &AccountListenerConfig) -> kb_core::Result<
return require_non_empty(&config.account_pubkey, "account_listener.account_pubkey");
}
fn validate_wallet(config: &WalletConfig) -> kb_core::Result<()> {
fn validate_wallet(config: &WalletConfig) -> ks_core::Result<()> {
match require_non_empty(&config.wallet_dir, "wallet.wallet_dir") {
std::result::Result::Ok(()) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -1066,13 +1066,13 @@ fn validate_wallet(config: &WalletConfig) -> kb_core::Result<()> {
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if config.temporary_wallet_persist && !config.temporary_wallet_enabled {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"wallet_temporary_persist_without_enablement",
"temporary wallet persistence requires temporary_wallet_enabled",
));
}
if config.temporary_wallet_enabled && config.cluster == "mainnet-beta" {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"wallet_temporary_mainnet_forbidden",
"the managed temporary wallet is forbidden on mainnet-beta profiles",
));
@@ -1080,9 +1080,9 @@ fn validate_wallet(config: &WalletConfig) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_wallet_alias(value: &str) -> kb_core::Result<()> {
fn validate_wallet_alias(value: &str) -> ks_core::Result<()> {
if value.is_empty() || value.len() > 64 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"wallet_alias_length_invalid",
"temporary wallet alias length must be between 1 and 64 bytes",
));
@@ -1090,7 +1090,7 @@ fn validate_wallet_alias(value: &str) -> kb_core::Result<()> {
if !value.bytes().enumerate().all(|(index, byte)| {
return byte.is_ascii_alphanumeric() || (index > 0 && (byte == b'_' || byte == b'-'));
}) {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"wallet_alias_invalid",
"temporary wallet alias contains invalid characters",
));
@@ -1098,44 +1098,44 @@ fn validate_wallet_alias(value: &str) -> kb_core::Result<()> {
return std::result::Result::Ok(());
}
fn validate_execution(config: &ExecutionConfig) -> kb_core::Result<()> {
fn validate_execution(config: &ExecutionConfig) -> ks_core::Result<()> {
let configured_spend = config
.localnet_max_spend_lamports
.saturating_add(config.devnet_max_spend_lamports)
.saturating_add(config.testnet_max_spend_lamports)
.saturating_add(config.mainnet_max_spend_lamports);
if configured_spend > 0 && !config.require_simulation {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_spend_without_simulation",
"any configured spend requires simulation",
));
}
if config.mainnet_max_spend_lamports > 0 && !config.require_operator_confirmation {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_mainnet_without_confirmation",
"mainnet spend requires operator confirmation",
));
}
if config.max_fee_lamports == 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_fee_limit_zero",
"max_fee_lamports must be greater than zero",
));
}
if config.recent_blockhash_max_age_slots == 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_blockhash_age_zero",
"recent_blockhash_max_age_slots must be greater than zero",
));
}
if config.confirmation_poll_interval_ms == 0 || config.confirmation_poll_interval_ms > 60_000 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_confirmation_poll_interval_invalid",
"confirmation_poll_interval_ms must be between 1 and 60000",
));
}
if config.confirmation_max_attempts == 0 || config.confirmation_max_attempts > 10_000 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_confirmation_attempts_invalid",
"confirmation_max_attempts must be between 1 and 10000",
));
@@ -1146,7 +1146,7 @@ fn validate_execution(config: &ExecutionConfig) -> kb_core::Result<()> {
fn validate_wallet_execution_pair(
wallet: &WalletConfig,
execution: &ExecutionConfig,
) -> kb_core::Result<()> {
) -> ks_core::Result<()> {
for (enabled, limit, cluster) in [
(wallet.localnet_send_enabled, execution.localnet_max_spend_lamports, "localnet"),
(wallet.devnet_send_enabled, execution.devnet_max_spend_lamports, "devnet"),
@@ -1158,20 +1158,20 @@ fn validate_wallet_execution_pair(
),
] {
if enabled && limit == 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_enabled_cluster_without_spend_limit",
format!("{cluster} sending requires a positive spend limit"),
));
}
}
if wallet.mainnet_send_enabled && !execution.require_operator_confirmation {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_mainnet_send_without_confirmation",
"mainnet sending requires operator confirmation",
));
}
if wallet.cluster != "devnet" && execution.devnet_airdrop_max_lamports > 0 {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"execution_devnet_airdrop_on_non_devnet_profile",
"devnet_airdrop_max_lamports must be zero outside devnet profiles",
));
@@ -1179,7 +1179,7 @@ fn validate_wallet_execution_pair(
return std::result::Result::Ok(());
}
fn validate_log_level(value: &str, field_name: &str) -> kb_core::Result<()> {
fn validate_log_level(value: &str, field_name: &str) -> ks_core::Result<()> {
if value == "trace"
|| value == "debug"
|| value == "info"
@@ -1189,15 +1189,15 @@ fn validate_log_level(value: &str, field_name: &str) -> kb_core::Result<()> {
{
return std::result::Result::Ok(());
}
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"log_level_invalid",
format!("{field_name}: {value}"),
));
}
fn require_non_empty(value: &str, field_name: &str) -> kb_core::Result<()> {
fn require_non_empty(value: &str, field_name: &str) -> ks_core::Result<()> {
if value.trim().is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"config_field_empty",
field_name.to_string(),
));
@@ -1349,8 +1349,8 @@ mod tests {
("info.log", "info", "human"),
("error.jsonl", "error", "json"),
] {
let route_directory = if crate_name == "kb-pipeline-demo-scenarios" {
"kb-pipeline"
let route_directory = if crate_name == "ks-pipeline-demo-scenarios" {
"ks-pipeline"
} else {
crate_name.as_str()
};
@@ -1380,10 +1380,10 @@ mod tests {
std::result::Result::Err(error) => panic!("example config must parse: {error}"),
};
assert!(!EXAMPLE_CONFIG.contains("api-key=95e73621"));
assert!(!EXAMPLE_CONFIG.contains("\"kb_wallet\""));
assert!(!EXAMPLE_CONFIG.contains("\"ks_wallet\""));
for profile in config.profiles {
assert!(profile.logging.targets.iter().any(|target| {
return target.enabled && target.targets == std::vec!["kb-wallet".to_string()];
return target.enabled && target.targets == std::vec!["ks-wallet".to_string()];
}));
}
}
@@ -1391,11 +1391,11 @@ mod tests {
#[test]
fn example_config_uses_canonical_pipeline_tracing_routes() {
let source = include_str!("../../config/example.config.json");
assert!(source.contains("\"kb-pipeline\""));
assert!(source.contains("logs/devnet/kb-pipeline/debug.log"));
assert!(source.contains("logs/mainnet_research/kb-pipeline/info.log"));
assert!(source.contains("logs/mainnet/kb-pipeline/error.jsonl"));
assert!(!source.contains("kb_pipeline"));
assert!(source.contains("\"ks-pipeline\""));
assert!(source.contains("logs/devnet/ks-pipeline/debug.log"));
assert!(source.contains("logs/mainnet_research/ks-pipeline/info.log"));
assert!(source.contains("logs/mainnet/ks-pipeline/error.jsonl"));
assert!(!source.contains("ks_pipeline"));
}
#[test]

View File

@@ -1,7 +1,12 @@
<!-- file: kb-core/CHANGELOG.md -->
<!-- version: 3 -->
<!-- file: ks-core/CHANGELOG.md -->
<!-- version: 4 -->
# CHANGELOG — kb-core
# CHANGELOG — ks-core
## `0.5.1-pre.002`
- renomme le package et le répertoire `kb-core` en `ks-core` et l'identifiant Rust `kb_core` en `ks_core` ;
- met à jour ses consommateurs, chemins documentaires et tests sans changer les primitives d'erreur partagées.
## 0.4.6
@@ -21,6 +26,6 @@
## 0.1.0-pre.062
- migration des primitives communes vers la crate consolidée `kb-core` ;
- migration des primitives communes vers la crate consolidée `ks-core` ;
- maintien dun type derreur explicite sans `anyhow` ni `thiserror` ;
- adaptation aux normes Rust 2024 et Khadhroony bot3.

View File

@@ -1,8 +1,8 @@
# file: kb-core/Cargo.toml
# version: 1
# file: ks-core/Cargo.toml
# version: 2
[package]
name = "kb-core"
name = "ks-core"
version.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -1,9 +1,9 @@
<!-- file: kb-core/README.md -->
<!-- version: 4 -->
<!-- file: ks-core/README.md -->
<!-- version: 5 -->
# kb-core
# ks-core
`kb-core` fournit les primitives minimales partagées par lensemble de `khadhroony-bot3`.
`ks-core` fournit les primitives minimales partagées par lensemble de `khadhroony-bot3`.
## Responsabilités
@@ -26,7 +26,7 @@ Voir [USAGE.md](USAGE.md) pour les exemples.
## Relations
`kb-core` est utilisée par toutes les crates qui ont besoin dun contrat derreur ou dune identité de module partagée. Elle ne contient ni configuration, ni transport, ni stockage, ni logique Solana.
`ks-core` est utilisée par toutes les crates qui ont besoin dun contrat derreur ou dune identité de module partagée. Elle ne contient ni configuration, ni transport, ni stockage, ni logique Solana.
## Documentation

View File

@@ -1,7 +1,7 @@
<!-- file: kb-core/TODO.md -->
<!-- version: 3 -->
<!-- file: ks-core/TODO.md -->
<!-- version: 4 -->
# TODO — kb-core
# TODO — ks-core
## Versions ultérieures

View File

@@ -1,7 +1,7 @@
<!-- file: kb-core/USAGE.md -->
<!-- version: 1 -->
<!-- file: ks-core/USAGE.md -->
<!-- version: 2 -->
# Utilisation de kb-core
# Utilisation de ks-core
## Objectif
@@ -10,9 +10,9 @@ La crate expose les contrats minimaux communs utilisés par les autres crates du
## Résultat partagé
```rust
fn validate_name(name: &str) -> kb_core::Result<()> {
fn validate_name(name: &str) -> ks_core::Result<()> {
if name.trim().is_empty() {
return std::result::Result::Err(kb_core::Error::new(
return std::result::Result::Err(ks_core::Error::new(
"name_empty",
"name must not be empty",
));
@@ -25,7 +25,7 @@ fn validate_name(name: &str) -> kb_core::Result<()> {
## Erreur personnalisée stable
```rust
let error = kb_core::Error::new(
let error = ks_core::Error::new(
"profile_missing",
"the requested profile does not exist",
);
@@ -42,9 +42,9 @@ assert_eq!(
## Familles derreur
```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");
let config_error = ks_core::Error::config("missing active profile");
let io_error = ks_core::Error::io("cannot read configuration file");
let db_error = ks_core::Error::db("database connection refused");
assert_eq!(config_error.code(), "config");
assert_eq!(io_error.code(), "io");
@@ -58,13 +58,13 @@ Les constructeurs publics disponibles couvrent notamment la configuration, les I
```rust
let read_result = std::fs::read_to_string("missing.file");
let core_result: kb_core::Result<std::string::String> =
let core_result: ks_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))
std::result::Result::Err(ks_core::Error::from(error))
},
};
```
@@ -72,17 +72,17 @@ let core_result: kb_core::Result<std::string::String> =
## Identité dun module
```rust
let name = kb_core::ModuleName(
let name = ks_core::ModuleName(
"spl_token_decoder".to_string(),
);
let version = kb_core::ModuleVersion(
let version = ks_core::ModuleVersion(
"0.4.6".to_string(),
);
let kind = kb_core::ModuleKind::Decoder;
let kind = ks_core::ModuleKind::Decoder;
assert_eq!(name.0, "spl_token_decoder");
assert_eq!(version.0, "0.4.6");
assert_eq!(kind, kb_core::ModuleKind::Decoder);
assert_eq!(kind, ks_core::ModuleKind::Decoder);
```
`ModuleKind` distingue actuellement les ingestors, extractors, observers, decoders, materializers, aggregators et validators.
@@ -103,6 +103,6 @@ Ces tests illustrent le contrat stable entre code, message et représentation te
## Limites durables
- `kb-core` ne remplace pas les types métier spécialisés ;
- `ks-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.

View File

@@ -1,5 +1,5 @@
// file: kb-core/src/error.rs
// version: 6
// file: ks-core/src/error.rs
// version: 7
//! Error and result primitives shared by the workspace.

View File

@@ -1,5 +1,5 @@
// file: kb-core/src/lib.rs
// version: 2
// file: ks-core/src/lib.rs
// version: 3
//! Core primitives, module identity and shared errors for the workspace.
#![warn(missing_docs)]

View File

@@ -1,5 +1,5 @@
// file: kb-core/src/module.rs
// version: 1
// file: ks-core/src/module.rs
// version: 2
//! Module identity and module-kind primitives.

View File

@@ -1,7 +1,12 @@
<!-- file: kb-lib/CHANGELOG.md -->
<!-- version: 50 -->
<!-- file: ks-lib/CHANGELOG.md -->
<!-- version: 51 -->
# CHANGELOG — kb-lib
# CHANGELOG — ks-lib
## `0.5.1-pre.002`
- renomme physiquement `kb-lib` en `ks-lib` et l'identifiant Rust public `kb_lib` en `ks_lib` dans les consommateurs et tests d'API externe ;
- conserve volontairement les identités runtime/persistées `kb-lib.*` pour `0.5.1-pre.003`, afin de séparer le renommage Cargo de la migration de provenance/replay.
## `0.4.8-pre.015` — réconciliation des matrices Metadata
@@ -104,7 +109,7 @@
- ajoute les helpers publics de matérialisation détats et le test dAPI externe correspondant.
- corrige le helper de test de snapshot afin dutiliser les variantes wire existantes `Encoding::Utf8` et `Format::Json`.
- précise que les opérations destructrices, irréversibles ou écrasantes restent exécutables : leur progression vers simulation, signature et envoi doit être gouvernée par le cadre commun `ExSafetyChecker`, et non supprimée du périmètre de lexécuteur.
- validation reçue le 5 août 2026 : `cargo fmt`, `cargo check --workspace`, `cargo clippy --all-targets`, audit workspace et 667 tests unitaires `kb-lib` réussis, avec les tests dAPI externes et les doc-tests.
- validation reçue le 5 août 2026 : `cargo fmt`, `cargo check --workspace`, `cargo clippy --all-targets`, audit workspace et 667 tests unitaires `ks-lib` réussis, avec les tests dAPI externes et les doc-tests.
## 0.4.8-pre.005 — instructions Solana Program Metadata
@@ -117,7 +122,7 @@
- retire le décodeur Solana Program Metadata de linventaire des décodeurs réservés.
- aligne la structure du composant sur les règles du workspace : façade limitée aux sous-modules et réexports, implémentation déplacée dans `decoder.rs`, constantes centralisées dans `constants.rs` et accès internes via `crate::`.
- corrige les vecteurs négatifs `Initialize` afin de placer explicitement les valeurs invalides après les 16 octets du seed et de vérifier séparément `Encoding`, `Compression`, `Format` et `DataSource`.
- validation reçue le 5 août 2026 : `cargo fmt`, `cargo check --workspace`, `cargo clippy --all-targets`, audit workspace et 660 tests unitaires `kb-lib` réussis, ainsi que les tests dAPI externes et la matrice de nomenclature.
- validation reçue le 5 août 2026 : `cargo fmt`, `cargo check --workspace`, `cargo clippy --all-targets`, audit workspace et 660 tests unitaires `ks-lib` réussis, ainsi que les tests dAPI externes et la matrice de nomenclature.
## 0.4.8-pre.004 — comptes Solana Program Metadata
@@ -149,7 +154,7 @@
- réorganisation de `README.md`, `USAGE.md`, `TODO.md` et du changelog selon leur rôle documentaire ;
- suppression des tâches Metaplex terminées du TODO ;
- maintien des campagnes réseau hors du TODO de `kb-lib`, la surface de builders étant achevée.
- maintien des campagnes réseau hors du TODO de `ks-lib`, la surface de builders étant achevée.
## 0.4.7-pre.006 — fermeture de lexécuteur Metaplex

View File

@@ -1,8 +1,8 @@
# file: kb-lib/Cargo.toml
# version: 15
# file: ks-lib/Cargo.toml
# version: 16
[package]
name = "kb-lib"
name = "ks-lib"
version.workspace = true
edition.workspace = true
license.workspace = true
@@ -14,8 +14,8 @@ base64.workspace = true
borsh.workspace = true
borsh_0_10.workspace = true
bs58.workspace = true
kb-core = { path = "../kb-core" }
kb-program-ids = { path = "../kb-program-ids" }
ks-core = { path = "../ks-core" }
ks-program-ids = { path = "../ks-program-ids" }
mpl-token-metadata.workspace = true
serde.workspace = true
serde_json.workspace = true

View File

@@ -1,9 +1,9 @@
<!-- file: kb-lib/README.md -->
<!-- version: 28 -->
<!-- file: ks-lib/README.md -->
<!-- version: 29 -->
# kb-lib
# ks-lib
`kb-lib` est la bibliothèque fonctionnelle consolidée de `khadhroony-bot3`. Elle fournit les modèles, décodeurs, matérialisateurs, exécuteurs et contrats de sécurité indépendants du transport, du stockage et de linterface utilisateur.
`ks-lib` est la bibliothèque fonctionnelle consolidée de `khadhroony-bot3`. Elle fournit les modèles, décodeurs, matérialisateurs, exécuteurs et contrats de sécurité indépendants du transport, du stockage et de linterface utilisateur.
## Périmètre
@@ -63,7 +63,7 @@ Linventaire audité comprend 25 composants nommés : onze matérialisateurs a
## Hors périmètre
`kb-lib` ne sélectionne aucun endpoint, ne lit pas directement un RPC, ne persiste aucune donnée, ne gère pas les secrets de wallet et ne soumet aucune transaction.
`ks-lib` ne sélectionne aucun endpoint, ne lit pas directement un RPC, ne persiste aucune donnée, ne gère pas les secrets de wallet et ne soumet aucune transaction.
## Surface publique principale
@@ -80,13 +80,13 @@ Les exemples dappel et invariants sont documentés dans [USAGE.md](USAGE.md).
## Relations avec le workspace
- dépend de `kb-core` et `kb-program-ids` ;
- est consommée par `kb-pipeline`, `kb-store`, `kb-onchain-transport`, `kb-pipeline-demo-scenarios` et `kb-app-demo-desktop` ;
- ne dépend jamais de `kb-store`, `kb-pipeline` ni dune application.
- dépend de `ks-core` et `ks-program-ids` ;
- est consommée par `ks-pipeline`, `ks-store`, `ks-onchain-transport`, `ks-pipeline-demo-scenarios` et `kb-app-demo-desktop` ;
- ne dépend jamais de `ks-store`, `ks-pipeline` ni dune application.
## Statut et limites
La surface fonctionnelle Metaplex de la crate est achevée. Les campagnes Devnet restantes relèvent de `kb-pipeline-demo-scenarios` et de `kb-app-demo-desktop`, non dun manque de builder dans `kb-lib`.
La surface fonctionnelle Metaplex de la crate est achevée. Les campagnes Devnet restantes relèvent de `ks-pipeline-demo-scenarios` et de `kb-app-demo-desktop`, non dun manque de builder dans `ks-lib`.
Pour Solana Program Metadata, les modèles wire, les décodeurs bornés de comptes, le décodeur contextualisé, la matérialisation des deux comptes et des neuf instructions stables, ainsi que lexécuteur typé des neuf opérations sont actifs. `Buffer` accepte tout reliquat comme données allouées sans inventer de PDA stable après changement dautorité ; `Metadata` valide la dérivation canonical ou non-canonical et distingue le contenu logique de la capacité ajoutée par `Extend`. Les instructions produisent des faits committés non autoritatifs ; les snapshots post-exécution restent la source de létat final. Les variantes qui dépendent de létat du compte restent des intentions wire jusquaux lectures stateful prévues, et aucune forme pré-stable nest déclarée compatible réseau sans preuve de cluster.

View File

@@ -1,7 +1,7 @@
<!-- file: kb-lib/TODO.md -->
<!-- version: 15 -->
<!-- file: ks-lib/TODO.md -->
<!-- version: 16 -->
# TODO — kb-lib
# TODO — ks-lib
## `0.5.x` — audit transversal décodage, matérialisation, exécution et sécurité

View File

@@ -1,27 +1,27 @@
<!-- file: kb-lib/USAGE.md -->
<!-- version: 16 -->
<!-- file: ks-lib/USAGE.md -->
<!-- version: 17 -->
# Utilisation de kb-lib
# Utilisation de ks-lib
## Objectif
Ce guide présente les familles dAPI publiques significatives de `kb-lib`. Les helpers privés, éléments `pub(crate)` et modules non réexportés ne font pas partie du contrat consommateur.
Ce guide présente les familles dAPI publiques significatives de `ks-lib`. Les helpers privés, éléments `pub(crate)` et modules non réexportés ne font pas partie du contrat consommateur.
## Dépendance
```toml
[dependencies]
kb-lib = { path = "../kb-lib" }
ks-lib = { path = "../ks-lib" }
```
Toutes les fonctions retournant `kb_core::Result<T>` utilisent le contrat derreur structuré du workspace.
Toutes les fonctions retournant `ks_core::Result<T>` utilisent le contrat derreur structuré du workspace.
## Décodage contextualisé
`DcApiInstructionDecoder` définit la reconnaissance et le décodage dune instruction contextualisée. Les décodeurs concrets sont des valeurs sans état.
```rust
use kb_lib::{DcApiInstructionDecoder, DcSolanaCoreDecoder};
use ks_lib::{DcApiInstructionDecoder, DcSolanaCoreDecoder};
let decoder = DcSolanaCoreDecoder;
let recognition = DcApiInstructionDecoder::recognize(&decoder, &input);
@@ -59,8 +59,8 @@ 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 = match kb_lib::decoder_spl_token_2022_parse_token_2022_state(
kb_lib::DcToken2022StateKind::Account,
let state = match ks_lib::decoder_spl_token_2022_parse_token_2022_state(
ks_lib::DcToken2022StateKind::Account,
&account_data,
) {
Ok(value) => value,
@@ -71,7 +71,7 @@ println!("parsed token-2022 state: {state:#?}");
```
```rust
let registry = match kb_lib::decoder_spl_elgamal_registry_parse_elgamal_registry_state(
let registry = match ks_lib::decoder_spl_elgamal_registry_parse_elgamal_registry_state(
&account_data,
) {
Ok(value) => value,
@@ -88,23 +88,23 @@ Les parseurs vérifient les bornes et formats quils annoncent. Ils ne reconst
Les modèles `DcMetadataSpm*` représentent uniquement le contrat on-chain du programme `ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S`. Ils ne téléchargent jamais les URL et ne lisent pas automatiquement les comptes référencés par `External`.
```rust
let seed_result = kb_lib::DcMetadataSpmSeed::from_utf8("idl");
let seed_result = ks_lib::DcMetadataSpmSeed::from_utf8("idl");
let seed = match seed_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
let external = kb_lib::DcMetadataSpmExternalData::from_zeroable_length(
let external = ks_lib::DcMetadataSpmExternalData::from_zeroable_length(
solana_pubkey::Pubkey::new_from_array([7_u8; 32]),
128,
4096,
);
let data = kb_lib::DcMetadataSpmData::External(external);
let data = ks_lib::DcMetadataSpmData::External(external);
let wire_bytes = match data.to_wire_bytes() {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
};
assert_eq!(seed.as_bytes().len(), kb_lib::DC_METADATA_SPM_SEED_BYTES);
assert_eq!(wire_bytes.len(), kb_lib::DC_METADATA_SPM_EXTERNAL_DATA_BYTES);
assert_eq!(seed.as_bytes().len(), ks_lib::DC_METADATA_SPM_SEED_BYTES);
assert_eq!(wire_bytes.len(), ks_lib::DC_METADATA_SPM_EXTERNAL_DATA_BYTES);
```
Le champ `length` externe suit le contrat zeroable : la valeur wire `0` devient `None` et signifie que la référence porte sur tout le compte à partir de `offset`. Les contenus `Direct` et `Url` doivent être non vides, et toute longueur doit rester représentable par le `u32` du header.
@@ -116,7 +116,7 @@ Les trois fonctions publiques de comptes vérifient le propriétaire `ProgM6…`
- `decoder_metadata_solana_program_metadata_decode_metadata_account` valide le PDA canonical ou non-canonical, `data_length`, les enums fermées et les contraintes propres à `Direct`, `Url` et `External`.
```rust
let snapshot = match kb_lib::decoder_metadata_solana_program_metadata_decode_account(
let snapshot = match ks_lib::decoder_metadata_solana_program_metadata_decode_account(
metadata_account.as_str(),
account_owner.as_str(),
&account_data,
@@ -126,10 +126,10 @@ let snapshot = match kb_lib::decoder_metadata_solana_program_metadata_decode_acc
};
match snapshot {
kb_lib::DcMetadataSpmAccountSnapshot::Buffer(value) => {
ks_lib::DcMetadataSpmAccountSnapshot::Buffer(value) => {
println!("buffer bytes={}", value.allocated_data_bytes);
},
kb_lib::DcMetadataSpmAccountSnapshot::Metadata(value) => {
ks_lib::DcMetadataSpmAccountSnapshot::Metadata(value) => {
println!("metadata program={}", value.program);
println!("logical bytes={}", value.data_length);
println!("reserved capacity={}", value.trailing_capacity_bytes);
@@ -142,12 +142,12 @@ Une URL est seulement décodée comme chaîne UTF-8 on-chain. Aucune requête HT
Le décodeur `DcMetadataSolanaProgramMetadataDecoder` reconnaît le Program ID `ProgM6…` et les neuf tags stables `0..8`. Il conserve les différences utiles entre le wire SDK et le runtime actuel, sans interpréter un suffixe ignoré comme un nouvel argument.
```rust
let decoder = kb_lib::DcMetadataSolanaProgramMetadataDecoder;
let recognition = kb_lib::DcApiInstructionDecoder::recognize(&decoder, &input);
let decoder = ks_lib::DcMetadataSolanaProgramMetadataDecoder;
let recognition = ks_lib::DcApiInstructionDecoder::recognize(&decoder, &input);
if !recognition.compatible {
return std::result::Result::Err("instruction incompatible".to_string());
}
let result = kb_lib::DcApiInstructionDecoder::decode(&decoder, &input);
let result = ks_lib::DcApiInstructionDecoder::decode(&decoder, &input);
println!("status={:?}", result.status);
```
@@ -162,9 +162,9 @@ Les trois domaines metadata disposent de matérialiseurs instructionnels spécia
Chaque type possède son propre `componentName`, son propre `processorName`, ses familles acceptées et un ownership exact. Les transactions échouées sont refusées. Les faits dinstructions ne remplacent jamais les snapshots autoritatifs lus après exécution.
```rust
let materializer = kb_lib::MtMetadataSolanaProgramMaterializer;
if kb_lib::MtApiEventMaterializer::accepts_observation(&materializer, &observation) {
let result = kb_lib::MtApiEventMaterializer::materialize(&materializer, &observation);
let materializer = ks_lib::MtMetadataSolanaProgramMaterializer;
if ks_lib::MtApiEventMaterializer::accepts_observation(&materializer, &observation) {
let result = ks_lib::MtApiEventMaterializer::materialize(&materializer, &observation);
println!("materialization status={:?}", result.status);
}
```
@@ -176,7 +176,7 @@ Les trois helpers détat acceptent les snapshots déjà validés par le déco
- `materializer_metadata_materialize_solana_program_metadata_metadata_snapshot` conserve le contenu direct, lURL ou la référence externe, ainsi que lautorité, la mutabilité, le format et la capacité allouée.
```rust
let output = match kb_lib::materializer_metadata_materialize_solana_program_metadata_account_snapshot(
let output = match ks_lib::materializer_metadata_materialize_solana_program_metadata_account_snapshot(
slot,
&snapshot,
) {
@@ -193,7 +193,7 @@ Une URL reste une chaîne observée avec `fetched = false`. Une référence exte
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(
let metadata = match ks_lib::decoder_metadata_metaplex_token_metadata_decode_metadata_account(
metadata_account.as_str(),
metadata_owner.as_str(),
&account_data,
@@ -207,7 +207,7 @@ println!("metadata name={}", metadata.name);
```
```rust
let edition = match kb_lib::decoder_metadata_metaplex_token_metadata_decode_edition_account(
let edition = match ks_lib::decoder_metadata_metaplex_token_metadata_decode_edition_account(
edition_account.as_str(),
metadata_owner.as_str(),
mint.as_str(),
@@ -236,7 +236,7 @@ Les signatures exactes doivent être vérifiées lors de lutilisation : certa
- `ExMetadataSolanaProgramMetadataExecutor`.
```rust
use kb_lib::{ExApiTypedInstructionExecutor, ExSplMemoExecutor};
use ks_lib::{ExApiTypedInstructionExecutor, ExSplMemoExecutor};
let executor = ExSplMemoExecutor;
let plan = ExApiTypedInstructionExecutor::build_prepared_plan(
@@ -270,20 +270,20 @@ Memo v1 et v3 restent non exécutables. Memo v4 est la seule génération exécu
Les mutations écrasantes, destructrices ou irréversibles ne sont pas retirées de lAPI. Elles exigent `allow_destructive_operation = true`, puis le plan complet est évalué par `ExSafetyChecker`. Cette approbation locale ne remplace ni la simulation RPC, ni la confirmation opérateur, ni les postconditions stateful.
```rust
let intent = kb_lib::ExMetadataSpmExecutionIntent {
let intent = ks_lib::ExMetadataSpmExecutionIntent {
intent_id: "extend-program-metadata".to_string(),
fee_payer: authority.clone(),
policy,
allow_destructive_operation: false,
operation: kb_lib::ExMetadataSpmOperation::Extend {
operation: ks_lib::ExMetadataSpmOperation::Extend {
account: metadata_account,
authority,
length: 256,
program_context: std::option::Option::None,
},
};
let executor = kb_lib::ExMetadataSolanaProgramMetadataExecutor;
let plan = match kb_lib::ExApiTypedInstructionExecutor::build_prepared_plan(
let executor = ks_lib::ExMetadataSolanaProgramMetadataExecutor;
let plan = match ks_lib::ExApiTypedInstructionExecutor::build_prepared_plan(
&executor,
&intent,
) {
@@ -313,7 +313,7 @@ Le consommateur construit un intent typé, puis appelle `ExApiTypedInstructionEx
Les opérations courantes utilisent leur wrapper canonique final. Les versions remplacées ne possèdent pas de builder public distinct. Les opérations obsolètes encore constructibles exigent que lintent autorise explicitement lexécution dépréciée ; leurs variantes Rust sont marquées `#[deprecated]`.
Avant utilisation du plan, le consommateur doit transmettre celui-ci au préflight et à lorchestration de `kb-pipeline`.
Avant utilisation du plan, le consommateur doit transmettre celui-ci au préflight et à lorchestration de `ks-pipeline`.
### Prérequis des opérations Metaplex
@@ -339,10 +339,10 @@ let evaluation = match checker.evaluate_prepared_plan(&plan) {
};
match evaluation.decision {
kb_lib::ExSafetyDecision::Allow => {
ks_lib::ExSafetyDecision::Allow => {
println!("execution plan accepted");
},
kb_lib::ExSafetyDecision::Deny => {
ks_lib::ExSafetyDecision::Deny => {
for violation in evaluation.violations {
eprintln!("safety violation: {violation:#?}");
}
@@ -355,7 +355,7 @@ match evaluation.decision {
`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(
let result = ks_lib::MtApiEventMaterializer::materialize(
&materializer,
&decoded_observation,
);

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder.rs
// version: 17
// file: ks-lib/src/decoder.rs
// version: 18
//! Consolidated decoder modules.
@@ -916,7 +916,7 @@ mod reserved_decoder_tests {
}
assert_eq!(decoder.program_ids().len(), 1);
for program_id in decoder.program_ids() {
assert!(kb_program_ids::find_registered_program_id(program_id).is_some());
assert!(ks_program_ids::find_registered_program_id(program_id).is_some());
let observation = crate::MdProgramObservation {
signature: crate::MdSignature("signature".to_string()),
slot: crate::MdSlot(1),

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/adapter.rs
// version: 5
// file: ks-lib/src/decoder/adapter.rs
// version: 6
//! `adapter` decoder family.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/adapter/saber_decimal_wrapper.rs
// version: 4
// file: ks-lib/src/decoder/adapter/saber_decimal_wrapper.rs
// version: 5
//! Reserved protocol decoder for `adapter_saber_decimal_wrapper`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAdapterSaberDecimalWrapperDecoder
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::ADAPTER_SABER_DECIMAL_WRAPPER_PROGRAM_ID];
return &[ks_program_ids::ADAPTER_SABER_DECIMAL_WRAPPER_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAdapterSaberDecimalWrapperDecoder
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/adapter/spl_token_wrap.rs
// version: 1
// file: ks-lib/src/decoder/adapter/spl_token_wrap.rs
// version: 2
//! Reserved protocol decoder for `adapter_spl_token_wrap`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAdapterSplTokenWrapDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::ADAPTER_SPL_TOKEN_WRAP_PROGRAM_ID];
return &[ks_program_ids::ADAPTER_SPL_TOKEN_WRAP_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAdapterSplTokenWrapDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm.rs
// version: 5
// file: ks-lib/src/decoder/amm.rs
// version: 6
//! `amm` decoder family.

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/aldrin_v1.rs
// version: 4
// file: ks-lib/src/decoder/amm/aldrin_v1.rs
// version: 5
//! Reserved protocol decoder for `amm_aldrin_v1`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmAldrinV1Decoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_ALDRIN_V1_PROGRAM_ID];
return &[ks_program_ids::AMM_ALDRIN_V1_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmAldrinV1Decoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/aldrin_v2.rs
// version: 4
// file: ks-lib/src/decoder/amm/aldrin_v2.rs
// version: 5
//! Reserved protocol decoder for `amm_aldrin_v2`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmAldrinV2Decoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_ALDRIN_V2_PROGRAM_ID];
return &[ks_program_ids::AMM_ALDRIN_V2_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmAldrinV2Decoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/alphaq.rs
// version: 4
// file: ks-lib/src/decoder/amm/alphaq.rs
// version: 5
//! Reserved protocol decoder for `amm_alphaq`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmAlphaqDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_ALPHAQ_PROGRAM_ID];
return &[ks_program_ids::AMM_ALPHAQ_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmAlphaqDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/believe.rs
// version: 4
// file: ks-lib/src/decoder/amm/believe.rs
// version: 5
//! Reserved protocol decoder for `amm_believe`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmBelieveDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_BELIEVE_PROGRAM_ID];
return &[ks_program_ids::AMM_BELIEVE_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmBelieveDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/bonk_swap.rs
// version: 4
// file: ks-lib/src/decoder/amm/bonk_swap.rs
// version: 5
//! Reserved protocol decoder for `amm_bonk_swap`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmBonkSwapDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_BONK_SWAP_PROGRAM_ID];
return &[ks_program_ids::AMM_BONK_SWAP_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmBonkSwapDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/fluxbeam.rs
// version: 4
// file: ks-lib/src/decoder/amm/fluxbeam.rs
// version: 5
//! Reserved protocol decoder for `amm_fluxbeam`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmFluxbeamDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_FLUXBEAM_PROGRAM_ID];
return &[ks_program_ids::AMM_FLUXBEAM_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmFluxbeamDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/goon_fi.rs
// version: 4
// file: ks-lib/src/decoder/amm/goon_fi.rs
// version: 5
//! Reserved protocol decoder for `amm_goon_fi`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGoonFiDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_GOON_FI_PROGRAM_ID];
return &[ks_program_ids::AMM_GOON_FI_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGoonFiDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/goosefx_gamma.rs
// version: 4
// file: ks-lib/src/decoder/amm/goosefx_gamma.rs
// version: 5
//! Reserved protocol decoder for `amm_goosefx_gamma`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGoosefxGammaDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_GOOSEFX_GAMMA_PROGRAM_ID];
return &[ks_program_ids::AMM_GOOSEFX_GAMMA_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGoosefxGammaDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/goosefx_v2.rs
// version: 4
// file: ks-lib/src/decoder/amm/goosefx_v2.rs
// version: 5
//! Reserved protocol decoder for `amm_goosefx_v2`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGoosefxV2Decoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_GOOSEFX_V2_PROGRAM_ID];
return &[ks_program_ids::AMM_GOOSEFX_V2_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGoosefxV2Decoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-lib/src/decoder/amm/guac_swap.rs
// version: 4
// file: ks-lib/src/decoder/amm/guac_swap.rs
// version: 5
//! Reserved protocol decoder for `amm_guac_swap`.
@@ -17,7 +17,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGuacSwapDecoder {
}
fn program_ids(&self) -> &'static [&'static str] {
return &[kb_program_ids::AMM_GUAC_SWAP_PROGRAM_ID];
return &[ks_program_ids::AMM_GUAC_SWAP_PROGRAM_ID];
}
fn supports_observation(
@@ -33,7 +33,7 @@ impl crate::DcApiProtocolDecoder for crate::DcAmmGuacSwapDecoder {
fn decode_observation(
&self,
_observation: &crate::MdProgramObservation,
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
) -> ks_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}

Some files were not shown because too many files have changed in this diff Show More