0.5.1-pre.002
This commit is contained in:
26
CHANGELOG.md
26
CHANGELOG.md
@@ -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 l’adaptateur Tauri ;
|
||||
- centralisation des scénarios réseau réutilisables dans `ks-pipeline-demo-scenarios` plutôt que dans l’adaptateur Tauri ;
|
||||
- réconciliation des matrices, registres runtime, exports publics, IDL, TODO et stockage ;
|
||||
- confirmation qu’aucune migration PostgreSQL spécialisée Metadata n’est nécessaire.
|
||||
|
||||
@@ -77,7 +77,7 @@ Ce changelog décrit les évolutions fonctionnelles globales du projet. Il ne re
|
||||
- décodeurs d’instructions 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 l’architecture 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
|
||||
|
||||
|
||||
24
Cargo.toml
24
Cargo.toml
@@ -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"
|
||||
|
||||
22
README.md
22
README.md
@@ -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).
|
||||
|
||||
@@ -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 d’instructions 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 ;
|
||||
|
||||
@@ -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 @@ L’exemple 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
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/DEVNET_EXECUTION_GUIDE.md -->
|
||||
<!-- version: 24 -->
|
||||
<!-- version: 25 -->
|
||||
|
||||
# Guide d’exé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 l’ordre 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 l’ordre 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 ;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/IDEA_REMINDERS.md -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Rappels d’idé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 l’exploitation 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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/OPERATION_NAMING_CONVENTION.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Convention canonique des identités runtime et des codes d’opé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 s’applique aux identités runtime, processeurs, surfaces, opérations et événements persistés. Elle ne s’applique 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 s’applique aux identités runtime, processeurs, surfaces, opérations et événements persistés. Elle ne s’applique 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 ;
|
||||
|
||||
@@ -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 d’inté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
|
||||
|
||||
@@ -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 d’endpoints, méthodes RPC standard et contrats liés à l’exécution RPC.
|
||||
- `kb-store` regroupe les contrats store-neutral et l’implémentation PostgreSQL.
|
||||
- `ks-onchain-transport` fournit les clients HTTP/WebSocket, pools, rôles d’endpoints, méthodes RPC standard et contrats liés à l’exécution RPC.
|
||||
- `ks-store` regroupe les contrats store-neutral et l’implémentation PostgreSQL.
|
||||
|
||||
Les transports n’effectuent 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 n’effectuent pas la matérialisation métier. Le stockage ne d
|
||||
- corrélation stateful ;
|
||||
- préflight et orchestration d’exé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 n’impose pas d’exposer 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 n’impose pas d’exposer 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 @@ L’exé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 lorsqu’ils 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 lorsqu’ils 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 à l’adaptation Tauri, aux payloads UI, à la présentation et à l’appel 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 l’UI et d’une 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 à l’adaptation Tauri, aux payloads UI, à la présentation et à l’appel 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 l’UI et d’une 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/` lorsqu’elles sont consommées par plusieurs tests.
|
||||
- Les archives documentaires ne participent ni au build ni aux décisions normatives.
|
||||
|
||||
|
||||
@@ -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 d’endpoints | 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 d’endpoints | 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 qu’il 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` ;
|
||||
- l’application 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 n’est 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 l’audit d’alignement.
|
||||
|
||||
## 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`
|
||||
|
||||
@@ -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 d’aucun 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 d’aucun scénario, wallet ou actif propre à un réseau de démonstration.
|
||||
|
||||
## 2. Familles de traitements
|
||||
|
||||
@@ -19,7 +19,7 @@ L’extraction 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 l’idempotence 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 l’idempotence 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 lorsqu’ils 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 lorsqu’ils 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 d’une 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 d’une 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 d’exé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 d’exé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
|
||||
|
||||
|
||||
@@ -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 l’effacement 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 qu’ils représentent des responsabilités opérationnelles différentes.
|
||||
La consolidation ne signifie pas l’effacement 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 qu’ils représentent des responsabilités opérationnelles différentes.
|
||||
|
||||
### 3.2 Contrats explicites
|
||||
|
||||
|
||||
@@ -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` lorsqu’ils dépassent la seule persistance. `kb-store` ne doit pas créer une seconde définition concurrente d’un contrat partagé.
|
||||
Les modèles métier communs restent dans `ks-lib` lorsqu’ils dépassent la seule persistance. `ks-store` ne doit pas créer une seconde définition concurrente d’un 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
|
||||
|
||||
|
||||
@@ -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` n’introduit 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` n’introduit 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 d’interface, 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 n’altè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 n’altè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.
|
||||
|
||||
@@ -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 l’archive
|
||||
|
||||
@@ -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,10 +23,10 @@ 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` |
|
||||
@@ -38,7 +38,7 @@ La migration `0.5.1` doit renommer les dix crates généralistes suivantes :
|
||||
| `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.
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/guides/CONFIGURATION.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Guide de configuration
|
||||
|
||||
## Objectif
|
||||
|
||||
Ce guide décrit le chargement et l’utilisation de la configuration bot3. La référence d’API détaillée reste `kb-config/USAGE.md`.
|
||||
Ce guide décrit le chargement et l’utilisation de la configuration bot3. La référence d’API 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`.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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 l’implé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`.
|
||||
|
||||
@@ -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
|
||||
L’extraction 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 qu’aprè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`.
|
||||
|
||||
@@ -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 d’un scénario validé vers le pipeline
|
||||
|
||||
`kb-pipeline-demo-scenarios` n’est pas la destination finale d’une 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` n’est pas la destination finale d’une 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.
|
||||
|
||||
Lorsqu’un composant d’un scénario est validé et qu’il 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 d’instructions, 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 l’orchestration réutilisable, y compris sur Mainnet lorsque le profil, la politique et l’appelant l’autorisent.
|
||||
- `ks-lib` pour le décodage, la matérialisation, la construction d’instructions, 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 l’orchestration réutilisable, y compris sur Mainnet lorsque le profil, la politique et l’appelant l’autorisent.
|
||||
|
||||
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`.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,7 +33,7 @@ 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 |
|
||||
@@ -59,7 +59,7 @@ 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 |
|
||||
@@ -144,7 +144,7 @@ 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` |
|
||||
@@ -441,7 +441,7 @@ 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` |
|
||||
@@ -528,7 +528,7 @@ Les treize variables historiques `TOKEN_2022_*` sont des fixtures Devnet et conv
|
||||
### 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` |
|
||||
@@ -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_*`.
|
||||
|
||||
|
||||
@@ -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 s’appliquent 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 d’une 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.
|
||||
- L’identité runtime suit `kb-lib.materializer.<domain>[.<subsystem>]`. Le `processorName` persisté suit `materializer.<domain>[.<subsystem>]` et doit être exactement l’identité runtime sans le préfixe `kb-lib.`. Le tracing target d’un composant actif est identique à son identité runtime.
|
||||
- Les constantes d’un 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 lorsqu’elles sont `pub` ou `pub(crate)`.
|
||||
- Les constantes d’un 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 lorsqu’elles 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 lorsqu’il 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 lorsqu’il 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 l’installation 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 l’installation du subscriber.
|
||||
- Il est interdit d’ajouter `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 d’orchestration.
|
||||
- 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 lorsqu’un 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 d’intégration, benches ou exemples. Une dépendance de test vers un décodeur ou matérialiseur concret est légitime lorsqu’elle sert uniquement à éprouver une orchestration générique fondée sur les traits API ; elle ne prouve pas qu’une 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 d’un `MtApiEventMaterializer` doit être ajoutée au registre applicatif et couverte par un test d’inventaire ordonné ; une crate présente dans le workspace ou dans `kb_pipeline` n’est pas activée automatiquement. Les matérialiseurs exclusivement stateful qui n’implé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 d’un `MtApiEventMaterializer` doit être ajoutée au registre applicatif et couverte par un test d’inventaire ordonné ; une crate présente dans le workspace ou dans `ks_pipeline` n’est pas activée automatiquement. Les matérialiseurs exclusivement stateful qui n’implé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.
|
||||
- L’ordre de préférence des formats est : schéma officiel `wincode`, schéma officiel Borsh, puis parseur local borné reproduisant exactement le runtime lorsque l’interface officielle n’expose 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 l’activation 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 l’ordre exact des metas, borner toute liste de comptes variable avant l’appel au builder et refuser les doublons lorsque leur répétition n’a pas de sémantique publiée.
|
||||
- Les features des interfaces doivent rester minimales et explicites. Une feature `serde`, `wincode`, `borsh`, `std`, `alloc` ou équivalente n’est activée que si la crate consommatrice l’utilise réellement.
|
||||
- Les crates applicatives ne doivent pas dépendre d’interfaces 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 d’interfaces 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 d’exé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 d’exé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 d’un 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 l’inventaire complet et ne peut pas sélectionner arbitrairement un sous-ensemble d’opé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, d’exécuteur, de store, d’application ou d’outil 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, d’exécuteur, de store, d’application ou d’outil 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.
|
||||
|
||||
|
||||
@@ -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 d’intégration ;
|
||||
- `kb-logging` : 17 tests ;
|
||||
- `kb-onchain-transport` : 118 tests ;
|
||||
- `kb-pipeline` : 109 tests, plus 3 tests d’inté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 d’intégration ;
|
||||
- `ks-logging` : 17 tests ;
|
||||
- `ks-onchain-transport` : 118 tests ;
|
||||
- `ks-pipeline` : 109 tests, plus 3 tests d’inté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
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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 l’adaptation 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 l’adaptation 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 n’est 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 l’inspection 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 d’exécution en pleine largeur sous la grille ;
|
||||
- enregistre la première validation Tauri de `pre.014` : `cargo check --workspace`, Clippy et l’audit 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 l’audit 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 l’exécution desktop complète de Token-2022 Token Metadata et Solana Program Metadata sur Devnet, tandis que l’ancien parcours Metaplex s’arrê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 qu’un parcours `Fungible` annonce un token standard incompatible avec le mint réellement préparé ;
|
||||
- conserve l’action 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 l’appel 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 l’evidence JSON le backfill canonique, l’extraction Core, le replay, la seconde passe d’idempotence, 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 l’observer Solana Core par un observer Metadata ciblant exclusivement `demo_execution_metadata` ;
|
||||
- déplace le garde de l’exé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 l’inventaire 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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 l’ordre, `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 l’ordre, `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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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());
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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}"),
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(¬ification) {
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
)));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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 l’unique propriétaire direct de `dotenvy` ;
|
||||
- validation statique que `ks-config` reste l’unique 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
|
||||
|
||||
@@ -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
|
||||
@@ -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 d’environnement, 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 d’environnement, 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
|
||||
@@ -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`
|
||||
|
||||
@@ -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 l’environnement du workspace, résout les placeholders p
|
||||
## Chargement de l’environnement
|
||||
|
||||
```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 l’unicité des profils, l’existence du profil actif, les URLs, les rôles d’endpoints, les limites d’exécution, les routes de logging et les contraintes wallet.
|
||||
Les erreurs utilisent `ks_core::Error` avec un code stable. Les validations couvrent notamment l’unicité des profils, l’existence du profil actif, les URLs, les rôles d’endpoints, les limites d’exécution, les routes de logging et les contraintes wallet.
|
||||
|
||||
## Tests instructifs
|
||||
|
||||
@@ -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()),
|
||||
)),
|
||||
@@ -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)]
|
||||
@@ -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]
|
||||
@@ -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 d’un type d’erreur explicite sans `anyhow` ni `thiserror` ;
|
||||
- adaptation aux normes Rust 2024 et Khadhroony bot3.
|
||||
@@ -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
|
||||
@@ -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 l’ensemble de `khadhroony-bot3`.
|
||||
`ks-core` fournit les primitives minimales partagées par l’ensemble 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 d’un contrat d’erreur ou d’une identité de module partagée. Elle ne contient ni configuration, ni transport, ni stockage, ni logique Solana.
|
||||
`ks-core` est utilisée par toutes les crates qui ont besoin d’un contrat d’erreur ou d’une identité de module partagée. Elle ne contient ni configuration, ni transport, ni stockage, ni logique Solana.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 d’erreur
|
||||
|
||||
```rust
|
||||
let config_error = kb_core::Error::config("missing active profile");
|
||||
let io_error = kb_core::Error::io("cannot read configuration file");
|
||||
let db_error = kb_core::Error::db("database connection refused");
|
||||
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é d’un 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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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)]
|
||||
@@ -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.
|
||||
|
||||
@@ -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 d’API externe correspondant.
|
||||
- corrige le helper de test de snapshot afin d’utiliser 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 l’exé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 d’API 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 d’API 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 l’inventaire 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 d’API 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 d’API 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 l’exécuteur Metaplex
|
||||
|
||||
@@ -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
|
||||
@@ -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 l’interface 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 l’interface utilisateur.
|
||||
|
||||
## Périmètre
|
||||
|
||||
@@ -63,7 +63,7 @@ L’inventaire 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 d’appel 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 d’une 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 d’une 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 d’un 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 d’un 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 l’exé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 d’autorité ; `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 jusqu’aux lectures stateful prévues, et aucune forme pré-stable n’est déclarée compatible réseau sans preuve de cluster.
|
||||
|
||||
@@ -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é
|
||||
|
||||
@@ -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 d’API 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 d’API 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 d’erreur structuré du workspace.
|
||||
Toutes les fonctions retournant `ks_core::Result<T>` utilisent le contrat d’erreur structuré du workspace.
|
||||
|
||||
## Décodage contextualisé
|
||||
|
||||
`DcApiInstructionDecoder` définit la reconnaissance et le décodage d’une 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 qu’ils 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 d’instructions 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, l’URL ou la référence externe, ainsi que l’autorité, 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 l’utilisation : 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 l’API. 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 l’intent autorise explicitement l’exé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 à l’orchestration de `kb-pipeline`.
|
||||
Avant utilisation du plan, le consommateur doit transmettre celui-ci au préflight et à l’orchestration 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 d’un backend de stockage.
|
||||
|
||||
```rust
|
||||
let result = kb_lib::MtApiEventMaterializer::materialize(
|
||||
let result = ks_lib::MtApiEventMaterializer::materialize(
|
||||
&materializer,
|
||||
&decoded_observation,
|
||||
);
|
||||
@@ -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),
|
||||
@@ -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.
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user