v0.1.0-pre.073

This commit is contained in:
2026-07-31 19:34:00 +02:00
parent 3b1ded6909
commit 5e1ad759d8
148 changed files with 14056 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/README.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Documentation active de Khadhroony Bot3
@@ -7,7 +7,7 @@
Ce répertoire contient la documentation active, normative ou opérationnelle de `khadhroony-bot3`.
La documentation historique de `khadhroony-bot2` est conservée sous `olddocs/archivekbot2/`. Elle ne doit être ni déplacée vers `docs/`, ni considérée comme normative. Tout nouveau document bot3 est réécrit après lecture du code, des tests, des matrices et des sources historiques pertinentes.
La documentation historique de `khadhroony-bot2` est conservée sous `olddocs/archivekbot2/`. La documentation historique de `khadhroony-bobobot` est conservée sous `olddocs/archivekbobobot/`. Elle ne doit être ni déplacée vers `docs/`, ni considérée comme normative. Tout nouveau document bot3 est réécrit après lecture du code, des tests, des matrices et des sources historiques pertinentes.
## 2. Architecture
@@ -94,3 +94,12 @@ Le premier lot documenté comprend :
## Audits
- [Audit dalignement des TODO par crate](audits/CRATE_TODO_VERSION_ALIGNMENT_AUDIT.md)
## Guides
- [Configuration](guides/CONFIGURATION.md)
- [Logging et tracing](guides/LOGGING.md)
- [RPC, backfill et WebSocket](guides/RPC_BACKFILL_AND_WEBSOCKET.md)
- [Extraction Core, replay et matérialisation](guides/REPLAY_CORE_EXTRACTION_AND_MATERIALIZATION.md)
- [PostgreSQL et stockage](guides/POSTGRES_STORAGE.md)
- [Validation Devnet](guides/DEVNET_VALIDATION.md)

View File

@@ -0,0 +1,79 @@
<!-- file: docs/guides/CONFIGURATION.md -->
<!-- version: 1 -->
# Guide de configuration
## Objectif
Ce guide décrit le chargement et lutilisation de la configuration bot3. La référence dAPI détaillée reste `kb-config/USAGE.md`.
## Fichiers actifs
- `config/example.config.json` : exemple utilisateur complet ;
- `config/schema.config.json` : contrat JSON formel ;
- `.env` et variantes locales : valeurs denvironnement non versionnées ;
- `.env.example` : noms de variables attendues sans secrets.
Le format actif est JSON. Le futur split de configuration prévu en `0.5.x` ne modifie pas le contrat actuel.
## Séquence de chargement
1. charger les fichiers denvironnement autorisés avec `load_workspace_environment` ;
2. lire le fichier JSON ;
3. résoudre les placeholders `${NAME}` ou `${NAME:-fallback}` ;
4. parser avec `load_config_from_str` ou `load_config_from_path` ;
5. valider le schéma et les invariants typés ;
6. sélectionner le profil actif avec `active_profile`.
## Exemple opérateur
```rust
let environment = match kb_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(
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) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
println!("loaded environment files={}", environment.loaded_files.len());
println!("active profile={}", profile.name);
```
## Invariants
- aucun secret ne doit être ajouté à lexemple versionné ;
- les placeholders non résolus doivent provoquer un diagnostic explicite ;
- le schéma embarqué et `config/schema.config.json` doivent rester identiques ;
- une sérialisation publique doit être précédée dune validation ;
- les noms de profils et rôles dendpoints doivent rester cohérents avec leurs consommateurs.
## Diagnostic
Pour isoler une erreur :
1. afficher la liste des fichiers denvironnement chargés ;
2. résoudre le JSON sans lécrire dans les logs sil contient des secrets ;
3. valider le schéma ;
4. valider le modèle typé ;
5. vérifier le profil actif ;
6. vérifier les rôles HTTP, WebSocket, stockage et logging.
## Références
- `kb-config/README.md` ;
- `kb-config/USAGE.md` ;
- `kb-config/TODO.md` ;
- `config/README.md` ;
- `docs/decisions/WINCODE_COMPATIBILITY_POLICY.md`.

View File

@@ -0,0 +1,65 @@
<!-- file: docs/guides/DEVNET_VALIDATION.md -->
<!-- version: 1 -->
# Guide de validation Devnet
## Objectif
Une validation Devnet démontre un parcours réel. Elle ne doit pas être confondue avec un test unitaire, une simulation ou une validation synthétique.
## Niveaux de preuve
1. test unitaire ou contractuel ;
2. validation synthétique sur fixtures ;
3. simulation RPC exacte ;
4. confirmation opérateur ;
5. soumission ;
6. confirmation finalisée ;
7. insertion canonique ;
8. extraction Core ;
9. replay et matérialisation ;
10. idempotence et vérification CLI finale.
Le rapport doit indiquer précisément les niveaux réellement exécutés.
## Prérequis
- profil Devnet explicite ;
- endpoint compatible ;
- wallet de test et fonds suffisants ;
- paramètres bornés ;
- scénario réutilisable hors desktop lorsque possible ;
- confirmation opérateur avant tout envoi.
## Commandes
Les scénarios peuvent être déclenchés depuis `kb-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
```
## Rapport
Conserver :
- scénario et version ;
- cluster ;
- signatures publiques ;
- opérations exécutées ;
- résultats de simulation et confirmation ;
- vérifications de stockage, replay et matérialisation ;
- limites et étapes non exécutées.
Ne pas conserver de keypair, secret ou preuve privée dans les deltas.
## ElGamal
Le registre ElGamal ne doit pas être déclaré validé sur Devnet ou Mainnet sans confirmation de déploiement, preuve `PubkeyValidity`, compte `Proof Context State` valide et scénario complet.
## Références
- `docs/PRE_062_DEVNET_VALIDATION_REPORT.md` ;
- `docs/DEVNET_EXECUTION_GUIDE.md` ;
- `kb-pipeline-demo-scenarios/USAGE.md` ;
- `kb-app-demo-desktop/USAGE.md`.

74
docs/guides/LOGGING.md Normal file
View File

@@ -0,0 +1,74 @@
<!-- file: docs/guides/LOGGING.md -->
<!-- version: 1 -->
# 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.
## Flux de démarrage
1. charger et valider la configuration avec `kb-config` ;
2. construire `LoggingConfig` ;
3. appeler `kb_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) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
tracing::info!(
target: kb_logging::tracing_target(),
routes = guard.route_count(),
"logging initialized"
);
```
## Routes
Une route définit notamment :
- sink console ou fichier ;
- niveau minimal ;
- format humain, compact, pretty ou JSON ;
- rotation ;
- targets exactes ou préfixes ;
- activation ANSI.
Les routes fichier ne doivent jamais écrire de secrets ou de keypairs.
## Nomenclature des targets
Les targets suivent les conventions du workspace, par exemple :
```text
kb-pipeline.backfill
kb-pipeline.decode-replay
kb-onchain-transport.http
kb-lib.executor.spl.token-2022
```
Une nouvelle target doit être ajoutée selon `docs/OPERATION_NAMING_CONVENTION.md` et les règles Khadhroony.
## Frontend desktop
Les fenêtres Tauri utilisent la permission tracing prévue par leurs capabilities. Les logs frontend sont adaptés vers le backend sans permettre au frontend de choisir arbitrairement une target sensible.
## Diagnostic
- vérifier les routes actives via `route_names()` ;
- confirmer le niveau global et les filtres spécifiques ;
- vérifier le chemin et les permissions dune route fichier ;
- vérifier que le guard nest pas détruit prématurément ;
- ne pas réinitialiser le subscriber global pendant lexécution.
## Références
- `kb-logging/README.md` ;
- `kb-logging/USAGE.md` ;
- `kb-config/USAGE.md` ;
- `docs/architecture/ARCHITECTURE.md`.

View File

@@ -0,0 +1,66 @@
<!-- file: docs/guides/POSTGRES_STORAGE.md -->
<!-- version: 1 -->
# 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.
## Connexion
```rust
let options = match kb_store::PostgresStoreOptions::new(
database_url,
10,
10_000,
true,
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let store = match kb_store::PostgresStore::connect(options).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
```
Toujours utiliser `masked_dsn()` dans les diagnostics.
## Domaines
- raw : acquisitions et observations ;
- Core : transactions, instructions, comptes et contexte normalisés ;
- decode : ledger, observations décodées et matérialisations ;
- replay : candidats et résumés bornés.
## Migrations
Les migrations sont idempotentes et ordonnées. Une nouvelle migration ne doit pas modifier rétroactivement une migration déjà publiée.
## Repositories
Les traits publics séparent le contrat de limplémentation PostgreSQL. Les opérations de lecture utilisent des filtres et paginations bornés.
## Diagnostics
- health snapshot ;
- migration snapshot ;
- backend diagnostics ;
- diagnostics des tables raw, Core et decode ;
- validation des noms de tables.
## Invariants
- aucune donnée canonique ne doit être dupliquée sans justification ;
- les écritures rejouables doivent être idempotentes ;
- la progression de campagne doit rester cohérente avec les lignes effectivement traitées ;
- les requêtes dynamiques nacceptent que des identifiants validés ;
- les erreurs PostgreSQL restent distinctes des erreurs de contrat.
## Références
- `docs/architecture/STORAGE_ARCHITECTURE.md` ;
- `kb-store/USAGE.md` ;
- `kb-store/README.md`.

View File

@@ -0,0 +1,77 @@
<!-- file: docs/guides/REPLAY_CORE_EXTRACTION_AND_MATERIALIZATION.md -->
<!-- version: 1 -->
# Guide extraction Core, replay et matérialisation
## Chaîne de traitement
```text
acquisition canonique
extraction Core
entrées de replay instruction-level
reconnaissance et décodage
observations et diagnostics
matérialisation optionnelle
```
## Extraction Core
Lextraction transforme une transaction canonique persistée en entités Core normalisées. Elle doit conserver les index, comptes, Program IDs, succès ou échec de transaction et contexte nécessaire aux instructions internes.
```rust
let summary = match kb_pipeline::execute_core_extraction(
request,
observer,
).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
```
## Decode replay
Le replay sélectionne des instructions Core, applique une politique de dispatch et invoque les décodeurs compatibles.
- une reconnaissance incompatible ne produit pas dobservation ;
- une transaction échouée peut produire une intention non committée ;
- les diagnostics doivent rester distincts des observations ;
- la même entrée et la même version de pipeline doivent produire un résultat déterministe.
## Matérialisation
La matérialisation est optionnelle et idempotente. Elle transforme les événements décodés en projections métier sans inventer un état confirmé.
Une tâche de matérialisation doit préciser :
- la provenance de lévénement ;
- le statut committé ou non committé ;
- les clés didempotence ;
- les invariants de mise à jour ;
- le traitement des événements obsolètes ou contradictoires.
## Reprise
La progression persistée ne doit avancer quaprès clôture cohérente du candidat. Les erreurs partielles restent rejouables.
## Tests de référence
- extraction Core legacy et v0 ;
- instructions outer et inner ;
- transactions échouées ;
- dispatch vers le décodeur exact ;
- matérialisation optionnelle ;
- replay forcé et idempotence ;
- corrélations stateful Token-2022.
## Références
- `docs/architecture/PIPELINE_ARCHITECTURE.md` ;
- `docs/architecture/STORAGE_ARCHITECTURE.md` ;
- `kb-pipeline/USAGE.md` ;
- `kb-lib/USAGE.md` ;
- `kb-store/USAGE.md`.

View File

@@ -0,0 +1,101 @@
<!-- file: docs/guides/RPC_BACKFILL_AND_WEBSOCKET.md -->
<!-- version: 2 -->
# 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 ;
- `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.
## Passage dun scénario validé vers le pipeline
`kb-pipeline-demo-scenarios` nest pas la destination finale dune logique réutilisable en production. Son rôle est de composer des APIs publiques existantes, préparer les fixtures, imposer les garde-fous opérateur et démontrer un parcours complet sur un réseau de validation.
Lorsquun composant dun scénario est validé et quil est générique, déterministe et utilisable indépendamment de la démonstration, il doit résider dans la couche appropriée :
- `kb-lib` pour le décodage, la matérialisation, la construction dinstructions, les préflights et les politiques de sécurité ;
- `kb-onchain-transport` pour les opérations réseau génériques ;
- `kb-store` pour les contrats de persistance ;
- `kb-pipeline` pour lorchestration réutilisable, y compris sur Mainnet lorsque le profil, la politique et lappelant lautorisent.
La crate de scénarios conserve :
- les fixtures et valeurs de démonstration ;
- la préparation Devnet ;
- les confirmations opérateur propres aux campagnes de validation ;
- les enchaînements de bout en bout destinés à prouver le comportement ;
- les rapports de validation et contrôles postérieurs au scénario.
Une validation Devnet ne provoque pas automatiquement une promotion vers Mainnet. Le composant promu doit également être indépendant du cluster, couvert par des tests, borné, compatible avec les politiques de sécurité et ne pas contenir dhypothèse propre aux fixtures Devnet.
## Rôles dendpoints
Un endpoint nest pas supposé supporter toutes les opérations. La configuration attribue des rôles HTTP ou WebSocket, puis les pools sélectionnent une cible compatible.
Avant une campagne :
1. résoudre le profil ;
2. vérifier la présence du rôle requis ;
3. vérifier les limites du fournisseur ;
4. fixer des bornes de pagination, concurrence et retry ;
5. préparer lobservateur et lannulation coopérative.
## Backfill HTTP
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(
request,
observer,
).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
println!("completed={}", summary.completed);
```
La frontière de reprise ne progresse quau travers des résultats contigus terminés. Une annulation ne doit pas sauter les candidats inachevés.
## WebSocket
La session WebSocket appartient au processus applicatif et non à la fenêtre qui laffiche. Pour `demo_ws` :
- fermer la fenêtre ne ferme pas une session active ;
- rouvrir la fenêtre relit létat courant ;
- la déconnexion résulte dune commande explicite, de la fermeture de lapplication ou dun timeout prévu ;
- les abonnements et notifications restent bornés.
## Adaptation canonique
Les réponses fournisseur sont converties avant le pipeline. Les différences legacy/v0, ALT, CPI, erreurs de transaction et encodages doivent rester explicites.
## Erreurs
Distinguer :
- transport indisponible ;
- erreur JSON-RPC distante ;
- réponse invalide ;
- adaptation canonique impossible ;
- erreur de stockage ;
- annulation opérateur.
## Tests de référence
- pools et rôles dendpoints ;
- fixtures `getTransaction` legacy et v0 ;
- pagination et reprise contiguë du backfill ;
- cycles de connexion, abonnement et déconnexion WebSocket ;
- maintien et restauration de létat desktop.
## Références
- `kb-onchain-transport/USAGE.md` ;
- `kb-pipeline/USAGE.md` ;
- `kb-app-demo-desktop/USAGE.md`.

View File

@@ -1,8 +1,12 @@
<!-- file: kb-config/CHANGELOG.md -->
<!-- version: 5 -->
<!-- version: 7 -->
# CHANGELOG — kb-config
## 0.1.0-pre.073
- ajout du guide transversal [`docs/guides/CONFIGURATION.md`](../docs/guides/CONFIGURATION.md) ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.

View File

@@ -1,8 +1,12 @@
<!-- file: kb-logging/CHANGELOG.md -->
<!-- version: 5 -->
<!-- version: 7 -->
# CHANGELOG — kb-logging
## 0.1.0-pre.073
- ajout du guide transversal [`docs/guides/LOGGING.md`](../docs/guides/LOGGING.md) ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.
@@ -13,7 +17,6 @@
## 0.1.0-pre.069
### Documentation
- création de `TODO.md`, `USAGE.md` et du changelog détaillé ;

View File

@@ -1,8 +1,12 @@
<!-- file: kb-onchain-transport/CHANGELOG.md -->
<!-- version: 2 -->
<!-- version: 4 -->
# CHANGELOG — kb-onchain-transport
## 0.1.0-pre.073
- ajout du guide transversal [`docs/guides/RPC_BACKFILL_AND_WEBSOCKET.md`](../docs/guides/RPC_BACKFILL_AND_WEBSOCKET.md) ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.

View File

@@ -1,12 +1,10 @@
<!-- file: kb-onchain-transport/TODO.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# TODO — kb-onchain-transport
## Avant alignement `0.4.6`
- [ ] Documentation - produire dans `pre.073` le guide transversal RPC, backfill et WebSocket à partir des APIs bot3 actuelles.
## Série `0.13.x`
- [ ] WebSocket - étendre le support Helius selon les contrats retenus.

View File

@@ -1,8 +1,12 @@
<!-- file: kb-pipeline-demo-scenarios/CHANGELOG.md -->
<!-- version: 2 -->
<!-- version: 4 -->
# CHANGELOG — kb-pipeline-demo-scenarios
## 0.1.0-pre.073
- ajout du guide transversal [`docs/guides/DEVNET_VALIDATION.md`](../docs/guides/DEVNET_VALIDATION.md) ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.

View File

@@ -1,8 +1,12 @@
<!-- file: kb-pipeline/CHANGELOG.md -->
<!-- version: 2 -->
<!-- version: 4 -->
# CHANGELOG — kb-pipeline
## 0.1.0-pre.073
- ajout du guide transversal [`docs/guides/REPLAY_CORE_EXTRACTION_AND_MATERIALIZATION.md`](../docs/guides/REPLAY_CORE_EXTRACTION_AND_MATERIALIZATION.md) ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.

View File

@@ -1,12 +1,11 @@
<!-- file: kb-pipeline/TODO.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# TODO — kb-pipeline
## Bloquants avant alignement `0.4.6`
- [ ] Audit - traiter les écarts pipeline réellement démontrés par `V0_4_6_ALIGNMENT_AUDIT.md`.
- [ ] Documentation - produire dans `pre.073` le guide de replay, extraction Core et matérialisation.
## Entre `0.4.6` et `0.4.7`

View File

@@ -1,8 +1,12 @@
<!-- file: kb-program-ids/CHANGELOG.md -->
<!-- version: 2 -->
<!-- version: 4 -->
# CHANGELOG — kb-program-ids
## 0.1.0-pre.073
- ajout de larchive documentaire bobobot, indexée par [`olddocs/archivekbobobot/001.README.md`](../olddocs/archivekbobobot/001.README.md), comme source historique future pour les Program IDs et IDL ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.

View File

@@ -1,8 +1,12 @@
<!-- file: kb-store/CHANGELOG.md -->
<!-- version: 5 -->
<!-- version: 7 -->
# CHANGELOG — kb-store
## 0.1.0-pre.073
- ajout du guide transversal [`docs/guides/POSTGRES_STORAGE.md`](../docs/guides/POSTGRES_STORAGE.md) ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.

View File

@@ -1,12 +1,10 @@
<!-- file: kb-store/TODO.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# TODO — kb-store
## Avant alignement `0.4.6`
- [ ] Documentation - produire dans `pre.073` le guide transversal dexploitation PostgreSQL et des contrats de stockage.
## Versions ultérieures
- [ ] Administration - définir les outils supplémentaires prévus par le ROADMAP avant leur implémentation.

View File

@@ -0,0 +1,31 @@
<!-- file: olddocs/archivekbobobot/001.README.md -->
<!-- version: 1 -->
# Archive documentaire khadhroony-bobobot
Cette arborescence conserve les documents historiques utiles de `khadhroony-bobobot v0.7.58-pre.003` en maintenant leurs chemins relatifs.
## Contenu conservé
- documents racine `README.md`, `CHANGELOG.md` et `ROADMAP.md` ;
- documents, rapports et prompts sous `docs/` ;
- IDL JSON historiques sous `idls/`.
## Contenu exclu
- code source Rust ;
- manifests de compilation ;
- configuration dexécution ;
- bases de données, fixtures et artefacts générés.
## Statut
Cette archive nest pas normative pour bot3. Elle sert de source historique pour reconstruire et vérifier notamment :
- les Program IDs ;
- les noms et familles de protocoles ;
- la présence et la provenance des IDL ;
- les références Solscan, Solana Explorer et dépôts Git ;
- les anciennes matrices de couverture.
Aucune donnée de cette archive ne doit être reprise automatiquement dans la documentation active. Chaque information doit être relue, vérifiée et adaptée.

View File

@@ -0,0 +1,92 @@
<!-- file: CHANGELOG.md -->
0.0.1 - initial skel
0.0.2 - Socle conforme
0.1.0 - Transport WebSocket générique
0.1.1 - Intégration Tauri minimale du WsClient
0.2.0 - Couche JSON-RPC WS Solana
0.3.0 - Registre subscriptions / notifications
0.3.1 - Ajout des helpers subscribe/unsubscribe à WsClient
0.3.2 - Ajout des helpers typed et du parsing typed basé sur solana-rpc-client-api
0.3.3 - Ajout du suffixe _raw aux helpers raw pour distinguer typed et raw
0.3.4 - Ajout de la fenêtre Demo Ws dans kb_demo_app pour tester les souscriptions live
0.3.5 - Stabilisation de Demo Ws, lecture correcte des endpoints activés depuis la config, limitation/throttling de laffichage UI sous fort débit
0.4.0 - Socle HttpClient générique async clonable, JSON-RPC HTTP 2.0, résolution dURL avec api_key_env_var, limiteur local req/sec + burst, helpers initiaux getHealth/getVersion/getSlot
0.4.1 - Ajout des premiers helpers HTTP Solana haut niveau, dans la continuité de lAPI du client WebSocket
0.4.2 - Préparation de la politique HTTP avancée : états de pause avant envoi, quotas par famille de méthodes et futur pool dendpoints
0.4.3 - Pool dendpoints HTTP
0.4.4 - Ajout de la fenêtre Demo Http dans kb_demo_app, exécution manuelle des méthodes HTTP via le pool, snapshot des endpoints et amélioration des presets UI
0.5.0 - Début du socle SQLite : configuration database, ouverture/validation de la base et premières briques de persistance
0.5.1 - Ajout des premières tables métier SQLite pour les endpoints connus HTTP/WS et les événements runtime, avec séparation entities/dtos/queries/types
0.5.2 - Ajout de la table des tokens observés, de leur statut local et des premières requêtes de persistance associées
0.5.3 - Préparation du stockage local des événements techniques et des signaux utiles à lanalyse, avec distinction runtime / on-chain / métier
0.5.4 - Ajout du modèle métier normalisé initial pour les DEX, tokens, pools, paires, composition des pools et listings
0.5.5 - Ajout des événements métier normalisés pour les swaps, liquidités, mints et burns de tokens
0.5.6 - Consolidation de la couche stockage : activation des foreign keys SQLite, lectures ciblées sur le modèle métier normalisé, index supplémentaires et tests unitaires dédiés
0.6.0 - Ajout du pipeline de détection technique : façade de persistance pour observations on-chain, signaux danalyse et candidats tokens depuis les connecteurs RPC
0.6.1 - Ajout du bridge de détection Solana WS : notifications JSON-RPC persistées en observations, avec détection initiale des mints SPL / Token-2022 depuis programNotification
0.6.2 - Branchement de WsClient vers le pipeline de détection via un relais asynchrone de notifications JSON-RPC WebSocket
0.6.3 - Enrichissement des notifications WebSocket utiles : extraction améliorée de pubkey, signature, owner, parsed account type et slot pour account/logs/signature notifications
0.6.4 - Premières règles de détection technique pour candidats pools/listings depuis programNotification en sappuyant sur les DEX connus en base
0.6.5 - Ajout de ws_manager.rs pour lorchestration multi-clients WebSocket, le bus dévénements unifié et le branchement centralisé du relais de détection
0.6.6 - Ajout de la fenêtre Demo Ws Manager dans kb_demo_app pour piloter plusieurs WsClient, visualiser le snapshot consolidé, tester le démarrage/arrêt par rôle et valider le flux unifié de WsEvent
0.7.0 - Ajout du socle de résolution transactionnelle orientée DEX : relais WS vers file de résolution, récupération getTransaction via HttpEndpointPool et persistance des résolutions dans les observations/signaux
0.7.1 - Ajout du modèle transactionnel enrichi : tables slots/transactions/instructions, requêtes daccès et projection structurée des transactions résolues
0.7.2 - Ajout du premier décodeur DEX spécifique Raydium AmmV4 / initialize2, persistance des événements DEX décodés et branchement automatique du décodage après résolution/projection transactionnelle
0.7.3 - Ajout de la détection métier depuis les événements DEX décodés, avec alimentation de kb_pools, kb_pairs, kb_pool_tokens et kb_pool_listings, et signaux de première apparition
0.7.4 - Ajout du premier lot multi-DEX v1 avec décodeurs Pump.fun (create_v2) et PumpSwap (buy/sell), plus détection métier Pump.fun vers token/pool/pair/listing
0.7.5 - Enrichissement de PumpSwap avec extraction des mints et du pool_v2, persistance des événements décodés enrichis et détection métier automatique pool/pair/listing
0.7.6 - Ajout du premier support Meteora DBC avec décodage create_pool/swap, persistance des événements décodés et détection métier automatique pool/pair/listing
0.7.7 - Ajout du premier support Meteora DAMM v2 avec décodage create_pool/swap, persistance des événements décodés et détection métier automatique pool/pair/listing
0.7.8 - Ajout du premier support Meteora DAMM v1 avec décodage create_pool/swap, persistance des événements décodés et détection métier automatique pool/pair/listing
0.7.9 - Ajout dun registre des surfaces de lancement, dune attribution automatique des pools détectés à une origine de lancement, et dun premier support Meteora Fun Launch au-dessus de Meteora DBC / DAMM
0.7.10 - Ajout du premier support Orca Whirlpools avec décodage create_pool/swap, persistance des événements décodés et détection métier automatique pool/pair/listing
0.7.11 - Ajout du premier support FluxBeam avec décodage create_pool/swap, persistance des événements décodés et détection métier automatique pool/pair/listing
0.7.12 - Ajout du premier support DexLab Swap/Pool avec décodage create_pool/swap, persistance des événements décodés et détection métier automatique pool/pair/listing
0.7.13 - Extension de la couche launch origins avec Bags et Moonit, ajout dun enregistrement programmatique des mappings Bags, et détection automatique Moonit via suffixe de token mint
0.7.14 - Ajout dune couche consolidée de traçabilité fondatrice multi-DEX avec enregistrement des pool origins, rattachement au decoded event, au pool/pair/listing et à léventuelle launch attribution
0.7.15 - Ajout dune couche wallets observés et participations observées, avec extraction des rôles depuis les payloads décodés et rattachement transaction / decoded event / pool / pair
0.7.16 - Ajout dune première couche trade events et pair metrics avec normalisation des swaps, agrégation par paire et branchement automatique dans le pipeline de résolution transactionnelle
0.7.17 - Ajout dune première couche WS hybride avec collecte de cibles `programSubscribe` / `accountSubscribe` et persistance technique dédupliquée des notifications `logs / program / account`
0.7.18 - Ajout dun premier backfill historique ciblé par token mint, basé sur `getSignaturesForAddress` + `getTransaction`, avec réutilisation du pipeline interne pour reconstruire transactions, pools, swaps, origins, wallets et métriques
0.7.19 - Ajout dune première couche holdings observés avec agrégation par couple wallet/token et branchement automatique dans le pipeline de résolution transactionnelle
0.7.20 - Ajout dune première couche candles / OHLCV avec matérialisation en base des timeframes usuels et régénération à la demande pour un timeframe arbitraire depuis les trade events
0.7.21 - Ajout dune première couche de signaux analytiques enrichis par paire avec persistance dédiée et détection de first trade, trade burst, buy/sell imbalance, price jump et volume spike
0.7.22 - Ajout dune première fenêtre `Demo Pipeline` dans `kb_demo_app` pour linspection en lecture seule du pipeline `0.7.x`, avec recherche par signature, token mint, pair id ou pool address, affichage structuré des transactions résolues, événements DEX décodés, pools, paires, listings, launch origins, pool origins, wallets et holdings observés, trade events, pair metrics, candles et signaux analytiques déjà persistés, ainsi que conservation dune instance partagée de la base SQLite pour éviter la réouverture et la réinitialisation du schéma à chaque commande UI
0.7.23 - Ajout du pilotage UI du backfill historique ciblé par `token mint` dans `kb_demo_app`, avec saisie du rôle HTTP et des limites de signatures, affichage du résumé de backfill, réinspection automatique du token dans `Demo Pipeline` lorsque des objets persistés sont effectivement reconstruits, et gestion explicite du cas où le backfill réussit sans matérialiser de token exploitable dans la base locale
0.7.24 - Ajout de laffichage graphique des candles / OHLCV dans `kb_demo_app` via `echarts`, avec sélection de paire et de timeframe, rendu chandelier + volume, et prise en charge des candles matérialisées ou régénérées à la demande depuis `Demo Pipeline`
0.7.25 - Enrichissement metadata des tokens, avec résolution locale limitée à SOL / WSOL, résolution des autres mints via comptes on-chain, Token-2022, Metaplex ou payloads DEX, et conservation explicite des cas non résolus
0.7.26 - Diagnostics locaux du pipeline persisté, correction de lagrégation instruction-scoped des swaps Raydium, clarification des compteurs de replay/upsert, et validation quaucun trade candidate issu dune transaction OK nest perdu
0.7.27 - Validation multi-DEX et non-régression du pipeline sur Pump.fun, PumpSwap, Raydium CPMM et Raydium CLMM, avec corpus de tests, diagnostics de référence et garanties sur les événements non pricés
0.7.28 - Refactor DEX commun et verrouillage des invariants de normalisation : séparation des événements décodés, actionnables, trade candidates et candle candidates ; conservation des transactions failed comme traçables mais non actionnables ; ajout de la règle bloquante empêchant tout trade/candle candidate sans payload de montants exploitable, notamment pour le cas partiel `meteora_damm_v1.swap` sans base/quote amount.
0.7.29 - Ajout dune matrice DEX commune (`dex_support_matrix`) utilisée par le catalogue DEX, la classification transactionnelle et lenregistrement des protocol candidates ; ajout du profil de validation `0.7.29_multi_dex_matrix_baseline` exposant la matrice dans le rapport de validation ; préparation explicite des surfaces planifiées sans inventer de program ids non vérifiés.
0.7.30 - Ajout dune taxonomie DEX plus fine pour les événements décodés : `eventLifecycleKind`, `eventActionability`, `nonTradeUseful`, compteurs diagnostics des événements non-trade utiles, trades non actionnables et classifications inconnues ; ajout du profil `0.7.30_non_trade_event_classification` sans modification volontaire de la matérialisation trade/candle.
0.7.31 - Application de la politique Option B : les transactions failed restent traçables dans les événements décodés mais ne peuvent plus alimenter `trade_events`, metrics ou candles ; le replay local réinitialise les tables de matérialisation marché avant reconstruction pour supprimer les anciennes lignes dérivées non actionnables.
0.7.32 - Clarification de la sémantique des diagnostics locaux : séparation des gaps littéraux de paires et des gaps bloquants/actionnables, ajout des compteurs de matérialisation par paire, résumé `pairActionabilitySummaries`, profil `0.7.32_validation_report_semantics` et garde-fous sur la matrice DEX sans modification de la matérialisation trade/candle.
0.7.33 - Ajout de la classification diagnostique `pairTradingReadiness` pour les paires, avec `quoteAssetClass`, `tradingRouteRequired`, résumé `pairTradingReadinessSummaries`, profil de validation `0.7.33_pair_trading_readiness` et mise à jour de la sélection UI Demo Pipeline 2 sans modifier la matérialisation trade/candle.
0.7.34 - Ajout du profil `0.7.34_non_trade_liquidity_lifecycle`, matérialisation des tables non-trade liquidité/lifecycle, warning non bloquant pour DEX attendus absents du corpus local, première tranche DLMM : `add_liquidity`, `remove_liquidity`, `initialize_position`, `initialize_bin_array`, intégration de la matérialisation non-trade dans les backfills token/pool ciblés, et distinction `PositionOpen`/`PositionClose` dans `LiquidityEventKind`.
0.7.35 - Ajout du profil `0.7.35_non_trade_fee_reward_admin`, matérialisation des événements non-trade fees/rewards/admin, raccordement aux diagnostics locaux et maintien strict de linvariant : aucun fee/reward/admin ne peut produire de trade, metric ou candle.
0.7.36 - Consolidation de la famille Meteora : corpus mixte `meteora_damm_v1`, `meteora_damm_v2`, `meteora_dbc` et `meteora_dlmm`, correction des discriminants DAMM v2 / DBC, validation du profil `0.7.36_meteora_family_consolidation`, et reclassement explicite des swaps DAMM v2 / DBC sans payload montant/prix en `non_actionable_trade` afin déviter tout trade/candle artificiel.
0.7.37 - Première tranche metadata/catalog : ajout du profil `0.7.37_token_metadata_catalog_enrichment`, exposition des compteurs metadata dans diagnostics/validation et raccordement UI Demo Pipeline 2 sans rendre les metadata manquantes bloquantes.
0.7.38 - Priorisation des metadata manquantes : ajout du profil `0.7.38_token_metadata_gap_prioritization`, samples `tokenMetadataGapSamples`, priorités tradable/quote/catalog, raccordement UI Demo Pipeline 2 et maintien du caractère non bloquant des metadata incomplètes.
0.7.39 - Réorientation DEX-first : distinction explicite des rôles `dex_effective`, `aggregator_router`, `launch_surface` et `to_verify` dans la matrice DEX, suppression de lalias ambigu `raydium`, ajout de `metaDAO` et `Printr` comme surfaces à vérifier sans `program_id`, profil `0.7.39_dex_first_effective_swap_surfaces`, validation locale avec invariants DEX-first maintenus et report des launch surfaces après les DEX effectifs.
0.7.40 - Ajout de Demo3 pour la constitution de corpus on-chain par `dex_code` / `program_id` via `getSignaturesForAddress` + `getTransaction`, extraction des mints, deltas SPL Token, comptes pool/state/vault/program candidats, ajout du backfill par signature dans Demo Pipeline 2, et validation pratique sur Raydium AMM v4 sans promotion automatique des comptes candidats.
0.7.41 - Raydium AMM v4 swap decoder v1 : décodage des inner instructions `675kPX...`, extraction pool/state, authority, vaults, mints, routeSource et montants exploitables, matérialisation trades/candles sur transactions OK, matrice AMM v4 passée en `supported`, et validation locale avec invariants trade/candle propres.
0.7.42 - Consolidation famille Raydium : audit conservatoire des instructions Raydium non décodées, décodage CLMM legacy `swap`, cleanup des audits remplacés, classification HTTP `getTransaction` comme requête lourde avec retry/backoff de backfill, mapping des événements non-swap prouvés `raydium_clmm` (`increase_liquidity_v2`, `decrease_liquidity_v2`, `open_position_with_token22_nft`, `close_position`) et `raydium_cpmm` (`initialize`, `withdraw`, `collect_creator_fee`), matérialisation de 25 liquidity events, 1 lifecycle event et 2 fee events sur corpus élargi, conservation des non-swaps AMM v4 legacy en audit.
0.7.43 - Reprise documentaire et normalisation DEX-first : `0.7.43` est conservé comme point de reprise non clos pour le lot Meteora, la suite est redécoupée par DEX/version séparés, le besoin dun ledger de décodage/replay est acté, les statuts `known` / `observed` / `decoded` / `materialized` / `verified_by_corpus` deviennent obligatoires, et aucun `program_id` ne doit être marqué vérifié sans preuve/corpus reproductible.
0.7.44 - Ledger de décodage/replay DEX : ajout de `k_sol_dex_decode_replay_ledger`, des DTO/entities/queries associés, des re-exports DB/lib, et intégration dans le replay local pour skipper uniquement létape de décodage DEX lorsquun passage certifié existe pour la même version logique de decoder. Les transactions multi-event ou multi-token restent marquées `unsafe` et sont redécodées sauf option future plus explicite ; le replay continue de reconstruire détection, matérialisation, trades, candles et classifications à partir des events persistés.
0.7.45 - Meteora DLMM normalisation finale : consolidation séparée de `meteora_dlmm` sur corpus dédié, maintien du wrapper Anchor `anchor_self_cpi_log` `e445a52e51cb9a1d`, enrichissement des swaps via `Swap` / `Swap2Evt`, cleanup des audits Anchor CPI swap déjà couverts, ajout des events upstream Git/IDL observés et vérifiés par corpus (`lb_pair_create_event`, `add_liquidity_event`, `remove_liquidity_event`, `claim_fee_event`, `position_create_event`, `position_close_event`, `close_position_if_empty`, `remove_liquidity_by_range2`, `add_liquidity_by_strategy2`, `add_liquidity_by_weight`), conservation des deux audits résiduels `e8abf2613a4d232d` en `instruction_audit` faute de mapping upstream Git/IDL confirmé, matérialisation locale validée avec `15` liquidity events et `6` lifecycle events sur le corpus DLMM élargi, et version logique replay `dex_decode.v0.7.45.dlmm_add_liquidity_strategies1`. Aucun nouveau `program_id` nest déclaré vérifié sans preuve/corpus reproductible.
0.7.46 - Meteora DAMM v1 events finalisés : extension conservatoire du decoder `meteora_damm_v1` depuis upstream Git/corpus local, events create_pool/add/remove liquidity/claim_fee/create_lock_escrow/lock_liquidity, corrections Demo3 ciblées et pagination multi-source, renommage documentaire/payload vers `upstream_git_*`, sans promotion de programme vault ou trade/candle sans preuve locale.
0.7.47 - Upstream Git Registry / DEX discovery preparation : registre générique `upstream_git`, extension Demo3 aux targets multi-surfaces, premiers decoders audit-only OpenBook v2 et Phoenix v1, matrices DEX/event coverage, revue DB et invariant maintenu : aucune entrée upstream ne produit trade/candle sans decoder spécialisé et corpus local.
0.7.48 - Raydium CPMM event coverage clôturé : couverture instructions/events CPMM Carbon/Raydium/fnzero, table coverage synchronisée, `k_sol_instruction_observations`, recherche Demo3 par instruction/discriminant, matérialisation validée des swaps, lifecycle, fees, admin/config, deposit/withdraw et `lp_change_event`, `swap_event` audit-only, fallback upstream remplacé quand le decoder local couvre lentrée.
0.7.49 - Raydium CLMM event coverage clôturé : 45 entrées listées, 33 instructions locales observées/décodées, 25 entrées matérialisées, ajout `k_sol_orderbook_events`, matérialisation des limit orders, liquidity, fees, rewards, admin/config et lifecycle prouvés par corpus, préparation audit-only des 11 Anchor Program-data events non observés, nettoyage des `raydium_clmm.instruction_audit` et `upstream_git.instruction_match` redondants, validation des invariants failed transaction / non-swap / trade-candle.
0.7.50-pre3 - Raydium Launchpad self-CPI/pool catalog correction : ajout du preset Demo3 `raydium_launchpad`, décodage direct des self-CPI Launchpad `trade_event` et `pool_create_event`, correction des indices `initialize*` (`pool_state=5`, `base_mint=6`, `quote_mint=7`) et routage des `initialize*` vers la matérialisation catalogue pool/pair Launchpad sans promotion trade/candle.
0.7.50 - Raydium Launchpad event coverage bootstrap : normalisation locale canonique vers `raydium_launchpad`, ajout de `RAYDIUM_LAUNCHPAD_PROGRAM_ID`, synchronisation des entrées Carbon Launchpad dans le registre upstream, fallback audit/mapped decoder pour discriminants Launchpad, enrichissement audit Anchor self-CPI, maintien conservatoire en `decoded_events_only`, rapport Launchpad et SQL de validation dédiés.
0.7.50-pre-r2 - Clôture CPMM/CLMM post-Launchpad : ajout des entrées Carbon `cpi_event` pour `raydium_cpmm` et `raydium_clmm`, ajout de `raydium_clmm.update_dynamic_fee_config`, normalisation des Program-data events CLMM, ajout de la table `k_sol_token_account_events` et de la matérialisation `create_support_mint_associated`, reclassement des familles ambiguës (`cpi_transport`, `liquidity_calculation`, `liquidity_change`, `position_open`, `pool_create`, `admin_config`, `account_create`, `idl_management`), codage du discriminant CPMM `40f4bc78a7e9690a` comme `raydium_cpmm.anchor_idl_instruction` decoded-only après inspection Solscan, et contexte de secours pour matérialisation liquidity CLMM via événements frères quand possible.
0.7.51 - Raydium AMM v4 event coverage clôturé : decoder maximal local pour tous les discriminants officiels AMM v4 `00..11`, spécialisation des swaps `swap_base_in/out` et `swap_base_in/out_v2`, suppression durable du `raydium_amm_v4.swap` legacy, index AMM v4 en discriminant 1 octet, matérialisation validée des swaps, liquidity, lifecycle, fees, admin/config et side effects orderbook, `pre_initialize` conservé comme lifecycle audit deprecated/partial, `simulate_info` decoded-only, reset replay renforcé par `protocol_name`, validation des invariants failed/non-swap/single-target/unexplained gaps et maintien de `raydium_pool_v4` en audit conditionnel sans decoder autonome.
0.7.52 - Raydium Stable Swap event coverage clôturé : decoder legacy 1 octet pour la surface locale `00..0d`, matérialisation lifecycle/liquidity/admin/fee/orderbook selon contexte, swaps `swap_base_in/out` matérialisés uniquement depuis deltas de vaults exacts (`stable_swap_vault_balance_delta`), conservation des bornes dinstruction comme audit-only, failed transactions decoded-only avec skip reasons, validation locale 407 tests et clippy `-D warnings` OK.
0.7.53 - Clôture PumpSwap : décodage transaction/log complet, matérialisation `buy/sell/buy_exact_quote_in` depuis sources exactes, events Anchor audit-only, tests synthétiques IDL, validation globale coverage SQL et non-régression Raydium.
0.7.54 - Clôture Pump.fun : decoder maximal local depuis IDL Solscan/upstream, décodage des 40 instructions et 23 events Anchor connus, matérialisation validée des trades `buy/sell/buy_exact_sol_in` et `trade_event` v2/exact sans double-count, non-trades launch/fee/reward/admin selon contexte, validation SQL Pump.fun propre et ouverture de `0.7.55 pump_fees`.
0.7.55 - Clôture Pump Fees : decoder local maximal `pump_fees` depuis l'IDL locale, `29` instructions et `20` events Anchor couverts, tests synthétiques des Anchor IDL non observés, matérialisation prudente fee/reward/admin/lifecycle, `get_fees` decoded-only, transactions failed audit-only, aucun trade/candle direct et SQL de validation Pump Fees propre.
0.7.56 - Clôture Meteora DBC : decoder local maximal depuis l'IDL `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN`, couverture des 28 instructions et 23 events Anchor, matérialisation validée des swaps `swap/swap2`, lifecycle, admin/config, lockers/migrations et fees/surplus/leftover, ajout du modèle `k_sol_fee_event_amounts` pour les legs de montants fee, helper générique parent fee -> legs scalaires, recovery fee `allowlisted_inner_spl_transfer` strictement allowlistée pour anciens DEX, validation croisée Pump/Raydium, 446 tests passés, clippy OK et SQL de fermeture DBC propre.
0.7.57 - Clôture Meteora DLMM : decoder local maximal `meteora_dlmm` sur `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo`, couverture des `76` instructions IDL, `30` events Anchor et `12` accounts, correction du discriminant non-IDL local `75c73e67068e1fcb` en `initialize_preset_parameter_v2`, matérialisation validée des swaps, exact-out, liquidity, bins, positions, lifecycle, fees, rewards, admin/config et limit orders, `swap_event/swap2_evt` routés en lifecycle `swap_log` sans double-count trade/candle, recovery fee/reward strictement allowlistée depuis inner SPL transfers, cleanup coverage duplicates, validation finale `460` tests passés, clippy OK et SQL de fermeture DLMM propre.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
<!-- file: docs/ARCHIVE_ORGANIZATION.md -->
# Organisation de larchive documentaire
La racine du workspace garde les documents de pilotage principaux :
```text
README.md
ROADMAP.md
CHANGELOG.md
```
Les documents spécialisés sont rangés par usage :
```text
docs/ matrices et revues transversales
docs/reports/ rapports de couverture par tranche DEX/version
docs/prompts/ prompts de reprise de session
validation_sql/ scripts SQL de validation
```
Cette réorganisation ne modifie pas le code Rust/Tauri. Elle sert uniquement à séparer les fichiers de pilotage, les rapports, les prompts et les validations SQL.

View File

@@ -0,0 +1,401 @@
<!-- file: docs/DB_EVENT_MODEL_REVIEW.md -->
# Database Event Model Review — `khadhroony-bobobot` `0.7.47-1FE5`
## Note `0.7.56` — modèle fee parent + amount legs
`0.7.56` ajoute `k_sol_fee_event_amounts` comme table enfant de `k_sol_fee_events`. Cette table est obligatoire dès qu'un event fee porte plusieurs montants, plusieurs mints ou plusieurs destinations. Le parent `k_sol_fee_events` reste l'ancre logique liée au `decoded_event_id`; les legs portent `leg_index`, `token_mint`, `amount_raw`, comptes source/destination et `amount_source`.
Invariants :
- tout parent fee avec `fee_token_mint + fee_amount_raw` doit avoir un leg scalaire automatique ;
- un fee multi-leg/multi-mint ne doit pas agréger artificiellement le parent ;
- les replays doivent supprimer/remplacer les legs avec le parent ;
- les transactions failed restent audit-only ;
- la recovery `allowlisted_inner_spl_transfer` est strictement allowlistée et ne s'applique pas par défaut aux futurs decoders.
Le contrôle standard `parent scalar without leg` doit être vide sur toute base de validation. Voir `docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md`.
## Conclusion courte
La base actuelle est **suffisante pour continuer le décodage exhaustif en audit-only**, parce que `k_sol_dex_decoded_events` garde les events décodés avec `payload_json`.
La base actuelle est **partiellement insuffisante pour exploiter tous les events en requêtes métier**, parce que certaines familles importantes nont pas encore de tables dédiées ou de modèle normalisé :
- transfers SPL / Token-2022 ;
- token account create/close ;
- wrap/unwrap SOL ;
- orderbook orders/fills/settlements ;
- vault deposit/withdraw ;
- launch/migration ;
- lock/unlock LP ;
- staking/unstaking ;
- coverage matrix persistée par discriminator/event.
## Ce qui existe déjà
Daprès le README, le modèle contient déjà notamment :
- `k_sol_chain_transactions`;
- `k_sol_chain_instructions`;
- `k_sol_dex_decoded_events`;
- `k_sol_trade_events`;
- `k_sol_liquidity_events`;
- `k_sol_pool_lifecycle_events`;
- `k_sol_fee_events`;
- `k_sol_reward_events`;
- `k_sol_pool_admin_events`;
- `k_sol_token_mint_events`;
- `k_sol_token_burn_events`;
- `k_sol_transaction_classifications`;
- `k_sol_protocol_candidates`;
- `k_sol_dex_decode_replay_ledger`.
Ces tables couvrent déjà les besoins principaux :
| Besoin | Couverture actuelle |
|---|---|
| Stockage brut/audit de tout event décodé | Oui, via `k_sol_dex_decoded_events.payload_json`. |
| Trades/candles | Oui. |
| Liquidity/lifecycle/fee/reward/admin | Oui, au moins structurellement. |
| Mint/burn | Oui, structurellement. |
| Replay/skip sûr | Oui, via ledger. |
| Event coverage attendu vs observé | Non ou seulement implicite. |
| Transfers/token account lifecycle | Non spécialisé. |
| Orderbook events | Non spécialisé. |
| Vault events | Non spécialisé. |
| Launch/migration | Non spécialisé ou dispersé. |
## Ne pas modifier la DB trop vite
Il ne faut pas créer une table pour chaque DEX ou chaque event upstream.
La bonne stratégie :
1. Décoder tout ce quon peut en `k_sol_dex_decoded_events`.
2. Ajouter `eventFamily`, `eventSemanticKind`, `eventActionability`, `proofStatus`, `sourceRepo`, `sourcePath`.
3. Matérialiser seulement les familles prouvées et utiles.
4. Ajouter des tables transversales uniquement quand plusieurs DEX en ont besoin.
## Ajouts DB recommandés
### 1. `k_sol_dex_event_coverage_entries`
But : stocker ce qui est **attendu/listé** depuis les sources upstream, même si non observé.
Colonnes conceptuelles :
```text
id
decoder_code
program_id
program_family
surface_kind
source_repo
source_path
entry_kind -- instruction/event/account/log/program_data
entry_name
discriminator_hex
discriminator_len
event_family -- swap/burn/mint/admin/etc.
expected_db_target
proof_status
local_event_kind
observed_count
materialized_count
trade_count
first_signature
last_signature
notes
created_at
updated_at
```
Rôle : rendre la couverture objectivable. Exemple : “Carbon liste 42 instructions Raydium CPMM, notre code en décode 18, 4 sont matérialisées”.
### 2. `k_sol_token_transfer_events`
But : matérialiser les transfers significatifs hors trade.
Colonnes conceptuelles :
```text
id
transaction_id
instruction_id
decoded_event_id
signature
slot
program_id
token_program_id
mint
source_token_account
destination_token_account
source_owner
destination_owner
amount_raw
amount_ui
transfer_kind -- transfer, transfer_checked, routed_transfer, vault_transfer
reason -- audit_only, vault_movement, migration, settlement, unknown
payload_json
```
Important : ne pas créer de trade depuis cette table. Elle sert au risque/analyse.
### 3. `k_sol_token_account_events`
But : suivre create/close/init ATA/token accounts.
```text
id
transaction_id
instruction_id
decoded_event_id
signature
slot
event_kind -- create_ata, init_account, close_account, wrap_sol, unwrap_sol
account_address
mint
owner
token_program_id
lamports_delta
payload_json
```
Cela aide à comprendre WSOL wrap/unwrap, close accounts, cleanup bots, préparation de trades.
### 4. `k_sol_orderbook_events`
But : stocker OpenBook/Phoenix et autres CLOB sans les confondre avec swaps AMM.
```text
id
transaction_id
instruction_id
decoded_event_id
signature
slot
protocol_name
market_account
event_kind -- order_place, order_cancel, order_fill, settle_funds, consume_events, open_orders_create, open_orders_close
side
price_lots
base_lots
quote_lots
maker
taker
client_order_id
raw_event_name
interpretation_status
payload_json
```
Les fills ne deviennent `trade_events` que quand maker/taker, base/quote, lots/decimals et sens économique sont validés.
### 5. `k_sol_vault_events`
But : suivre vault deposit/withdraw, Meteora Vault, Kamino/Vault-like programs.
```text
id
transaction_id
instruction_id
decoded_event_id
signature
slot
protocol_name
vault_account
event_kind -- deposit, withdraw, claim, rebalance, update_config
mint_a
mint_b
amount_a_raw
amount_b_raw
owner
payload_json
```
### 6. `k_sol_launch_events`
But : séparer launch/bonding/migration du DEX effectif.
```text
id
transaction_id
instruction_id
decoded_event_id
signature
slot
launch_protocol
event_kind -- create, buy, sell, migrate, graduate, initialize_curve, close_curve
token_mint
curve_account
migration_target_program
migration_pool
quote_mint
amount_token_raw
amount_quote_raw
payload_json
```
### 7. `k_sol_liquidity_lock_events`
But : traiter LP lock/unlock explicitement.
```text
id
transaction_id
instruction_id
decoded_event_id
signature
slot
protocol_name
pool_id
pair_id
lock_account
owner
event_kind -- create_lock, lock, unlock, extend_lock, close_lock
lp_mint
lp_amount_raw
unlock_time
payload_json
```
## Alternative minimaliste
Si on veut éviter trop de migrations immédiates, le minimum à ajouter dabord est :
1. `k_sol_dex_event_coverage_entries`;
2. `k_sol_token_transfer_events`;
3. `k_sol_orderbook_events`.
Les autres tables peuvent attendre.
## Impact sur le plan des versions
Chaque version DEX doit répondre à deux questions :
### Couverture decoder
- A-t-on listé tous les events upstream ?
- A-t-on un decoder audit pour chaque discriminator connu ?
- Les events non observés sont-ils marqués `upstream_git_mapped_unverified` ?
### Couverture DB
- Levent peut-il rester dans `k_sol_dex_decoded_events` ?
- Doit-il être matérialisé dans une table existante ?
- Faut-il une table transversale nouvelle ?
- Une table nouvelle peut-elle servir à plusieurs DEX ?
## Décision pratique pour `0.7.48`
Avant de reprendre `raydium_cpmm`, faire une micro-tranche DB/doc :
```text
0.7.48-pre — event coverage + DB model checkpoint
```
Objectif :
- ajouter ou documenter `k_sol_dex_event_coverage_entries`;
- ne pas encore ajouter toutes les tables métier ;
- produire un rapport par DEX :
- listed events,
- decoded events,
- materialized events,
- missing DB target,
- trade_count invariant.
## Note `0.7.48` — Raydium CPMM sans nouvelle table DB
La tranche `0.7.48` confirme que `k_sol_dex_decoded_events` suffit pour continuer la couverture exhaustive CPMM en audit-only.
Aucune nouvelle table n'est ajoutée pour CPMM :
- les swaps exploitables restent dans `k_sol_trade_events` via les chemins existants ;
- `deposit` / `withdraw` utilisent les tables non-trade existantes seulement si le corpus et le rattachement pool/pair sont fiables ;
- les fees/admin/config/permission restent non-trade et ne peuvent pas produire candles ;
- les transfers SPL, account lifecycle, wrap/unwrap SOL, vault et launch/migration restent des familles transversales futures, à promouvoir seulement si plusieurs DEX en justifient le besoin.
## Note 0.7.48 final — Instruction observations et CPMM
La tranche `raydium_cpmm` ajoute `k_sol_instruction_observations` comme table technique dindex local, non comme table métier. Elle sert à chercher les instructions observées par `decoder_code`, `instruction_name` et `discriminator_hex`, puis à relier ces observations au corpus backfillé/rejoué.
La matérialisation métier reste limitée aux tables existantes : `k_sol_trade_events`, `k_sol_liquidity_events`, `k_sol_pool_lifecycle_events`, `k_sol_fee_events` et `k_sol_pool_admin_events`. Les opérations SPL Token / Token-2022 visibles dans Solscan (`burn`, `transfer`, `transferChecked`, `closeAccount`) ne sont pas promues en tables métier dans `0.7.48`; elles justifient seulement une future table transversale si plusieurs DEX le nécessitent.
## Note 0.7.49 — Raydium CLMM sans nouvelle table transversale immédiate
La reprise `raydium_clmm` confirme que la table `k_sol_dex_event_coverage_entries` suffit pour inventorier les instructions/events CLMM avant promotion métier. Les entrées IDL-only ajoutées en `0.7.49` restent des lignes de coverage et de recherche, pas des tables métier.
Aucune nouvelle table transversale n'est ajoutée dans ce delta :
- les swaps spécialisés restent dans `k_sol_trade_events` seulement lorsque les montants et le sens économique sont validés ;
- les liquidity/positions CLMM restent à distinguer : une position NFT/tick n'est pas forcément une liquidity row simple ;
- les fees et rewards peuvent utiliser `k_sol_fee_events` / `k_sol_reward_events` seulement après preuve de corpus et typage fin ;
- les side effects SPL Token / Token-2022 (`mint`, `burn`, `transfer`, `closeAccount`, wrap/unwrap SOL) restent indirects tant qu'une preuve multi-DEX ne justifie pas une table transversale.
La table `k_sol_instruction_observations` reste technique : elle sert à trouver des signatures et discriminants observés localement, sans être une preuve métier.
## Note `0.7.50-pre-r2` — `k_sol_token_account_events`
La re-vérification Raydium CLMM introduit une table dédiée `k_sol_token_account_events` pour les événements de cycle de vie de comptes token qui ne sont ni des swaps, ni de la liquidité, ni du lifecycle pool. Le premier cas d'usage est `raydium_clmm.create_support_mint_associated`.
### Règle de matérialisation
- `create_support_mint_associated` cible `k_sol_token_account_events`.
- `cpi_event` reste `k_sol_dex_decoded_events_only` : c'est un transport Anchor/CPI, pas un event métier autonome.
- `liquidity_calculate_event` reste `k_sol_dex_decoded_events_only` : c'est un event de calcul/diagnostic, pas une mutation de liquidité fiable.
- `create_operation_account` et `update_operation_account` relèvent de `k_sol_pool_admin_events` quand le corpus le permet.
### Colonnes principales
`k_sol_token_account_events` conserve `transaction_id`, `decoded_event_id`, `dex_id`, `pool_id`, `pair_id`, `signature`, `instruction_index`, `slot`, `protocol_name`, `program_id`, `event_kind`, `token_account`, `token_mint`, `owner_wallet`, `account_action`, `payload_json`, `executed_at` et `created_at`.
Cette table permet de suivre les événements Token-2022/ATA significatifs sans les confondre avec les trades ou les liquidités.
## Note `0.7.51` — impact AMM v4 sur le modèle DB
Aucune nouvelle table n'est ajoutée pour `raydium_amm_v4`.
Décisions DB maintenues :
- `k_sol_instruction_observations` reste une table technique d'indexation instruction/discriminant ;
- AMM v4 utilise des discriminants d'un octet, donc l'index technique doit conserver `09`, `0b`, `10`, `11`, etc. sans les convertir en discriminants Anchor huit octets ;
- le refresh de `k_sol_instruction_observations` reconstruit les observations par transaction avant upsert, afin de supprimer les restes historiques en huit octets après changement de stratégie d'indexation ;
- les side effects SPL Token / Token-2022 restent transversaux et ne doivent pas être promus comme events directs `raydium_amm_v4.*` ;
- les side effects Serum/OpenBook de AMM v4 doivent être documentés comme contexte orderbook, pas comme trades OpenBook autonomes ;
- `raydium_pool_v4` ne justifie aucune table ni aucun decoder séparé sans corpus local.
Le modèle actuel suffit pour ouvrir la tranche : decoded events + coverage entries + instruction observations + matérialisations existantes trade/liquidity/lifecycle/fee/admin/orderbook. Une extension future orderbook/vault/token-account ne doit être ajoutée qu'après preuves multi-DEX.
### Clôture `0.7.51` — AMM v4 et modèle DB
La validation finale AMM v4 confirme qu'aucune nouvelle table n'est requise pour `raydium_amm_v4`.
Règles validées :
- chaque decoded event AMM v4 matérialisé cible au plus une table métier principale ;
- `migrate_to_open_book`, `monitor_step` et `admin_cancel_orders` alimentent `k_sol_orderbook_events` uniquement ;
- `pre_initialize` alimente `k_sol_pool_lifecycle_events` comme audit deprecated/partial, sans création de paire exploitable ;
- `simulate_info` reste dans `k_sol_dex_decoded_events` uniquement ;
- les `deposit` / `withdraw` sans pool/pair catalogue ou sans deltas exploitables restent decoded-only expliqués ;
- les side effects SPL Token / Token-2022 restent transversaux.
Contrôle final AMM v4 : le SQL `materialized_target_count > 1` doit rester vide.
## 0.7.52 — Raydium Stable Swap DB model decision
No schema migration is introduced for `raydium_stable_swap` at tranche opening.
Stable Swap maps to existing DB targets:
- `initialize` / `pre_initialize``k_sol_pool_lifecycle_events` when pool context is sufficient;
- `deposit` / `withdraw``k_sol_liquidity_events` when pool/pair context is sufficient;
- `swap_base_in` / `swap_base_out``k_sol_trade_events` and candles only when mints and amounts are reliable;
- `swap_event``k_sol_dex_decoded_events` only until a corpus-backed materialization decision exists.
Side effects from SPL Token, Token-2022, Serum/OpenBook-style accounts or router transport remain transverse evidence and are not promoted as direct `raydium_stable_swap.*` business events without an explicit later DB decision.

View File

@@ -0,0 +1,365 @@
<!-- file: docs/DEX_DECODER_MATRIX.md -->
# DEX Decoder Matrix — `khadhroony-bobobot` `0.7.57 meteora_dlmm closed`
## Note `0.7.57 closed` — Meteora DLMM clôturé et suite discovery
La tranche `0.7.57` ferme `meteora_dlmm` / `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo`. Elle remplace la couverture partielle historique `0.7.45` par un decoder local maximal aligné sur l'IDL locale, avec correction du discriminant `75c73e67068e1fcb` en `initialize_preset_parameter_v2`. Les résidus observés utiles ne restent plus en decoded-only.
La prochaine étape n'est pas un nouveau decoder direct : `0.7.58 sqlite_db_transaction_merger` construit d'abord un corpus consolidé de non-régression, puis `0.7.59 demo4_program_surface_discovery` affichera et scorera les contenus inconnus/non pris en compte, sans auto-materialization ni auto-promotion.
## Note `0.7.56 closed` — Meteora DBC clôturé, DLMM ensuite
La tranche `0.7.56` ferme `meteora_dbc` / `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN` depuis l'IDL locale `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json`.
Le decoder local couvre les `28` instructions et les `23` events Anchor IDL. Les trades/candles ne sont produits que depuis `swap` / `swap2` avec montants et mints fiables. Les migrations, lockers, lifecycle, admin/config et fees sont matérialisés quand le contexte est fiable ; sinon ils restent decoded-only/audit-only avec raison explicite. Les transactions failed restent audit-only.
Le modèle fee est maintenant transversal : `k_sol_fee_events` reste le parent, `k_sol_fee_event_amounts` porte les legs. Les parents fees scalaires créent automatiquement un leg ; les fees multi-leg/multi-mint n'agrègent pas artificiellement le parent. La recovery `allowlisted_inner_spl_transfer` est allowlistée et ne s'applique jamais par défaut à un futur decoder.
La prochaine tranche programmée est `0.7.57 meteora_dlmm` avec objectif full decode + full materialization sur `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo`.
## Note `0.7.55 closed` — Pump Fees clôturé, Meteora DBC ensuite
La tranche `0.7.55` ferme `pump_fees` comme surface fee/config/accounting. Le decoder local couvre les `29` instructions et `20` events Anchor de l'IDL locale, avec tests synthétiques pour les Anchor events IDL non observés. Les transactions failed restent audit-only, `get_fees` reste decoded-only, et aucun trade/candle direct n'est créé.
Deux discriminators Solscan non présents dans l'IDL locale restent conservés en coverage comme surfaces futures : `revoke_fee_sharing_authority_event` (`7217653c0ebe993e`) et `transfer_fee_sharing_authority_event` (`7c8fc6f54db808ec`).
La tranche suivante après `0.7.55` a été `0.7.56 meteora_dbc`, désormais clôturée ; la prochaine tranche courante est `0.7.57 meteora_dlmm`.
## Note `0.7.54 closed` — Pump.fun clôturé
La tranche `0.7.54` ferme `pump_fun` avant `pump_fees`. La surface Pump.fun principale est couverte depuis le code local, l'IDL Solscan locale `idls/pump_fun.6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.json`, le registre upstream et le corpus SQLite.
Décisions structurantes :
- `pump_fun` est `supported / closed` côté decoder et validation locale ;
- toutes les instructions/events connus de l'IDL locale sont inventoriés ;
- `buy`, `sell`, `buy_exact_sol_in` peuvent être matérialisés directement avec montants fiables ;
- `buy_v2`, `sell_v2`, `buy_exact_quote_in_v2` restent decoded/audit/routing et s'appuient sur `pump_fun.trade_event` pour la matérialisation canonique ;
- `pump_fun.trade_event` matérialise les v2/exact quand les montants exécutés et la corrélation instruction sont prouvés ;
- les non-trades Pump.fun alimentent uniquement les tables business adaptées ou restent audit-only avec skip reason.
`pump_fees` est clôturé en `0.7.55`; la prochaine tranche est `0.7.56 meteora_dbc`.
## Note `0.7.53 final` — PumpSwap clôturé et sources IDL locales
Le répertoire `idls/` devient une source locale de savoir en plus des liens Git. Les IDL Solscan locales doivent être comparées au registre upstream et au corpus avant promotion métier. `pump_swap` est clôturé côté transaction/log decoder : instructions IDL, events Anchor audit-only, `buy_exact_quote_in` via `BuyEvent` exact, tests synthétiques et SQL global. Raydium AMM v4 / CLMM / CPMM ne nécessitent pas de correction dans cette clôture ; les gaps Meteora sont reportés.
`sol-parser-sdk/idls/raydium_pool_v4.json` a été vérifié comme source annexe distincte des fichiers `idls/raydium_*.json` présents localement : il expose notamment `swapBaseIn` et des comptes OpenBook/Serum, mais aucun fichier local ne porte ce nom ni ne correspond à son empreinte/format. Il reste donc un audit conditionnel, pas une source bloquante pour `0.7.53`.
Cette matrice complète `kb_lib/src/dex_support_matrix.rs`. Elle documente **ce qui est fait**, **ce qui reste à faire**, et **le niveau de preuve attendu** par DEX/version.
## Règle de lecture
| Statut | Sens |
|---|---|
| `supported` | Decoder local actif et matérialisation métier possible sur corpus validé. |
| `partial` | Decoder partiel ou surface partielle : des events existent, mais la couverture nest pas complète. |
| `audit-only` | Decoder local spécialisé, mais aucun trade/candle/matérialisation marché. |
| `planned` | Program id ou surface connue, mais decoder non prioritaire ou non activé. |
| `to_verify` | Source externe ou candidat : aucun statut vérifié sans corpus local. |
| `ignored/historical` | À conserver pour historique ou compatibilité, mais non prioritaire. |
## Sources upstream à comparer
- Carbon decoders : `https://github.com/sevenlabs-hq/carbon/tree/main/decoders`
- Solana Streamer : `https://github.com/0xfnzero/solana-streamer`
- Sol Parser SDK IDLs : `https://github.com/0xfnzero/sol-parser-sdk/tree/main/idls`
- Pinax Substreams Solana IDLs : `https://github.com/pinax-network/substreams-solana-idls/tree/main/src`
- HODL Warden Solana Tx Parser : `https://github.com/hodlwarden/solana-tx-parser/tree/main/src`
- OpenBook v2 : `https://github.com/openbook-dex/openbook-v2`
- Phoenix on-chain MM : `https://github.com/all-in-one-blockchain/phoenix-onchain-mm`
- Vybe DEX/AMM support list : `https://docs.vybenetwork.com/docs/available-dexs-amms`
## Matrice prioritaire DEX/version
| Ordre | DEX/version | État actuel | Fait | Reste à faire |
|---:|---|---|---|---|
| 1 | `raydium_cpmm` | `supported / 0.7.50-pre-r2 closure recheck` | Couverture CPMM clôturée : swaps, lifecycle, fees, admin/config, deposit/withdraw, `lp_change_event`, `swap_event` decoded-only, `cpi_event` transport Carbon et `anchor_idl_instruction` Solscan/manual pour `40f4bc78a7e9690a`. | Ne pas promouvoir `anchor_idl_instruction` : c'est de la gestion Anchor IDL, pas un événement AMM métier. |
| 2 | `raydium_clmm` | `supported / 0.7.50-pre-r2 closure recheck` | Couverture CLMM complétée : `cpi_event`, `update_dynamic_fee_config`, Program-data events locaux, `create_support_mint_associated` vers `k_sol_token_account_events`, familles sans `unknown`, router/swap Program-data en decoded-only. | Rejouer la base CLMM et confirmer que les seuls résidus sont `decoded_events_only`, transactions failed ou absence prouvée de contexte pool/pair. |
| 3 | `raydium_launchpad` | `bootstrap / 0.7.50` | Surface canonique normalisée, 1 entrée programme + 26 discriminants Carbon/IDL listés, fallback audit/mapped decoder, SQL dédié. | Créer DB neuve, backfill par discriminant, replay forcé, promouvoir seulement après corpus local. |
| 4 | `raydium_amm_v4` | `supported / 0.7.51 closed` | Decoder maximal AMM v4 `00..11`, swaps spécialisés, lifecycle/liquidity/fees/admin/orderbook validés. | Stable Swap clôturé ensuite en `0.7.52`; surveiller les surfaces restantes. |
| 5 | `raydium_stable_swap` | `supported / 0.7.52 closed` | Decoder legacy 1 octet, surface `00..0d`, swaps matérialisés depuis deltas vault exacts. | Surveiller seulement de nouveaux discriminants ou `swap_event` observé. |
| 6 | `raydium_pool_v4` | `to_verify / late-phase conditional audit` | IDL annexe mentionnée par fnzero, non présente dans l'archive locale, pas de program id/rôle confirmé ici. | Ne pas promouvoir tant que program id distinct, rôle exact et corpus exploitable ne sont pas confirmés. |
| 7 | `pump_swap` | `supported / 0.7.53 closed` | `buy`, `sell` + `buy_exact_quote_in` matérialisable via `BuyEvent` exact ; instructions non-trade spécialisées : liquidity, fee/creator fee, admin/config, cashback/token incentives, volume accumulator ; events Anchor autonomes audit-only. | Trades/candles uniquement depuis montants exacts ; failed tx decoded-only ; `instruction_bounds_only` reste decoded-only ; tests synthétiques IDL et SQL global ajoutés. |
| 8 | `pump_fun` | `supported / 0.7.54 closed` | Surface launch/bonding/migration Pump.fun couverte localement ; trades directs et `trade_event` canonique validés. | Ne rouvrir que pour bug prouvé ou changement externe. |
| 9 | `pump_fees` | `supported / 0.7.55 closed` | Surface fee/config/accounting couverte localement : `29` instructions, `20` events Anchor, fee/reward/admin/lifecycle, tests synthétiques Anchor IDL non observés, failed tx audit-only. | Aucun trade/candle direct ; conserver les deux discriminators Solscan hors IDL comme futures surfaces non observées. |
| 10 | `meteora_dbc` | `supported / closed 0.7.56` | Decoder local maximal : `28` instructions, `23` events Anchor, swaps `swap/swap2`, lifecycle/admin/fees, `k_sol_fee_event_amounts`, validation SQL propre. | Ne pas rouvrir sauf bug prouvé ; préserver la policy fee parent+legs et la recovery allowlistée. |
| 11 | `meteora_dlmm` | `supported / closed 0.7.57` | Decoder local maximal : `76` instructions IDL, `30` events Anchor, `12` accounts, correction `initialize_preset_parameter_v2`, swaps/exact-out, liquidity, bins, positions, lifecycle, fees/rewards, admin/config et orderbook. | Ne pas rouvrir sauf bug prouvé ; `swap_event/swap2_evt` restent lifecycle `swap_log`, pas trade ; préserver recovery fee/reward allowlistée. |
| 12 | `meteora_damm_v1` | `supported / 0.7.58 parity` | Couverture `0.7.46` : swap, create_pool, add/remove liquidity, claim_fee, create_lock_escrow, lock_liquidity. | Vérifier les surfaces upstream non observées ; améliorer rattachement pool/pair pour remove_liquidity non matérialisés ; revalidation stricte. |
| 13 | `meteora_damm_v2` | `partial / 0.7.59 planned` | `swap`, `instruction_audit`, registry/discriminants et corpus Demo3 existent. | Couvrir tous les events Carbon/source : create pool, liquidity, fees, dynamic config, admin ; déterminer actionability des swaps ; matérialiser si montants fiables. |
| 14 | `phoenix_v1` | `audit-only / 0.7.60 planned` | Decoder local audit-only ; `log_audit`, order place/cancel, withdraw ; parsing strict `0x0f`; events `Reduce`, `Place`, `TimeInForce` observés ; `trade_count=0`. | Terminer tous les events Git : `Fill`, `FillSummary`, `Fee`, `Evict`, `ExpiredOrder`, etc. ; ajouter counts/flags audit ; seulement ensuite étudier trade materialization. |
| 15 | `openbook_v2` | `audit-only / 0.7.61 planned` | Decoder local audit-only ; instructions order/cancel/consume/settle ; `Program data` mappé : `FillLog`, `OpenOrdersPositionLog`, `TotalOrderFillEvent`, `SettleFundsLog`; `trade_count=0`. | Vérifier layouts fill/out et sens maker/taker/base/quote ; ajouter table audit éventuelle ; ne matérialiser trades quaprès validation du sens économique. |
| 16 | `orca_whirlpools` | `partial / 0.7.62 planned` | Premier decoder historique présent ; swaps/create_pool partiels. | Comparer Carbon/IDL complet ; couvrir liquidity, positions, fees/rewards, tick arrays ; valider swaps exploitables et non-trades. |
| 17 | `legacy_launch_candidates` | `planned launch` | Anciennes entrées launch à réévaluer après `raydium_launchpad`. | Ne pas confondre Launchpad, LaunchLab, CPMM/CLMM/AMM v4 ; rattacher aux pools tradables seulement après corpus. |
| 18 | `meteora_vault` | `to_verify` | Présent comme indice upstream / compte associé. | Corpus direct obligatoire ; decoder séparé si events vault réels ; aucune promotion via DAMM indirect. |
| 19 | `fluxbeam` | `partial/to_verify` | Decoder initial existant ; Demo3 peut produire des candidats. | Vérifier source/IDL ; compléter swap, pool, liquidity, fees/admin ; matérialisation uniquement après corpus. |
| 20 | `dexlab` | `partial/to_verify` | Decoder initial historique ; ancienne entrée beta supprimée. | Reconfirmer program id/source ; décoder events disponibles ; distinguer DexLab natif et liens OpenBook/market. |
| 19 | `lifinity_v2` | `to_verify` | Program id listé par sources externes/Vybe ; pas de corpus concluant. | Trouver IDL/source ; Demo3 par program/market ; audit-only dabord. |
| 20 | `stabble_stable_swap` / `stabble_weighted_swap` | `to_verify` | Program ids/indices via sources externes ; candidats Demo3 observables. | Source/IDL + corpus + decoder audit-only ; déterminer surface AMM et montants exploitables. |
| 21 | `bonkswap` | `to_verify` | Program id/Carbon/Vybe selon registre ; swaps candidats possibles. | Vérifier program id, source et corpus ; décoder tous events ; pas de trade sans montants. |
| 22 | `boop` / `boop_fun` | `to_verify / launch` | Entrée de découverte. | Séparer launch surface et swap effectif ; corpus + source obligatoire. |
| 23 | `moonshot` / `moonit` | `to_verify / launch` | Moonshot buy/sell observés via upstream candidates ; Moonit launch attribution historique. | Source/IDL + migration + rattachement pools ; éviter heuristiques seules. |
| 24 | `heaven` | `to_verify` | Program id/candidat ajouté en matrice. | Vérifier sil est launch, AMM ou les deux ; corpus dédié. |
| 25 | `printr` | `to_verify` | Preset Demo3 ajouté ; candidats observables. | Source/IDL, discriminants, corpus, decoder audit-only. |
| 26 | `metadao_*` | `to_verify` | Presets spécifiques : launchpad, bid wall, futarchy, AMM. | Traiter par programme séparé ; ne pas utiliser mint ids comme program ids ; corpus obligatoire. |
| 27 | `jupiter_*`, `dflow_aggregator_v4`, `okx_dex` | `aggregator_router` | Registry/discovery pour contexte transactionnel. | Ne pas matérialiser en DEX direct ; utiliser pour routeSource/routing/context. |
## Checklist obligatoire par DEX/version
Pour chaque DEX ou version, la tranche doit fermer les points suivants :
- [ ] Source Git/IDL recensée.
- [ ] Tous les `program_id` vérifiés localement ou marqués `to_verify`.
- [ ] Tous les discriminants dinstructions listés.
- [ ] Tous les discriminants devents/logs listés.
- [ ] Demo3 corpus constitué.
- [ ] Demo2 backfill de signatures réussies.
- [ ] Replay forcé sur base `0.7.47+`.
- [ ] SQL : decoded events par kind.
- [ ] SQL : `trade_count=0` pour audit-only.
- [ ] SQL : trade/candle uniquement si montants exploitables.
- [ ] Cleanup `upstream_git.instruction_match` si decoder spécialisé local.
- [ ] Décision finale : `audit-only`, `materialized`, `partial`, ou `to_verify`.
## Notes de matérialisation
Un event peut devenir `materialized` uniquement si :
1. la transaction est `OK` ;
2. les comptes nécessaires sont identifiés ;
3. les mints sont fiables ;
4. les montants sont fiables ;
5. le sens base/quote est validé ;
6. les requêtes SQL prouvent labsence de faux trades/candles ;
7. les tests et clippy sont verts.
## Annexe — snapshot de `kb_lib/src/dex_support_matrix.rs` (`1FE5`)
| Code | Rôle | Surface | Program id status | Observed | Decoded | Materialized | Status | Skip reason |
|---|---|---|---|---:|---:|---:|---|---|
| `pump_fun` | `launch_surface` | `launch/bonding` | `known` | oui | oui | oui | `0.7.54_closed` | Decoder maximal IDL/local ; v2/exact matérialisés via `trade_event` canonique ; non-trades selon contexte. |
| `pump_swap` | `dex_effective` | `AMM` | `known` | oui | oui | oui | `supported` | |
| `raydium_cpmm` | `dex_effective` | `AMM` | `known` | oui | oui | oui | `supported` | |
| `raydium_clmm` | `dex_effective` | `CLMM` | `known` | oui | oui | oui | `supported` | |
| `raydium_amm_v4` | `dex_effective` | `AMM` | `known` | oui | oui | oui | `supported` | |
| `raydium_launchpad` | `launch_surface` | `launch` | `known` | non | oui | non | `bootstrap` | decoded_events_only_until_local_corpus |
| `raydium_liquidity_locking` | `to_verify` | `liquidity_locking` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `raydium_router` | `aggregator_router` | `router` | `known` | non | non | non | `partial` | router_not_materialized_as_direct_trade_surface |
| `raydium_stable_swap` | `dex_effective` | `AMM` | `known` | oui | oui | oui | `supported` | 0.7.52 closed; swaps via `stable_swap_vault_balance_delta` uniquement |
| `meteora_dlmm` | `dex_effective` | `DLMM` | `known` | oui | oui | oui | `supported` | |
| `meteora_dlc` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | surface_and_program_id_to_verify |
| `meteora_damm_v1` | `dex_effective` | `AMM` | `known` | oui | oui | non | `partial` | meteora_damm_v1_swap_without_amount_payload |
| `meteora_damm_v2` | `dex_effective` | `AMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay |
| `meteora_dbc` | `dex_effective` | `bonding_curve` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay |
| `orca_whirlpools` | `dex_effective` | `CLMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay |
| `fluxbeam` | `dex_effective` | `AMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay |
| `dexlab` | `dex_effective` | `AMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay |
| `bags` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify |
| `letsbonk` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify |
| `bonk` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify |
| `bonk_fun` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify |
| `okx_dex` | `aggregator_router` | `aggregator` | `to_verify` | non | non | non | `planned` | program_id_to_verify |
| `boop_fun` | `launch_surface` | `launch` | `to_verify` | non | non | non | `planned` | program_id_to_verify |
| `moonshot` | `launch_surface` | `launch` | `to_verify` | non | non | non | `planned` | historical_entities_py_program_id_requires_corpus_verification |
| `believe` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify |
| `metadao` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | umbrella_surface_programs_split_into_specific_discovery_targets |
| `metadao_launchpad_v0_7_0` | `to_verify` | `launch` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification |
| `metadao_bid_wall_v0_7_0` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification |
| `metadao_futarchy_v0_6_0` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification |
| `metadao_amm_v0_5_0` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification |
| `printr` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | solscan_program_label_requires_local_corpus_verification |
| `zora` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | solscan_program_label_requires_local_corpus_verification |
| `moonit` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify |
| `launchbeam` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify |
| `heaven` | `launch_surface` | `launch` | `to_verify` | non | non | non | `planned` | program_id_to_verify |
| `gavel` | `to_verify` | `auction` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `pump_fees` | `supported` | `fee_program` | `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` | non | non | non | `0.7.55 closed` | fee/reward/admin/lifecycle only ; no trade/candle |
| `meteora_pools` | `dex_effective` | `AMM` | `alias_of_meteora_damm_v1` | non | non | non | `to_verify` | program_id_alias_held_by_meteora_damm_v1 |
| `dflow_aggregator_v4` | `aggregator_router` | `aggregator` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `drift_v2` | `to_verify` | `perps` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `jupiter_swap` | `aggregator_router` | `aggregator` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `jupiter_dca` | `aggregator_router` | `dca` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `jupiter_limit_order` | `aggregator_router` | `limit_order` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `jupiter_limit_order_2` | `aggregator_router` | `limit_order` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `jupiter_perpetuals` | `to_verify` | `perps` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `jupiter_lend` | `to_verify` | `lending` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `kamino_lending` | `to_verify` | `lending` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `kamino_vault` | `to_verify` | `vault` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `kamino_farms` | `to_verify` | `farms` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `kamino_limit_order` | `to_verify` | `limit_order` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `marginfi_v2` | `to_verify` | `lending` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `onchain_labs_dex_v1` | `dex_effective` | `AMM` | `alias_of_okx_dex` | non | non | non | `to_verify` | program_id_alias_held_by_okx_dex |
| `onchain_labs_dex_v2` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `pancake_swap` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `vertigo` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `virtuals` | `launch_surface` | `launch` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `wavebreak` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification |
| `aldrin` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `aldrin_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `crema` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `cropper` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `lifinity_v1` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `lifinity_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `mercurial` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `orca_v1` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `orca_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `phoenix` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `saber` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `saber_decimals` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `openbook_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `fox` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `sanctum_infinity` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `saros` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `stabble_stable_swap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `stabble_weighted_swap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `stepn` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `solayer` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `penguin` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `sanctum` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `one_dex` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `solfi` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `bonkswap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `guacswap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `invariant` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `oasis` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `token_swap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `helium_network` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `marinade_liquid_staking` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `francium_yield_pools` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `marinade_governance` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `serum_dao` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `port_finance` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `solend_classic` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `hyperspace_nft_amm` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `magic_eden_nft_amm` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `raydium_staking_early` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `orca_aquafarm_v1` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `quarry_merge_mining` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification |
| `goosefx_v1` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `obric_v2` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `ondo_global_market` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `scorch` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `zerofi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `manifest_clob` | `to_verify` | `orderbook` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `alphaq` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `goonfi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `goonfi_v2` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `byreal` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `bisonfi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `fusionamm` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `woofi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `aquifer` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `humidifi` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
| `solfi_v2` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source |
## Note `0.7.48` — Raydium CPMM
`raydium_cpmm` reste `supported`, mais sa couverture est maintenant explicitée au niveau entry/event coverage.
Entrées CPMM couvertes localement depuis Carbon/fnzero/IDL :
- swaps : `swap_base_input`, `swap_base_output` ;
- events Anchor self-CPI audit-only : `lp_change_event`, `swap_event` ;
- pool/lifecycle : `initialize`, `initialize_with_permission` ;
- liquidity : `deposit`, `withdraw` ;
- fees : `collect_creator_fee`, `collect_fund_fee`, `collect_protocol_fee` ;
- admin/config/permission : `create_amm_config`, `update_amm_config`, `update_pool_status`, `create_permission_pda`, `close_permission_pda`.
`create_amm_config` est traité comme admin/config, pas comme pool creation. `swap_event` est conservé comme audit-only pour ne pas doubler les trades matérialisés depuis les instructions `swap_base_input` / `swap_base_output`.
## Note `0.7.48 final` — Raydium CPMM
`raydium_cpmm` est considéré `supported` et clôturable pour la tranche `0.7.48`. Les entrées matérialisées couvrent swaps (`swap_base_input`, `swap_base_output`), liquidity (`deposit`, `withdraw`, `lp_change_event`), lifecycle (`initialize`, `initialize_with_permission`), fees (`collect_creator_fee`, `collect_fund_fee`, `collect_protocol_fee`) et admin/config (`create_amm_config`, `create_permission_pda`, `update_amm_config`).
`swap_event` reste audit-only pour éviter tout doublon de trade/candle. `close_permission_pda` et `update_pool_status` restent connus upstream mais non observés localement.
## Note `0.7.49` — Raydium CLMM initial coverage sync
`raydium_clmm` reste `supported`, mais la tranche `0.7.49` rouvre sa couverture événementielle complète au lieu de se limiter aux swaps.
État local repris : `swap`, `swap_v2`, `increase_liquidity_v2`, `decrease_liquidity_v2`, `open_position_with_token22_nft` et `close_position` disposent déjà d'un chemin local spécialisé ou mappé. Les autres entrées CLMM restent à confirmer par corpus avant toute promotion.
Le registre est complété avec les entrées issues de l'IDL officiel Raydium non présentes dans le snapshot Carbon courant : `close_limit_order`, `close_protocol_position`, `create_customizable_pool`, `create_dynamic_fee_config`, `create_support_mint_associated` et `settle_limit_order`.
Règle de clôture : les positions CLMM, fees/rewards et surfaces limit-order ne doivent produire aucune ligne trade/candle tant que le sens économique, les montants, les comptes et les mints ne sont pas prouvés par replay local.
## Note `0.7.50-pre-r2` — CPMM/CLMM source parity
La clôture `0.7.50-pre-r2` complète les tranches `0.7.48` et `0.7.49` sans rouvrir leur logique trade/candle :
- `raydium_cpmm.cpi_event` est ajouté comme transport Anchor/CPI decoded-only, distinct de `swap_base_input` / `swap_base_output`.
- Le discriminant CPMM `40f4bc78a7e9690a` est codé comme `raydium_cpmm.anchor_idl_instruction` decoded-only après inspection Solscan : gestion Anchor IDL, aucune matérialisation métier.
- `raydium_clmm.cpi_event` et `raydium_clmm.update_dynamic_fee_config` sont ajoutés depuis Carbon.
- Les Program-data events CLMM reçoivent des `local_event_kind` et familles explicites.
- `create_support_mint_associated` introduit une cible métier spécialisée : `k_sol_token_account_events`.
## Note `0.7.51` — `raydium_amm_v4`
| Champ | Décision `0.7.51` |
|---|---|
| Code local | `raydium_amm_v4` |
| Program id canonique | `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` |
| Statut | `supported / 0.7.51 closed` ; max-decoder local `00..11` validé |
| Sources principales | Carbon `raydium-amm-v4-decoder`, Pinax `src/raydium/amm`, fnzero `raydium_amm_v4.json`, Solscan Program IDL |
| Swaps | `swap_base_in`, `swap_base_out`, `swap_base_in_v2`, `swap_base_out_v2` |
| Pool lifecycle | `initialize`, `initialize2`, `pre_initialize` |
| Liquidity | `deposit`, `withdraw` |
| Fees/admin/orderbook side effects | `withdraw_pnl`, `withdraw_srm`, `set_params`, `monitor_step`, `admin_cancel_orders`, `migrate_to_open_book`, config account ops |
| SPL Token / Token-2022 side effects | transversaux, non promus comme `raydium_amm_v4.*` directs |
| `raydium_pool_v4` | audit comparatif uniquement ; pas de decoder autonome sans program id et corpus local |
La tranche a été validée sur base SQLite dédiée : tous les discriminants `00..11` sont observés localement. Les gaps de matérialisation restants sont expliqués par decoded-only, transaction failed ou absence de catalogue/deltas exploitables.
## 0.7.52 — Raydium Stable Swap
| decoder_code | program id | status | layout | notes |
|---|---|---|---|---|
| `raydium_stable_swap` | `5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h` | supported / closed | legacy 1 octet | Surface locale `00..0d` couverte ; swaps `swap_base_in/out` matérialisés uniquement depuis deltas vault exacts ; instruction bounds et failed tx restent decoded-only. |
## 0.7.54 — Pump.fun
| Decoder | Program id | Statut | Source discriminants | Couverture locale initiale | Règles métier |
|---|---|---:|---|---|---|
| `pump_fun` | `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` | supported / 0.7.54 closed | upstream registry + `idls/pump_fun.6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.json` + corpus SQLite validé | `40` instructions et `23` events Anchor connus couverts ; `buy/sell/buy_exact_sol_in` matérialisés ; `buy_v2/sell_v2/buy_exact_quote_in_v2` audit/routing ; `trade_event` matérialise les montants exécutés v2/exact | `k_sol_trade_events` uniquement avec montants exacts ; `create/migrate` vers `k_sol_launch_events` ; creator fees vers `k_sol_fee_events` ; cashback/incentives vers `k_sol_reward_events` ; admin/config vers `k_sol_pool_admin_events` ; decoded-only/audit-only avec skip reason sinon |
## 0.7.53 — PumpSwap
| Decoder | Program id | Statut | Source discriminants | Couverture locale | Règles métier |
|---|---|---:|---|---|---|
| `pump_swap` | `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` | supported / 0.7.53 closed | upstream registry + `idls/pump_swap.pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA.json` + corpus Demo3/replay | instructions : `buy`, `sell`, `buy_exact_quote_in`, `deposit`, `withdraw`, `create_pool`, `create_config`, `update_fee_config`, creator-fee, cashback, token incentives, volume accumulator, admin/config ; events Anchor autonomes audit-only | `buy_exact_quote_in` trade uniquement avec `pump_swap_anchor_buy_event`; aucun non-swap en trade/candle ; failed tx decoded-only ; `buy_event`/`sell_event` Program-data audit-only ; `transfer_creator_fees_to_pump_v2` et `update_buyback_config` confirmés par Solscan IDL ; `set_reserved_fee_recipient` conservé sur preuve log locale |
## 0.7.55 — Pump Fees
| Decoder | Program id | Statut | Source discriminants | Couverture locale | Règles métier |
|---|---|---:|---|---|---|
| `pump_fees` | `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` | supported / `0.7.55 closed` | `idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json` + Carbon partiel + Solscan discriminators | `29` instructions et `20` events Anchor couverts ; tests synthétiques pour les Anchor events IDL non observés ; replay final propre ; watchlist `pump_fees` vide | Aucun trade/candle direct ; `get_fees` decoded-only ; social claim vers reward ; donation/buyback vers fee ; config/authority/tier/admin vers admin/lifecycle ; failed tx audit-only ; deux events Solscan hors IDL conservés non observés. |
## 0.7.56 — Meteora DBC clôturé
| Decoder | Program id | Statut | Source locale | Couverture | Décision métier |
|---|---|---|---|---|---|
| `meteora_dbc` | `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN` | `supported / closed 0.7.56` | `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json` | `28` instructions IDL + `23` events Anchor IDL, tests synthétiques et validation SQL dédiée | `swap`/`swap2` seuls vers trade/candle direct ; lifecycle/admin/fee selon contexte ; fees parent+legs ; failed tx audit-only. |
Validation finale : `446` tests, clippy OK, `480 replayed`, `264 trades`, `1 liquidity`, `122 lifecycle`, `1056 candles`, `89` parents fee DBC, `96` fee amount legs, invariants SQL propres.
## 0.7.57 — Meteora DLMM clôturé
| Decoder | Program id | Statut | Source locale | Couverture finale | Décision métier |
|---|---|---|---|---|---|
| `meteora_dlmm` | `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo` | `supported / closed 0.7.57` | `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` | `76` instructions IDL, `30` events Anchor, `12` accounts, `initialize_preset_parameter_v2` ajouté depuis corpus local | Les 6 swaps instructionnels produisent seuls les trades/candles ; Anchor `swap_event/swap2_evt` = lifecycle `swap_log`; liquidity/bin/position/lifecycle/admin/orderbook/fee/reward matérialisés selon cible ; failed tx audit-only. |
Validation finale : `460` tests, clippy OK, `769 replayed`, `106 trades`, `664 liquidity`, `1107 lifecycle`, `424 candles`, `8062` instruction observations, catalogue `169/218/218`. Checks SQL bloquants propres.
### 0.7.57 pre.001 — Meteora DLMM
`meteora_dlmm` passe de tranche `next` à tranche ouverte `pre.001` : lIDL locale complète est inventoriée, tous les discriminants instruction/event sont classifiés localement, et les familles non prouvées restent decoded-only/audit-safe avec `skip*Reason`.

View File

@@ -0,0 +1,353 @@
<!-- file: docs/DEX_EVENT_COVERAGE_MATRIX.md -->
# DEX Event Coverage Matrix — `khadhroony-bobobot` `0.7.57 meteora_dlmm closed`
Cette matrice complète `docs/DEX_DECODER_MATRIX.md` avec une lecture par familles d'événements. Elle ne remplace pas la preuve locale : une entrée Git/IDL reste un indice tant qu'elle n'est pas observée dans le corpus local puis validée par replay et SQL.
## Règles de statut
| Statut | Sens |
|---|---|
| `decoded` | Un decoder local produit un event spécialisé ou un event audit-only classé. |
| `materialized` | L'event alimente une table métier existante validée par corpus. |
| `audit-only` | L'event reste dans `k_sol_dex_decoded_events` et ne produit jamais trade/candle. |
| `upstream_git_mapped_unverified` | L'entrée est connue depuis Carbon/fnzero/IDL, mais non observée localement. |
| `not_applicable` | La famille n'existe pas pour ce DEX/version ou appartient à un autre programme. |
## `0.7.48` — `raydium_cpmm`
Sources inventoriées : Carbon `carbon-raydium-cpmm-decoder`, fnzero `solana-streamer` / `sol-parser-sdk` IDL `raydium_cpmm.json`.
| Famille | Entrées Raydium CPMM | Statut `0.7.48` | Cible DB | Justification / règle |
|---|---|---|---|---|
| `swap` | `swap_base_input`, `swap_base_output`, `swap_event` | `materialized` pour `swap_base_*`; `swap_event` audit-only | `k_sol_trade_events` seulement pour `swap_base_*`; `k_sol_dex_decoded_events_only` pour `swap_event` | `swap_event` est décodé mais ne produit jamais trade/candle afin d'éviter les doublons. |
| `pool_create` | `initialize`, `initialize_with_permission` | `materialized` | `k_sol_pool_lifecycle_events` | `initialize_with_permission` est lifecycle-only et ne crée plus d'admin row. |
| `add_liquidity` | `deposit`, `lp_change_event(changeType=0)` | `materialized` | `k_sol_liquidity_events` | `deposit` et `lp_change_event(changeType=0)` matérialisent liquidity, sans trade/candle. |
| `remove_liquidity` | `withdraw`, `lp_change_event(changeType=1)` | `materialized` | `k_sol_liquidity_events` | `withdraw` et `lp_change_event(changeType=1)` matérialisent liquidity, sans trade/candle. |
| `position_open` | `-` | `not_applicable` | `-` | CPMM n'a pas de position CLMM. |
| `position_close` | `-` | `not_applicable` | `-` | CPMM n'a pas de position CLMM. |
| `fee` | `collect_creator_fee`, `collect_fund_fee`, `collect_protocol_fee` | `materialized` | `k_sol_fee_events` | Les trois familles de fee CPMM observées sont matérialisées avec `trade_count=0`. |
| `reward` | `-` | `not_applicable` | `-` | Aucune entrée reward CPMM dans Carbon/fnzero IDL inventoriée pour cette tranche. |
| `admin/config` | `create_amm_config`, `update_amm_config`, `create_permission_pda`, `update_pool_status`, `close_permission_pda` | `materialized` pour les entrées observées ; `upstream_git_mapped_unverified` pour `update_pool_status` / `close_permission_pda` | `k_sol_pool_admin_events` ou decoded-only selon corpus | `create_amm_config`, `create_permission_pda` et `update_amm_config` sont matérialisés ; les deux autres restent non observés localement. |
| `mint` | `-` direct | `not_applicable` | `-` | Mint LP implicite possible dans les instructions, mais pas d'instruction CPMM `mint` dédiée. |
| `burn` | `-` direct | `not_applicable` | `-` | Burn LP implicite possible dans `withdraw`, mais pas d'instruction CPMM `burn` dédiée. |
| `transfer` | SPL Token inner transfers | `audit-only` indirect | `k_sol_dex_decoded_events` pour cette tranche | Pas de table `k_sol_token_transfer_events` ajoutée en `0.7.48`. |
| `account_create` | comptes système/ATA indirects | `audit-only` indirect | decoded-only | Hors programme CPMM direct. |
| `account_close` | comptes système/ATA indirects | `audit-only` indirect | decoded-only | Hors programme CPMM direct. |
| `wrap_sol` | user/router side | `not_applicable` | `-` | Préparation WSOL hors CPMM. |
| `unwrap_sol` | user/router side | `not_applicable` | `-` | Cleanup WSOL hors CPMM. |
| `order_place` | `-` | `not_applicable` | `-` | CPMM est AMM, pas orderbook. |
| `order_cancel` | `-` | `not_applicable` | `-` | CPMM est AMM, pas orderbook. |
| `order_fill` | `-` | `not_applicable` | `-` | CPMM est AMM, pas orderbook. |
| `consume_events` | `-` | `not_applicable` | `-` | CPMM est AMM, pas orderbook. |
| `settle_funds` | `-` | `not_applicable` | `-` | CPMM est AMM, pas orderbook. |
| `vault_deposit` | `-` | `not_applicable` | `-` | Les vaults CPMM sont des comptes de pool, pas une surface vault séparée. |
| `vault_withdraw` | `-` | `not_applicable` | `-` | Les vaults CPMM sont des comptes de pool, pas une surface vault séparée. |
| `lock` | `-` | `not_applicable` | `-` | Raydium liquidity locking est une surface séparée. |
| `unlock` | `-` | `not_applicable` | `-` | Raydium liquidity locking est une surface séparée. |
| `launch` | `-` | `not_applicable` | `-` | Raydium LaunchLab/Launchpad est séparé de CPMM. |
| `migration` | `-` | `not_applicable` | `-` | Les migrations launch → pool relèvent des launch surfaces. |
| `stake` | `-` | `not_applicable` | `-` | Hors CPMM. |
| `unstake` | `-` | `not_applicable` | `-` | Hors CPMM. |
| `unknown/unmapped audit` | `raydium_cpmm.instruction_audit` | `audit-only` | `k_sol_dex_decoded_events_only` | Toute instruction observée mais non mappée reste audit-only et ne produit jamais trade/candle. |
## Validation attendue
- `k_sol_dex_event_coverage_entries.decoder_code = 'raydium_cpmm'` contient toutes les entrées Carbon/fnzero synchronisées.
- `upstream_git.instruction_match` ne doit plus apparaître pour une instruction CPMM remplacée par un decoder local spécialisé.
- Les familles non-trade CPMM doivent rester `trade_count = 0`.
- Les transactions failed CPMM doivent rester décodées/auditables mais non matérialisées en trade/candle.
## Note `0.7.48-part2-fix2` — CPMM official instruction parity
La couverture `raydium_cpmm` est alignée avec les instructions exposées par le programme officiel Raydium CP-Swap et par Carbon : `create_amm_config`, `update_amm_config`, `update_pool_status`, `collect_protocol_fee`, `collect_fund_fee`, `collect_creator_fee`, `create_permission_pda`, `close_permission_pda`, `initialize`, `initialize_with_permission`, `deposit`, `withdraw`, `swap_base_input`, `swap_base_output`, `lp_change_event` et `swap_event`.
`lp_change_event` est maintenant classé `event_family=liquidity` dans la table coverage, parce que l'event couvre à la fois dépôt et retrait. La matérialisation reste déterminée par `changeType` dans le payload décodé : `0` = add/deposit, `1` = remove/withdraw.
## Note `0.7.48 final` — Raydium CPMM clôturable
Validation finale locale : `deposit` = `11/11` liquidity, `withdraw` = `14/14` liquidity, `lp_change_event` = `25/25` liquidity, fees = `26/26` fee, admin/config observés = `23/23` admin, lifecycle = `9/9`, `swap_event` = audit-only avec `0` trade, et trades matérialisés uniquement depuis `swap_base_input` / `swap_base_output`.
`close_permission_pda` et `update_pool_status` restent `upstream_git_mapped_unverified` faute de corpus local. Les filtres Solscan `instruction=9c5420764587467b` et `instruction=82576c062ee0757b` n'ont pas fourni de signatures exploitables dans l'horizon testé.
## `0.7.49` — `raydium_clmm` final coverage
Sources inventoriées : Carbon `raydium-clmm-decoder`, fnzero `sol-parser-sdk`, Pinax `substreams-solana-idls/src/raydium/clmm`, Raydium/Solscan Program IDL.
État final validé : `45` entrées listées, `33` instructions locales observées/décodées, `25` entrées matérialisées, `1186` trades, `raydium_clmm.instruction_audit = 0`, fallback `upstream_git.instruction_match` localement couvert = `0`.
| Famille | Entrées Raydium CLMM | Statut `0.7.49` | Cible DB | Justification / règle |
|---|---|---|---|---|
| `swap` | `swap`, `swap_v2` | `materialized` | `k_sol_trade_events` | Seuls ces swaps produisent trades/candles lorsque les montants sont exploitables. |
| `swap audit` | `swap_event`, `swap_router_base_in` | `observed/audit` ou `upstream_git_unverified` selon corpus | `k_sol_dex_decoded_events_only` | Pas de double trade/candle. |
| `pool_create` | `create_pool`, `create_customizable_pool` | `decoded`; `create_pool` matérialisé quand prouvé | `k_sol_pool_lifecycle_events` | Création de pool = lifecycle, pas admin. |
| `add_liquidity` | `increase_liquidity`, `increase_liquidity_v2`, open position variants | `decoded`; variantes prouvées matérialisées | `k_sol_liquidity_events` | CLMM implique position/tick/NFT ; matérialisation seulement sur corpus OK. |
| `remove_liquidity` | `decrease_liquidity`, `decrease_liquidity_v2`, close position variants | `decoded`; variantes prouvées matérialisées | `k_sol_liquidity_events` | Aucune promotion trade/candle. |
| `fee` | `collect_fund_fee`, `collect_protocol_fee` | `decoded`; protocol fee matérialisé si tx OK | `k_sol_fee_events` | Mapping fee sans trade/candle. |
| `reward` | `initialize_reward`, `collect_remaining_rewards`, `set_reward_params`, `transfer_reward_owner`, `update_reward_infos` | `decoded`; variantes prouvées matérialisées | `k_sol_reward_events` / `k_sol_pool_admin_events` | Reward/config selon instruction. |
| `admin/config` | `create_amm_config`, `create_dynamic_fee_config`, `create_operation_account`, `update_amm_config`, `update_operation_account`, `update_pool_status` | `decoded`; variantes prouvées matérialisées | `k_sol_pool_admin_events` ou decoded-only | Config/admin sans trade/candle. |
| `account_create` | `create_support_mint_associated` | `observed/decoded` | `k_sol_token_account_events` prévu / decoded-only selon corpus | Side effect technique ; pas de trade/candle. |
| `order_place` | `open_limit_order`, `increase_limit_order` | `decoded/materialized` | `k_sol_orderbook_events` | Orderbook CLMM, jamais trade/candle. |
| `order_cancel` | `decrease_limit_order`, `close_limit_order` | `decoded/materialized` | `k_sol_orderbook_events` | Orderbook CLMM, jamais trade/candle. |
| `settle_funds` | `settle_limit_order` | `decoded/materialized` | `k_sol_orderbook_events` | Settlement orderbook, pas trade direct. |
| `mint/burn/transfer/account_close/wrap/unwrap` | Side effects SPL Token / Token-2022 | `indirect` | decoded-only | Pas de promotion en `raydium_clmm.*` sans instruction directe. |
| `launch/migration/lock/unlock/stake/unstake/vault` | `-` | `not_applicable` | `-` | Surfaces hors CLMM direct. |
| `unknown/unmapped audit` | `raydium_clmm.instruction_audit`, fallback upstream | `closed` | `k_sol_dex_decoded_events_only` | Résidu validé à zéro après replay. |
Les 11 Anchor / `Program data` events restent `upstream_git_unverified` et préparés audit-only faute dobservation locale : `collect_personal_fee_event`, `collect_protocol_fee_event`, `config_change_event`, `create_personal_position_event`, `decrease_liquidity_event`, `increase_liquidity_event`, `liquidity_calculate_event`, `liquidity_change_event`, `pool_created_event`, `swap_event`, `update_reward_infos_event`.
## `0.7.50` — `raydium_launchpad` bootstrap
Sources inventoriées : Carbon `raydium-launchpad-decoder`, Solscan Program IDL `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj`, fnzero IDL listings, Raydium SDK Launchpad examples. Code local canonique : `raydium_launchpad`. Aucun alias Rust `raydium_launchlab` ne doit être conservé dans lAPI publique.
État de départ préparé : `1` entrée programme et `26` entrées discriminées listées depuis Carbon/IDL. Toutes les entrées Launchpad sont gardées `decoded_events_only` en bootstrap, même si leur famille inférée est `swap`, `pool_create`, `fee`, `admin_config`, `launch` ou `migration`. La matérialisation métier est volontairement différée jusqu'au corpus local.
| Famille | Entrées Raydium Launchpad | Statut `0.7.50` bootstrap | Cible DB initiale | Justification / règle |
|---|---|---|---|---|
| `swap` | `buy_exact_in`, `buy_exact_out`, `sell_exact_in`, `sell_exact_out`, `trade_event` | `upstream_git_mapped_unverified` puis `decoded/audit-only` si observé | `k_sol_dex_decoded_events_only` | Aucun trade/candle avant preuve locale de montants, sens et absence de doublon avec la surface DEX de migration. |
| `pool_create` | `initialize`, `initialize_v2`, `initialize_with_token_2022`, `pool_create_event` | `upstream_git_mapped_unverified` | `decoded_events_only` | Lifecycle launch/pool non promu tant que le compte pool/mint/quote n'est pas validé localement. |
| `add_liquidity` | `-` direct confirmé | `not_applicable` | `-` | Peut apparaître via DEX de destination ou SPL side effects, pas comme instruction Launchpad directe prouvée. |
| `remove_liquidity` | `-` direct confirmé | `not_applicable` | `-` | Même règle que `add_liquidity`. |
| `position_open` | `-` | `not_applicable` | `-` | Pas de position CLMM/LP NFT directe confirmée. |
| `position_close` | `-` | `not_applicable` | `-` | Pas de position CLMM/LP NFT directe confirmée. |
| `fee` | `claim_creator_fee`, `claim_platform_fee`, `claim_platform_fee_from_vault`, `claim_vested_event`, `claim_vested_token`, `collect_fee`, `collect_migrate_fee` | `upstream_git_mapped_unverified` puis `decoded/audit-only` si observé | `decoded_events_only` | Fee/vesting/migration fee utile pour stratégie, mais pas matérialisé sans corpus. |
| `reward` | `-` direct confirmé | `not_applicable` | `-` | Vesting n'est pas promu en reward transversal dans cette tranche. |
| `admin/config` | `create_config`, `create_platform_config`, `remove_platform_curve_param`, `update_config`, `update_platform_config`, `update_platform_curve_param` | `upstream_git_mapped_unverified` puis `decoded/audit-only` si observé | `decoded_events_only` | Admin/config utile pour audit, pas de table métier promue. |
| `mint` | SPL Token / Token-2022 side effects possibles | `indirect` | `decoded_events_only` | Ne devient pas `raydium_launchpad.*` sans instruction directe du programme. |
| `burn` | SPL Token / Token-2022 side effects possibles | `indirect` | `decoded_events_only` | Même règle que `mint`. |
| `transfer` | SPL Token / Token-2022 side effects attendus | `indirect` | `decoded_events_only` | Même règle que CPMM/CLMM : side effect transversal. |
| `account_create` | `create_vesting_account`, `create_vesting_event` | `upstream_git_mapped_unverified` | `decoded_events_only` | Vesting/account audit uniquement, pas de nouvelle table transversale. |
| `account_close` | `-` direct confirmé | `not_applicable` | `-` | Aucun close direct Launchpad confirmé. |
| `wrap_sol` | Side effect utilisateur/router possible | `indirect` | `decoded_events_only` | Hors programme Launchpad direct. |
| `unwrap_sol` | Side effect utilisateur/router possible | `indirect` | `decoded_events_only` | Hors programme Launchpad direct. |
| `order_place` | `-` | `not_applicable` | `-` | Launchpad n'est pas traité comme orderbook. |
| `order_cancel` | `-` | `not_applicable` | `-` | Launchpad n'est pas traité comme orderbook. |
| `order_fill` | `-` | `not_applicable` | `-` | Launchpad n'est pas traité comme orderbook. |
| `consume_events` | `-` | `not_applicable` | `-` | Launchpad n'est pas traité comme orderbook. |
| `settle_funds` | `-` | `not_applicable` | `-` | Launchpad n'est pas traité comme orderbook. |
| `vault_deposit` | `-` direct confirmé | `not_applicable` | `-` | Aucun vault direct Launchpad confirmé. |
| `vault_withdraw` | `-` direct confirmé | `not_applicable` | `-` | Aucun vault direct Launchpad confirmé. |
| `lock` | `-` direct confirmé | `not_applicable` | `-` | Liquidity locking reste une autre surface Raydium. |
| `unlock` | `-` direct confirmé | `not_applicable` | `-` | Liquidity locking reste une autre surface Raydium. |
| `launch` | `initialize*`, `pool_create_event` | `upstream_git_mapped_unverified` | `decoded_events_only` | La promotion `k_sol_launch_events` est différée. |
| `migration` | `migrate_to_amm`, `migrate_to_cpswap`, `collect_migrate_fee` | `upstream_git_mapped_unverified` | `decoded_events_only` | Destination AMM/CPMM à valider localement avant liaison métier. |
| `stake` | `-` | `not_applicable` | `-` | Aucun stake direct Launchpad confirmé. |
| `unstake` | `-` | `not_applicable` | `-` | Aucun unstake direct Launchpad confirmé. |
| `unknown/unmapped audit` | `raydium_launchpad.instruction_audit` | `audit-only` | `decoded_events_only` | Résidu à réduire par discriminant après backfill ciblé et replay. |
Rapport détaillé : `docs/reports/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md`.
SQL de validation : `validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql`.
### 0.7.50-pre3 Launchpad note
pre3 correction: Launchpad self-CPI selector `e445a52e51cb9a1d` is transport only. Known embedded event discriminators are decoded as `raydium_launchpad.trade_event` and `raydium_launchpad.pool_create_event`. The Launchpad `initialize*` instruction family now supplies pool/pair catalog context; `trade_event` remains decoded-only until trade/candle promotion is explicitly proven.
## Note `0.7.50-pre-r2` — Raydium CPMM/CLMM closure re-check
Sources ajoutées à la vérification CPMM/CLMM : Carbon `raydium-cpmm-decoder`, Carbon `raydium-clmm-decoder`, Solscan Program IDL CPMM/CLMM et `sol-parser-sdk` IDL Raydium.
### CPMM
- `cpi_event` est ajouté à la matrice CPMM avec `event_family=cpi_transport`, `expected_db_target=k_sol_dex_decoded_events_only`, `local_event_kind=raydium_cpmm.cpi_event` et discriminant `e445a52e51cb9a1d`.
- `swap_event` reste `decoded_events_only` pour éviter le double comptage avec `swap_base_input` / `swap_base_output`.
- Le discriminant local `40f4bc78a7e9690a` est codé comme `raydium_cpmm.anchor_idl_instruction`, `event_family=idl_management`, `expected_db_target=k_sol_dex_decoded_events_only`, après inspection Solscan des logs `IdlCreateAccount` / `IdlCloseAccount`.
### CLMM
- `cpi_event` est ajouté à la matrice CLMM avec `event_family=cpi_transport`, `expected_db_target=k_sol_dex_decoded_events_only`, `local_event_kind=raydium_clmm.cpi_event` et discriminant `e445a52e51cb9a1d`.
- `update_dynamic_fee_config` est ajouté avec `event_family=admin_config`, `expected_db_target=k_sol_pool_admin_events`, `local_event_kind=raydium_clmm.update_dynamic_fee_config` et discriminant `0707500802c784f0`.
- Les Program-data events CLMM sont maintenant rattachés localement : `swap_event`, `pool_created_event`, `liquidity_change_event`, `create_personal_position_event`, `decrease_liquidity_event`, `increase_liquidity_event`, `collect_protocol_fee_event`, `config_change_event`, `update_reward_infos_event`.
- `swap_event` et `swap_router_base_in` restent `decoded_events_only` : les trades canoniques sont `swap` / `swap_v2`, afin d'éviter le double comptage et la matérialisation de routes sans pool direct.
- `liquidity_calculate_event` est classé `liquidity_calculation` et reste `decoded_events_only`, car il sert au diagnostic/calcul et non à une mutation de liquidité fiable.
- `create_support_mint_associated` cible la nouvelle table `k_sol_token_account_events`.
- `create_operation_account` et `update_operation_account` sont normalisés en `admin_config`.
Validation attendue après replay : aucune entrée CPMM/CLMM ne doit rester en `event_family='unknown'` hors `program`, les fallbacks `upstream_git.instruction_match` ne doivent pas dupliquer une entrée locale couverte, et les transactions failed ne doivent matérialiser ni trade, ni liquidity, ni fee/admin/reward/orderbook/token-account.
Rapport associé : `docs/reports/RAYDIUM_CPMM_CLMM_RECHECK_REPORT_0_7_50_PRE_R2.md`.
## `0.7.51` — `raydium_amm_v4`
Sources inventoriées : Carbon `raydium-amm-v4-decoder`, Pinax `src/raydium/amm`, fnzero `raydium_amm_v4.json`, Solscan Program IDL. `raydium_pool_v4` est comparé mais non promu.
Validation locale finale : tous les discriminants AMM v4 officiels `00..11` sont observés ; `instruction_audit`, fallback upstream, decoded sans coverage, observations 8 octets, non-swap trade, failed tx trade, gaps inexpliqués et multi-target materialization sont vides.
| Famille | Entrées AMM v4 | Statut `0.7.51-final` | Cible DB | Règle |
|---|---|---|---|---|
| `swap` | `swap_base_in`, `swap_base_out`, `swap_base_in_v2`, `swap_base_out_v2` | observed/materialized partiel expliqué | `k_sol_trade_events` | Trade/candle seulement si tx successful + montants vault fiables ; sinon `skipTradeReason`. |
| `pool_create` | `initialize`, `initialize2_pool` | observed/materialized | `k_sol_pool_lifecycle_events` | Alimente lifecycle et catalogue seulement quand les mints/pool sont prouvés. |
| `pool_create` deprecated | `pre_initialize` | observed/materialized audit minimal | `k_sol_pool_lifecycle_events` | Lifecycle deprecated/partial ; ne crée pas de pair exploitable sans mints. |
| `liquidity_add` | `deposit` | observed/materialized partiel expliqué | `k_sol_liquidity_events` | Jamais trade/candle ; pools absents du catalogue restent decoded-only expliqués. |
| `liquidity_remove` | `withdraw` | observed/materialized partiel expliqué | `k_sol_liquidity_events` | Jamais trade/candle ; deltas/catalogue manquants doivent être explicités. |
| `fee` | `withdraw_pnl`, `withdraw_srm` | observed/materialized partiel expliqué | `k_sol_fee_events` | Jamais trade/candle. |
| `admin/config` | `set_params`, `create_config_account`, `update_config_account` | observed/materialized | `k_sol_pool_admin_events` | Preuve métier par corpus uniquement. |
| `orderbook side effects` | `monitor_step`, `migrate_to_open_book`, `admin_cancel_orders` | observed/materialized | `k_sol_orderbook_events` | Side effects OpenBook/Serum ; pas de trade OpenBook autonome, pas de lifecycle en double. |
| `cpi/informational` | `simulate_info` | observed decoded-only | `k_sol_dex_decoded_events_only` | Audit technique uniquement. |
| `token side effects` | SPL Token / Token-2022 inner instructions | transversal | decoded-only actuellement | Ne pas promouvoir comme AMM v4 direct. |
| `unknown/unmapped audit` | residual `raydium_amm_v4.instruction_audit` | vide | decoded-only si futur inconnu | Tout residual doit être expliqué avant promotion. |
## 0.7.52 — `raydium_stable_swap`
Status: **closed on local corpus**.
| entry | discriminator | family | expected target | local event kind | status |
|---|---:|---|---|---|---|
| `initialize` | `00` | `pool_create` | `k_sol_pool_lifecycle_events` | `raydium_stable_swap.initialize` | observed/materialized when context complete |
| `init_model_data` | `01` | `model_setup` | decoded-only | `raydium_stable_swap.init_model_data` | observed decoded-only / explained |
| `update_model_data` | `02` | `admin_config` | `k_sol_pool_admin_events` | `raydium_stable_swap.update_model_data` | observed/materialized |
| `deposit` | `03` | `liquidity_add` | `k_sol_liquidity_events` | `raydium_stable_swap.deposit` | observed/materialized |
| `withdraw` | `04` | `liquidity_remove` | `k_sol_liquidity_events` | `raydium_stable_swap.withdraw` | observed/materialized |
| `monitor_step` | `05` | `order_place` | `k_sol_orderbook_events` | `raydium_stable_swap.monitor_step` | observed/materialized |
| `set_params` | `06` | `admin_config` | `k_sol_pool_admin_events` | `raydium_stable_swap.set_params` | observed/materialized |
| `withdraw_pnl` | `07` | `fee` | `k_sol_fee_events` | `raydium_stable_swap.withdraw_pnl` | observed/materialized |
| `withdraw_srm` | `08` | `fee` | `k_sol_fee_events` | `raydium_stable_swap.withdraw_srm` | observed/materialized when context complete |
| `swap_base_in` | `09` | `swap` | `k_sol_trade_events` from vault deltas only | `raydium_stable_swap.swap_base_in` | success/vault-delta materialized; failed decoded-only |
| `pre_initialize` | `0a` | `pool_create` | lifecycle or decoded-only | `raydium_stable_swap.pre_initialize` | observed decoded-only / explained in current corpus |
| `swap_base_out` | `0b` | `swap` | `k_sol_trade_events` from vault deltas only | `raydium_stable_swap.swap_base_out` | success/vault-delta materialized; failed decoded-only |
| `simulate_info` | `0c` | `cpi_transport` | decoded-only | `raydium_stable_swap.simulate_info` | observed decoded-only / explained |
| `admin_cancel_orders` | `0d` | `orderbook_admin` | `k_sol_orderbook_events` | `raydium_stable_swap.admin_cancel_orders` | observed/materialized when context complete |
| `swap_event` | `40c6cde8260871e2` | `cpi_transport` | decoded-only | `raydium_stable_swap.swap_event` | upstream mapped; not observed locally |
Stable Swap swaps are not materialized from instruction min/max bounds. `swap_base_in/out` require `amountSource=stable_swap_vault_balance_delta`; `stable_swap_instruction_bounds_only` remains decoded-only and, in the final corpus, appears only on failed transactions.
## 0.7.54 — `pump_fun` closed
Program id unique : `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P`.
Source locale prioritaire : `idls/pump_fun.6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.json`.
Replay final rapporté : `1679 replayed`, `89 trades`, `10 lifecycle`, `348 candle upserts`, catalogue `52 tokens / 50 pools / 50 pairs`.
| Entry / groupe | Discriminator | Family | Expected DB target | Local event kind cible | Status final |
|---|---:|---|---|---|---|
| `create` / `create_v2` / `create_event` | `181ec828051c0777` / `d6904cec5f8b31b4` / `1b72a94ddeeb6376` | `launch` | `k_sol_launch_events` ou decoded-only | `pump_fun.create*` | couvert ; launch matérialisé quand mint/bonding/creator sont fiables |
| `migrate` / `migrate_v2` / migration events | `9beae792ec9ea21e` / `bbcb121fceedfe29` / voir IDL | `migration` | `k_sol_launch_events` ou decoded-only | `pump_fun.migrate*` | couvert ; migration matérialisée quand contexte fiable |
| `buy` / `sell` | `66063d1201daebea` / `33e685a4017f83ad` | `swap` | `k_sol_trade_events` | `pump_fun.buy` / `pump_fun.sell` | matérialisés directement avec montants fiables : `17` buy, `25` sell |
| `buy_exact_sol_in` | `38fc74089edfcd5f` | `swap` | `k_sol_trade_events` | `pump_fun.buy_exact_sol_in` | matérialisé directement ; `15` trades, y compris logs `Program data` tronqués exploitables |
| `buy_v2` / `sell_v2` / `buy_exact_quote_in_v2` | `b817ee6167c5d33d` / `5df6823ce7e940b2` / `c2ab1c46684d5b2f` | `swap` | audit/routing + `trade_event` canonique | `pump_fun.*_v2` | decoded/covered, non matérialisés directement ; les montants exécutés sont matérialisés via `pump_fun.trade_event` |
| `trade_event` | `bddb7fd34ee661ee` | `swap` | `k_sol_trade_events` | `pump_fun.trade_event` | `72` decoded / `25` trades ; source canonique des v2/exact quand corrélée ; skip explicite si couvert par trade direct |
| `collect_creator_fee*` / `distribute_creator_fees*` | voir IDL | `fee` | `k_sol_fee_events` ou decoded-only | `pump_fun.collect_creator_fee*`, `pump_fun.distribute_creator_fees*` | couvert ; matérialisation fee seulement avec montant/acteur fiables |
| `claim_cashback*` / `claim_token_incentives` / volume accumulators | voir IDL | `reward` | `k_sol_reward_events` ou decoded-only | `pump_fun.claim_*`, volume accumulator events | couvert ; rewards matérialisées seulement si preuve suffisante |
| creator/admin/config group | voir IDL | `admin_config` | `k_sol_pool_admin_events` ou decoded-only | `pump_fun.admin_*`, `pump_fun.set_*`, `pump_fun.toggle_*`, quote/buyback/reserve entries | couvert ; promotion seulement si action/comptes exploitables |
### Invariants de fermeture `0.7.54`
- Aucun `pump_fun` local decoded event sans coverage.
- Aucun fallback `upstream_git` résiduel pour les entrées Pump.fun couvertes localement.
- Aucun business event matérialisé depuis transaction failed.
- Aucun non-swap Pump.fun matérialisé en trade/candle.
- Aucun double-count entre instruction trade directe et `trade_event` Anchor.
- Aucun trade candidate Pump.fun réussi sans matérialisation ni skip reason.
- Les entrées IDL-only sont couvertes localement ; les non observées restent `mapped_unverified` ou audit-only, pas des gaps bloquants.
## 0.7.53 — `pump_swap`
Program id unique : `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA`.
| Entry | Discriminator | Family | Expected DB target | Local event kind | Status |
|---|---:|---|---|---|---|
| `buy` | `66063d1201daebea` | `swap` | `k_sol_trade_events` | `pump_swap.buy` | local specialized decoder ; materialize only from exact transfer/vault deltas |
| `sell` | `33e685a4017f83ad` | `swap` | `k_sol_trade_events` | `pump_swap.sell` | local specialized decoder ; materialize only from exact transfer/vault deltas |
| `buy_exact_quote_in` | `c62e1552b4d9e870` | `swap` | `k_sol_trade_events` only when exact Anchor `BuyEvent` is present ; otherwise decoded-only | `pump_swap.buy_exact_quote_in` | local specialized decoder ; `amountSource=pump_swap_anchor_buy_event` materializes trades ; `instruction_bounds_only` rows keep explicit `skipTradeReason` |
| `create_pool` | `e992d18ecf6840bc` | `pool_create` | `k_sol_pool_lifecycle_events` or decoded-only | `pump_swap.create_pool` | local specialized instruction ; non-trade |
| `deposit` | `f223c68952e1f2b6` | `liquidity_add` | `k_sol_liquidity_events` or decoded-only | `pump_swap.deposit` | local specialized instruction ; non-trade |
| `withdraw` | `b712469c946da122` | `liquidity_remove` | `k_sol_liquidity_events` or decoded-only | `pump_swap.withdraw` | local specialized instruction ; non-trade |
| `collect_coin_creator_fee` | `a039592ab58b2b42` | `fee` | `k_sol_fee_events` or decoded-only | `pump_swap.collect_coin_creator_fee` | local specialized instruction ; non-trade |
| `transfer_creator_fees_to_pump` | `8b348655e4e56cf1` | `fee` | `k_sol_fee_events` or decoded-only | `pump_swap.transfer_creator_fees_to_pump` | local specialized instruction ; non-trade |
| `transfer_creator_fees_to_pump_v2` | `01214eb921432c5c` | `fee` | `k_sol_fee_events` or decoded-only | `pump_swap.transfer_creator_fees_to_pump_v2` | Solscan IDL proof + local log proof: `transfer_creator_fees_to_pump_v2` / `Instruction: TransferCreatorFeesToPumpV2` ; non-trade |
| `claim_cashback` | `253a237ebe35e4c5` | `reward` | `k_sol_reward_events` or decoded-only | `pump_swap.claim_cashback` | local specialized instruction ; non-trade |
| `claim_token_incentives` | `1004471ccc01281b` | `reward` | `k_sol_reward_events` or decoded-only | `pump_swap.claim_token_incentives` | local specialized instruction ; non-trade |
| `init_user_volume_accumulator` | `5e06ca73ff60e8b7` | `reward` | `k_sol_reward_events` or decoded-only | `pump_swap.init_user_volume_accumulator` | local specialized instruction ; non-trade |
| `sync_user_volume_accumulator` | `561fc057a3574fee` | `reward` | `k_sol_reward_events` or decoded-only | `pump_swap.sync_user_volume_accumulator` | local specialized instruction ; non-trade |
| `close_user_volume_accumulator` | `f945a4da9667548a` | `reward` | `k_sol_reward_events` or decoded-only | `pump_swap.close_user_volume_accumulator` | local specialized instruction ; non-trade |
| `update_buyback_config` | `fbe0ab92a01a71e9` | `admin_config` | `k_sol_pool_admin_events` or decoded-only | `pump_swap.update_buyback_config` | Solscan IDL proof + local log proof: `update_buyback_config` / `Instruction: UpdateBuybackConfig` ; non-trade |
| `set_reserved_fee_recipient` | `cfbdb247a77a44b4` | `admin_config` | `k_sol_pool_admin_events` or decoded-only | `pump_swap.set_reserved_fee_recipient` | local log proof only: `Instruction: SetReservedFeeRecipient` ; absent from checked Solscan IDL raw ; non-trade |
| admin/config group | see report | `admin_config` | `k_sol_pool_admin_events` or decoded-only | `pump_swap.*` | local specialized instruction ; non-trade ; includes `toggle_cashback_enabled` and `migrate_pool_coin_creator` as admin-only |
| `buy_event` / `sell_event` | `67f4521f2cf57777` / `3e2f370aa503dc2a` | `swap_event_audit` | decoded-only | not local-instruction mapped | Program-data event discriminators listed; not used to duplicate local instruction trades |
| auxiliary Program-data events | see report | fee/reward/admin/liquidity | decoded-only until payload-specific materializer exists | not local-instruction mapped | explicit upstream status required after replay |
### Fermeture `0.7.53`
- `pump_swap` ne présente plus de decoded event local sans coverage dans le corpus de clôture.
- `buy_exact_quote_in` est matérialisé seulement quand le `BuyEvent` Anchor donne les montants exacts ; les bornes dinstruction seules restent non actionnables.
- Les events Anchor `*_event` sont décodés en audit-only pour éviter les doublons, sauf exception matérialisable explicitement testée.
- Les gaps globaux Pump.fun/PumpSwap/Pump Fees sont fermés ; la watchlist résiduelle courante ne contient plus `pump_fees` et garde seulement `jupiter_swap.route_v2` comme observation ponctuelle.
- Les checks Raydium AMM v4 / CLMM / CPMM normalisés sont vides ; aucune correction Raydium nest incluse dans cette clôture.
## 0.7.55 — Pump Fees
| Entry group | Discriminants | Famille | Target attendu | Local event kind | Notes |
|---|---:|---|---|---|---|
| `get_fees` | `e7257e55cf5b3f34` | audit | decoded-only | `pump_fees.get_fees` | Calcul/preview de fees ; ne pas matérialiser comme fee payé sans transfert réalisé. |
| social fee claim/create | IDL locale | reward / lifecycle | `k_sol_reward_events` ou `k_sol_pool_lifecycle_events` | `pump_fees.claim_social_fee_pda*`, `pump_fees.social_fee_pda_*` | Claim matérialisable seulement avec montant/acteur/mint fiables et transaction OK. |
| donation fee PDA | IDL locale | fee / lifecycle | `k_sol_fee_events` ou `k_sol_pool_lifecycle_events` | `pump_fees.*donation_fee_pda*` | Crank avec montant fiable vers fee ; création de PDA vers lifecycle. |
| buyback | IDL locale | fee / admin/lifecycle | `k_sol_fee_events`, `k_sol_pool_admin_events` ou lifecycle | `pump_fees.*buyback*` | Sweep matérialisable comme fee si montant fiable ; init/update comme lifecycle/admin. |
| fee sharing/config/authority/tier | IDL locale + Carbon partiel | admin_config / lifecycle | `k_sol_pool_admin_events` ou `k_sol_pool_lifecycle_events` | `pump_fees.*config*`, `pump_fees.*authority*`, `pump_fees.*tier*`, `pump_fees.update_fee_shares*` | Aucun trade/candle ; decoded-only/audit-only si données métier insuffisantes. |
## 0.7.55 Pump Fees — clôture
Programme : `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ`. Source locale prioritaire : `idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json`.
| Famille | Entrées | Target | Statut | Notes |
|---|---|---|---|---|
| fee calculation | `get_fees` / `e7257e55cf5b3f34` | `k_sol_dex_decoded_events_only` | decoded-only validé | Calcul/preview ; ne représente pas une fee payée. |
| reward/social fee | `claim_social_fee_pda`, `claim_social_fee_pda_v2`, `social_fee_pda_claimed` | `k_sol_reward_events` | matérialisé si tx OK | Écarts expliqués par failed tx. |
| donation fee | `create_donation_fee_pda`, `crank_donation_fee_pda`, events associés | lifecycle / `k_sol_fee_events` | matérialisé si tx OK | Création PDA vers lifecycle ; crank vers fee. |
| buyback | `initialize_buyback`, `sweep_buyback`, authority/rate-limit | lifecycle / fee / admin | matérialisé si tx OK | `sweep_buyback` et `sweep_buyback_event` alimentent fee. |
| fee sharing/config/authority/tier | config/reset/transfer/revoke/update/upsert | `k_sol_pool_admin_events` ou lifecycle | matérialisé si tx OK | Aucun trade/candle ; failed tx audit-only. |
| Anchor IDL non observés | `SetAuthorityEvent`, `SetClaimRateLimitEvent`, `SetDisableFlagsEvent`, `SetSocialClaimAuthorityEvent` | admin/audit | tests synthétiques | Aucun corpus Solscan au moment de clôture ; decoder conservé pour transactions futures. |
| Solscan hors IDL locale | `revoke_fee_sharing_authority_event`, `transfer_fee_sharing_authority_event` | admin | mapped_unverified | Discriminators trouvés via Solscan ; conservés comme surfaces futures. |
Invariants propres : fallback `pump_fees` vide, decoded sans coverage vide, successful non-materialized sans skip/policy vide, failed tx matérialisée vide, multi-target vide, anti-trade/candle direct vide, watchlist globale sans `pump_fees`.
## 0.7.56 — Meteora DBC clôturé
Programme : `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN`. Source locale prioritaire : `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json`.
| Groupe | Entrées | Famille | Cible DB | Local event kind | Décision finale |
|---|---|---|---|---|---|
| swaps | `swap`, `swap2` | swap | `k_sol_trade_events` + candles | `meteora_dbc.swap`, `meteora_dbc.swap2` | Matérialisés seulement avec montants et mints base/quote fiables ; `swap2` validé via transferts CPI/amount inference. |
| virtual pool init | `initialize_virtual_pool_with_spl_token`, `initialize_virtual_pool_with_token2022`, `EvtInitializePool` | pool_create | `k_sol_pool_lifecycle_events` + catalog si contexte complet | `meteora_dbc.initialize_virtual_pool_with_*`, `meteora_dbc.evt_initialize_pool_event` | Lifecycle/catalog prudent ; failed tx audit-only. |
| migration / lockers | `migrate_meteora_damm*`, `migration_damm_v2*`, `create_locker`, `EvtCurveComplete` | migration / lifecycle | `k_sol_pool_lifecycle_events` | `meteora_dbc.migrate_*`, `meteora_dbc.migration_*`, `meteora_dbc.create_locker` | Lifecycle, pas liquidity artificielle pour LP claim/lock ; metadata-only decoded-only si contexte insuffisant. |
| fees/surplus/leftover | `claim_*fee*`, `withdraw_migration_fee`, `zap_protocol_fee`, `*_withdraw_surplus`, `withdraw_leftover`, events Anchor fee | fee | `k_sol_fee_events` + `k_sol_fee_event_amounts` | `meteora_dbc.*fee*`, `meteora_dbc.*surplus*`, `meteora_dbc.*leftover*` | Montants réels depuis CPI SPL ou lamport delta ; maxima d'instruction refusés ; multi-leg/multi-mint dans `k_sol_fee_event_amounts`. |
| admin/config/metadata/operator | `create_config`, `create_operator_account`, `close_*operator*`, metadata, `transfer_pool_creator`, config events | admin_config | `k_sol_pool_admin_events` ou decoded-only | `meteora_dbc.*config*`, `meteora_dbc.*operator*`, `meteora_dbc.*metadata*`, `meteora_dbc.transfer_pool_creator` | Admin si compte/acteur fiables ; payload metadata générique decoded-only avec raison. |
| Anchor swap events | `EvtSwap`, `EvtSwap2` | swap/audit | decoded-only sauf corrélation sûre | `meteora_dbc.evt_swap_event`, `meteora_dbc.evt_swap2_event` | Les events portent des montants mais pas toujours le contexte mint/pair ; pas de double-count avec l'instruction swap matérialisée. |
Validation finale DBC : `89` parents fee, `96` legs fee amount, aucun parent scalaire sans leg, aucun leg orphelin, aucun decoded event local sans coverage, aucun failed tx matérialisé, aucun multi-target, aucun non-swap vers trade/candle.
## `0.7.57` — `meteora_dlmm` final coverage
Programme : `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo`. Source locale : `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json`. Surface finale : `76` instructions IDL, `30` events Anchor, `12` accounts, plus correction locale `initialize_preset_parameter_v2` (`75c73e67068e1fcb`) observée dans le corpus.
Validation finale : `460` tests, clippy OK, `769` replayed, `106` trades, `664` liquidity, `1107` lifecycle, `424` candle upserts, `8062` instruction observations. Les checks decoded sans coverage, successful non-materialized, failed tx materialized, multi-target, non-swap trade/candle, fee scalar sans leg, orphan fee legs et coverage duplicates sont vides.
| Famille | Entrées DLMM | Statut `0.7.57` | Cible DB | Justification / règle |
|---|---|---|---|---|
| `swap` | `swap`, `swap2`, `swap_exact_out`, `swap_exact_out2`, `swap_with_price_impact`, `swap_with_price_impact2` | `materialized` | `k_sol_trade_events` + candles | Seules ces instructions produisent trade/candle direct quand montants/mints/pool sont fiables. |
| `swap_log` | `swap_event`, `swap2_evt` | `materialized` | `k_sol_pool_lifecycle_events` | Logs Anchor informatifs matérialisés sans double-count trade/candle. |
| `pool_create` | `create_pool`, `lb_pair_create_event`, `initialize_*_lb_pair*`, `initialize_permission_lb_pair` | `materialized` si observé, sinon `upstream_git_mapped_unverified` | `k_sol_pool_lifecycle_events` | Pool lifecycle ; pas de trade direct. |
| `liquidity_add` | `add_liquidity*`, `add_liquidity_event` | `materialized` | `k_sol_liquidity_events` | Montants/side effects liquidity ; aucun trade/candle. |
| `liquidity_remove` | `remove_liquidity*`, `remove_all_liquidity`, `remove_liquidity_event` | `materialized` | `k_sol_liquidity_events` | Retrait liquidity ; failed tx audit-only. |
| `liquidity_change` | `rebalance_liquidity`, `rebalancing_event` | `materialized` | `k_sol_liquidity_events` | Changement de liquidité/bin ; pas de trade. |
| `position_open` | `initialize_position*`, `position_create_event` | `materialized` | `k_sol_pool_lifecycle_events` | Position/bin lifecycle, pas liquidity artificielle quand l'opération est structurelle. |
| `position_close` | `close_position*`, `position_close_event` | `materialized` | `k_sol_pool_lifecycle_events` | Fermeture position lifecycle. |
| `position_update` | `increase_position_length*`, `decrease_position_length*`, `update_position_operator*`, position update events | `materialized` si observé | `k_sol_pool_lifecycle_events` | Mise à jour de position ; pas admin générique. |
| `bin/oracle lifecycle` | `initialize_bin_array*`, `close_bin_array`, `go_to_a_bin*`, `increase_oracle_length`, `migrate_bin_array` | `materialized` si observé | `k_sol_pool_lifecycle_events` | `close_bin_array` a `16/14` car `2` failed tx `Custom 6015`, comportement attendu. |
| `fee` | `claim_fee*`, `claim_fee*_event`, `composition_fee_event`, `withdraw_protocol_fee`, `zap_protocol_fee` | `materialized` | `k_sol_fee_events` + `k_sol_fee_event_amounts` | Recovery inner SPL transfer strictement allowlistée ; legs multi-mint conservés sans agrégation artificielle. |
| `reward` | `claim_reward*`, `claim_reward*_event`, `fund_reward*`, `initialize_reward*`, `withdraw_ineligible_reward*` | `materialized` si observé | `k_sol_reward_events` | Claims/funding avec amounts récupérés quand transfert réel ; `initialize_reward*` sans amount est normal. |
| `admin/config` | `update_base_fee_parameters`, `fee_parameter_update_event`, `set_pair_status*`, `set_activation_point`, `set_pre_activation*`, preset/token badge/operator/config, `initialize_preset_parameter_v2` | `materialized` si observé | `k_sol_pool_admin_events` | Admin/config non financier ; pas trade/candle. |
| `orderbook` | `place_limit_order*`, `cancel_limit_order*`, `close_limit_order*` | `materialized` | `k_sol_orderbook_events` | Limit/orderbook events sans trade/candle. |
| `account metadata` | `lb_pair`, `bin_array`, `position_v2`, `oracle`, `operator`, `token_badge`, etc. | `upstream_git_mapped_unverified` / non observé | `k_sol_dex_decoded_events_only` | Accounts IDL listés pour coverage, pas de matérialisation métier directe. |
| `instruction_audit` | résidu inconnu | `closed` | `k_sol_pool_admin_events` seulement si observé | Résidu final observé = `0`; `75c73e67068e1fcb` a été promu en `initialize_preset_parameter_v2`. |

View File

@@ -0,0 +1,213 @@
<!-- file: docs/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md -->
# Raydium Launchpad event coverage report — `0.7.50`
## Scope
`0.7.50` opens the `raydium_launchpad` tranche after the functional closure of `0.7.49 raydium_clmm`.
Local canonical decoder/surface code:
```text
raydium_launchpad
```
Canonical program id:
```text
LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj
```
The legacy local name `raydium_launchlab` is not kept in the public Rust API. Coverage rows, upstream registry rows, launch origin entries, and support matrix rows use `raydium_launchpad`.
## Sources used
Primary source hints for this tranche:
- Carbon decoder registry/source: `sevenlabs-hq/carbon/decoders/raydium-launchpad-decoder`.
- Solscan Program IDL/account page: `https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj#programIdl`.
- fnzero IDL sources: `sol-parser-sdk` / `solana-program-idls` listings, including `raydium_launchpad.json` and separate `raydium_pool_v4.json` as an audit-only source.
- Raydium SDK Launchpad examples for account-shape hints only.
These sources are not treated as final business proof. Promotion still requires local corpus observation and SQL validation.
## Bootstrap implementation delta
Implemented in this delta:
- `RAYDIUM_LAUNCHPAD_PROGRAM_ID` added as the canonical public constant.
- Upstream generated registry rows normalized from `raydium_launchlab` to `raydium_launchpad`.
- Built-in launch surface code normalized to `raydium_launchpad`.
- DEX support/catalog entries normalized to `raydium_launchpad`.
- Raydium instruction audit fallback now recognizes Launchpad program id.
- Launchpad mapped instruction fallback added for locally listed Launchpad discriminators.
- Coverage target override keeps Launchpad rows `decoded_events_only` until corpus promotion.
- SQL validation file added for the `0.7.50` tranche.
## Listed Launchpad entries
The local upstream registry now lists one program entry plus the following 26 discriminator entries.
| Entry kind | Entry name | Discriminator | Initial family | Initial DB target |
|---|---:|---:|---|---|
| instruction | `buy_exact_in` | `faea0d7bd59c13ec` | swap | decoded_events_only |
| instruction | `buy_exact_out` | `18d3742869039938` | swap | decoded_events_only |
| instruction | `claim_creator_fee` | `1a618acb84ab8dfc` | fee | decoded_events_only |
| instruction | `claim_platform_fee` | `9c27d0874ced3d48` | fee | decoded_events_only |
| instruction | `claim_platform_fee_from_vault` | `75f1c6a8f8da501d` | fee | decoded_events_only |
| event | `claim_vested_event` | `15c2725778d3e220` | fee/vesting audit | decoded_events_only |
| instruction | `claim_vested_token` | `3121681ebd9d4f23` | fee/vesting audit | decoded_events_only |
| instruction | `collect_fee` | `3cadf767045d8230` | fee | decoded_events_only |
| instruction | `collect_migrate_fee` | `ffba96dfeb76c9ba` | fee/migration audit | decoded_events_only |
| instruction | `create_config` | `c9cff3724b6f2fbd` | admin_config | decoded_events_only |
| instruction | `create_platform_config` | `b05ac4affd71dc14` | admin_config | decoded_events_only |
| instruction | `create_vesting_account` | `81b2020dd9ace6da` | account_create/vesting audit | decoded_events_only |
| event | `create_vesting_event` | `96980bb334d2bf7d` | account_create/vesting audit | decoded_events_only |
| instruction | `initialize` | `afaf6d1f0d989bed` | pool_create/launch | decoded_events_only |
| instruction | `initialize_v2` | `4399af27da102620` | pool_create/launch | decoded_events_only |
| instruction | `initialize_with_token_2022` | `25be7ede2c9aab11` | pool_create/launch | decoded_events_only |
| instruction | `migrate_to_amm` | `cf52c091fecf91df` | migration | decoded_events_only |
| instruction | `migrate_to_cpswap` | `885cc8671cda908c` | migration | decoded_events_only |
| event | `pool_create_event` | `97d7e20976a173ae` | pool_create | decoded_events_only |
| instruction | `remove_platform_curve_param` | `1b1e3ea95de01891` | admin_config | decoded_events_only |
| instruction | `sell_exact_in` | `9527de9bd37c981a` | swap | decoded_events_only |
| instruction | `sell_exact_out` | `5fc8472208090ba6` | swap | decoded_events_only |
| event | `trade_event` | `bddb7fd34ee661ee` | swap | decoded_events_only |
| instruction | `update_config` | `1d9efcbf0a53db63` | admin_config | decoded_events_only |
| instruction | `update_platform_config` | `c33c4c81922d438f` | admin_config | decoded_events_only |
| instruction | `update_platform_curve_param` | `8a908afadc800439` | admin_config | decoded_events_only |
Notes:
- The buy/sell instruction account hints currently use account index `4` as candidate pool account and indexes `9`/`10` as candidate token mints, based on Carbon/Raydium Launchpad account shape hints. This is an audit helper, not a materialization proof.
- Fee/admin/migration/vesting entries intentionally do not infer pool/token accounts until corpus confirms the account semantics.
- Program-data transport is represented by `cpi_event`; embedded events are decoded by their own discriminators and materialized only when their event family has a validated target.
## Family audit matrix
| Family | Launchpad status in `0.7.50` final | Decision |
|---|---|---|
| swap | `trade_event` materialized as trades/candles; buy/sell instructions materialized as launch breadcrumbs. | No duplicate trades from instruction breadcrumbs. |
| pool_create | `initialize`, `initialize_v2`, `initialize_with_token_2022`, `pool_create_event`. | Pool lifecycle/catalogue materialized when transaction succeeded. |
| add_liquidity | No direct Launchpad entry confirmed. | Non-applicable unless local corpus proves direct Launchpad liquidity instruction. |
| remove_liquidity | No direct Launchpad liquidity remove entry confirmed. | Non-applicable unless local corpus proves direct Launchpad liquidity instruction. |
| position_open | No direct Launchpad position instruction confirmed. | Non-applicable. |
| position_close | No direct Launchpad position instruction confirmed. | Non-applicable. |
| fee | claim/collect fee entries listed. | Fee table materialization enabled for observed successful transactions. |
| reward | No direct reward instruction confirmed. | Non-applicable unless local corpus proves otherwise. |
| admin/config | create/update config and platform curve/config entries listed. | Pool admin materialization enabled for observed successful transactions. |
| mint | Token minting may appear as SPL Token/Token-2022 side effect. | Not `raydium_launchpad.*` without direct program proof. |
| burn | Token burn may appear as SPL Token/Token-2022 side effect. | Not `raydium_launchpad.*` without direct program proof. |
| transfer | Transfers are expected as SPL Token/Token-2022 side effects. | Not `raydium_launchpad.*` without direct program proof. |
| account_create / vesting | `create_vesting_account`, `create_platform_vesting_account`, vesting events. | Launch event materialization enabled for observed successful transactions; unobserved events remain mapped. |
| account_close | No direct Launchpad account close confirmed. | Non-applicable. |
| wrap_sol | No direct Launchpad wrap SOL confirmed. | Side effect only unless corpus proves direct instruction. |
| unwrap_sol | No direct Launchpad unwrap SOL confirmed. | Side effect only unless corpus proves direct instruction. |
| order_place | No orderbook surface confirmed. | Non-applicable. |
| order_cancel | No orderbook surface confirmed. | Non-applicable. |
| order_fill | No orderbook surface confirmed. | Non-applicable. |
| consume_events | No orderbook surface confirmed. | Non-applicable. |
| settle_funds | No orderbook surface confirmed. | Non-applicable. |
| vault_deposit | No direct vault deposit confirmed. | Non-applicable. |
| vault_withdraw | No direct vault withdraw confirmed. | Non-applicable. |
| lock | No direct lock confirmed. | Non-applicable. |
| unlock | No direct unlock confirmed. | Non-applicable. |
| launch | initialize/pool_create path listed. | Decode/audit only. |
| migration | `migrate_to_amm`, `migrate_to_cpswap`, `collect_migrate_fee` listed. | Decode/audit only. Destination DEX materialization must be proven locally. |
| stake | No direct stake confirmed. | Non-applicable. |
| unstake | No direct unstake confirmed. | Non-applicable. |
| unknown/unmapped audit | `raydium_launchpad.instruction_audit` retained for unmatched program instructions. | Must trend toward zero for locally covered discriminators after backfill/replay. |
## SQL validation expectations
After targeted backfill and replay:
1. `k_sol_dex_event_coverage_entries` should contain the Launchpad program entry and discriminator entries.
2. Mapped entries should have `local_event_kind = raydium_launchpad.<entry_name>` and initial `proof_status = upstream_git_mapped_unverified` until observed.
3. Locally observed instructions should increment `k_sol_instruction_observations` for `decoder_code = raydium_launchpad`.
4. `upstream_git.instruction_match` fallback rows for `upstreamDecoderCode = raydium_launchpad` should be zero for locally covered instruction discriminators.
5. `raydium_launchpad.*` rows must not produce trades/candles unless a later corpus-backed patch explicitly promotes a specific event.
6. Failed transactions may be decoded/audited, but must not be materialized in trade/candle tables.
Validation file:
```text
validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql
```
## Suggested targeted Solscan discovery loop
For each discriminator:
```text
https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
Then:
1. copy a small batch of recent non-failed signatures;
2. backfill through Demo2 textarea batch;
3. replay with `forceDexDecode=yes` and `deferInstructionObservations=yes`;
4. run the validation SQL;
5. promote only entries whose local payload and account semantics are proven.
## `raydium_pool_v4.json` audit status
The current workspace archive does not contain a local `raydium_pool_v4.json` copy. External fnzero IDL listings expose a separate `raydium_pool_v4.json` beside `raydium_launchpad.json`, but this delta does not confirm its program id or business role.
Decision for `0.7.50`:
- do not promote `raydium_pool_v4` as a DEX/surface;
- keep `0.7.53 raydium_pool_v4 audit / program-id decision` conditional;
- require program id confirmation and local corpus before any roadmap promotion.
## Current limitations
This delta was prepared from the provided archive only. No live RPC backfill, fresh SQLite replay, `cargo fmt`, `cargo test`, or `cargo clippy` could be executed in the current environment because the Rust toolchain is unavailable here. The SQL and code paths are prepared for local validation in the normal project environment.
## Local corpus snapshot from first 0.7.50 backfill
Observed after targeted Demo2 backfills and pool backfill on a fresh 0.7.50 DB:
- coverage listed entries: `27`;
- decoded/local mapped entries: `26`;
- observed entries: `21`;
- materialized entries: `0`;
- total observed coverage count: `672`;
- total materialized count: `0`;
- trade count: `0`;
- residual `upstream_git.instruction_match` for `raydium_launchpad`: `0`;
- residual `raydium_launchpad.instruction_audit`: `287`;
- residual audit discriminators: `e445a52e51cb9a1d` (`276`), `9247ad4562130f6a` (`10`), `a25b92c75d85eaed` (`1`).
The `e445a52e51cb9a1d` selector is handled as Anchor self-CPI event transport. It is not promoted as a Raydium Launchpad business instruction. The two low-count residual discriminators remain local-corpus audit-only until an IDL/upstream mapping is confirmed.
## pre3 correction — Demo3 preset and Launchpad pool catalog
The first replay after pre2 confirmed that Anchor self-CPI selector `e445a52e51cb9a1d` carries Launchpad `trade_event` (`bddb7fd34ee661ee`) and `pool_create_event` (`97d7e20976a173ae`). pre3 therefore decodes those two self-CPI event rows as direct `raydium_launchpad.*` events instead of leaving them under `raydium_launchpad.instruction_audit`. `trade_event` remains audit/decoded-only and is still not promoted to `k_sol_trade_events` or candles.
pre3 also fixes the Launchpad `initialize`, `initialize_v2` and `initialize_with_token_2022` account mapping using the Carbon account shape: `pool_state` index 5, `base_mint` index 6 and `quote_mint` index 7. These initialize rows are now routed to business-level pool detection as `raydium_launchpad` bonding-curve pools with pending status, which should allow pool `6HLQPoLrzX6LqePRiXQ1GGs2Dd9K3dp9VhTSHBugYzzZ` to appear in the local catalog after a forced replay when its initialize transaction is present locally.
Demo3 now exposes a `Raydium Launchpad` preset with program id `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj`.
## Final `0.7.50` closure snapshot
Validated closure state reported by local replay:
- `cargo test -p kb_lib`: 404 passed, 0 failed.
- Local replay: 437 replayed, 437 ledger upserts, 30 unsafe ledger rows, 256 trades, 115 lifecycle rows, 1024 candle upserts, 6205 instruction observations.
- Launchpad catalogue: 58 tokens, 58 pools, 58 pairs after replay.
- Coverage normalization: no ambiguous `unknown` family remains; only the synthetic `program` row may have an empty family.
- `trade_event`: 260 decoded, 250 successful materialized trades; 10 failed transactions intentionally not materialized.
- `buy_exact_*` / `sell_exact_*`: materialized as `k_sol_launch_events` swap-instruction breadcrumbs, not as trades.
- `cpi_event`: kept as `cpi_transport` / decoded-only; embedded events are decoded by direct event discriminator.
- Successful `trade_event` rows without materialized `k_sol_trade_events`: zero.
Post-closure recheck assets added:
- `validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_50_PRE_R2.sql`
- `validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_50_PRE_R2.sql`
- `docs/SOLSCAN_ACCOUNT_SOURCE_MATRIX.md`
- `kb_lib::SOLSCAN_ACCOUNT_SOURCES`

View File

@@ -0,0 +1,159 @@
<!-- file: docs/SOLSCAN_ACCOUNT_SOURCE_MATRIX.md -->
# Solscan account source matrix
This file records the manual Solscan account inventory added during the `0.7.50` Raydium Launchpad closure. It is a source catalogue, not a support guarantee. Entries with `solscan_program_idl` can be used as IDL candidates; entries with `no_idl` require source/corpus work before decoder promotion.
| Label | Account id | IDL status | Source |
|---|---|---|---|
| `1Dex Program` | `DEXYosS6oEGvk8uCDayvwEZz4qEyDJRf9nFgYCaqPMTm` | `no_idl` | https://solscan.io/account/DEXYosS6oEGvk8uCDayvwEZz4qEyDJRf9nFgYCaqPMTm |
| `AlphaQ` | `ALPHAQmeA7bjrVuccPsYPiCvsi428SNwte66Srvs4pHA` | `no_idl` | https://solscan.io/account/ALPHAQmeA7bjrVuccPsYPiCvsi428SNwte66Srvs4pHA |
| `Aldrin AMM` | `AMM55ShdkoGRB5jVYPjWziwk8m5MpwyDgsMWHaMSQWH6` | `no_idl` | https://solscan.io/account/AMM55ShdkoGRB5jVYPjWziwk8m5MpwyDgsMWHaMSQWH6 |
| `Aldrin AMM V2` | `CURVGoZn8zycx6FXwwevgBTB2gVvdbGTEpvMJDbgs2t4` | `no_idl` | https://solscan.io/account/CURVGoZn8zycx6FXwwevgBTB2gVvdbGTEpvMJDbgs2t4 |
| `ApePro Smart Wallet Program` | `JSW99DKmxNyREQM14SQLDykeBvEUG63TeohrvmofEiw` | `solscan_program_idl` | https://solscan.io/account/JSW99DKmxNyREQM14SQLDykeBvEUG63TeohrvmofEiw#programIdl |
| `Aquifer` | `AQU1FRd7papthgdrwPTTq5JacJh8YtwEXaBfKU3bTz45` | `no_idl` | https://solscan.io/account/AQU1FRd7papthgdrwPTTq5JacJh8YtwEXaBfKU3bTz45 |
| `Axiom Trade` | `FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9` | `no_idl` | https://solscan.io/account/FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9 |
| `Bags: Token Authority` | `BAGSB9TpGrZxQbEsrEznv5jXXdwyP6AXerN8aVRiAmcv` | `solscan_account` | https://solscan.io/account/BAGSB9TpGrZxQbEsrEznv5jXXdwyP6AXerN8aVRiAmcv |
| `Believe : Token Authority` | `5qWya6UjwWnGVhdSBL3hyZ7B45jbk6Byt1hwd7ohEGXE` | `no_idl` | https://solscan.io/account/5qWya6UjwWnGVhdSBL3hyZ7B45jbk6Byt1hwd7ohEGXE |
| `BisonFi` | `BiSoNHVpsVZW2F7rx2eQ59yQwKxzU5NvBcmKshCSUypi` | `no_idl` | https://solscan.io/account/BiSoNHVpsVZW2F7rx2eQ59yQwKxzU5NvBcmKshCSUypi |
| `BonkSwap` | `BSwp6bEBihVLdqJRKGgzjcGLHkcTuzmSo1TQkHepzH8p` | `solscan_program_idl` | https://solscan.io/account/BSwp6bEBihVLdqJRKGgzjcGLHkcTuzmSo1TQkHepzH8p#programIdl |
| `Boop.fun` | `boop8hVGQGqehUK2iVEMEnMrL5RbjywRzHKBmBE7ry4` | `solscan_program_idl` | https://solscan.io/account/boop8hVGQGqehUK2iVEMEnMrL5RbjywRzHKBmBE7ry4#programIdl |
| `Byreal: CLMM` | `REALQqNEomY6cQGZJUGwywTBD2UmDT32rZcNnfxQ5N2` | `solscan_program_idl` | https://solscan.io/account/REALQqNEomY6cQGZJUGwywTBD2UmDT32rZcNnfxQ5N2#programIdl |
| `Bubblegum` | `BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY` | `solscan_program_idl` | https://solscan.io/account/BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY#programIdl |
| `Carrot DeFi` | `CarrotwivhMpDnm27EHmRLeQ683Z1PufuqEmBZvD282s` | `solscan_program_idl` | https://solscan.io/account/CarrotwivhMpDnm27EHmRLeQ683Z1PufuqEmBZvD282s#programIdl |
| `CCTP TokenMessengerMinter` | `CCTPiPYPc6AsJuwueEnWgSgucamXDZwBd53dQ11YiKX3` | `solscan_program_idl` | https://solscan.io/account/CCTPiPYPc6AsJuwueEnWgSgucamXDZwBd53dQ11YiKX3#programIdl |
| `CCTP TokenMessengerMinterV2` | `CCTPV2vPZJS2u2BBsUoscuikbYjnpFmbFsvVuJdgUMQe` | `solscan_program_idl` | https://solscan.io/account/CCTPV2vPZJS2u2BBsUoscuikbYjnpFmbFsvVuJdgUMQe#programIdl |
| `Clone` | `C1onEW2kPetmHmwe74YC1ESx3LnFEpVau6g2pg4fHycr` | `solscan_program_idl` | https://solscan.io/account/C1onEW2kPetmHmwe74YC1ESx3LnFEpVau6g2pg4fHycr#programIdl |
| `Crema Finance Program` | `CLMM9tUoggJu2wagPkkqs9eFG4BWhVBZWkP1qv3Sp7tR` | `no_idl` | https://solscan.io/account/CLMM9tUoggJu2wagPkkqs9eFG4BWhVBZWkP1qv3Sp7tR |
| `Cropper Finance` | `CTMAxxk34HjKWxQ3QLZK1HpaLXmBveao3ESePXbiyfzh` | `no_idl` | https://solscan.io/account/CTMAxxk34HjKWxQ3QLZK1HpaLXmBveao3ESePXbiyfzh |
| `Cropper Whirlpool` | `H8W3ctz92svYg6mkn1UtGfu2aQr2fnUFHM1RhScEtQDt` | `no_idl` | https://solscan.io/account/H8W3ctz92svYg6mkn1UtGfu2aQr2fnUFHM1RhScEtQDt |
| `deBridge Destination` | `dst5MGcFPoBeREFAA5E3tU5ij8m5uVYwkzkSAbsLbNo` | `no_idl` | https://solscan.io/account/dst5MGcFPoBeREFAA5E3tU5ij8m5uVYwkzkSAbsLbNo |
| `deBridge Source` | `src5qyZHqTqecJV4aY6Cb6zDZLMDzrDKKezs22MPHr4` | `no_idl` | https://solscan.io/account/src5qyZHqTqecJV4aY6Cb6zDZLMDzrDKKezs22MPHr4 |
| `Dexlab Swap` | `DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N` | `no_idl` | https://solscan.io/account/DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N |
| `DFlow Aggregator v4` | `DF1ow4tspfHX9JwWJsAb9epbkA8hmpSEAtxXy1V27QBH` | `solscan_program_idl` | https://solscan.io/account/DF1ow4tspfHX9JwWJsAb9epbkA8hmpSEAtxXy1V27QBH#programIdl |
| `Drift V2 Program` | `dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH` | `solscan_program_idl` | https://solscan.io/account/dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH#programIdl |
| `Fluxbeam Program` | `FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X` | `no_idl` | https://solscan.io/account/FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X |
| `Fusion AMM` | `fUSioN9YKKSa3CUC2YUc4tPkHJ5Y6XW1yz8y6F7qWz9` | `solscan_program_idl` | https://solscan.io/account/fUSioN9YKKSa3CUC2YUc4tPkHJ5Y6XW1yz8y6F7qWz9#programIdl |
| `Futarchy AMM` | `FUTARELBfJfQ8RDGhg1wdhddq1odMAJUePHFuBYfUxKq` | `solscan_program_idl` | https://solscan.io/account/FUTARELBfJfQ8RDGhg1wdhddq1odMAJUePHFuBYfUxKq#programIdl |
| `Gavel` | `srAMMzfVHVAtgSJc8iH6CfKzuWuUTzLHVCE81QU1rgi` | `no_idl` | https://solscan.io/account/srAMMzfVHVAtgSJc8iH6CfKzuWuUTzLHVCE81QU1rgi |
| `GoonFi` | `goonERTdGsjnkZqWuVjs73BZ3Pb9qoCUdBUL17BnS5j` | `no_idl` | https://solscan.io/account/goonERTdGsjnkZqWuVjs73BZ3Pb9qoCUdBUL17BnS5j |
| `GoonFi V2` | `goonuddtQRrWqqn5nFyczVKaie28f3kDkHWkHtURSLE` | `no_idl` | https://solscan.io/account/goonuddtQRrWqqn5nFyczVKaie28f3kDkHWkHtURSLE |
| `GooseFX: GAMMA` | `GAMMA7meSFWaBXF25oSUgmGRwaW6sCMFLmBNiMSdbHVT` | `solscan_program_idl` | https://solscan.io/account/GAMMA7meSFWaBXF25oSUgmGRwaW6sCMFLmBNiMSdbHVT#programIdl |
| `GooseFX V2` | `GFXsSL5sSaDfNFQUYsHekbWBW1TsFdjDYzACh62tEHxn` | `solscan_program_idl` | https://solscan.io/account/GFXsSL5sSaDfNFQUYsHekbWBW1TsFdjDYzACh62tEHxn#programIdl |
| `Guac Swap` | `Gswppe6ERWKpUTXvRPfXdzHhiCyJvLadVvXGfdpBqcE1` | `solscan_program_idl` | https://solscan.io/account/Gswppe6ERWKpUTXvRPfXdzHhiCyJvLadVvXGfdpBqcE1#programIdl |
| `HawkFi Program` | `FqGg2Y1FNxMiGd51Q6UETixQWkF5fB92MysbYogRJb3P` | `no_idl` | https://solscan.io/account/FqGg2Y1FNxMiGd51Q6UETixQWkF5fB92MysbYogRJb3P |
| `Heaven DEX` | `HEAVENoP2qxoeuF8Dj2oT1GHEnu49U5mJYkdeC8BAX2o` | `no_idl` | https://solscan.io/account/HEAVENoP2qxoeuF8Dj2oT1GHEnu49U5mJYkdeC8BAX2o |
| `Helium Treasury Management` | `treaf4wWBBty3fHdyBpo35Mz84M8k3heKXmjmi9vFt5` | `solscan_program_idl` | https://solscan.io/account/treaf4wWBBty3fHdyBpo35Mz84M8k3heKXmjmi9vFt5#programIdl |
| `HumidiFi` | `9H6tua7jkLhdm3w8BvgpTn5LZNU7g4ZynDmCiNN3q6Rp` | `no_idl` | https://solscan.io/account/9H6tua7jkLhdm3w8BvgpTn5LZNU7g4ZynDmCiNN3q6Rp |
| `Hylo Exchange` | `HYEXCHtHkBagdStcJCp3xbbb9B7sdMdWXFNj6mdsG4hn` | `solscan_program_idl` | https://solscan.io/account/HYEXCHtHkBagdStcJCp3xbbb9B7sdMdWXFNj6mdsG4hn#programIdl |
| `Hylo Stability Pool` | `HysTabVUfmQBFcmzu1ctRd1Y1fxd66RBpboy1bmtDSQQ` | `solscan_program_idl` | https://solscan.io/account/HysTabVUfmQBFcmzu1ctRd1Y1fxd66RBpboy1bmtDSQQ#programIdl |
| `Invariant Swap` | `HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt` | `no_idl` | https://solscan.io/account/HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt |
| `Jito Tip Distribution` | `4R3gSG8BpU4t19KYj8CfnbtRpnT8gtk4dvTHxVRwc2r7` | `solscan_program_idl` | https://solscan.io/account/4R3gSG8BpU4t19KYj8CfnbtRpnT8gtk4dvTHxVRwc2r7#programIdl |
| `Jupiter Aggregator v6` | `JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4` | `solscan_program_idl` | https://solscan.io/account/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4#programIdl |
| `Jupiter Aggregator v4` | `JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB` | `solscan_program_idl` | https://solscan.io/account/JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB#programIdl |
| `Jupiter DCA program` | `DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M` | `solscan_program_idl` | https://solscan.io/account/DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M#programIdl |
| `Jupiter Lend Borrow` | `jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi` | `no_idl` | https://solscan.io/account/jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi |
| `Jupiter Lend Earn` | `jup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9` | `solscan_program_idl` | https://solscan.io/account/jup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9#programIdl |
| `Jupiter Lend Flash Loan` | `jupgfSgfuAXv4B6R2Uxu85Z1qdzgju79s6MfZekN6XS` | `no_idl` | https://solscan.io/account/jupgfSgfuAXv4B6R2Uxu85Z1qdzgju79s6MfZekN6XS |
| `Jupiter Lend Liquidity` | `jupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC` | `no_idl` | https://solscan.io/account/jupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC |
| `Jupiter Limit Order` | `jupoNjAxXgZ4rjzxzPMP4oxduvQsQtZzyknqvzYNrNu` | `solscan_program_idl` | https://solscan.io/account/jupoNjAxXgZ4rjzxzPMP4oxduvQsQtZzyknqvzYNrNu#programIdl |
| `Jupiter Limit Order V2` | `j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X` | `solscan_program_idl` | https://solscan.io/account/j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X#programIdl |
| `Jupiter Lock` | `LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn` | `solscan_program_idl` | https://solscan.io/account/LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn#programIdl |
| `Jupiter Perpetuals` | `PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu` | `solscan_program_idl` | https://solscan.io/account/PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu#programIdl |
| `Jupiter Prediction Market` | `3ZZuTbwC6aJbvteyVxXUS7gtFYdf7AuXeitx6VyvjvUp` | `no_idl` | https://solscan.io/account/3ZZuTbwC6aJbvteyVxXUS7gtFYdf7AuXeitx6VyvjvUp |
| `Jupiter Stable Program` | `JUPUSDecMzAVgztLe6eGhwUBj1Pn3j9WAXwmtHmfbRr` | `solscan_program_idl` | https://solscan.io/account/JUPUSDecMzAVgztLe6eGhwUBj1Pn3j9WAXwmtHmfbRr#programIdl |
| `Jup Studio: Authority` | `8rE9CtCjwhSmbwL5fbJBtRFsS3ohfMcDFeTTC7t4ciUA` | `no_idl` | https://solscan.io/account/8rE9CtCjwhSmbwL5fbJBtRFsS3ohfMcDFeTTC7t4ciUA |
| `Kamino Program` | `6LtLpnUFNByNXLyCoK9wA2MykKAmQNZKBdY8s47dehDc` | `solscan_program_idl` | https://solscan.io/account/6LtLpnUFNByNXLyCoK9wA2MykKAmQNZKBdY8s47dehDc#programIdl |
| `Kamino Lending Program` | `KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD` | `solscan_program_idl` | https://solscan.io/account/KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD#programIdl |
| `Kamino Farm` | `FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr` | `solscan_program_idl` | https://solscan.io/account/FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr#programIdl |
| `Kamino Vault Program` | `kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr` | `solscan_program_idl` | https://solscan.io/account/kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr#programIdl |
| `Kvault Program` | `KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd` | `solscan_program_idl` | https://solscan.io/account/KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd#programIdl |
| `LayerZero Endpoint` | `76y77prsiCMvXMjuoZ5VRrhG5qYBrUMYTE5WgHqgjEn6` | `solscan_program_idl` | https://solscan.io/account/76y77prsiCMvXMjuoZ5VRrhG5qYBrUMYTE5WgHqgjEn6#programIdl |
| `LayerZero Executor` | `6doghB248px58JSSwG4qejQ46kFMW4AMj7vzJnWZHNZn` | `solscan_program_idl` | https://solscan.io/account/6doghB248px58JSSwG4qejQ46kFMW4AMj7vzJnWZHNZn#programIdl |
| `letsbonk.fun: PlatformConfig` | `FfYek5vEz23cMkWsdJwG2oa6EphsvXSHrGpdALN4g6W1` | `no_idl` | https://solscan.io/account/FfYek5vEz23cMkWsdJwG2oa6EphsvXSHrGpdALN4g6W1 |
| `Lifinity Swap` | `EewxydAPCCVuNEyrVN68PuSYdQ7wKn27V9Gjeoi8dy3S` | `no_idl` | https://solscan.io/account/EewxydAPCCVuNEyrVN68PuSYdQ7wKn27V9Gjeoi8dy3S |
| `Lifinity Swap V2` | `2wT8Yq49kHgDzXuPxZSaeLaH1qbmGXtEyPy64bL7aD3c` | `solscan_program_idl` | https://solscan.io/account/2wT8Yq49kHgDzXuPxZSaeLaH1qbmGXtEyPy64bL7aD3c#programIdl |
| `Manifest` | `MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms` | `no_idl` | https://solscan.io/account/MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms |
| `Marcopolo Swap` | `9tKE7Mbmj4mxDjWatikzGAtkoWosiiZX9y6J4Hfm2R8H` | `no_idl` | https://solscan.io/account/9tKE7Mbmj4mxDjWatikzGAtkoWosiiZX9y6J4Hfm2R8H |
| `Marginfi` | `MFLQPPPPjNinkdKoy2odNFBhvpY43XtCDZjBwG2fwn5` | `no_idl` | https://solscan.io/account/MFLQPPPPjNinkdKoy2odNFBhvpY43XtCDZjBwG2fwn5 |
| `Marginfi V2` | `MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA` | `solscan_program_idl` | https://solscan.io/account/MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA#programIdl |
| `Marinade Finance` | `MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD` | `solscan_program_idl` | https://solscan.io/account/MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD#programIdl |
| `Mercurial Stable Swap` | `MERLuDFBMmsHnsBPZw2sDQZHvXFMwp8EdjudcU2HKky` | `no_idl` | https://solscan.io/account/MERLuDFBMmsHnsBPZw2sDQZHvXFMwp8EdjudcU2HKky |
| `MetaDAO AMM Program v0.5` | `AMMJdEiCCa8mdugg6JPF7gFirmmxisTfDJoSNSUi5zDJ` | `solscan_program_idl` | https://solscan.io/account/AMMJdEiCCa8mdugg6JPF7gFirmmxisTfDJoSNSUi5zDJ#programIdl |
| `MetaDAO Bid Wall Program` | `WALL8ucBuUyL46QYxwYJjidaFYhdvxUFrgvBxPshERx` | `solscan_program_idl` | https://solscan.io/account/WALL8ucBuUyL46QYxwYJjidaFYhdvxUFrgvBxPshERx#programIdl |
| `MetaDAO ICO` | `moontUzsdepotRGe5xsfip7vLPTJnVuafqdUWexVnPM` | `solscan_program_idl` | https://solscan.io/account/moontUzsdepotRGe5xsfip7vLPTJnVuafqdUWexVnPM#programIdl |
| `Metaplex Token Metadata` | `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s` | `no_idl` | https://solscan.io/account/metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s |
| `Meteora DLMM Program` | `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo` | `solscan_program_idl` | https://solscan.io/account/LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo#programIdl |
| `Meteora Pools Program` | `Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB` | `solscan_program_idl` | https://solscan.io/account/Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB#programIdl |
| `Meteora Dynamic Bonding Curve` | `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN` | `solscan_program_idl` | https://solscan.io/account/dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN#programIdl |
| `Meteora DAMM v2` | `cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG` | `solscan_program_idl` | https://solscan.io/account/cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG#programIdl |
| `Meteora Vault Program` | `24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi` | `solscan_program_idl` | https://solscan.io/account/24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi#programIdl |
| `Moonit` | `MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG` | `solscan_program_idl` | https://solscan.io/account/MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG#programIdl |
| `Moonshot : Token Authority` | `7rtiKSUDLBm59b1SBmD9oajcP8xE64vAGSMbAN5CXy1q` | `no_idl` | https://solscan.io/account/7rtiKSUDLBm59b1SBmD9oajcP8xE64vAGSMbAN5CXy1q |
| `Mpl Core` | `CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d` | `no_idl` | https://solscan.io/account/CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d |
| `Name Service Program` | `namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX` | `no_idl` | https://solscan.io/account/namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX |
| `Numeraire` | `NUMERUNsFCP3kuNmWZuXtm1AaQCPj9uw6Guv2Ekoi5P` | `solscan_program_idl` | https://solscan.io/account/NUMERUNsFCP3kuNmWZuXtm1AaQCPj9uw6Guv2Ekoi5P#programIdl |
| `Obric V2` | `obriQD1zbpyLz95G5n7nJe6a4DPjpFwa5XYPoNm113y` | `no_idl` | https://solscan.io/account/obriQD1zbpyLz95G5n7nJe6a4DPjpFwa5XYPoNm113y |
| `OKX Labs 1` | `6m2CDdhRgxpH4WjvdzxAYbGxwdGUz5MziiL5jek2kBma` | `solscan_program_idl` | https://solscan.io/account/6m2CDdhRgxpH4WjvdzxAYbGxwdGUz5MziiL5jek2kBma#programIdl |
| `OKX: DEX Router` | `proVF4pMXVaYqmy4NjniPh4pqKNfMmsihgd4wdkCX3u` | `solscan_program_idl` | https://solscan.io/account/proVF4pMXVaYqmy4NjniPh4pqKNfMmsihgd4wdkCX3u#programIdl |
| `Ondo Global Markets` | `XzTT4XB8m7sLD2xi6snefSasaswsKCxx5Tifjondogm` | `solscan_program_idl` | https://solscan.io/account/XzTT4XB8m7sLD2xi6snefSasaswsKCxx5Tifjondogm#programIdl |
| `Openbook V2` | `opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb` | `solscan_program_idl` | https://solscan.io/account/opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb#programIdl |
| `Orca Whirlpools Program` | `whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc` | `solscan_program_idl` | https://solscan.io/account/whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc#programIdl |
| `Orca Wavebreak` | `waveQX2yP3H1pVU8djGvEHmYg8uamQ84AuyGtpsrXTF` | `solscan_program_idl` | https://solscan.io/account/waveQX2yP3H1pVU8djGvEHmYg8uamQ84AuyGtpsrXTF#programIdl |
| `Orca Token Swap` | `DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1` | `no_idl` | https://solscan.io/account/DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1 |
| `Orca Token Swap V2` | `9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP` | `no_idl` | https://solscan.io/account/9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP |
| `Ore V3 Program` | `oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWv` | `no_idl` | https://solscan.io/account/oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWv |
| `PancakeSwap` | `HpNfyc2Saw7RKkQd8nEL4khUcuPhQ7WwY1B2qjx8jxFq` | `solscan_program_idl` | https://solscan.io/account/HpNfyc2Saw7RKkQd8nEL4khUcuPhQ7WwY1B2qjx8jxFq#programIdl |
| `Penguin Finance` | `PSwapMdSai8tjrEXcxFeQth87xC4rRsa4VA5mhGhXkP` | `no_idl` | https://solscan.io/account/PSwapMdSai8tjrEXcxFeQth87xC4rRsa4VA5mhGhXkP |
| `Phoenix` | `PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY` | `no_idl` | https://solscan.io/account/PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY |
| `Printr` | `T8HsGYv7sMk3kTnyaRqZrbRPuntYzdh12evXBkprint` | `solscan_program_idl` | https://solscan.io/account/T8HsGYv7sMk3kTnyaRqZrbRPuntYzdh12evXBkprint#programIdl |
| `Pump.fun` | `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` | `solscan_program_idl` | https://solscan.io/account/6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P#programIdl |
| `Pump.fun AMM` | `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` | `solscan_program_idl` | https://solscan.io/account/pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA#programIdl |
| `Pump Fees Program` | `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` | `solscan_program_idl` | https://solscan.io/account/pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ#programIdl |
| `pumpup.ai` | `PdMDrKEMaX8q7CCJb7NvUCxerBCcsFUa4LjBEynTtEd` | `solscan_program_idl` | https://solscan.io/account/PdMDrKEMaX8q7CCJb7NvUCxerBCcsFUa4LjBEynTtEd#programIdl |
| `Raydium AMM Routing` | `routeUGWgWzqBWFcrCfv8tritsqukccJPu3q5GPP3xS` | `no_idl` | https://solscan.io/account/routeUGWgWzqBWFcrCfv8tritsqukccJPu3q5GPP3xS |
| `Raydium Concentrated Liquidity` | `CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK` | `solscan_program_idl` | https://solscan.io/account/CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK#programIdl |
| `Raydium CPMM` | `CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C` | `solscan_program_idl` | https://solscan.io/account/CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C#programIdl |
| `Raydium LaunchLab` | `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj` | `solscan_program_idl` | https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj#programIdl |
| `Raydium LaunchLab: PlatformConfig` | `4Bu96XjU84XjPDSpveTVf6LYGCkfW5FK7SNkREWcEfV4` | `no_idl` | https://solscan.io/account/4Bu96XjU84XjPDSpveTVf6LYGCkfW5FK7SNkREWcEfV4 |
| `Raydium liquidity pool AMM` | `5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h` | `no_idl` | https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h |
| `Raydium Liquidity Pool V2` | `RVKd61ztZW9GUwhRbbLoYVRE5Xf1B2tVscKqwZqXgEr` | `no_idl` | https://solscan.io/account/RVKd61ztZW9GUwhRbbLoYVRE5Xf1B2tVscKqwZqXgEr |
| `Raydium Liquidity Pool V3` | `27haf8L6oxUeXrHrgEgsexjSY5hbVUWEmvv9Nyxg8vQv` | `no_idl` | https://solscan.io/account/27haf8L6oxUeXrHrgEgsexjSY5hbVUWEmvv9Nyxg8vQv |
| `Raydium Liquidity Pool V4` | `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` | `no_idl` | https://solscan.io/account/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8 |
| `Raydium Lock LP` | `LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE` | `solscan_program_idl` | https://solscan.io/account/LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE#programIdl |
| `Saber Decimal Wrapper` | `DecZY86MU5Gj7kppfUCEmd4LbXXuyZH1yHaP2NTqdiZB` | `solscan_program_idl` | https://solscan.io/account/DecZY86MU5Gj7kppfUCEmd4LbXXuyZH1yHaP2NTqdiZB#programIdl |
| `Saber Stable Swap` | `SSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZ` | `no_idl` | https://solscan.io/account/SSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZ |
| `Saros AMM` | `SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr` | `no_idl` | https://solscan.io/account/SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr |
| `Sanctum Multi-Validator SPL Stake Pool Program` | `SPMBzsVUuoHA4Jm6KunbsotaahvVikZs1JyTW6iJvbn` | `no_idl` | https://solscan.io/account/SPMBzsVUuoHA4Jm6KunbsotaahvVikZs1JyTW6iJvbn |
| `Sanctum Router Program` | `stkitrT1Uoy18Dk1fTrgPw8W6MVzoCfYoAFT4MLsmhq` | `no_idl` | https://solscan.io/account/stkitrT1Uoy18Dk1fTrgPw8W6MVzoCfYoAFT4MLsmhq |
| `Sanctum: S Controller` | `5ocnV1qiCgaQR8Jb8xWnVbApfaygJ8tNoZfgPwsgx9kx` | `no_idl` | https://solscan.io/account/5ocnV1qiCgaQR8Jb8xWnVbApfaygJ8tNoZfgPwsgx9kx |
| `Sanctum Single Validator SPL Stake Pool Program` | `SP12tWFxD9oJsVWNavTTBZvMbA6gkAmxtVgxdqvyvhY` | `solscan_account` | https://solscan.io/account/SP12tWFxD9oJsVWNavTTBZvMbA6gkAmxtVgxdqvyvhY |
| `SharkyFi` | `SHARKobtfF1bHhxD2eqftjHBdVSCbKo9JtgK71FhELP` | `no_idl` | https://solscan.io/account/SHARKobtfF1bHhxD2eqftjHBdVSCbKo9JtgK71FhELP |
| `Solayer` | `sSo1iU21jBrU9VaJ8PJib1MtorefUV4fzC9GURa2KNn` | `no_idl` | https://solscan.io/account/sSo1iU21jBrU9VaJ8PJib1MtorefUV4fzC9GURa2KNn |
| `Solend Protocol` | `So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo` | `no_idl` | https://solscan.io/account/So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo |
| `SolFi` | `SoLFiHG9TfgtdUXUjWAxi3LtvYuFyDLVhBWxdMZxyCe` | `no_idl` | https://solscan.io/account/SoLFiHG9TfgtdUXUjWAxi3LtvYuFyDLVhBWxdMZxyCe |
| `SolFi V2` | `SV2EYYJyRz2YhfXwXnhNAevDEui5Q6yrfyo13WtupPF` | `no_idl` | https://solscan.io/account/SV2EYYJyRz2YhfXwXnhNAevDEui5Q6yrfyo13WtupPF |
| `stabble CLMM` | `6dMXqGZ3ga2dikrYS9ovDXgHGh5RUsb2RTUj6hrQXhk6` | `solscan_program_idl` | https://solscan.io/account/6dMXqGZ3ga2dikrYS9ovDXgHGh5RUsb2RTUj6hrQXhk6#programIdl |
| `stabble Stable Swap` | `swapNyd8XiQwJ6ianp9snpu4brUqFxadzvHebnAXjJZ` | `solscan_program_idl` | https://solscan.io/account/swapNyd8XiQwJ6ianp9snpu4brUqFxadzvHebnAXjJZ#programIdl |
| `stabble Weighted Swap` | `swapFpHZwjELNnjvThjajtiVmkz3yPQEHjLtka2fwHW` | `solscan_program_idl` | https://solscan.io/account/swapFpHZwjELNnjvThjajtiVmkz3yPQEHjLtka2fwHW#programIdl |
| `Stake Pool` | `SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy` | `no_idl` | https://solscan.io/account/SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy |
| `Stake Program` | `Stake11111111111111111111111111111111111111` | `no_idl` | https://solscan.io/account/Stake11111111111111111111111111111111111111 |
| `Step Finance Swap Program` | `SSwpMgqNDsyV7mAgN9ady4bDVu5ySjmmXejXvy2vLt1` | `no_idl` | https://solscan.io/account/SSwpMgqNDsyV7mAgN9ady4bDVu5ySjmmXejXvy2vLt1 |
| `StepN DOOAR Swap` | `Dooar9JkhdZ7J3LHN3A7YCuoGRUggXhQaG4kijfLGU2j` | `no_idl` | https://solscan.io/account/Dooar9JkhdZ7J3LHN3A7YCuoGRUggXhQaG4kijfLGU2j |
| `Scorch` | `SCoRcH8c2dpjvcJD6FiPbCSQyQgu3PcUAWj2Xxx3mqn` | `no_idl` | https://solscan.io/account/SCoRcH8c2dpjvcJD6FiPbCSQyQgu3PcUAWj2Xxx3mqn |
| `Streamflow` | `strmRqUCoQUgGUan5YhzUZa6KqdzwX5L6FpUxfmKg5m` | `solscan_program_idl` | https://solscan.io/account/strmRqUCoQUgGUan5YhzUZa6KqdzwX5L6FpUxfmKg5m#programIdl |
| `Swap Program` | `SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8` | `no_idl` | https://solscan.io/account/SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8 |
| `Swig Program` | `swigypWHEksbC64pWKwah1WTeh9JXwx8H1rJHLdbQMB` | `no_idl` | https://solscan.io/account/swigypWHEksbC64pWKwah1WTeh9JXwx8H1rJHLdbQMB |
| `System Program` | `11111111111111111111111111111111` | `no_idl` | https://solscan.io/account/11111111111111111111111111111111 |
| `Tessera V` | `TessVdML9pBGgG9yGks7o4HewRaXVAMuoVj4x83GLQH` | `no_idl` | https://solscan.io/account/TessVdML9pBGgG9yGks7o4HewRaXVAMuoVj4x83GLQH |
| `Titan Exchange Router` | `T1TANpTeScyeqVzzgNViGDNrkQ6qHz9KrSBS4aNXvGT` | `no_idl` | https://solscan.io/account/T1TANpTeScyeqVzzgNViGDNrkQ6qHz9KrSBS4aNXvGT |
| `Token 2022 Program` | `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` | `no_idl` | https://solscan.io/account/TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
| `Token Program` | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` | `no_idl` | https://solscan.io/account/TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA |
| `Vertigo Program` | `vrTGoBuy5rYSxAfV3jaRJWHH6nN9WK4NRExGxsk1bCJ` | `solscan_program_idl` | https://solscan.io/account/vrTGoBuy5rYSxAfV3jaRJWHH6nN9WK4NRExGxsk1bCJ#programIdl |
| `Virtuals` | `5U3EU2ubXtK84QcRjWVmYt9RaDyA8gKxdUrPFXmZyaki` | `solscan_program_idl` | https://solscan.io/account/5U3EU2ubXtK84QcRjWVmYt9RaDyA8gKxdUrPFXmZyaki#programIdl |
| `Woofi` | `WooFif76YGRNjk1pA8wCsN67aQsD9f9iLsz4NcJ1AVb` | `solscan_program_idl` | https://solscan.io/account/WooFif76YGRNjk1pA8wCsN67aQsD9f9iLsz4NcJ1AVb#programIdl |
| `Wormhole: Bridge` | `wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb` | `no_idl` | https://solscan.io/account/wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb |
| `ZeroFi` | `ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY` | `no_idl` | https://solscan.io/account/ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY |
| `Zeta Matching Engine` | `zDEXqXEG7gAyxb1Kg9mK5fPnUdENCGKzWrM21RMdWRq` | `no_idl` | https://solscan.io/account/zDEXqXEG7gAyxb1Kg9mK5fPnUdENCGKzWrM21RMdWRq |
| `Zeta Program` | `ZETAxsqBRek56DhiGXrn75yj2NHU3aYUnxvHXpkf3aD` | `solscan_program_idl` | https://solscan.io/account/ZETAxsqBRek56DhiGXrn75yj2NHU3aYUnxvHXpkf3aD#programIdl |
| `Zora Program` | `zoRabwLGd5zXaV7Gxacppw8tcceXEiTrSKyNLSaSTUc` | `no_idl` | https://solscan.io/account/zoRabwLGd5zXaV7Gxacppw8tcceXEiTrSKyNLSaSTUc |

View File

@@ -0,0 +1,42 @@
<!-- file: docs/VALIDATION_STATUS_0_7_51.md -->
# Validation status — `0.7.51 raydium_amm_v4`
## Commandes demandées
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## Résultat dans le sandbox
Non exécuté : `cargo`, `rustc` et `rustfmt` ne sont pas disponibles dans l'environnement de génération.
```text
cargo fmt -> cargo: command not found
```
## Contrôles statiques effectués
- Extraction et modification de l'archive `0.7.50-raydium-launchpad-final`.
- Vérification de l'équilibre basique `{}` et `()` sur les fichiers Rust modifiés.
- Vérification des occurrences ajoutées : aucun `unwrap` / `expect` ajouté dans les nouveaux blocs AMM v4.
- Création des livrables docs + SQL demandés.
## Validation locale requise
Appliquer le delta, puis exécuter localement :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
Ensuite créer une base SQLite vide dédiée `0.7.51`, constituer le corpus Demo3/Demo2 AMM v4, replay avec `forceDexDecode=yes`, puis exécuter :
```text
validation_sql/SQL_VALIDATION_RAYDIUM_AMM_V4_0_7_51.sql
```

View File

@@ -0,0 +1,47 @@
<!-- file: docs/VALIDATION_STATUS_0_7_51_FINAL.md -->
# Validation Status — `0.7.51 raydium_amm_v4 final`
## Rust
```text
cargo test -p kb_lib -> 405 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
## Replay final
```text
195 replayed
0 decode skipped
195 ledger upserts
70 unsafe ledger rows
168 trades
7 liquidity
15 lifecycle
0 tokenAccount
668 candle upserts
instructionObservations = 2599
resetDeleted = 1578
catalog = 61 tokens / 65 pools / 65 pairs
```
## SQL blocking checks
Résultat attendu et rapporté : `vide` pour les contrôles suivants.
- `raydium_amm_v4.swap` legacy ;
- decoded events AMM v4 sans coverage entry ;
- observations AMM v4 en discriminant plus long qu'un octet ;
- non-swap AMM v4 avec trade ;
- failed tx AMM v4 avec trade ;
- successful non-materialized AMM v4 sans raison explicite ;
- matérialisation multi-target AMM v4.
## Points validés
- Tous les discriminants officiels AMM v4 `00..11` sont observés localement.
- `pre_initialize` : `decoded_success_count=7`, `lifecycle_count=7`.
- `migrate_to_open_book` : orderbook-only (`lifecycle_count=0`, `orderbook_count=6`).
- `simulate_info` : decoded-only.
- `raydium_pool_v4` : audit-only / décision conditionnelle, sans decoder local.

View File

@@ -0,0 +1,56 @@
<!-- file: docs/VALIDATION_STATUS_0_7_51_MAX_DECODER.md -->
# Validation status — `0.7.51 raydium_amm_v4 max-decoder`
## Scope
Delta incrémental après le premier patch `0.7.51 raydium_amm_v4`.
Objectifs couverts :
- correction du test `swap_base_in` avec une payload `0x09` ;
- ajout d'un test dédié `swap_base_in_v2` avec une payload `0x10` ;
- suppression de la route métier legacy `raydium_amm_v4.swap` ;
- reconnaissance locale maximale des discriminants AMM v4 officiels `00..11` ;
- conservation des instructions dépréciées comme events decoded-only ou non-trade matérialisables si corpus successful ;
- reclassement orderbook/fee/admin/liquidity/lifecycle pour les non-swaps AMM v4 ;
- reconstruction des observations techniques par transaction avant upsert ;
- extension du SQL de validation AMM v4.
## Sandbox validation
Non exécutée dans l'environnement de génération : `cargo`, `rustc` et `rustfmt` ne sont pas disponibles.
## Validation locale obligatoire
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## Replay local attendu
Après application du delta, relancer le replay dédié `0.7.51` avec :
```text
skipDexDecode = no
forceDexDecode = yes
deferInstructionObservations = yes
```
Puis exécuter :
```text
validation_sql/SQL_VALIDATION_RAYDIUM_AMM_V4_0_7_51.sql
```
Les contrôles bloquants attendus vides sont :
- `raydium_amm_v4.instruction_audit` résiduel ;
- `upstream_git.instruction_match` localement couvert ;
- `raydium_amm_v4.swap` legacy ;
- decoded AMM v4 sans coverage entry ;
- observations AMM v4 avec `length(discriminator_hex) > 2` ;
- non-swap AMM v4 avec `trade_count > 0` ;
- failed tx matérialisée en trade.

View File

@@ -0,0 +1,69 @@
<!-- file: docs/VALIDATION_STATUS_0_7_52_FINAL.md -->
# Validation status — 0.7.52 Raydium Stable Swap final
## Scope
Decoder: `raydium_stable_swap`
Program id:
```text
5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h
```
## Local commands
```text
cargo test -p kb_lib
407 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
cargo clippy -p kb_lib --all-targets -- -D warnings
ok
```
## Final replay snapshot
```text
replayed=298
decode_skipped=0
ledger_upserts=298
unsafe_ledger_rows=258
trades=290
liquidity=16
lifecycle=4
tokenAccount=0
candle_upserts=1160
instructionObservations=5317
resetDeleted=1059
catalog=40 tokens / 59 pools / 59 pairs
```
## Stable Swap swap closure
```text
raydium_stable_swap.swap_base_in stable_swap_instruction_bounds_only failed decoded=27 trades=0
raydium_stable_swap.swap_base_in stable_swap_vault_balance_delta success decoded=171 trades=171
raydium_stable_swap.swap_base_out stable_swap_instruction_bounds_only failed decoded=2 trades=0
raydium_stable_swap.swap_base_out stable_swap_vault_balance_delta success decoded=4 trades=4
```
No successful Stable Swap swap remains without trade or skip reason.
## Invariants
| invariant | status |
|---|---|
| residual local `instruction_audit` | empty |
| residual `upstream_git.instruction_match` for covered entries | empty |
| decoded without coverage | empty |
| non-swap materialized as trade | empty |
| failed tx materialized as trade | empty |
| multi-target materialization | empty |
| unexplained successful non-materialized event | empty |
| successful swap via vault deltas | `trade_count = decoded_count` |
| failed swap instruction bounds only | `trade_count = 0` |
## Decision
`0.7.52 raydium_stable_swap` is closed for the current local corpus.

View File

@@ -0,0 +1,51 @@
<!-- file: docs/VALIDATION_STATUS_0_7_56_FINAL.md -->
# Validation Status — `0.7.56 meteora_dbc final`
## Build
```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
## Replay final DBC
```text
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
0 tokenAccount
1056 candle upserts
instructionObservations = 7167
resetDeleted = 3583
catalog = 86 tokens / 60 pools / 60 pairs
```
## Fee model final DBC
```text
k_sol_fee_events meteora_dbc = 89 parents
k_sol_fee_event_amounts meteora_dbc = 96 legs
parent scalar without leg = empty
orphan fee amount legs = empty
allowlisted recovery on DBC = empty by design
```
## Cross-base fee recovery checks
| Base | Result |
|---|---|
| `meteora_dbc` | stable, no regression, 89/96 fee parent/legs. |
| `raydium_launchpad` | allowlisted CPI recovery enriched all observed claim/collect fee parents in tested corpus. |
| `raydium_cpmm` | creator fee recovered; fund/protocol fee explicit no-transfer in tested corpus. |
| `pump_swap` | coin creator fee mostly recovered; zero/no-transfer cases explicit. |
| `pump_fees` | donation and sweep buyback recovered when CPI SPL transfers are present. |
## Closure decision
`0.7.56 meteora_dbc` is closed. Next tranche: `0.7.57 meteora_dlmm` full decode + full materialization.

View File

@@ -0,0 +1,73 @@
# Validation status — 0.7.57 Meteora DLMM final
## Build
```text
cargo test -p kb_lib -> 460 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
## Replay
Recommended replay settings used:
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Final replay summary:
```text
769 replayed
0 decode skipped
769 ledger upserts
646 unsafe ledger rows
106 trades
664 liquidity
1107 lifecycle
0 tokenAccount
424 candle upserts
instructionObservations = 8062
resetDeleted = 9898
catalog = 169 tokens / 218 pools / 218 pairs
```
## Final SQL gates
| Gate | Result |
|---|---:|
| Upstream fallback for local DLMM coverage | empty |
| Local `instruction_audit` observed | `0` |
| Decoded DLMM without coverage | empty |
| Successful non-materialized without explicit skip/policy | empty |
| Failed transaction business materialization | empty |
| Multi-target materialization | empty |
| Non-swap trade/candle safety | empty |
| Fee parent scalar without amount leg | empty |
| Orphan fee amount legs | empty |
| Reward/fee collision | clean separation |
| Limit/orderbook trade/candle double-count | empty |
| Logical duplicate coverage rows | empty |
## Final materialization counters
```text
trade events = 106
liquidity events = 664
lifecycle events = 1107
candles = 424
```
## Important decisions
- `swap_event` and `swap2_evt` are materialized as lifecycle `swap_log`, not as trades.
- `initialize_preset_parameter_v2` was added from corpus evidence for discriminator `75c73e67068e1fcb`.
- `close_bin_array` has `16` observations but only `14` materializations because `2` transactions failed with `Custom 6015`.
- `initialize_reward` and `initialize_reward_event` remain without amounts because they are configuration/init events, not transfers.
- No observed useful DLMM event remains decoded-only.
## Closure decision
`0.7.57 meteora_dlmm` is considered closed for the validated corpus. Future changes require new corpus evidence.

View File

@@ -0,0 +1,193 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.47_1FE5_CONTINUATION_V2.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.47-1FE5`
Reprise du projet `khadhroony-bobobot`.
## Archive de départ
Utiliser comme base de travail :
```text
kb_lib-v0.7.47-1FE5-full.zip
```
Joindre aussi les docs mises à jour :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
```
## Décision de planification
Ne plus tenter “tous les events de tous les decoders” dans une seule session. Lobjectif reste de couvrir tous les decoders disponibles dans Carbon et les sources Git/IDL, mais par tranches DEX/version.
Ordre cible :
```text
raydium_cpmm
raydium_clmm
pump_swap
pump_fun
meteora_dbc
meteora_dlmm
meteora_damm_v1
meteora_damm_v2
phoenix_v1
openbook_v2
orca_whirlpools
launch surfaces
DEX historiques / candidats
```
## Sources upstream obligatoires
Ces sources sont des indices de décodage, pas des preuves de validation locale :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders
https://github.com/0xfnzero/solana-streamer
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
https://github.com/pinax-network/substreams-solana-idls/tree/main/src
https://github.com/hodlwarden/solana-tx-parser/tree/main/src
https://github.com/openbook-dex/openbook-v2
https://github.com/all-in-one-blockchain/phoenix-onchain-mm
https://docs.vybenetwork.com/docs/available-dexs-amms
```
## État validé
Dernier état validé côté `kb_lib` :
```text
cargo test -p kb_lib
371 passed
```
Clippy doit être relancé à chaque tranche :
```bash
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## 0.7.47 acquis
- Upstream Git Registry ajouté.
- Demo3 étendu : multi-target, multi-source, pagination, orderbook targets, burn/mint/transfer/wrap/unwrap/stake.
- Demo2 backfill signature fonctionnel.
- Replay local avec ledger.
- OpenBook v2 decoder audit-only.
- Phoenix v1 decoder audit-only.
- Les decoders audit-only ne produisent aucun trade/candle.
## OpenBook v2
Program id :
```text
opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb
```
État :
```text
audit-only local decoder
upstream_git fallback cleaned
Program data mapped:
- FillLog
- OpenOrdersPositionLog
- TotalOrderFillEvent
- SettleFundsLog
trade_count = 0
```
Ne pas activer de trade/candle tant que maker/taker/base/quote et les lots ne sont pas validés.
## Phoenix v1
Program id :
```text
PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY
```
État :
```text
audit-only local decoder
log instruction strict 0x0f
events observed:
- Reduce
- Place
- TimeInForce
currentInstructionTag mappings:
- 0x09 CancelUpToWithFreeFunds
- 0x0c WithdrawFunds
- 0x10 PlaceMultiplePostOnlyOrders
trade_count = 0
```
Prochaine action préférée : finir Phoenix v1 avec tous les events disponibles dans les sources Git/IDL, mais rester audit-only jusquà validation économique.
## Contraintes
- Rust 2024.
- Pas de `mod.rs`.
- Fichiers Rust avec entête `// file: ...`.
- Exposition centralisée via `lib.rs`.
- `#![deny(unreachable_pub)]`, `#![warn(missing_docs)]`.
- Pas de `anyhow`.
- Pas de `thiserror`.
- Pas de `?`, `unwrap`, `expect` dans le code applicatif.
- Utiliser `match`, `if let Err`, `let Err = ... else`.
- Si une requête DB est ajoutée/modifiée, mettre à jour `kb_lib/src/db.rs`, puis `kb_lib/src/lib.rs` si nécessaire.
## Méthode par DEX/version
Pour chaque DEX/version :
1. inspecter Carbon + autres sources Git/IDL ;
2. lister tous les discriminants instructions/events ;
3. compléter `upstream_registry` / matrice si nécessaire ;
4. utiliser Demo3 pour corpus ;
5. backfill Demo2 ;
6. replay forcé ;
7. valider SQL ;
8. ajouter decoder audit-only ou materialized selon preuve ;
9. supprimer les doublons `upstream_git.instruction_match` si decoder spécialisé ;
10. ne jamais produire trade/candle sans montants exploitables et sens économique validé.
## Requêtes de sécurité audit-only
```sql
SELECT
de.protocol_name,
de.event_kind,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name IN ('openbook_v2', 'phoenix_v1')
GROUP BY de.protocol_name, de.event_kind
ORDER BY trade_count DESC;
```
Attendu :
```text
trade_count = 0
```
## Livrable attendu
Pour chaque tranche :
- fichiers ajoutés/modifiés seulement ;
- archive zip ;
- commandes de test ;
- requêtes SQL ;
- notes sur ce qui reste non vérifié ;
- ne pas prétendre quun event ou program id est vérifié sans corpus local.

View File

@@ -0,0 +1,157 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.47_EVENT_COVERAGE_V3.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.47-1FE5` / Event coverage
Reprise du projet `khadhroony-bobobot`.
## Archive de départ
Utiliser :
```text
khadhroony-bobobot-v0.7.47-1FE5-full.zip
```
Et les docs :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
```
## Décision de reprise
Ne pas essayer de “faire tous les events de tous les DEX” dans une seule session.
La stratégie est maintenant :
```text
un DEX/version = une tranche
tous les events listés = audit coverage
matérialisation seulement après corpus + SQL + invariants
```
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
## Objectif événementiel
Décoder le maximum devents, pas seulement les swaps.
Inclure explicitement :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Raison : burn, perte de liquidité, changements admin/config, vault withdraw, migration, mint anormal, close account, etc. peuvent influencer une décision de trading même si ce ne sont pas des trades.
## Base de données
La base actuelle suffit pour audit-only via `k_sol_dex_decoded_events`, mais elle nest pas suffisante pour tout exploiter en requêtes métier.
À considérer avant ou pendant `0.7.48` :
```text
k_sol_dex_event_coverage_entries
k_sol_token_transfer_events
k_sol_token_account_events
k_sol_orderbook_events
k_sol_vault_events
k_sol_launch_events
k_sol_liquidity_lock_events
```
Priorité minimale :
```text
1. k_sol_dex_event_coverage_entries
2. k_sol_token_transfer_events
3. k_sol_orderbook_events
```
## Ordre des versions
```text
0.7.48-pre event coverage + DB model checkpoint
0.7.48 raydium_cpmm
0.7.49 raydium_clmm
0.7.50 pump_swap
0.7.51 pump_fun
0.7.52 meteora_dbc
0.7.53 meteora_dlmm
0.7.54 meteora_damm_v1
0.7.55 meteora_damm_v2
0.7.56 phoenix_v1
0.7.57 openbook_v2
0.7.58 orca_whirlpools
0.7.59 launch surfaces
0.7.60 DEX historiques/candidats
0.7.61 validation consolidée
```
## Règles fixes
- Un event non-trade ne produit jamais trade/candle.
- Une transaction failed reste audit, jamais trade/candle.
- Un discriminator upstream nest pas une preuve métier.
- Un program id upstream nest pas vérifié sans corpus local.
- Chaque decoder spécialisé doit remplacer le fallback `upstream_git.instruction_match` pour éviter les doublons.
- Tout event connu mais non observé reste `upstream_git_mapped_unverified`.
- Tout event observé mais non matérialisé reste audit-only ou decoded, pas materialized.
## Prochaine tâche recommandée
Commencer par :
```text
0.7.48-pre — event coverage + DB model checkpoint
```
Livrables attendus :
1. ajouter/documenter une table de couverture event/discriminator ;
2. générer un rapport de couverture par DEX/version ;
3. préparer `raydium_cpmm` avec la liste complète des events depuis Carbon/fnzero/IDL ;
4. ne pas changer encore la matérialisation trade/candle.

View File

@@ -0,0 +1,251 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.47_UPSTREAM_REGISTRY.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.47`
Reprise du projet `khadhroony-bobobot`.
## Contexte
Le workspace contient principalement :
- `kb_lib` : logique métier Solana/DEX, clients HTTP/WS, décodage, détection, SQLite, replay, validation, diagnostics, metadata, candles, signaux ;
- `kb_demo_app` : application Tauri V2 de démo/inspection. Elle doit rester une façade UI et ne pas contenir de logique métier DEX profonde.
La version `0.7.46` est clôturée sur `meteora_damm_v1`.
## État validé à la fin de `0.7.46`
- `cargo test -p kb_lib` : vert.
- `cargo clippy -p kb_lib --all-targets -- -D warnings` : vert.
- Demo2 et Demo3 fonctionnent bien pour backfill et discovery.
- Demo3 supporte :
- multi-target ;
- multi-source ;
- pagination `before` / `until` ;
- `max_pages` ;
- `newest_first` / `oldest_first`.
- Le replay local supporte le ledger de décodage/replay et les options `skipDexDecode` / `forceDexDecode`.
- `meteora_damm_v1` couvre les surfaces observées localement :
- `swap` ;
- `claim_fee` ;
- `create_lock_escrow` ;
- `lock_liquidity` ;
- `remove_liquidity` ;
- `add_liquidity` ;
- `create_pool`.
- Les statuts/payloads ne doivent plus utiliser une terminologie spécifique à un dépôt externe particulier.
- Les statuts génériques attendus sont :
- `upstream_git_unverified` ;
- `upstream_git_mapped_unverified` ;
- `upstream_git_local_corpus_observed` ;
- `upstream_git_local_corpus_materialized` ;
- `upstream_git_layout_unverified` si le layout est connu depuis une source Git mais pas encore validé localement.
## Décision base de données pour `0.7.47`
La version `0.7.46` est considérée finalisée. Ne pas demander ni proposer de replay forcé de lancienne base `0.7.46` pour clôturer cette version, sauf demande explicite.
Pour `0.7.47`, le développement et la validation doivent se faire de préférence sur une **nouvelle base SQLite dédiée**. Cette base servira à constituer un corpus propre avec Demo3 et Demo2 sur plusieurs paires, pools ou programmes de DEX différents.
Règles pratiques :
- lancienne base `0.7.46` peut servir de référence historique ou de comparaison, mais elle ne doit pas être migrée ou redécodée automatiquement ;
- si une validation DB est nécessaire en `0.7.47`, elle doit cibler la nouvelle base de travail `0.7.47` ;
- les backfills `0.7.47` doivent être construits à partir de Demo3 discovery puis Demo2 signature/pool backfill ;
- le replay local reste utile, mais seulement après constitution du corpus `0.7.47`, pas comme étape de finalisation de `0.7.46` ;
- les entrées du registre upstream Git restent des indices tant quelles ne sont pas observées sur cette nouvelle base ou sur un corpus explicitement indiqué.
## Objectif de `0.7.47`
`0.7.47` est dédiée à :
```text
Upstream Git Registry / DEX discovery preparation
```
Lobjectif nest pas de valider directement un DEX unique. Lobjectif est de créer un registre générique permettant dindexer les `program_id`, discriminants dinstructions, discriminants devents, noms dinstructions, familles de programmes et types de surfaces issus de dépôts Git externes de decoders Solana.
Ces entrées sont des **indices de découverte**, pas des preuves métier. Elles doivent rester non vérifiées tant quelles ne sont pas confirmées par :
1. Demo3 discovery ;
2. backfill signature/pool via Demo2 ;
3. replay local sur la base de travail `0.7.47` ;
4. requêtes SQL de validation sur cette même base ;
5. invariants métier : pas de faux trade, pas de fausse candle, pas de promotion de `program_id` sans corpus.
## Noms recommandés
Modules possibles :
```text
kb_lib/src/upstream_registry.rs
kb_lib/src/upstream_registry_types.rs
kb_lib/src/upstream_registry_match.rs
kb_lib/src/upstream_registry_generated.rs
```
Nom fonctionnel :
```text
Upstream Git Registry
```
Ne pas utiliser de nom de dépôt externe spécifique dans les noms publics, les statuts, les tables ou les payloads métier.
## Première tranche attendue
Créer une première version statique du registre dans `kb_lib`, sans modifier la DB si ce nest pas nécessaire.
Chaque entrée de registre devrait contenir au minimum :
```text
source_repo
source_path
decoder_code
program_id
program_family
surface_kind
entry_kind = instruction | event | account | program
entry_name
discriminator_hex
discriminator_len
proof_status
notes
```
Les entrées de registre doivent être exposées à `kb_demo_app` via une commande Demo3 ou une commande dédiée, mais la logique reste dans `kb_lib`.
## Familles à indexer en priorité
DEX / AMM / CLMM / orderbook :
```text
meteora_damm_v2
meteora_dbc
meteora_dlmm
meteora_vault
raydium_amm_v4
raydium_clmm
raydium_cpmm
raydium_launchpad
raydium_liquidity_locking
raydium_stable_swap
orca_whirlpools
fluxbeam
lifinity_v2
phoenix_v1
openbook_v2
stabble_stable_swap
stabble_weighted_swap
bonkswap
boop
moonshot
heaven
okx_dex
pancake_swap
vertigo
virtuals
wavebreak
onchain_labs_dex_v1
onchain_labs_dex_v2
```
Agrégateurs / ordres / perps / lending :
```text
jupiter_swap
jupiter_dca
jupiter_limit_order
jupiter_limit_order_2
jupiter_perpetuals
jupiter_lend
kamino_lending
kamino_vault
kamino_farms
kamino_limit_order
drift_v2
marginfi_v2
dflow_aggregator_v4
zeta
```
Contexte transactionnel non DEX :
```text
system_program
token_program
token_2022
associated_token_account
address_lookup_table
memo_program
stake_program
mpl_token_metadata
mpl_core
bubblegum
name_service
marinade_finance
solayer_restaking_program
swig
sharky
circle_message_transmitter_v2
circle_token_messenger_v2
```
## Règles de validation
- Une entrée upstream Git reste `upstream_git_unverified` tant quelle na pas été vue localement.
- Une entrée branchée dans un decoder mais jamais vue localement reste `upstream_git_mapped_unverified`.
- Une entrée vue après Demo3/backfill/replay peut devenir `upstream_git_local_corpus_observed`.
- Une entrée qui alimente correctement une table métier dédiée peut devenir `upstream_git_local_corpus_materialized`.
- Aucun `program_id`, event ou discriminator ne doit être déclaré vérifié uniquement parce quil existe dans un dépôt Git externe.
- Aucun event non-trade ne doit produire trade, metric ou candle.
## Contraintes de code
- Rust 2024.
- Pas de `mod.rs`.
- Fichiers Rust avec entête `// file: ...`.
- Fichiers `.toml` avec entête `# file: ...`.
- Exposition centralisée via `lib.rs`.
- `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]`.
- Pas de `anyhow`.
- Pas de `thiserror`.
- Pas de `?`, `unwrap`, `expect` dans le code applicatif.
- Utiliser `match`, `if let Err`, `let Err = ... else`.
- Tests verts à chaque étape.
- Si une requête DB est ajoutée/modifiée, mettre à jour les re-exports dans `kb_lib/src/db.rs`, puis `kb_lib/src/lib.rs` si nécessaire.
## Format de livraison attendu
Pour chaque tranche :
1. expliquer brièvement les fichiers touchés ;
2. fournir une archive des fichiers ajoutés/modifiés seulement, avec larborescence du projet ;
3. indiquer les commandes de test à lancer ;
4. indiquer les requêtes SQL utiles si validation DB nécessaire ;
5. ne jamais prétendre quun `program_id` ou un event est vérifié sans preuve/corpus.
dexlab
bags / letsbonk / bonk_fun
believe
moonit
launchbeam
metadao / metaDAO
printr
zora
aldrin
aldrin_v2
crema
cropper
cropper_legacy
guacswap
invariant
lifinity_v1
openbook_v1 / serum-style legacy
orca_v1
orca_v2
saber
saros
serum_v3
token_swap

View File

@@ -0,0 +1,329 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.49_RAYDIUM_CLMM.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.49` / Raydium CLMM event coverage
Reprise du projet `khadhroony-bobobot` après clôture fonctionnelle de `0.7.48 raydium_cpmm`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.48-raydium-cpmm-final
```
Docs à fournir aussi :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_48.sql
```
## État validé avant reprise
`0.7.48` a clôturé la tranche `raydium_cpmm` :
```text
k_sol_dex_event_coverage_entries synchronisée en snake_case local
k_sol_instruction_observations ajoutée comme table technique d'index instruction/discriminator
Demo3 enrichie avec recherche instruction/discriminator
Solscan instruction=<discriminator> utilisé comme accélérateur de recherche de signatures
raydium_cpmm Program data décodé pour lp_change_event / swap_event
raydium_cpmm deposit / withdraw / lp_change_event matérialisés liquidity
raydium_cpmm initialize / initialize_with_permission matérialisés lifecycle-only
raydium_cpmm collect_*_fee matérialisés fee
raydium_cpmm create_amm_config / create_permission_pda / update_amm_config matérialisés admin/config
raydium_cpmm swap_event conservé audit-only
close_permission_pda et update_pool_status conservés upstream_git_mapped_unverified faute de corpus local
instruction inconnue 40f4bc78a7e9690a conservée raydium_cpmm.instruction_audit
```
Validation locale finale observée :
```text
cargo test -p kb_lib: ok, 386 passed
cargo clippy -p kb_lib --all-targets -- -D warnings: ok
replay local: 1124 replayed, 561 trades, 50 liquidity, 9 lifecycle, 2224 candle upserts
```
Couverture finale `raydium_cpmm` :
```text
lp_change_event 25/25 liquidity, 0 trade
swap_event 529 decoded-only, 0 trade
deposit 11/11 liquidity, 0 trade
withdraw 14/14 liquidity, 0 trade
initialize 5/5 lifecycle, 0 admin, 0 trade
initialize_with_permission 4/4 lifecycle, 0 admin, 0 trade
collect_creator_fee 4/4 fee, 0 trade
collect_fund_fee 7/7 fee, 0 trade
collect_protocol_fee 15/15 fee, 0 trade
create_amm_config 6/6 admin, 0 trade
create_permission_pda 4/4 admin, 0 trade
update_amm_config 13/13 admin, 0 trade
swap_base_input 750 decoded, 482 trades
swap_base_output 25 decoded, 17 trades
close_permission_pda upstream_git_mapped_unverified
update_pool_status upstream_git_mapped_unverified
```
Invariants maintenus :
```text
non-trade event = jamais trade/candle
failed transaction = audit-only
upstream Git/IDL/Solscan = indice, pas preuve métier
program_id upstream non promu sans corpus local
chaque decoder spécialisé remplace le fallback upstream_git.instruction_match
side effects SPL Token / Token-2022 restent transversaux, pas raydium_cpmm.* directs
pas de nouvelle table métier transversale sans preuve multi-DEX
```
## Décision de reprise
Commencer `0.7.49` par `raydium_clmm`, avant Pump/Meteora.
Ordre courant :
```text
0.7.49 raydium_clmm
0.7.50 pump_swap
0.7.51 pump_fun
0.7.52 meteora_dbc
0.7.53 meteora_dlmm upstream parity
0.7.54 meteora_damm_v1 upstream parity
0.7.55 meteora_damm_v2
0.7.56 phoenix_v1 audit-only completion
0.7.57 openbook_v2 audit-only completion
0.7.58 orca_whirlpools
0.7.59+ launch surfaces, candidats/historiques, validation consolidée
```
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
Pour `0.7.49 raydium_clmm`, utiliser aussi explicitement :
```text
https://solscan.io/account/CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK#programIdl
```
et les filtres Solscan de type :
```text
https://solscan.io/account/CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
Solscan doit servir à trouver vite des signatures à backfiller, jamais comme preuve métier finale.
## Objectif `0.7.49` — `raydium_clmm`
Objectif : reprendre `raydium_clmm` comme deuxième tranche Raydium/version après CPMM.
À faire :
1. lire le code local `raydium_clmm` et les matérialisations existantes ;
2. lister toutes les instructions/events CLMM depuis Carbon/fnzero/IDL/Raydium/Solscan Program IDL ;
3. synchroniser/remplir `k_sol_dex_event_coverage_entries` pour `raydium_clmm` ;
4. utiliser `k_sol_instruction_observations` pour inspecter les discriminants réellement observés localement ;
5. ajouter à Demo3 les filtres instruction/discriminant CLMM si un binding/UI manque encore ;
6. chercher des signatures ciblées via Solscan `instruction=<discriminator>` ;
7. backfiller les signatures utiles dans Demo Pipeline 2 ;
8. rejouer localement `forceDexDecode=yes` ;
9. comparer listed/decoded/observed/materialized/trade_count via SQL coverage ;
10. compléter le decoder spécialisé `raydium_clmm` seulement pour les events confirmables ;
11. remplacer/nettoyer le fallback `upstream_git.instruction_match` quand un decoder local spécialisé couvre l'entrée ;
12. garder les events connus mais non observés en `upstream_git_mapped_unverified` ;
13. garder les events observés mais non matérialisés en audit-only/decoded ;
14. ne matérialiser que les non-trades prouvés par corpus et compatibles avec les tables existantes ;
15. ne pas modifier les règles trade/candle sauf bug de faux positif prouvé.
## Familles à couvrir explicitement
Ne pas se limiter aux swaps.
Inclure dans l'audit coverage CLMM :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Pour `raydium_clmm`, certaines familles sont probablement non applicables ou seulement observées comme side effects SPL Token/Token-2022. Elles doivent être explicitement justifiées dans la coverage matrix.
## Points d'attention hérités de CPMM
- `decoder_code` local doit rester en `snake_case` : `raydium_clmm`, pas `raydium-clmm`.
- Les slugs/chemins upstream peuvent garder les tirets : `raydium-clmm-decoder`.
- Les events side effects SPL Token (`burn`, `transfer`, `transferChecked`, `closeAccount`) ne doivent pas devenir `raydium_clmm.*` sans preuve qu'ils sont des instructions directes du programme CLMM.
- `k_sol_instruction_observations` est technique et peut être enrichie ; ne pas la confondre avec une table métier.
- `initialize_*` / création de pool doit rester lifecycle-only si c'est bien une création, pas admin.
- Les positions CLMM sont potentiellement des tables/catégories existantes ou à auditer : ne pas forcer liquidity simple si l'event représente une position NFT/tick.
- Les rewards/fees CLMM peuvent nécessiter un mapping plus fin que CPMM.
## Requêtes SQL utiles
Coverage CLMM :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_clmm'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Instruction observations CLMM :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_clmm'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC;
```
Non-trade safety :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(le.id) AS liquidity_count,
COUNT(fe.id) AS fee_count,
COUNT(pa.id) AS admin_count,
COUNT(ple.id) AS lifecycle_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events pa
ON pa.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events ple
ON ple.decoded_event_id = de.id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_clmm'
GROUP BY de.event_kind
ORDER BY de.event_kind;
```
Fallback upstream CLMM :
```sql
SELECT
json_extract(payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(payload_json, '$.entryName') AS entry_name,
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS fallback_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'upstream_git'
AND event_kind = 'upstream_git.instruction_match'
AND json_extract(payload_json, '$.upstreamDecoderCode') = 'raydium_clmm'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex
ORDER BY fallback_count DESC, entry_name;
```
Failed transaction safety :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_clmm'
AND tx.err_json IS NOT NULL
AND tx.err_json <> ''
GROUP BY de.event_kind
ORDER BY trade_count DESC, decoded_count DESC;
```
## Contraintes de code
Conserver les règles du workspace :
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Livrables attendus pour `0.7.49`
1. delta archive avec uniquement les fichiers ajoutés/modifiés ;
2. mise à jour `README.md`, `ROADMAP.md`, `CHANGELOG.md` si la tranche avance ;
3. rapport de couverture `raydium_clmm` ;
4. SQL de validation ;
5. tests verts :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```

View File

@@ -0,0 +1,150 @@
<!-- file: docs/prompts/PROMPT_0_7_53_PUMP_SWAP.md -->
# Prompt de reprise — `0.7.53 pump_swap`
Nous reprenons le workspace Rust/Tauri `khadhroony-bobobot` après le commit final `0.7.52 raydium_stable_swap`.
## Objectif de tranche
Version cible : `0.7.53`
Surface cible unique : `pump_swap`
Program id cible unique :
```text
pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA
```
Règle de phasage validée : **une version = un `program_id`**.
`raydium_pool_v4.json` est explicitement repoussé vers la fin du phasage. Il ne doit pas bloquer `0.7.53`.
## Contexte validé avant reprise
Raydium est clos sur les surfaces suivantes :
- `raydium_cpmm``CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C` ;
- `raydium_clmm``CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK` ;
- `raydium_launchpad``LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj` ;
- `raydium_amm_v4``675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` ;
- `raydium_stable_swap``5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h`.
`0.7.52 raydium_stable_swap` est clos avec :
- `cargo test -p kb_lib` : `407 passed`, `0 failed` ;
- `cargo clippy -p kb_lib --all-targets -- -D warnings` : OK ;
- swaps matérialisés uniquement depuis `amountSource=stable_swap_vault_balance_delta` ;
- failed transactions conservées decoded-only ;
- aucun successful swap non expliqué.
## Sources à utiliser pour `pump_swap`
Sources obligatoires à vérifier avant de patcher :
- `kb_lib/src/constants.rs` et `SOLSCAN_ACCOUNT_SOURCES` ;
- sources upstream Git déjà intégrées dans le registre : Carbon, fnzero, Pinax, HODL Warden si disponibles ;
- IDL Solscan du programme `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` si disponible ;
- corpus local Demo3 + backfill signature/pool ;
- `k_sol_dex_event_coverage_entries` après replay.
Les sources Git/IDL/Solscan sont des indices. La preuve métier exige corpus local, replay et SQL.
## Tâches attendues
1. Inspecter le support local existant de `pump_swap`.
2. Lister toutes les instructions/events/discriminators disponibles depuis les sources upstream/IDL.
3. Comparer avec les events localement couverts.
4. Compléter le decoder `pump_swap` pour couvrir au minimum :
- `buy` ;
- `sell` ;
- fees / creator fees / protocol fees si présents ;
- admin/config si présents ;
- events auxiliaires tels que cashback, volume accumulator ou équivalents si présents dans les sources.
5. Matérialiser en `k_sol_trade_events` et `k_sol_pair_candles` uniquement si les montants exacts et le sens économique sont prouvés.
6. Conserver les failed transactions comme decoded-only avec `failed_transaction`.
7. Matérialiser les non-trade uniquement vers les tables adaptées : liquidity, fee, admin, lifecycle, reward, orderbook ou decoded-only selon le cas.
8. Nettoyer les fallbacks `upstream_git.instruction_match` uniquement quand un decoder local spécialisé couvre vraiment lentrée.
9. Mettre à jour la coverage DB et la matrice documentaire.
10. Ajouter ou mettre à jour le SQL de validation dédié : `validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql`.
## Invariants obligatoires
- Aucun non-swap ne doit créer de trade/candle.
- Aucune transaction failed ne doit créer de trade/candle.
- Aucun trade/candle ne doit être créé depuis des bornes dinstruction ou des montants incomplets.
- Aucun router/aggregator ne doit créer un doublon si le DEX effectif matérialise déjà le trade.
- Aucun `program_id` ne doit être inventé.
- Aucun compte non-programme de `SOLSCAN_ACCOUNT_SOURCES` ne doit être promu en decoder autonome.
- `kb_demo_app` ne doit pas contenir de logique métier DEX profonde.
## Contraintes de code
Respecter les contraintes du projet :
- Rust 2024 ;
- aucun fichier `mod.rs` ;
- pas de `pub mod` ; utiliser `mod` + `pub use` ;
- pas de `anyhow`, pas de `thiserror` ;
- pas de `?`, `unwrap`, `expect` dans le code applicatif `kb_lib` ;
- gestion derreurs explicite via `match`, `if let Err`, `let Err = ... else` ;
- rustdoc publique ;
- `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]` ;
- tracing obligatoire ;
- tests offline ;
- si une requête DB est ajoutée ou modifiée, mettre à jour les re-exports dans `kb_lib/src/db.rs`, puis dans `kb_lib/src/lib.rs`.
## Validation attendue
Commandes locales à exécuter après patch :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
Replay attendu sur une base dédiée `0.7.53 pump_swap` :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
SQL de clôture attendu :
- coverage par entrée `pump_swap` ;
- instruction observations ;
- absence daudit résiduel local non expliqué ;
- absence de fallback upstream pour les entrées couvertes localement ;
- failed tx -> zéro trade ;
- non-swap -> zéro trade ;
- decoded without coverage -> vide ;
- successful non-materialized inexpliqués -> vide ;
- multi-target materialization -> vide ;
- résumé matérialisation par event_kind.
## Livrables documentaires
Mettre à jour au minimum :
- `ROADMAP.md` ;
- `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/PUMP_SWAP_EVENT_COVERAGE_REPORT.md` ;
- `validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql`.
## Décision attendue en fin de tranche
`0.7.53 pump_swap` est clôturable uniquement si :
```text
- tous les events/instructions disponibles ont un statut explicite ;
- les swaps réussis exploitables produisent trades/candles ;
- les failed transactions restent decoded-only ;
- les non-trade sont matérialisés dans les bonnes tables ou restent decoded-only expliqués ;
- la coverage DB ne contient pas de gap local inexpliqué ;
- cargo test et clippy sont OK.
```

View File

@@ -0,0 +1,272 @@
<!-- file: docs/prompts/PROMPT_0_7_54_PUMP_FUN.md -->
# Prompt de reprise — khadhroony-bobobot 0.7.54 — pump_fun
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture documentaire et fonctionnelle de `0.7.53 pump_swap`.
## 1. Fichiers à utiliser comme base
Je fournis larchive la plus récente du workspace, intégrant normalement les deltas de clôture `0.7.53`.
À considérer comme sources locales de savoir :
- le code Rust du workspace ;
- les fichiers Markdown (`README.md`, `ROADMAP.md`, `CHANGELOG.md`, `docs/**`) ;
- les SQL de validation dans `validation_sql/**` ;
- le répertoire `idls/**`, ajouté au projet, contenant des IDL JSON téléchargés depuis Solscan ;
- les liens Git/upstream déjà documentés dans les docs ;
- les résultats SQL/logs que je colle dans la conversation.
Ne pas supposer que les docs sont parfaites : les vérifier contre le code et contre les IDL locales.
## 2. État validé avant cette version
La version `0.7.53` a fermé `pump_swap` côté transaction/log decoder :
- `cargo test -p kb_lib` : `421 passed`;
- `cargo clippy -p kb_lib --all-targets -- -D warnings` : OK ;
- `pump_swap.buy`, `pump_swap.sell`, `pump_swap.buy_exact_quote_in` matérialisent correctement les trades ;
- `buy_exact_quote_in` utilise `pump_swap_anchor_buy_event` quand lAnchor `BuyEvent` exact est disponible ;
- les `*_event` Anchor PumpSwap sont décodés en audit-only sauf exception métier explicite ;
- `claim_token_incentives_event` est prêt à matérialiser `k_sol_reward_events` si un event réussi apparaît ;
- `pump_swap` ne présente plus de decoded event sans coverage, ni fallback upstream résiduel, ni trade candidate réussi non matérialisé ;
- les surfaces Raydium déjà travaillées (`raydium_amm_v4`, `raydium_clmm`, `raydium_cpmm`) ne doivent pas être rouvertes sauf bug prouvé ;
- les petits gaps Meteora sont volontairement différés.
Ne pas modifier PumpSwap ou Raydium sauf preuve SQL/code claire dune régression.
## 3. Objectif de la version 0.7.54
Objectif principal : ouvrir et avancer une tranche `pump_fun`.
Cette tranche doit traiter la surface launch/mint Pump.fun, qui est logiquement prioritaire avant `pump_fees`.
Le backlog global montre des entrées `pump_fun` encore en fallback upstream, notamment :
- `pump_fun.collect_creator_fee` / discriminator `1416567bc61cdb84` ;
- `pump_fun.migrate_bonding_curve_creator` / `577c34bf3426d6e8` ;
- `pump_fun.distribute_creator_fees` / `a572670079cef751` ;
- `pump_fun.admin_set_creator` / `4519ab8e39ef0d04` ;
- `pump_fun.extend_account` / `ea66c2cb96483ee5` ;
- `pump_fun.set_creator` / `fe94ff70cf8eaaa5` ;
- `pump_fun.migrate` / `9beae792ec9ea21e` ;
- `pump_fun.claim_cashback` / `253a237ebe35e4c5` ;
- `pump_fun.sell` / `33e685a4017f83ad` ;
- autres discriminators `pump_fun` observés dans `k_sol_instruction_observations`.
Lobjectif nest pas seulement de faire disparaître un fallback : il faut couvrir proprement la surface `pump_fun` :
- registry/coverage ;
- decoder local ou statut local explicitement decoded-only/audit-only ;
- matérialisation métier si les données sont fiables ;
- tests unitaires ;
- SQL de validation ;
- documentation.
## 4. Périmètre
### Inclus
- `pump_fun` launch/mint/bonding-curve surface ;
- instructions/events liés à création/migration/configuration/creator fees/cashback si présents dans IDL ou corpus ;
- intégration coverage ;
- matérialisation vers tables métier seulement si fiable.
### Hors périmètre sauf nécessité démontrée
- `pump_swap`, déjà fermé en `0.7.53` ;
- `raydium_*`, sauf régression prouvée ;
- `meteora_*`, volontairement différé ;
- `jupiter_swap`, `dflow_aggregator_v4`, `onchain_labs_dex_v2`, `orca_whirlpools`, backlog futur ;
- `pump_fees`, qui doit venir après `pump_fun`, probablement en `0.7.55`.
## 5. Méthode obligatoire
### 5.1 Nouvelle base SQLite
Créer une nouvelle DB dédiée à `0.7.54`, ne pas travailler sur lancienne DB de validation PumpSwap.
Démarrage attendu :
- catalog initial propre ou connu ;
- backfills ciblés ;
- replay forcé ;
- validation SQL.
### 5.2 Backfill de corpus
Construire un corpus local à partir de :
1. filtres Solscan.io quand disponibles ;
2. Demo3 discovery quand nécessaire ;
3. batch backfill de groupes de signatures ;
4. program/signature backfill si pertinent ;
5. signatures issues des requêtes SQL `sample_signature`.
Utiliser dabord les signatures fortes observées dans le backlog :
- `pump_fun.collect_creator_fee`;
- `pump_fun.migrate_bonding_curve_creator`;
- `pump_fun.distribute_creator_fees`;
- `pump_fun.admin_set_creator`;
- `pump_fun.extend_account`;
- `pump_fun.set_creator`;
- `pump_fun.migrate`;
- `pump_fun.claim_cashback`;
- puis autres discriminators observés.
Après chaque groupe de backfill :
- replay local avec `skipDexDecode=no`;
- utiliser `forceDexDecode=yes` quand le decoder/coverage change ;
- `deferInstructionObservations=yes` ;
- rafraîchir catalog ;
- relancer les SQL de surveillance.
### 5.3 Sources
Utiliser en priorité :
- `idls/**` local ;
- code existant ;
- docs existantes ;
- `upstream_registry_generated.rs` ;
- sources Git déjà référencées dans les docs ;
- Solscan signatures/logs ;
- payloads locaux DB.
Si une IDL locale contredit une source Git, signaler la divergence et ne pas inventer.
## 6. Contraintes de code Rust
Respecter strictement les conventions du projet :
- Rust 2024 ;
- pas de `?` ;
- pas de `unwrap()` / `expect()` en code applicatif ;
- pas de `anyhow` / `thiserror` ;
- `match` / `if let Err` explicites ;
- async-first ;
- `tracing` obligatoire ;
- pas de `mod.rs` ;
- pas de `pub mod` ; utiliser `mod` + `pub use` ;
- imports limités, types appelés de façon qualifiée quand cest la convention locale ;
- tests offline ;
- ne pas casser `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]`.
Si des requêtes DB sont ajoutées ou déplacées, penser aux re-exports :
- `kb_lib/src/db.rs` ;
- `kb_lib/src/lib.rs`.
## 7. Matérialisation attendue
Pour `pump_fun`, ne pas forcer une matérialisation si les montants/acteurs/comptes ne sont pas prouvés.
Classer explicitement chaque entrée :
- `k_sol_launch_events` pour les événements de launch/mint/migration ;
- `k_sol_fee_events` si linstruction représente réellement des frais exploitables ;
- `k_sol_pool_admin_events` si cest de la configuration/admin/creator ;
- `k_sol_reward_events` uniquement si cest réellement une récompense/incitation/cashback fiable ;
- `k_sol_dex_decoded_events_only` si audit-only ou données insuffisantes ;
- `k_sol_trade_events` seulement si cest un swap/trade fiable ;
- `skip*Reason` explicite quand non matérialisable.
Ne jamais matérialiser une transaction failed comme business event.
## 8. SQL de validation à utiliser
Utiliser et adapter :
- `validation_sql/SQL_VALIDATION_DEX_COVERAGE_GLOBAL_0_7_53.sql`;
- les SQL de validation PumpSwap comme modèle ;
- une nouvelle validation dédiée à `pump_fun`, par exemple :
- `validation_sql/SQL_VALIDATION_PUMP_FUN_0_7_54.sql`.
Requêtes minimales attendues :
1. coverage `pump_fun` ;
2. instruction observations `pump_fun` ;
3. decoded events `pump_fun` sans coverage ;
4. fallback upstream `pump_fun` résiduel ;
5. successful non-materialized events sans skip reason ;
6. failed tx materialization safety ;
7. multi-target materialization safety ;
8. materialization summary ;
9. comparaison entre `k_sol_instruction_observations` et `k_sol_dex_event_coverage_entries` ;
10. global watchlist après replay.
## 9. Invariants de validation
Après correction, viser :
- pas de `pump_fun` decoded event local sans coverage ;
- pas de fallback `upstream_git` résiduel pour les entrées `pump_fun` couvertes localement ;
- pas de materialized business event sur failed transaction ;
- pas de multi-target incohérent ;
- tous les events/instructions observés ont :
- un decoder local,
- ou un statut audit-only,
- ou un skip reason explicite,
- ou une justification documentée sils restent upstream-only.
## 10. Documentation à mettre à jour
À la fin de la tranche, mettre à jour :
- `CHANGELOG.md` : une ligne ;
- `README.md` : état courant, nouvelle version, validation ;
- `ROADMAP.md` : phasage et clôture/état de `pump_fun`, puis annonce de `pump_fees` en version suivante ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- éventuellement un rapport :
- `docs/reports/PUMP_FUN_EVENT_COVERAGE_REPORT.md`.
Ne pas gonfler les docs inutilement : noter les faits validés, les limites, et les prochaines tranches.
## 11. Format de livraison attendu
Ne pas fournir une archive complète du workspace sauf demande explicite.
Fournir un delta zip contenant uniquement les fichiers modifiés/ajoutés.
Nom recommandé :
`khadhroony-bobobot-v0.7.54-pump_fun-delta-N-files.zip`
Chaque réponse de livraison doit inclure :
- résumé des changements ;
- liste exacte des fichiers modifiés ;
- commandes à lancer :
- `cargo fmt`
- `cargo test -p kb_lib`
- `cargo clippy -p kb_lib --all-targets -- -D warnings`
- replay recommandé ;
- SQL à exécuter ;
- ce qui est attendu dans les résultats.
## 12. Priorités si plusieurs gaps apparaissent
Ordre de priorité :
1. `pump_fun` ;
2. `pump_fees` seulement si strictement nécessaire pour comprendre un flux `pump_fun` ;
3. ne pas traiter Meteora dans cette version ;
4. ne pas rouvrir Raydium sauf régression démontrée ;
5. ne pas ouvrir Jupiter/dFlow/onchain_labs dans cette tranche sauf pour les classer en backlog.
## 13. Première tâche demandée
Commencer par analyser larchive fournie :
1. identifier les fichiers existants liés à `pump_fun`, `pump_fees`, upstream registry, coverage, materialization ;
2. chercher dans `idls/**` sil existe une IDL Solscan liée à `pump_fun` ;
3. produire un état des lieux court :
- entrées upstream disponibles ;
- entrées observées dans SQL/logs fournis ;
- fichiers à modifier ;
- hypothèse de classification par entry ;
- SQL initial de backfill/validation ;
4. proposer puis produire le premier delta archive minimal.

View File

@@ -0,0 +1,347 @@
<!-- file: docs/prompts/PROMPT_0_7_55_PUMP_FEES.md -->
# Prompt de reprise — khadhroony-bobobot 0.7.55 — pump_fees
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture technique de `0.7.54 pump_fun`.
## 1. Archive et fichiers à fournir
Utiliser l'archive la plus récente après clôture `0.7.54 pump_fun`.
À considérer comme sources locales de savoir :
- code Rust du workspace ;
- `README.md`, `ROADMAP.md`, `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/PUMP_FUN_EVENT_COVERAGE_REPORT.md` ;
- `validation_sql/SQL_VALIDATION_PUMP_FUN_0_7_54.sql` ;
- `validation_sql/SQL_VALIDATION_PUMP_FUN_MATERIALIZATION_0_7_54.sql` ;
- `idls/**`, en particulier `idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json` ;
- les logs/requêtes SQL collés pendant la session.
Ne pas supposer que la documentation est parfaite : vérifier contre le code, l'IDL locale et le corpus SQLite.
## 2. État validé avant cette version
`0.7.54 pump_fun` est clos.
Replay final rapporté :
```text
1679 replayed
0 decode skipped
1679 ledger upserts
145 unsafe ledger rows
89 trades
0 liquidity
10 lifecycle
0 tokenAccount
348 candle upserts
instructionObservations = 13905
resetDeleted = 1112
catalog = 52 tokens / 50 pools / 50 pairs
```
Checks de fermeture Pump.fun :
- upstream fallback Pump.fun : vide ;
- decoded Pump.fun sans coverage : vide ;
- successful non-materialized sans skip reason : vide ;
- failed transaction materialization safety : vide ;
- multi-target materialization safety : vide ;
- trade candidates Pump.fun sans matérialisation ni skip : vide ;
- watchlist globale : plus aucun `pump_fun`.
Décisions Pump.fun à préserver :
- `buy`, `sell`, `buy_exact_sol_in` sont matérialisés directement quand les montants sont fiables ;
- `buy_v2`, `sell_v2`, `buy_exact_quote_in_v2` ne sont pas matérialisés directement ;
- `trade_event` est la source canonique des montants exécutés v2/exact ;
- aucun double-count entre instruction trade et event Anchor ;
- transactions failed audit-only.
Ne pas rouvrir `pump_fun`, `pump_swap` ou Raydium sauf bug prouvé par SQL/code.
## 3. Objectif de `0.7.55 pump_fees`
Ouvrir et clôturer la surface `pump_fees`.
Program id cible :
```text
pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ
```
IDL locale :
```text
idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json
```
exemple de code:
https://github.com/sevenlabs-hq/carbon/tree/main/decoders/pump-fees-decoder
L'IDL locale contient au minimum :
- `29` instructions ;
- `20` events ;
- `9` accounts ;
- `34` types.
Règle forte :
> Tout ce qui peut être décodé doit être décodé. Tout ce qui peut être matérialisé de façon fiable doit être matérialisé. Ce qui ne peut pas être matérialisé doit rester decoded-only/audit-only avec `skip*Reason` explicite.
Le programme `pump_fees` est a priori un programme de fee/config/accounting. Aucun trade/candle direct n'est attendu sauf preuve transactionnelle très forte d'un swap économique autonome.
## 4. Backlog initial observé
La watchlist globale après `0.7.54 pump_fun` montre notamment :
```text
pump_fees get_fees e7257e55cf5b3f34 173 decoded / 171 tx
pump_fees create_fee_sharing_config c34e564c6f34fbd5 21 decoded / 21 tx
pump_fees update_fee_shares bd0d8863bba4ed23 14 decoded / 14 tx
```
Ces trois entrées doivent être les premières sources de corpus/backfill.
## 5. Périmètre fonctionnel
### Inclus
- décodage de toutes les instructions `pump_fees` connues par l'IDL locale ;
- décodage de tous les events Anchor `pump_fees` connus par l'IDL locale ;
- décodage Borsh des arguments et payloads quand les layouts sont définis ;
- classification coverage par famille : fee, reward, admin/config, buyback, social fee, donation fee, fee sharing, account lifecycle ;
- matérialisation vers les tables métier existantes quand les données sont fiables :
- `k_sol_fee_events` ;
- `k_sol_reward_events` si cashback/social/donation/claim représente une récompense exploitable ;
- `k_sol_pool_admin_events` pour config/admin/authority/tier/update ;
- `k_sol_pool_lifecycle_events` si création/initialisation de compte/config est pertinente ;
- `k_sol_dex_decoded_events_only` pour les vues/calculs/audit-only ;
- SQL de validation dédié ;
- documentation finale et rapport.
### Hors périmètre sauf preuve stricte
- nouveau trade/candle direct ;
- réouverture Pump.fun/PumpSwap ;
- Raydium/Meteora/Jupiter/dFlow ;
- refactor réseau ou UI non nécessaire.
## 6. Méthode obligatoire : nouvelle base SQLite
Créer une nouvelle DB dédiée à `0.7.55 pump_fees`.
Ne pas réutiliser l'ancienne DB de validation Pump.fun sauf pour lire des signatures de départ.
Après chaque backfill ou patch decoder :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Puis :
- refresh catalog ;
- replay local ;
- relancer SQL de validation ;
- noter les compteurs replay.
## 7. Corpus et backfills
Construire le corpus local à partir de :
1. signatures `sample_signature` de la watchlist globale ;
2. filtres Solscan.io par program id + instruction/discriminator quand disponibles ;
3. Demo3 discovery multi-source/multi-target ;
4. batch backfill par groupes de signatures ;
5. program/signature backfill ciblé si nécessaire ;
6. signatures issues des requêtes SQL `instruction_observations`, fallback upstream et decoded-only résiduels.
Démarrer par :
- `get_fees` / `e7257e55cf5b3f34` ;
- `create_fee_sharing_config` / `c34e564c6f34fbd5` ;
- `update_fee_shares` / `bd0d8863bba4ed23`.
Ensuite couvrir les autres instructions/events de l'IDL locale, même non observés, par tests synthétiques lorsque le layout est connu.
## 8. Instructions IDL locales à inventorier
Inventorier et classifier au minimum :
- `claim_social_fee_pda` ;
- `claim_social_fee_pda_v2` ;
- `crank_donation_fee_pda` ;
- `create_donation_fee_pda` ;
- `create_fee_sharing_config` ;
- `create_social_fee_pda` ;
- `extend_fee_config` ;
- `get_fees` ;
- `initialize_buyback` ;
- `initialize_fee_config` ;
- `initialize_fee_program_global` ;
- `reset_fee_sharing_config` ;
- `reset_fee_sharing_config_v2` ;
- `revoke_fee_sharing_authority` ;
- `set_authority` ;
- `set_claim_rate_limit` ;
- `set_disable_flags` ;
- `set_social_claim_authority` ;
- `sweep_buyback` ;
- `transfer_fee_sharing_authority` ;
- `update_admin` ;
- `update_buyback_authority` ;
- `update_buyback_claim_rate_limit` ;
- `update_fee_config` ;
- `update_fee_shares` ;
- `update_fee_shares_v2` ;
- `update_stable_fee_config` ;
- `upsert_fee_tiers` ;
- `upsert_stable_fee_tiers`.
Events Anchor à inventorier :
- `CreateFeeSharingConfigEvent` ;
- `DonationFeePdaCranked` ;
- `DonationFeePdaCreated` ;
- `ExtendFeeConfigEvent` ;
- `InitializeFeeConfigEvent` ;
- `InitializeFeeProgramGlobalEvent` ;
- `ResetFeeSharingConfigEvent` ;
- `SetAuthorityEvent` ;
- `SetClaimRateLimitEvent` ;
- `SetDisableFlagsEvent` ;
- `SetSocialClaimAuthorityEvent` ;
- `SocialFeePdaClaimed` ;
- `SocialFeePdaCreated` ;
- `SweepBuybackEvent` ;
- `UpdateAdminEvent` ;
- `UpdateFeeConfigEvent` ;
- `UpdateFeeSharesEvent` ;
- `UpdateStableFeeConfigEvent` ;
- `UpsertFeeTiersEvent` ;
- `UpsertStableFeeTiersEvent`.
## 9. Contraintes de code Rust
Respecter strictement les conventions du projet :
- Rust 2024 ;
- pas de `?` ;
- pas de `unwrap()` / `expect()` en code applicatif ;
- pas de `anyhow` / `thiserror` ;
- `match` / `if let Err` explicites ;
- async-first ;
- `tracing` obligatoire ;
- pas de `mod.rs` ;
- pas de `pub mod` ; utiliser `mod` + `pub use` ;
- imports limités, types appelés de façon qualifiée quand c'est la convention locale ;
- tests offline ;
- ne pas casser `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]`.
Si des requêtes DB sont ajoutées ou déplacées, penser aux re-exports :
- `kb_lib/src/db.rs` ;
- `kb_lib/src/lib.rs`.
## 10. Matérialisation attendue
Ne pas se contenter de decoded-only si une matérialisation fiable est possible.
Classification cible :
- `get_fees` : probablement decoded-only ou fee calculation audit ; ne pas matérialiser comme fee payé sans transfert/montant réalisé ;
- fee sharing config : `k_sol_pool_admin_events` ou lifecycle/config si comptes exploitables ;
- social/donation fee PDA create/claim/crank : `k_sol_fee_events`, `k_sol_reward_events` ou admin/lifecycle selon le sens exact des flux ;
- buyback init/sweep/update : fee/admin/buyback selon comptes et montants ;
- authority/config/tier updates : `k_sol_pool_admin_events` ;
- Anchor events : matérialiser s'ils portent le montant/acteur/compte fiable ; sinon audit-only avec skip reason ;
- transactions failed : decoded-only/audit-only, jamais business matérialisé.
Aucun `pump_fees` ne doit créer de `k_sol_trade_events` ni de candle sauf preuve irréfutable d'un trade économique autonome et non doublonné.
## 11. SQL de validation attendu
Créer :
```text
validation_sql/SQL_VALIDATION_PUMP_FEES_0_7_55.sql
```
Requêtes minimales :
1. upstream fallback samples `pump_fees` ;
2. local instruction observations `pump_fees` ;
3. coverage `pump_fees` ;
4. decoded events `pump_fees` sans coverage ;
5. residual upstream fallback pour entrées couvertes ;
6. successful non-materialized sans skip reason ;
7. failed transaction materialization safety ;
8. multi-target materialization safety ;
9. materialization summary par table ;
10. instruction observation versus coverage ;
11. contrôle anti-trade/candle direct `pump_fees` ;
12. global watchlist après replay.
## 12. Invariants de fermeture
La tranche `0.7.55` ne doit être considérée close que si :
- aucun fallback `upstream_git` `pump_fees` ne reste pour les entrées couvertes localement ;
- aucun decoded event `pump_fees` local sans coverage ;
- aucune transaction failed n'alimente une table métier ;
- aucun event multi-target incohérent ;
- aucune ligne successful non-materialized sans `skip*Reason` ;
- aucun trade/candle `pump_fees` artificiel ;
- toutes les instructions/events de l'IDL locale sont soit décodés/matérialisés, soit audit-only, soit non observés mais couverts par tests synthétiques ;
- la watchlist globale ne contient plus de `pump_fees` comme backlog dominant.
## 13. Documentation à mettre à jour en fin de tranche
Mettre à jour :
- `CHANGELOG.md` ;
- `README.md` ;
- `ROADMAP.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- créer `docs/reports/PUMP_FEES_EVENT_COVERAGE_REPORT.md` ;
- créer ou mettre à jour le SQL de validation dédié.
## 14. Format de livraison attendu
Fournir un delta zip contenant uniquement les fichiers modifiés/ajoutés.
Nom recommandé :
```text
khadhroony-bobobot-v0.7.55-pump_fees-delta-N-files.zip
```
Chaque livraison doit inclure :
- résumé des changements ;
- liste exacte des fichiers modifiés ;
- commandes à lancer :
- `cargo fmt` ;
- `cargo test -p kb_lib` ;
- `cargo clippy -p kb_lib --all-targets -- -D warnings` ;
- replay recommandé ;
- SQL à exécuter ;
- résultats attendus.
## 15. Première tâche demandée
1. Inspecter le code et l'IDL `pump_fees` locale.
2. Comparer `upstream_registry_generated.rs`, `idls/pump_fees...json` et le corpus SQL.
3. Créer une base SQLite neuve `0.7.55`.
4. Backfiller les signatures `get_fees`, `create_fee_sharing_config`, `update_fee_shares`.
5. Ajouter le decoder local maximal `pump_fees` : instructions + events + tests synthétiques.
6. Ajouter coverage/materialization/validation SQL.
7. Rejouer et fermer seulement si tous les invariants sont propres.

View File

@@ -0,0 +1,218 @@
<!-- file: docs/prompts/PROMPT_0_7_56_METEORA_DBC.md -->
# Prompt de reprise — khadhroony-bobobot 0.7.56 — meteora_dbc
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture technique de `0.7.55 pump_fees`.
## 1. Archive et fichiers à fournir
Utiliser l'archive la plus récente après clôture `0.7.55 pump_fees`.
À considérer comme sources locales de savoir :
- code Rust du workspace ;
- `README.md`, `ROADMAP.md`, `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/PUMP_FEES_EVENT_COVERAGE_REPORT.md` ;
- `validation_sql/SQL_VALIDATION_PUMP_FEES_0_7_55.sql` ;
- `idls/**`, en particulier `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json` ;
- les logs/requêtes SQL collés pendant la session.
Ne pas supposer que la documentation est parfaite : vérifier contre le code, l'IDL locale, les sources Git et le corpus SQLite.
## 2. État validé avant cette version
`0.7.55 pump_fees` est clos.
Replay final rapporté :
```text
127 replayed
0 decode skipped
150 ledger upserts
125 unsafe ledger rows
4 trades
0 liquidity
115 lifecycle
0 tokenAccount
16 candle upserts
instructionObservations = 2234
resetDeleted = 1644
catalog = 11 tokens / 10 pools / 10 pairs
```
Validation build :
```text
cargo test -p kb_lib -> 431 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Checks de fermeture Pump Fees :
- fallback `upstream_git` `pump_fees` : vide ;
- `instruction_name` vide : vide ;
- `event_family = unknown` ou vide pour instruction/event : vide ;
- decoded `pump_fees` sans coverage : vide ;
- successful non-materialized sans skip/policy : vide ;
- failed transaction materialization safety : vide ;
- multi-target materialization safety : vide ;
- anti-trade/candle direct `pump_fees` : vide ;
- watchlist globale : plus aucun `pump_fees`, seulement `jupiter_swap.route_v2` ponctuel.
Décisions Pump Fees à préserver :
- `get_fees` est decoded-only ;
- claims social fee vers `k_sol_reward_events` seulement si succès et montant fiable ;
- donation/buyback vers `k_sol_fee_events` seulement si succès et montant fiable ;
- config/authority/tier/update vers `k_sol_pool_admin_events` ;
- create/init/extend vers `k_sol_pool_lifecycle_events` ;
- aucun trade/candle direct ;
- failed tx audit-only ;
- les discriminators Solscan `revoke_fee_sharing_authority_event` et `transfer_fee_sharing_authority_event` restent conservés comme futures surfaces non observées.
Ne pas rouvrir `pump_fees`, `pump_fun`, `pump_swap` ou Raydium sauf bug prouvé par SQL/code.
## 3. Objectif de `0.7.56 meteora_dbc`
Ouvrir et clôturer la surface `meteora_dbc`.
Program id cible :
```text
dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN
```
IDL locale prioritaire :
```text
idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json
```
Règle forte :
> Tout ce qui peut être décodé doit être décodé. Tout ce qui peut être matérialisé de façon fiable doit être matérialisé. Ce qui ne peut pas être matérialisé doit rester decoded-only/audit-only avec `skip*Reason` explicite.
La surface DBC doit couvrir launch/bonding curve, pool/config lifecycle, swaps exploitables, migration, fees/admin/config, et events Anchor associés.
## 4. Méthode obligatoire : nouvelle base SQLite
Créer une nouvelle DB dédiée à `0.7.56 meteora_dbc`.
Ne pas réutiliser l'ancienne DB de validation Pump Fees sauf pour lire des signatures de départ.
Après chaque backfill ou patch decoder :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Puis :
- refresh catalog ;
- replay local ;
- relancer SQL de validation ;
- noter les compteurs replay.
## 5. Corpus et backfills
Construire le corpus local à partir de :
1. signatures `sample_signature` de la watchlist globale et des coverage gaps ;
2. filtres Solscan.io par program id + instruction/discriminator quand disponibles ;
3. Demo3 discovery multi-source/multi-target ;
4. batch backfill par groupes de signatures ;
5. program/signature backfill ciblé si nécessaire ;
6. signatures issues des requêtes SQL `instruction_observations`, fallback upstream et decoded-only résiduels.
Inclure explicitement les transactions failed dans le corpus d'audit, mais ne jamais les matérialiser métier.
## 6. Sources à comparer
Comparer au minimum :
- `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json` ;
- Carbon `meteora-dbc-decoder` ;
- Pinax/Substreams Solana IDLs si disponibles ;
- Solana Streamer / sol-parser-sdk si des layouts Meteora DBC y apparaissent ;
- code local existant `kb_lib/src/dex/*meteora*` ;
- `upstream_registry_generated.rs` ;
- corpus SQLite neuf.
## 7. Matérialisation attendue
Ne pas se contenter de decoded-only si une matérialisation fiable est possible.
Cibles probables :
- swaps exploitables -> `k_sol_trade_events` + candles si montants, sens, mint base/quote et pool/pair sont fiables ;
- pool/config/create -> `k_sol_pool_lifecycle_events` et catalog/pool/pair si comptes fiables ;
- liquidity/deposit/withdraw -> `k_sol_liquidity_events` si montants et pool fiables ;
- migration -> lifecycle/admin selon sémantique exacte ;
- fees/creator fees/admin/config -> `k_sol_fee_events` ou `k_sol_pool_admin_events` ;
- events sans contexte suffisant -> decoded-only/audit-only avec skip reason.
Transactions failed : decoded-only/audit-only, jamais business matérialisées.
## 8. SQL de validation attendu
Créer :
```text
validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql
```
Requêtes minimales :
1. upstream fallback samples `meteora_dbc` ;
2. local instruction observations `meteora_dbc` ;
3. coverage `meteora_dbc` ;
4. decoded events `meteora_dbc` sans coverage ;
5. residual upstream fallback pour entrées couvertes ;
6. successful non-materialized sans skip reason ;
7. failed transaction materialization safety ;
8. multi-target materialization safety ;
9. materialization summary par table, avec colonnes successful/failed ;
10. instruction observation versus coverage ;
11. anti-faux trade/candle pour events non swap ;
12. global watchlist après replay.
## 9. Invariants de fermeture
La tranche `0.7.56` ne doit être considérée close que si :
- aucun fallback `upstream_git` `meteora_dbc` ne reste pour les entrées couvertes localement ;
- aucun decoded event `meteora_dbc` local sans coverage ;
- aucune transaction failed n'alimente une table métier ;
- aucun event multi-target incohérent ;
- aucune ligne successful non-materialized sans `skip*Reason` ;
- aucun faux trade/candle sur event non swap ;
- toutes les instructions/events de l'IDL locale sont soit décodés/matérialisés, soit audit-only, soit non observés mais couverts par tests synthétiques ;
- la watchlist globale ne contient plus de `meteora_dbc` comme backlog dominant.
## 10. Documentation à mettre à jour en fin de tranche
Mettre à jour :
- `CHANGELOG.md` ;
- `README.md` ;
- `ROADMAP.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- créer `docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md` ;
- créer `validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql`.
## 11. Format de livraison attendu
Fournir un delta zip contenant uniquement les fichiers modifiés/ajoutés.
Nom recommandé :
```text
khadhroony-bobobot-v0.7.56-meteora_dbc-delta-pre.xxx.zip
```
Inclure dans chaque livraison : résumé des changements, liste exacte des fichiers modifiés, commandes `cargo fmt`, `cargo test -p kb_lib`, `cargo clippy -p kb_lib --all-targets -- -D warnings`, replay recommandé, SQL à exécuter et résultats attendus.

View File

@@ -0,0 +1,457 @@
<!-- file: docs/prompts/PROMPT_0_7_57_METEORA_DLMM_FULL_DECODE_MATERIALIZATION.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.57` — `meteora_dlmm` full decode / full materialization
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture de `0.7.56 meteora_dbc`.
## 1. Archive et fichiers à fournir
Utiliser l'archive la plus récente après application des docs `0.7.56 final`.
Fichiers à lire en priorité :
- `README.md` ;
- `ROADMAP.md` ;
- `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md` ;
- `docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md` ;
- `docs/VALIDATION_STATUS_0_7_56_FINAL.md` ;
- `validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql` ;
- `validation_sql/SQL_VALIDATION_METEORA_DLMM_0_7_57.sql` ;
- `idls/**`, en particulier `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` ;
- `kb_lib/src/dex/meteora_dlmm.rs` ;
- `kb_lib/src/non_trade_event_materialization.rs` ;
- `kb_lib/src/db/queries/fee_event_amount.rs`.
Ne pas supposer que l'ancien support `0.7.45 meteora_dlmm` est suffisant : il était partiel. `0.7.57` doit viser la parité IDL/corpus complète.
## 2. État validé avant cette version
`0.7.56 meteora_dbc` est clos.
Build final :
```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Replay final DBC :
```text
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
1056 candle upserts
instructionObservations = 7167
catalog = 86 tokens / 60 pools / 60 pairs
```
Socle fee final :
```text
k_sol_fee_events meteora_dbc = 89 parents
k_sol_fee_event_amounts meteora_dbc = 96 legs
parent scalar without leg = empty
orphan fee amount legs = empty
```
Règles fee à préserver :
- parent fee scalaire -> leg `k_sol_fee_event_amounts` automatique ;
- fee multi-leg/multi-mint -> parent sans agrégation artificielle, legs explicites ;
- pas de montant depuis `maxAmount`, `u64::MAX`, bornes ou limites de claim ;
- recovery CPI SPL générique uniquement si policy/allowlist explicite ;
- aucun futur decoder ne doit hériter de `allowlisted_inner_spl_transfer` par défaut.
## 3. Objectif de `0.7.57 meteora_dlmm`
Program id cible :
```text
LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
```
IDL locale prioritaire :
```text
idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json
```
Nom IDL : `lb_clmm`.
Surface IDL :
```text
76 instructions
30 events Anchor
12 accounts
```
Objectif : **full decode + full materialization**.
Règle forte :
> Tout ce qui peut être décodé doit être décodé. Tout ce qui peut être matérialisé de façon fiable doit être matérialisé. Ce qui ne peut pas être matérialisé doit rester decoded-only/audit-only avec `skip*Reason` explicite. les instructions/events/anchors/discriminator non observés aprés backfill sur une base de donnée vierge devront avoir des tests syntetiques.
## 4. Méthode obligatoire
Créer une nouvelle DB dédiée à `0.7.57 meteora_dlmm`.
Après chaque backfill ou patch decoder :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Puis : refresh catalog, replay local, SQL validation, note des compteurs.
Ne pas rouvrir `meteora_dbc`, Pump ou Raydium sauf bug prouvé par SQL.
## 5. Sources à comparer
Comparer au minimum :
- IDL locale `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` ;
- Carbon Meteora DLMM decoder ;
- Pinax/Substreams Solana IDLs ;
- Solana Streamer / sol-parser-sdk si DLMM y apparaît ;
- code local historique `kb_lib/src/dex/meteora_dlmm.rs` ;
- coverage existante `k_sol_dex_event_coverage_entries` ;
- corpus SQLite neuf ;
- anciens rapports `0.7.45` et matrices pour comprendre ce qui était déjà validé.
## 6. Checklist d'instructions IDL à inventorier
| Instruction | Discriminator hex |
|---|---|
| `add_liquidity` | `b59d59438fb63448` |
| `add_liquidity2` | `e4a24e1c46db7473` |
| `add_liquidity_by_strategy` | `0703967f94283dc8` |
| `add_liquidity_by_strategy2` | `03dd95da6f8d76d5` |
| `add_liquidity_by_strategy_one_side` | `2905eeaf64e106cd` |
| `add_liquidity_by_weight` | `1c8cee63e7a21595` |
| `add_liquidity_by_weight2` | `d13b3f5b6fc899e4` |
| `add_liquidity_one_side` | `5e9b6797465fdca5` |
| `add_liquidity_one_side_precise` | `a1c26754ab47fa9a` |
| `add_liquidity_one_side_precise2` | `2133a3c975627de7` |
| `cancel_limit_order` | `849c841f4328e861` |
| `claim_fee` | `a9204f8988e84689` |
| `claim_fee2` | `70bf65ab1c907fbb` |
| `claim_reward` | `955fb5f25e5a9ea2` |
| `claim_reward2` | `be037f77b2579db7` |
| `close_bin_array` | `44ae5850b5cc13e0` |
| `close_claim_fee_operator_account` | `b8d5581fb3658224` |
| `close_limit_order_if_empty` | `397c249b7ef95dab` |
| `close_operator_account` | `ab09d54a7817031d` |
| `close_position` | `7b86510031446262` |
| `close_position2` | `ae5a2373ba2893e2` |
| `close_position_if_empty` | `3b7cd4765b986e9d` |
| `close_preset_parameter` | `04949164861ab53d` |
| `close_preset_parameter2` | `27195f6b7411731c` |
| `close_token_badge` | `6c92566eb3fe0a68` |
| `create_operator_account` | `dd40f695f099e5a3` |
| `decrease_position_length` | `c2db882019606925` |
| `for_idl_type_generation_do_not_call` | `b46945505f32496c` |
| `fund_reward` | `bc32f9a55d97263f` |
| `go_to_a_bin` | `9248aee028fd54ae` |
| `increase_oracle_length` | `be3d7d57674f9ead` |
| `increase_position_length` | `505375d3420d2195` |
| `increase_position_length2` | `ffd2cc477389e171` |
| `initialize_bin_array` | `235613b94ed44bd3` |
| `initialize_bin_array_bitmap_extension` | `2f9de2b40cf02147` |
| `initialize_customizable_permissionless_lb_pair` | `2e2729876fb7c840` |
| `initialize_customizable_permissionless_lb_pair2` | `f349817e3313f16b` |
| `initialize_lb_pair` | `2d9aedd2dd0fa65c` |
| `initialize_lb_pair2` | `493b2478ed536cc6` |
| `initialize_permission_lb_pair` | `6c66d555fb033515` |
| `initialize_position` | `dbc0ea47bebf6650` |
| `initialize_position2` | `8f13f291d50f6873` |
| `initialize_position_by_operator` | `fbbdbef475fe2394` |
| `initialize_position_pda` | `2e527d92558de499` |
| `initialize_preset_parameter` | `42bc47d3626d0eba` |
| `initialize_reward` | `5f87c0c4f281e644` |
| `initialize_token_badge` | `fd4dcd5f1be059df` |
| `place_limit_order` | `6cb021ba92e501c5` |
| `rebalance_liquidity` | `5c04b0c177b95309` |
| `remove_all_liquidity` | `0a333d2370691855` |
| `remove_liquidity` | `5055d14818ceb16c` |
| `remove_liquidity2` | `e6d7527ff165e392` |
| `remove_liquidity_by_range` | `1a526698f04a691a` |
| `remove_liquidity_by_range2` | `cc02c391359191cd` |
| `set_activation_point` | `5bf90fa51a81fe7d` |
| `set_pair_status` | `43f8e7899a95d9ae` |
| `set_pair_status_permissionless` | `4e3b98d346b72ed0` |
| `set_permissionless_operation_bits` | `543acb8ba351beba` |
| `set_pre_activation_duration` | `a53dc9f4829f1664` |
| `set_pre_activation_swap_address` | `398b2f7bd850df0a` |
| `swap` | `f8c69e91e17587c8` |
| `swap2` | `414b3f4ceb5b5b88` |
| `swap_exact_out` | `fa49652126cf4bb8` |
| `swap_exact_out2` | `2bd7f784893cf351` |
| `swap_with_price_impact` | `38ade6d0ade49ccd` |
| `swap_with_price_impact2` | `4a62c0d6b1334b33` |
| `update_base_fee_parameters` | `4ba8dfa110c3032f` |
| `update_dynamic_fee_parameters` | `5ca12ef6ffbd1616` |
| `update_fees_and_reward2` | `208eb89a6741b858` |
| `update_fees_and_rewards` | `9ae6fa0decd14bdf` |
| `update_position_operator` | `cab8678fb4bf74d9` |
| `update_reward_duration` | `8aaec4a9d5ebfe6b` |
| `update_reward_funder` | `d31c3020d7a02317` |
| `withdraw_ineligible_reward` | `94ce2ac3f7316708` |
| `withdraw_protocol_fee` | `9ec99ebd215da267` |
| `zap_protocol_fee` | `d59bbb2238b65bf0` |
## 7. Checklist d'events Anchor IDL à inventorier
| Event | Discriminator hex |
|---|---|
| `AddLiquidity` | `1f5e7d5ae3343dba` |
| `CancelLimitOrderEvt` | `83eac285090ebdd1` |
| `ClaimFee` | `4b7a9a308c4a7ba3` |
| `ClaimFee2` | `e8abf2613a4d232d` |
| `ClaimReward` | `947486cc16ab555f` |
| `ClaimReward2` | `1b8ff421502b6e92` |
| `CloseLimitOrderEvt` | `8e87084c5c3f7653` |
| `CompositionFee` | `80977b6a1166718e` |
| `DecreasePositionLength` | `3476eb55aca90f80` |
| `DynamicFeeParameterUpdate` | `5858b287c2925bf3` |
| `FeeParameterUpdate` | `304cf17590d7f22c` |
| `FundReward` | `f6e43a8291aa4fcc` |
| `GoToABin` | `3b8a4c448a83b043` |
| `IncreaseObservation` | `63f91179a69ccfd7` |
| `IncreasePositionLength` | `9def2acc1e38df2e` |
| `InitializeReward` | `d399583e953cb146` |
| `LbPairCreate` | `b94afc7d1bd7bc6f` |
| `PlaceLimitOrderEvt` | `2b4f1ba9f41ce13f` |
| `PositionClose` | `ffc4106b1cca3580` |
| `PositionCreate` | `908efc549d352579` |
| `Rebalancing` | `006d75b33d5bc7c8` |
| `RemoveLiquidity` | `74f461e8671f983a` |
| `SetPositionPermissionlessOperationBitsEvt` | `c3e593f51d7d30a8` |
| `Swap` | `516ce3becdd00ac4` |
| `Swap2Evt` | `2e7452d7941b544d` |
| `UpdatePositionLockReleasePoint` | `85d642e0400c07bf` |
| `UpdatePositionOperator` | `277330ccf62f4239` |
| `UpdateRewardDuration` | `dff5e099311da3ac` |
| `UpdateRewardFunder` | `e0b2ae4afca555b4` |
| `WithdrawIneligibleReward` | `e7bd419566d79af4` |
## 8. Matérialisation attendue
### Swaps
Cibles :
```text
swap
swap2
swap_exact_out
swap_exact_out2
swap_with_price_impact
swap_with_price_impact2
Swap
Swap2Evt
```
Décision :
- `k_sol_trade_events` + candles uniquement si montants exécutés, sens, pool, token X/Y et mints sont fiables ;
- les events Anchor swap ne doivent pas double-compter une instruction swap déjà matérialisée ;
- exact-out et price-impact ne doivent pas utiliser des bornes comme montants exécutés ;
- si le contexte n'est pas fiable : `skipTradeReason` + `skipCandleReason`.
### Liquidity / bins / positions
Cibles :
```text
add_liquidity*
remove_liquidity*
remove_all_liquidity
rebalance_liquidity
initialize_position*
close_position*
position create/close/update events
initialize_bin_array*
close_bin_array
```
Décision :
- `k_sol_liquidity_events` quand les montants token X/Y, pool, position et acteur sont fiables ;
- lifecycle pour création/fermeture position/bin/pair ;
- skip reason explicite pour position/bin sans montants exploitables.
### Pools / catalog
Cibles :
```text
initialize_lb_pair
initialize_lb_pair2
initialize_permission_lb_pair
initialize_customizable_permissionless_lb_pair
initialize_customizable_permissionless_lb_pair2
LbPairCreate
```
Décision : lifecycle/catalog/pool/pair si mints X/Y, pool, config/preset et comptes vault sont fiables.
### Fees
Cibles :
```text
claim_fee
claim_fee2
withdraw_protocol_fee
zap_protocol_fee
ClaimFee
ClaimFee2
CompositionFee
```
Décision :
- `k_sol_fee_events` + `k_sol_fee_event_amounts` obligatoires si montant/mint fiable ;
- utiliser parent scalaire + leg automatique pour mono-fee ;
- utiliser multi-leg sans agrégation parent si plusieurs mints/composants ;
- ne pas confondre composition fee inclus dans swap/liquidity avec claim fee matérialisable ;
- déclarer explicitement toute policy de recovery ; ne pas ajouter DLMM à l'allowlist générique sans preuve et tests.
### Rewards
Cibles :
```text
initialize_reward
fund_reward
claim_reward
claim_reward2
withdraw_ineligible_reward
ClaimReward
ClaimReward2
FundReward
InitializeReward
WithdrawIneligibleReward
```
Décision : `k_sol_reward_events` si montant/mint/reward index fiables ; decoded-only sinon.
### Admin/config/status/operator/token badge
Cibles :
```text
update_base_fee_parameters
update_dynamic_fee_parameters
update_fees_and_rewards
update_fees_and_reward2
set_pair_status
set_pair_status_permissionless
set_activation_point
set_pre_activation_duration
set_pre_activation_swap_address
set_permissionless_operation_bits
create_operator_account
close_operator_account
close_claim_fee_operator_account
initialize_token_badge
close_token_badge
initialize_preset_parameter
close_preset_parameter
close_preset_parameter2
```
Décision : `k_sol_pool_admin_events` si acteur/cible fiables ; decoded-only avec raison sinon.
### Limit orders / orderbook-like events
Cibles :
```text
place_limit_order
cancel_limit_order
close_limit_order_if_empty
PlaceLimitOrderEvt
CancelLimitOrderEvt
CloseLimitOrderEvt
```
Décision : `k_sol_orderbook_events` si sémantique fiable ; pas de trade/candle sans fill exact.
## 9. SQL de validation attendu
Créer/mettre à jour :
```text
validation_sql/SQL_VALIDATION_METEORA_DLMM_0_7_57.sql
```
Le fichier doit vérifier au minimum :
1. fallback upstream DLMM ;
2. instruction observations DLMM ;
3. coverage DLMM ;
4. decoded DLMM sans coverage ;
5. successful non-materialized sans skip reason ;
6. failed tx materialization ;
7. multi-target materialization ;
8. trade/candle sur non-swap ;
9. fee parent/legs ;
10. orphan fee legs ;
11. reward/fee separation ;
12. orderbook/limit-order sans double-count ;
13. watchlist globale.
## 10. Invariants de fermeture
`0.7.57 meteora_dlmm` ne peut être clôturé que si :
- les `76` instructions et `30` events Anchor IDL sont dans la coverage ou explicitement non observés avec tests synthétiques ;
- aucun fallback upstream DLMM ne reste pour les entrées couvertes localement ;
- aucun decoded DLMM local sans coverage ;
- aucune tx failed n'alimente une table métier ;
- aucun event multi-target incohérent ;
- aucune ligne successful non-materialized sans `skip*Reason` ou policy explicite ;
- aucun non-swap ne produit trade/candle ;
- aucun fee parent scalaire sans leg ;
- aucun leg fee orphelin ;
- aucun reward n'est classé fee par défaut ;
- aucun limit/order event ne produit une candle sans fill exact ;
- la watchlist globale ne contient plus de backlog dominant `meteora_dlmm`.
## 11. Contraintes de code à respecter
- Rust 2024 ;
- async-first ;
- tracing obligatoire ;
- pas de `?`, pas de `unwrap/expect` en production ;
- pas de `anyhow` / `thiserror` ;
- pas de `mod.rs` ;
- pas de `pub mod` : utiliser `mod` + `pub use` ;
- imports seulement pour les traits ;
- `#![deny(unreachable_pub)]`, `#![warn(missing_docs)]` ;
- tests offline ;
- pas de macro DB/coverage ;
- après modification DB : re-exports `kb_lib/src/db.rs` et `kb_lib/src/lib.rs` ;
- après modification decoder : vérifier `kb_lib/src/dex.rs`, `kb_lib/src/lib.rs`, coverage et tests synthétiques.
## 12. Format de livraison attendu
Livrer des deltas successifs :
```text
khadhroony-bobobot-v0.7.57-meteora_dlmm-delta-pre.xxx.zip
```
Chaque réponse doit indiquer : fichiers modifiés, raisons, tests à lancer, SQL à exécuter, résultat attendu, et risques éventuels.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_58_demo4_program_surface_discovery.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.58`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md
```

View File

@@ -0,0 +1,447 @@
<!-- file: docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md -->
# Prompt — 0.7.58 Binaire de fusion de bases SQLite transactionnelles + validation anti-régression inter-DEX
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.57-pre.015..023 -> nettoyage PumpSwap / guard PumpFees après régression cross-surface
```
Décision de planification mise à jour :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Le binaire de fusion passe avant `demo4`, car il devient un outil de non-régression indispensable pour les futurs décodeurs/materializers.
## Objectif principal
Créer un outil binaire de fusion de bases SQLite transactionnelles permettant de construire une base consolidée de corpus, par exemple `final.db`, à partir :
```text
final.db existante
+ base dédiée pump_swap.db
+ base dédiée pump_fun.db
+ base dédiée pump_fees.db
+ base dédiée raydium_*.db
+ base dédiée meteora_*.db
```
Le binaire doit fusionner les transactions/instructions déjà backfillées sans RPC, sans redécoder et sans matérialiser pendant le merge.
Ensuite, la base consolidée doit être rejouable localement avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
But : détecter les régressions inter-DEX comme celle observée où un décodage `pump_fees` tronqué interrompait la matérialisation `pump_swap.buy_exact_quote_in` dans la même transaction.
## Règle de workflow future
Pour chaque nouveau DEX ou nouvelle surface :
1. Créer une base vide dédiée au DEX en cours.
2. Backfiller uniquement les signatures/pools nécessaires pour ce DEX.
3. Développer le decoder/materializer sur cette base dédiée.
4. Clore avec les SQL propres du DEX.
5. Fusionner la base dédiée dans `final.db` ou dans une copie `final.next.db`.
6. Rejouer `final.next.db` avec `forceDexDecode=yes`.
7. Lancer les validations globales anti-régression sur Pump/Raydium/Meteora et sur les surfaces closes.
8. Promouvoir `final.next.db` en `final.db` seulement si les gates sont propres.
Commande conceptuelle :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/pump_swap.db --input ./corpus/pump_fees.db --mode raw-corpus --dry-run
```
Puis, après validation dry-run :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/new_dex.db --mode raw-corpus --replace-output
```
## Emplacement recommandé
Créer un package outil séparé :
```text
kb_tools/
Cargo.toml
src/bin/kb_db_merge.rs
```
Ajouter `kb_tools` dans le workspace principal.
Alternative acceptable si la structure workspace rend cela plus simple :
```text
kb_lib/src/bin/kb_db_merge.rs
```
Mais privilégier `kb_tools` pour éviter de mélanger outil CLI et librairie métier.
## Contraintes de code
Respecter les contraintes projet :
- Rust 2024 ;
- async-first si accès DB async ;
- tracing obligatoire ;
- pas de `?` dans le code applicatif ;
- pas de `unwrap` / `expect` hors tests ;
- pas de `anyhow` / `thiserror` ;
- pas de `mod.rs` ;
- pas de `pub mod`, utiliser `mod` + `pub use` ;
- imports directs seulement pour les traits ;
- tests offline ;
- types DB sous `kb_lib/src/db/entities/` et `kb_lib/src/db/dtos/`, pas sous `queries/` ;
- si des requêtes DB sont ajoutées/modifiées : mettre à jour les re-exports dans `kb_lib/src/db.rs` puis `kb_lib/src/lib.rs`.
## Modes CLI
Modes initiaux :
```text
raw-corpus
signatures-only
full-copy-safe
```
Le mode par défaut doit être :
```text
raw-corpus
```
### `raw-corpus`
Copier uniquement les données nécessaires à un replay local fiable :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
Ne pas copier les tables matérialisées par défaut :
```text
k_sol_dex_decoded_events
k_sol_trade_events
k_sol_liquidity_events
k_sol_pool_lifecycle_events
k_sol_pair_candles
k_sol_fee_events
k_sol_reward_events
k_sol_pool_admin_events
k_sol_orderbook_events
k_sol_token_account_events
k_sol_instruction_observations
k_sol_dex_event_coverage_entries
```
Raison : ces tables dépendent de la version de decoder/materializer et doivent être reconstruites par replay local.
### `signatures-only`
Créer une table de staging de signatures/slots/source, sans copier les transactions complètes. Ce mode est utile pour audit ou pour préparer des backfills contrôlés.
### `full-copy-safe`
Mode optionnel, non prioritaire.
Copier aussi des lignes décodées/matérialisées uniquement si :
- le schema version est compatible ;
- la version logique de decoder est identique ;
- toutes les foreign keys peuvent être remappées ;
- le mode est explicitement demandé.
Ne jamais en faire le mode par défaut.
## Options CLI minimales
```text
--output <path>
--input <path> répétable
--mode <raw-corpus|signatures-only|full-copy-safe>
--dry-run
--replace-output
--source-label <label> répétable ou inféré depuis le fichier
--limit <n> optionnel pour tests
--batch-size <n> optionnel
```
Options utiles pour `final.db` :
```text
--allow-existing-output
--merge-into-copy-of <path>
--conflict-policy <record|prefer-complete|fail>
```
Par défaut : ne pas écraser loutput existant sans `--replace-output` ou `--merge-into-copy-of`.
## Politique de déduplication
Identité canonique :
```text
signature
```
Règles :
- Une signature déjà présente dans loutput ne doit pas être dupliquée.
- Si `slot`, `err_json`, `transaction_json`, `meta_json` ou les instructions diffèrent, enregistrer un conflit.
- Ne pas écraser silencieusement.
- Si une version est plus complète, ne la préférer que si la politique `prefer-complete` est demandée et que le conflit est journalisé.
- Garder une provenance complète source -> output.
Tables suggérées :
```text
k_sol_db_merge_sources
k_sol_db_merge_transactions
k_sol_db_merge_conflicts
```
Champs source suggérés :
```text
source_id
source_path
source_label
source_schema_version
source_created_at
input_transaction_count
copied_transaction_count
skipped_duplicate_count
conflict_count
```
Champs transaction de merge suggérés :
```text
signature
slot
source_id
source_transaction_id
output_transaction_id
copy_status
conflict_status
copied_at
```
## Compatibilité de schéma
Le binaire doit inspecter chaque input via :
```sql
SELECT name, sql FROM sqlite_master WHERE type = 'table';
PRAGMA table_info(k_sol_chain_transactions);
PRAGMA table_info(k_sol_chain_instructions);
```
Pour `raw-corpus`, refuser proprement une DB qui ne contient pas :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
ou les colonnes nécessaires au replay local.
Le message derreur doit indiquer :
```text
source DB
missing table
missing column
mode demandé
```
## Stratégie de copie
Algorithme recommandé :
1. Créer ou initialiser loutput avec le schéma courant `kb_lib`.
2. Enregistrer chaque input dans `k_sol_db_merge_sources`.
3. Lire les transactions source par slot/signature.
4. Pour chaque transaction :
- si signature absente de loutput : insérer transaction + instructions enfants ;
- si signature présente : comparer les champs canoniques ;
- si identique : enregistrer duplicate skipped ;
- si différent : enregistrer conflit.
5. Remapper `source_transaction_id -> output_transaction_id` pour les instructions.
6. Commit par batch.
7. Imprimer un résumé final.
## Validation anti-régression intégrée à 0.7.58
Ajouter une documentation et, si possible, un script SQL :
```text
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
```
Checks merge minimaux :
```sql
-- duplicate signatures in output should be empty
SELECT signature, COUNT(*)
FROM k_sol_chain_transactions
GROUP BY signature
HAVING COUNT(*) > 1;
-- orphan instructions should be empty
SELECT ins.id
FROM k_sol_chain_instructions ins
LEFT JOIN k_sol_chain_transactions tx ON tx.id = ins.transaction_id
WHERE tx.id IS NULL;
-- conflicts summary
SELECT *
FROM k_sol_db_merge_conflicts
ORDER BY id DESC
LIMIT 100;
```
Checks anti-régression DEX après replay de `final.next.db` :
```sql
-- successful decoded events without any materialized target
SELECT
de.protocol_name,
de.event_kind,
json_extract(de.payload_json, '$.eventActionability') AS event_actionability,
json_extract(de.payload_json, '$.skipTradeReason') AS skip_trade_reason,
COUNT(*) AS missing_count,
MIN(tx.signature) AS sample_signature
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events lie ON lie.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events ple ON ple.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fee ON fee.decoded_event_id = de.id
LEFT JOIN k_sol_reward_events rew ON rew.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events adm ON adm.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events obe ON obe.decoded_event_id = de.id
LEFT JOIN k_sol_token_account_events tae ON tae.decoded_event_id = de.id
WHERE (tx.err_json IS NULL OR tx.err_json = '' OR tx.err_json = 'null')
AND te.id IS NULL
AND lie.id IS NULL
AND ple.id IS NULL
AND fee.id IS NULL
AND rew.id IS NULL
AND adm.id IS NULL
AND obe.id IS NULL
AND tae.id IS NULL
GROUP BY de.protocol_name, de.event_kind, event_actionability, skip_trade_reason
ORDER BY missing_count DESC, de.protocol_name, de.event_kind;
```
Cette requête ne doit pas forcément être vide, mais tout résidu doit être explicitement classé : failed-only, decoded-only justifié, non_actionable prouvé, ou nouveau bug.
## Vérification/correction Pump/Raydium incluse dans 0.7.58
La tranche `0.7.58` doit inclure un passage de non-régression sur les surfaces déjà closes, au minimum :
```text
pump_swap
pump_fun
pump_fees
raydium_cpmm
raydium_clmm
raydium_amm_v4
raydium_stable_swap
raydium_launchpad
meteora_dbc
meteora_dlmm
```
Objectif : détecter et corriger les régressions cross-surface, par exemple :
```text
un decoder A ne doit pas faire échouer la matérialisation dun decoder B dans la même transaction.
```
Règle de decoder :
- un payload tronqué/incompatible sur une surface secondaire ne doit pas aborter toute la transaction si lentrée peut être ignorée proprement ;
- préférer `Ok(None)` + observation/debug contrôlé pour les payloads tronqués connus ;
- conserver `Err` pour corruption critique, violation de schéma interne ou incohérence qui rend la transaction non fiable ;
- ajouter des tests synthétiques pour chaque guard.
## Tests attendus
Ajouter tests unitaires/offline pour :
1. merge dune DB vers output vide ;
2. merge de deux DBs disjointes ;
3. duplicate signature identique ;
4. duplicate signature conflictuelle ;
5. conflit instruction enfant ;
6. dry-run sans écriture ;
7. output existant refusé sans option explicite ;
8. source provenance enregistrée ;
9. replay final DB possible après merge raw-corpus ;
10. non-régression PumpSwap/PumpFees : payload PumpFees tronqué nempêche pas PumpSwap de matérialiser un trade exact.
## Livrables attendus
```text
kb_tools/Cargo.toml
kb_tools/src/bin/kb_db_merge.rs
kb_lib/src/db/entities/db_merge_source.rs
kb_lib/src/db/entities/db_merge_transaction.rs
kb_lib/src/db/entities/db_merge_conflict.rs
kb_lib/src/db/dtos/db_merge_*.rs
kb_lib/src/db/queries/db_merge_*.rs
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
docs/reports/SQLITE_DB_TRANSACTION_MERGER_0_7_58.md
```
Mettre à jour :
```text
Cargo.toml
kb_lib/src/db.rs
kb_lib/src/lib.rs
README.md
ROADMAP.md
CHANGELOG.md
```
## Critères de clôture 0.7.58
- `cargo test -p kb_lib` OK ;
- `cargo test -p kb_tools` OK si package séparé ;
- clippy `-D warnings` OK ;
- dry-run merge lisible ;
- merge réel de plusieurs bases OK ;
- pas de duplicate signatures ;
- pas dinstructions orphelines ;
- conflits journalisés ;
- replay local de `final.next.db` OK ;
- validation anti-régression Pump/Raydium/Meteora exécutée et documentée.
## Note finale
Le merger ne remplace pas `demo3` ni `demo4`.
Il sert à construire un corpus consolidé de non-régression à partir des bases dédiées. `demo4`, déplacé en `0.7.59`, servira ensuite à explorer les surfaces encore inconnues dans cette base consolidée.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_58_demo4_program_surface_discovery.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.58`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md
```

View File

@@ -0,0 +1,447 @@
<!-- file: docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md -->
# Prompt — 0.7.58 Binaire de fusion de bases SQLite transactionnelles + validation anti-régression inter-DEX
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.57-pre.015..023 -> nettoyage PumpSwap / guard PumpFees après régression cross-surface
```
Décision de planification mise à jour :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Le binaire de fusion passe avant `demo4`, car il devient un outil de non-régression indispensable pour les futurs décodeurs/materializers.
## Objectif principal
Créer un outil binaire de fusion de bases SQLite transactionnelles permettant de construire une base consolidée de corpus, par exemple `final.db`, à partir :
```text
final.db existante
+ base dédiée pump_swap.db
+ base dédiée pump_fun.db
+ base dédiée pump_fees.db
+ base dédiée raydium_*.db
+ base dédiée meteora_*.db
```
Le binaire doit fusionner les transactions/instructions déjà backfillées sans RPC, sans redécoder et sans matérialiser pendant le merge.
Ensuite, la base consolidée doit être rejouable localement avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
But : détecter les régressions inter-DEX comme celle observée où un décodage `pump_fees` tronqué interrompait la matérialisation `pump_swap.buy_exact_quote_in` dans la même transaction.
## Règle de workflow future
Pour chaque nouveau DEX ou nouvelle surface :
1. Créer une base vide dédiée au DEX en cours.
2. Backfiller uniquement les signatures/pools nécessaires pour ce DEX.
3. Développer le decoder/materializer sur cette base dédiée.
4. Clore avec les SQL propres du DEX.
5. Fusionner la base dédiée dans `final.db` ou dans une copie `final.next.db`.
6. Rejouer `final.next.db` avec `forceDexDecode=yes`.
7. Lancer les validations globales anti-régression sur Pump/Raydium/Meteora et sur les surfaces closes.
8. Promouvoir `final.next.db` en `final.db` seulement si les gates sont propres.
Commande conceptuelle :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/pump_swap.db --input ./corpus/pump_fees.db --mode raw-corpus --dry-run
```
Puis, après validation dry-run :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/new_dex.db --mode raw-corpus --replace-output
```
## Emplacement recommandé
Créer un package outil séparé :
```text
kb_tools/
Cargo.toml
src/bin/kb_db_merge.rs
```
Ajouter `kb_tools` dans le workspace principal.
Alternative acceptable si la structure workspace rend cela plus simple :
```text
kb_lib/src/bin/kb_db_merge.rs
```
Mais privilégier `kb_tools` pour éviter de mélanger outil CLI et librairie métier.
## Contraintes de code
Respecter les contraintes projet :
- Rust 2024 ;
- async-first si accès DB async ;
- tracing obligatoire ;
- pas de `?` dans le code applicatif ;
- pas de `unwrap` / `expect` hors tests ;
- pas de `anyhow` / `thiserror` ;
- pas de `mod.rs` ;
- pas de `pub mod`, utiliser `mod` + `pub use` ;
- imports directs seulement pour les traits ;
- tests offline ;
- types DB sous `kb_lib/src/db/entities/` et `kb_lib/src/db/dtos/`, pas sous `queries/` ;
- si des requêtes DB sont ajoutées/modifiées : mettre à jour les re-exports dans `kb_lib/src/db.rs` puis `kb_lib/src/lib.rs`.
## Modes CLI
Modes initiaux :
```text
raw-corpus
signatures-only
full-copy-safe
```
Le mode par défaut doit être :
```text
raw-corpus
```
### `raw-corpus`
Copier uniquement les données nécessaires à un replay local fiable :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
Ne pas copier les tables matérialisées par défaut :
```text
k_sol_dex_decoded_events
k_sol_trade_events
k_sol_liquidity_events
k_sol_pool_lifecycle_events
k_sol_pair_candles
k_sol_fee_events
k_sol_reward_events
k_sol_pool_admin_events
k_sol_orderbook_events
k_sol_token_account_events
k_sol_instruction_observations
k_sol_dex_event_coverage_entries
```
Raison : ces tables dépendent de la version de decoder/materializer et doivent être reconstruites par replay local.
### `signatures-only`
Créer une table de staging de signatures/slots/source, sans copier les transactions complètes. Ce mode est utile pour audit ou pour préparer des backfills contrôlés.
### `full-copy-safe`
Mode optionnel, non prioritaire.
Copier aussi des lignes décodées/matérialisées uniquement si :
- le schema version est compatible ;
- la version logique de decoder est identique ;
- toutes les foreign keys peuvent être remappées ;
- le mode est explicitement demandé.
Ne jamais en faire le mode par défaut.
## Options CLI minimales
```text
--output <path>
--input <path> répétable
--mode <raw-corpus|signatures-only|full-copy-safe>
--dry-run
--replace-output
--source-label <label> répétable ou inféré depuis le fichier
--limit <n> optionnel pour tests
--batch-size <n> optionnel
```
Options utiles pour `final.db` :
```text
--allow-existing-output
--merge-into-copy-of <path>
--conflict-policy <record|prefer-complete|fail>
```
Par défaut : ne pas écraser loutput existant sans `--replace-output` ou `--merge-into-copy-of`.
## Politique de déduplication
Identité canonique :
```text
signature
```
Règles :
- Une signature déjà présente dans loutput ne doit pas être dupliquée.
- Si `slot`, `err_json`, `transaction_json`, `meta_json` ou les instructions diffèrent, enregistrer un conflit.
- Ne pas écraser silencieusement.
- Si une version est plus complète, ne la préférer que si la politique `prefer-complete` est demandée et que le conflit est journalisé.
- Garder une provenance complète source -> output.
Tables suggérées :
```text
k_sol_db_merge_sources
k_sol_db_merge_transactions
k_sol_db_merge_conflicts
```
Champs source suggérés :
```text
source_id
source_path
source_label
source_schema_version
source_created_at
input_transaction_count
copied_transaction_count
skipped_duplicate_count
conflict_count
```
Champs transaction de merge suggérés :
```text
signature
slot
source_id
source_transaction_id
output_transaction_id
copy_status
conflict_status
copied_at
```
## Compatibilité de schéma
Le binaire doit inspecter chaque input via :
```sql
SELECT name, sql FROM sqlite_master WHERE type = 'table';
PRAGMA table_info(k_sol_chain_transactions);
PRAGMA table_info(k_sol_chain_instructions);
```
Pour `raw-corpus`, refuser proprement une DB qui ne contient pas :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
ou les colonnes nécessaires au replay local.
Le message derreur doit indiquer :
```text
source DB
missing table
missing column
mode demandé
```
## Stratégie de copie
Algorithme recommandé :
1. Créer ou initialiser loutput avec le schéma courant `kb_lib`.
2. Enregistrer chaque input dans `k_sol_db_merge_sources`.
3. Lire les transactions source par slot/signature.
4. Pour chaque transaction :
- si signature absente de loutput : insérer transaction + instructions enfants ;
- si signature présente : comparer les champs canoniques ;
- si identique : enregistrer duplicate skipped ;
- si différent : enregistrer conflit.
5. Remapper `source_transaction_id -> output_transaction_id` pour les instructions.
6. Commit par batch.
7. Imprimer un résumé final.
## Validation anti-régression intégrée à 0.7.58
Ajouter une documentation et, si possible, un script SQL :
```text
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
```
Checks merge minimaux :
```sql
-- duplicate signatures in output should be empty
SELECT signature, COUNT(*)
FROM k_sol_chain_transactions
GROUP BY signature
HAVING COUNT(*) > 1;
-- orphan instructions should be empty
SELECT ins.id
FROM k_sol_chain_instructions ins
LEFT JOIN k_sol_chain_transactions tx ON tx.id = ins.transaction_id
WHERE tx.id IS NULL;
-- conflicts summary
SELECT *
FROM k_sol_db_merge_conflicts
ORDER BY id DESC
LIMIT 100;
```
Checks anti-régression DEX après replay de `final.next.db` :
```sql
-- successful decoded events without any materialized target
SELECT
de.protocol_name,
de.event_kind,
json_extract(de.payload_json, '$.eventActionability') AS event_actionability,
json_extract(de.payload_json, '$.skipTradeReason') AS skip_trade_reason,
COUNT(*) AS missing_count,
MIN(tx.signature) AS sample_signature
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events lie ON lie.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events ple ON ple.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fee ON fee.decoded_event_id = de.id
LEFT JOIN k_sol_reward_events rew ON rew.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events adm ON adm.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events obe ON obe.decoded_event_id = de.id
LEFT JOIN k_sol_token_account_events tae ON tae.decoded_event_id = de.id
WHERE (tx.err_json IS NULL OR tx.err_json = '' OR tx.err_json = 'null')
AND te.id IS NULL
AND lie.id IS NULL
AND ple.id IS NULL
AND fee.id IS NULL
AND rew.id IS NULL
AND adm.id IS NULL
AND obe.id IS NULL
AND tae.id IS NULL
GROUP BY de.protocol_name, de.event_kind, event_actionability, skip_trade_reason
ORDER BY missing_count DESC, de.protocol_name, de.event_kind;
```
Cette requête ne doit pas forcément être vide, mais tout résidu doit être explicitement classé : failed-only, decoded-only justifié, non_actionable prouvé, ou nouveau bug.
## Vérification/correction Pump/Raydium incluse dans 0.7.58
La tranche `0.7.58` doit inclure un passage de non-régression sur les surfaces déjà closes, au minimum :
```text
pump_swap
pump_fun
pump_fees
raydium_cpmm
raydium_clmm
raydium_amm_v4
raydium_stable_swap
raydium_launchpad
meteora_dbc
meteora_dlmm
```
Objectif : détecter et corriger les régressions cross-surface, par exemple :
```text
un decoder A ne doit pas faire échouer la matérialisation dun decoder B dans la même transaction.
```
Règle de decoder :
- un payload tronqué/incompatible sur une surface secondaire ne doit pas aborter toute la transaction si lentrée peut être ignorée proprement ;
- préférer `Ok(None)` + observation/debug contrôlé pour les payloads tronqués connus ;
- conserver `Err` pour corruption critique, violation de schéma interne ou incohérence qui rend la transaction non fiable ;
- ajouter des tests synthétiques pour chaque guard.
## Tests attendus
Ajouter tests unitaires/offline pour :
1. merge dune DB vers output vide ;
2. merge de deux DBs disjointes ;
3. duplicate signature identique ;
4. duplicate signature conflictuelle ;
5. conflit instruction enfant ;
6. dry-run sans écriture ;
7. output existant refusé sans option explicite ;
8. source provenance enregistrée ;
9. replay final DB possible après merge raw-corpus ;
10. non-régression PumpSwap/PumpFees : payload PumpFees tronqué nempêche pas PumpSwap de matérialiser un trade exact.
## Livrables attendus
```text
kb_tools/Cargo.toml
kb_tools/src/bin/kb_db_merge.rs
kb_lib/src/db/entities/db_merge_source.rs
kb_lib/src/db/entities/db_merge_transaction.rs
kb_lib/src/db/entities/db_merge_conflict.rs
kb_lib/src/db/dtos/db_merge_*.rs
kb_lib/src/db/queries/db_merge_*.rs
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
docs/reports/SQLITE_DB_TRANSACTION_MERGER_0_7_58.md
```
Mettre à jour :
```text
Cargo.toml
kb_lib/src/db.rs
kb_lib/src/lib.rs
README.md
ROADMAP.md
CHANGELOG.md
```
## Critères de clôture 0.7.58
- `cargo test -p kb_lib` OK ;
- `cargo test -p kb_tools` OK si package séparé ;
- clippy `-D warnings` OK ;
- dry-run merge lisible ;
- merge réel de plusieurs bases OK ;
- pas de duplicate signatures ;
- pas dinstructions orphelines ;
- conflits journalisés ;
- replay local de `final.next.db` OK ;
- validation anti-régression Pump/Raydium/Meteora exécutée et documentée.
## Note finale
Le merger ne remplace pas `demo3` ni `demo4`.
Il sert à construire un corpus consolidé de non-régression à partir des bases dédiées. `demo4`, déplacé en `0.7.59`, servira ensuite à explorer les surfaces encore inconnues dans cette base consolidée.

View File

@@ -0,0 +1,330 @@
<!-- file: docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md -->
# Prompt — 0.7.59 Demo4 Program Surface Discovery
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
```
Décision de planification : `demo4_program_surface_discovery` est déplacé de `0.7.58` vers `0.7.59` afin de permettre dabord la création dune base consolidée `final.db`.
Cette base consolidée doit permettre à Demo4 dexplorer :
```text
program_id inconnus
program_id connus avec discriminants non mappés
Anchor logs Instruction non mappés
Program data events non mappés
upstream fallbacks
layouts répétitifs daccounts/data
success/failed split
```
## Objectif principal
Ajouter une fenêtre `Demo4` dans `kb_demo_app` et les requêtes `kb_lib` associées pour afficher les surfaces non prises en compte sans les promouvoir automatiquement.
Demo4 est un outil dobservation, de tri et de préparation de futures tranches de decoder. Il ne doit pas créer de trade, candle, pool, pair, fee, reward, admin ou lifecycle métier.
## Règles strictes
Demo4 doit être read-only par défaut.
Interdictions :
- ne pas matérialiser automatiquement ;
- ne pas ajouter automatiquement de coverage comme supportée ;
- ne pas marquer automatiquement un `program_id` comme connu ;
- ne pas générer de decoder métier ;
- ne pas promouvoir un upstream fallback vers un decoder local sans intervention humaine ;
- ne pas masquer les failed transactions ;
- ne pas supprimer les observations existantes.
Actions autorisées :
- lister ;
- grouper ;
- scorer ;
- exporter Markdown/CSV/JSON ;
- marquer manuellement un candidat comme `reviewed`, `ignored`, `accepted_for_future_decoder`, si table de statut ajoutée ;
- ouvrir une signature dans Demo Pipeline 2 ou Demo3.
## Sources de données prioritaires
Demo4 doit exploiter la base consolidée construite par `0.7.58`, par exemple :
```text
final.db
final.next.db
```
Cette base est issue de merges raw-corpus de bases dédiées :
```text
pump_swap.db
pump_fun.db
pump_fees.db
raydium_*.db
meteora_*.db
```
Le bénéfice attendu : détecter les surfaces inconnues et les régressions qui napparaissent pas dans une base DEX isolée.
## Surfaces à afficher
### 1. Program IDs non routés
Afficher les `program_id` présents dans `k_sol_chain_instructions` qui ne correspondent pas à une surface supportée ou connue.
Colonnes utiles :
```text
program_id
instruction_count
tx_count
success_count
failed_count
first_slot
last_slot
sample_signature
sample_data_prefix
sample_account_count
```
### 2. Discriminators non mappés sur program id connu
Pour un `program_id` déjà supporté, afficher les discriminants inconnus ou encore en `instruction_audit`.
Colonnes utiles :
```text
protocol_guess
program_id
discriminator_hex
data_prefix
instruction_count
tx_count
success_count
failed_count
sample_signature
known_anchor_log_name si disponible
upstream_match_status si disponible
```
### 3. Anchor logs `Instruction: ...`
Extraire depuis `meta_json.logMessages` :
```text
Program log: Instruction: <Name>
```
Normaliser le nom :
```text
InitializePresetParameterV2 -> initialize_preset_parameter_v2
```
Calculer si possible :
```text
sha256("global:<snake_case_name>")[0..8]
```
Comparer au discriminator observé.
### 4. Program data / Anchor events non mappés
Lister les `Program data:` ou events Anchor observés mais non classés localement.
Colonnes utiles :
```text
program_id
anchor_event_discriminator_hex
payload_size
tx_count
success_count
failed_count
sample_signature
possible_event_name
upstream_match_status
```
### 5. Upstream fallbacks
Afficher les événements qui viennent encore de :
```text
upstream_git.instruction_match
upstream_git.event_match
instruction_audit
```
Demo4 doit aider à décider si lentrée doit devenir :
```text
local decoder
coverage 0/0 conservée
decoded-only justifié
materialized admin/lifecycle/fee/reward/liquidity/orderbook
ignored
```
## UI attendue
Fichiers probables :
```text
kb_demo_app/src/demo4.html
kb_demo_app/src/demo4.ts
kb_demo_app/src/main.ts
kb_demo_app/src/shared/api.ts
kb_demo_app/src/shared/types.ts
```
Ajouter une fenêtre Tauri si nécessaire dans :
```text
kb_demo_app/src-tauri/src/main.rs
kb_demo_app/tauri.conf.json
```
Organisation UI suggérée :
```text
Filters:
- program_id
- protocol_guess
- success/failed/all
- minimum tx_count
- known/unknown program
- audit/upstream/unknown discriminator
- date/slot range si disponible
Tabs:
1. Unknown programs
2. Known program unknown discriminators
3. Anchor instruction logs
4. Program data events
5. Upstream fallbacks
6. Regression suspects
```
## API / services kb_lib suggérés
Créer des DTOs sous :
```text
kb_lib/src/db/dtos/program_surface_candidate_summary.rs
kb_lib/src/db/dtos/program_surface_candidate_sample.rs
```
Créer des requêtes sous :
```text
kb_lib/src/db/queries/program_surface_discovery.rs
```
Créer éventuellement une façade :
```text
kb_lib/src/program_surface_discovery.rs
```
Rappel : si des requêtes DB sont ajoutées, mettre à jour les re-exports dans :
```text
kb_lib/src/db.rs
kb_lib/src/lib.rs
```
## Table de statut optionnelle
Si utile, ajouter :
```text
k_sol_program_surface_candidates
```
Statuts possibles :
```text
new
reviewed
accepted_for_future_decoder
ignored
promoted_manually
rejected
```
Ne jamais passer automatiquement à `promoted_manually`.
## Intégration avec 0.7.58
Demo4 doit intégrer explicitement la notion de source DB/merge si les tables `k_sol_db_merge_*` existent.
Exemples daffichages utiles :
```text
candidate observed in sources: pump_swap.db, pump_fees.db
candidate observed only after final.db merge
candidate correlated with replay decode failure
candidate appears in transaction with multiple DEX protocols
```
Objectif : rendre visibles les régressions cross-surface comme le cas PumpSwap/PumpFees.
## SQL de validation Demo4
Ajouter :
```text
validation_sql/SQL_VALIDATION_DEMO4_PROGRAM_SURFACE_DISCOVERY_0_7_59.sql
```
Checks :
```sql
-- Demo4 queries should not create decoded/materialized rows
SELECT COUNT(*) FROM k_sol_dex_decoded_events;
SELECT COUNT(*) FROM k_sol_trade_events;
-- candidate status table should not auto-promote anything
SELECT status, COUNT(*)
FROM k_sol_program_surface_candidates
GROUP BY status;
```
Adapter selon schéma réel.
## Tests attendus
- requêtes unknown program sur fixture minimale ;
- discriminants inconnus sur program connu ;
- extraction Anchor `Instruction: Name` ;
- hash Anchor discriminator ;
- split success/failed ;
- no write en mode read-only ;
- export Markdown/CSV stable ;
- table statut manuelle si implémentée.
## Critères de clôture 0.7.59
- `cargo test -p kb_lib` OK ;
- `cargo test` UI/Tauri si existant OK ;
- clippy `-D warnings` OK ;
- Demo4 affiche les surfaces inconnues depuis `final.db` ;
- aucun auto-decode métier ;
- aucune auto-materialization ;
- export exploitable pour préparer `0.7.60 meteora_damm_v1` ou une tranche future ;
- README/ROADMAP/CHANGELOG mis à jour.
## Note finale
Demo4 ne remplace pas les prompts DEX. Il prépare les prochaines tranches en rendant les surfaces observées lisibles, priorisées et reproductibles.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_59_sqlite_db_transaction_merger_binary.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.59`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md
```

View File

@@ -0,0 +1,330 @@
<!-- file: docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md -->
# Prompt — 0.7.59 Demo4 Program Surface Discovery
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
```
Décision de planification : `demo4_program_surface_discovery` est déplacé de `0.7.58` vers `0.7.59` afin de permettre dabord la création dune base consolidée `final.db`.
Cette base consolidée doit permettre à Demo4 dexplorer :
```text
program_id inconnus
program_id connus avec discriminants non mappés
Anchor logs Instruction non mappés
Program data events non mappés
upstream fallbacks
layouts répétitifs daccounts/data
success/failed split
```
## Objectif principal
Ajouter une fenêtre `Demo4` dans `kb_demo_app` et les requêtes `kb_lib` associées pour afficher les surfaces non prises en compte sans les promouvoir automatiquement.
Demo4 est un outil dobservation, de tri et de préparation de futures tranches de decoder. Il ne doit pas créer de trade, candle, pool, pair, fee, reward, admin ou lifecycle métier.
## Règles strictes
Demo4 doit être read-only par défaut.
Interdictions :
- ne pas matérialiser automatiquement ;
- ne pas ajouter automatiquement de coverage comme supportée ;
- ne pas marquer automatiquement un `program_id` comme connu ;
- ne pas générer de decoder métier ;
- ne pas promouvoir un upstream fallback vers un decoder local sans intervention humaine ;
- ne pas masquer les failed transactions ;
- ne pas supprimer les observations existantes.
Actions autorisées :
- lister ;
- grouper ;
- scorer ;
- exporter Markdown/CSV/JSON ;
- marquer manuellement un candidat comme `reviewed`, `ignored`, `accepted_for_future_decoder`, si table de statut ajoutée ;
- ouvrir une signature dans Demo Pipeline 2 ou Demo3.
## Sources de données prioritaires
Demo4 doit exploiter la base consolidée construite par `0.7.58`, par exemple :
```text
final.db
final.next.db
```
Cette base est issue de merges raw-corpus de bases dédiées :
```text
pump_swap.db
pump_fun.db
pump_fees.db
raydium_*.db
meteora_*.db
```
Le bénéfice attendu : détecter les surfaces inconnues et les régressions qui napparaissent pas dans une base DEX isolée.
## Surfaces à afficher
### 1. Program IDs non routés
Afficher les `program_id` présents dans `k_sol_chain_instructions` qui ne correspondent pas à une surface supportée ou connue.
Colonnes utiles :
```text
program_id
instruction_count
tx_count
success_count
failed_count
first_slot
last_slot
sample_signature
sample_data_prefix
sample_account_count
```
### 2. Discriminators non mappés sur program id connu
Pour un `program_id` déjà supporté, afficher les discriminants inconnus ou encore en `instruction_audit`.
Colonnes utiles :
```text
protocol_guess
program_id
discriminator_hex
data_prefix
instruction_count
tx_count
success_count
failed_count
sample_signature
known_anchor_log_name si disponible
upstream_match_status si disponible
```
### 3. Anchor logs `Instruction: ...`
Extraire depuis `meta_json.logMessages` :
```text
Program log: Instruction: <Name>
```
Normaliser le nom :
```text
InitializePresetParameterV2 -> initialize_preset_parameter_v2
```
Calculer si possible :
```text
sha256("global:<snake_case_name>")[0..8]
```
Comparer au discriminator observé.
### 4. Program data / Anchor events non mappés
Lister les `Program data:` ou events Anchor observés mais non classés localement.
Colonnes utiles :
```text
program_id
anchor_event_discriminator_hex
payload_size
tx_count
success_count
failed_count
sample_signature
possible_event_name
upstream_match_status
```
### 5. Upstream fallbacks
Afficher les événements qui viennent encore de :
```text
upstream_git.instruction_match
upstream_git.event_match
instruction_audit
```
Demo4 doit aider à décider si lentrée doit devenir :
```text
local decoder
coverage 0/0 conservée
decoded-only justifié
materialized admin/lifecycle/fee/reward/liquidity/orderbook
ignored
```
## UI attendue
Fichiers probables :
```text
kb_demo_app/src/demo4.html
kb_demo_app/src/demo4.ts
kb_demo_app/src/main.ts
kb_demo_app/src/shared/api.ts
kb_demo_app/src/shared/types.ts
```
Ajouter une fenêtre Tauri si nécessaire dans :
```text
kb_demo_app/src-tauri/src/main.rs
kb_demo_app/tauri.conf.json
```
Organisation UI suggérée :
```text
Filters:
- program_id
- protocol_guess
- success/failed/all
- minimum tx_count
- known/unknown program
- audit/upstream/unknown discriminator
- date/slot range si disponible
Tabs:
1. Unknown programs
2. Known program unknown discriminators
3. Anchor instruction logs
4. Program data events
5. Upstream fallbacks
6. Regression suspects
```
## API / services kb_lib suggérés
Créer des DTOs sous :
```text
kb_lib/src/db/dtos/program_surface_candidate_summary.rs
kb_lib/src/db/dtos/program_surface_candidate_sample.rs
```
Créer des requêtes sous :
```text
kb_lib/src/db/queries/program_surface_discovery.rs
```
Créer éventuellement une façade :
```text
kb_lib/src/program_surface_discovery.rs
```
Rappel : si des requêtes DB sont ajoutées, mettre à jour les re-exports dans :
```text
kb_lib/src/db.rs
kb_lib/src/lib.rs
```
## Table de statut optionnelle
Si utile, ajouter :
```text
k_sol_program_surface_candidates
```
Statuts possibles :
```text
new
reviewed
accepted_for_future_decoder
ignored
promoted_manually
rejected
```
Ne jamais passer automatiquement à `promoted_manually`.
## Intégration avec 0.7.58
Demo4 doit intégrer explicitement la notion de source DB/merge si les tables `k_sol_db_merge_*` existent.
Exemples daffichages utiles :
```text
candidate observed in sources: pump_swap.db, pump_fees.db
candidate observed only after final.db merge
candidate correlated with replay decode failure
candidate appears in transaction with multiple DEX protocols
```
Objectif : rendre visibles les régressions cross-surface comme le cas PumpSwap/PumpFees.
## SQL de validation Demo4
Ajouter :
```text
validation_sql/SQL_VALIDATION_DEMO4_PROGRAM_SURFACE_DISCOVERY_0_7_59.sql
```
Checks :
```sql
-- Demo4 queries should not create decoded/materialized rows
SELECT COUNT(*) FROM k_sol_dex_decoded_events;
SELECT COUNT(*) FROM k_sol_trade_events;
-- candidate status table should not auto-promote anything
SELECT status, COUNT(*)
FROM k_sol_program_surface_candidates
GROUP BY status;
```
Adapter selon schéma réel.
## Tests attendus
- requêtes unknown program sur fixture minimale ;
- discriminants inconnus sur program connu ;
- extraction Anchor `Instruction: Name` ;
- hash Anchor discriminator ;
- split success/failed ;
- no write en mode read-only ;
- export Markdown/CSV stable ;
- table statut manuelle si implémentée.
## Critères de clôture 0.7.59
- `cargo test -p kb_lib` OK ;
- `cargo test` UI/Tauri si existant OK ;
- clippy `-D warnings` OK ;
- Demo4 affiche les surfaces inconnues depuis `final.db` ;
- aucun auto-decode métier ;
- aucune auto-materialization ;
- export exploitable pour préparer `0.7.60 meteora_damm_v1` ou une tranche future ;
- README/ROADMAP/CHANGELOG mis à jour.
## Note finale
Demo4 ne remplace pas les prompts DEX. Il prépare les prochaines tranches en rendant les surfaces observées lisibles, priorisées et reproductibles.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_59_sqlite_db_transaction_merger_binary.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.59`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md
```

View File

@@ -0,0 +1,232 @@
<!-- file: docs/prompts/PROMPT_0_7_60_meteora_damm_next_dex.md -->
# Prompt — 0.7.60 Meteora DAMM v1 puis DAMM v2
## Décision
Ne pas fusionner Meteora DAMM v1 et Meteora DAMM v2 dans une seule tranche dimplémentation.
Utiliser des versions séparées :
```text
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Raison :
- `program_id` différents ;
- surfaces IDL/discriminators différentes ;
- corpus historiques et besoins de validation différents ;
- clôture SQL plus lisible ;
- risque réduit de faux positifs cross-version ;
- rollback plus simple si une version contient une hypothèse incorrecte.
Partage autorisé :
- helpers communs privés ;
- patterns communs de récupération fee/reward amounts ;
- conventions communes de coverage/tests ;
- structure commune de rapport ;
- template SQL commun.
Ne pas partager la classification de decoder dune manière qui masque les discriminators version-spécifiques ou les layouts propres à chaque programme.
## Contexte
`0.7.57 meteora_dlmm` est clos.
Les tranches intermédiaires planifiées avant DAMM sont maintenant :
```text
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
0.7.59 -> demo4_program_surface_discovery
```
Raison du changement : la régression PumpSwap/PumpFees a montré quune base DEX isolée ne suffit pas. Les futurs décodeurs doivent être validés à la fois sur une base dédiée et sur une base consolidée `final.db` issue du merger.
Surfaces Meteora connues :
```text
meteora_dbc -> clos 0.7.56
meteora_dlmm -> clos 0.7.57
meteora_damm_v1 -> 0.7.60
meteora_damm_v2 -> 0.7.61
meteora_vault -> plus tard, surface séparée
```
## Workflow obligatoire pour 0.7.60+
Pour chaque nouvelle tranche DEX :
1. Créer une base vide dédiée au DEX.
2. Backfiller le corpus DAMM v1 dans cette base dédiée.
3. Développer decoder/materializer sur cette base.
4. Clore les gates SQL DAMM v1 localement.
5. Fusionner la base dédiée dans une copie de `final.db` via le merger `0.7.58`.
6. Rejouer la base fusionnée avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
7. Lancer les validations globales anti-régression Pump/Raydium/Meteora.
8. Ne considérer la tranche close que si la base dédiée et la base fusionnée sont propres.
## Cible 0.7.60 — meteora_damm_v1
Program id depuis la roadmap :
```text
Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
```
Objectif principal :
```text
Full decode + full materialization pour toutes les instructions/events DAMM v1 disponibles depuis les IDL locales et les sources upstream.
```
Familles attendues :
```text
swap
pool_create
add_liquidity
remove_liquidity
lock/unlock liquidity si présent
fee/admin/config
lifecycle/migration si présent
```
Règles :
- Pas de decoded-only pour une entrée utile observée si elle peut être matérialisée sûrement.
- Ne pas créer de trade/candle depuis des non-swaps.
- Ne pas matérialiser les transactions failed.
- Ne pas agréger artificiellement les fees multi-mint.
- Utiliser `k_sol_fee_event_amounts` pour les legs fee fiables.
- Utiliser la récupération inner SPL transfer seulement avec allowlist explicite et tests.
- Conserver toutes les entrées IDL/upstream non observées dans la coverage avec `0/0` et proof status clair.
- Un decoder ne doit pas aborter toute une transaction multi-protocoles pour un payload secondaire tronqué/incompatible si lentrée peut être ignorée proprement.
## Sources à vérifier
Inspecter dabord le répertoire local :
```text
idls/
```
Puis comparer avec :
```text
Carbon decoders
Pinax/substreams-solana-idls
0xfnzero sol-parser-sdk / solana-streamer
ancien code local et rapports historiques du projet
samples Solscan / backfills Demo3
surfaces visibles dans Demo4 si 0.7.59 est disponible
```
Ne pas considérer les anciens résultats `0.7.36` ou `0.7.46` comme clôture finale. Revalider depuis le schéma courant et les règles actuelles de matérialisation.
## Plan de travail
1. Créer ou rafraîchir les entrées coverage `meteora_damm_v1`.
2. Vérifier le `program_id` et la surface IDL locale.
3. Étendre lenum/local classifier des discriminators.
4. Ajouter le naming dans `instruction_observation_index`.
5. Décoder toutes les instructions et tous les events Anchor disponibles.
6. Matérialiser swaps, liquidity, lifecycle, fee, reward/admin/orderbook si applicable.
7. Ajouter des tests synthétiques pour chaque instruction/event IDL, y compris non observé.
8. Ajouter le SQL de validation DAMM v1.
9. Rejouer sur base fraîche dédiée avec `forceDexDecode=yes`.
10. Fusionner la base dédiée vers `final.next.db` via `kb_db_merge`.
11. Rejouer `final.next.db`.
12. Lancer les gates cross-DEX.
13. Clore seulement si les gates locales et globales sont propres.
## Gates SQL obligatoires
Reprendre le pattern DLMM :
```text
fallback upstream pour entrées localement couvertes -> vide
instruction_name null/blank -> vide
decoded sans coverage -> vide
successful non-materialized without skip/policy -> vide
failed tx materialization -> vide
multi-target materialization -> vide
non-swap trade/candle -> vide
fee scalar parent without leg -> vide
orphan fee legs -> vide
coverage logical duplicates -> vide
watchlist sans backlog meteora_damm_v1
```
Ajouter les gates anti-régression globales après merge :
```text
successful non-materialized Pump/Raydium/Meteora expliqué ou vide
pure instruction_audit inattendu -> vide
decoder errors cross-surface -> vide
failed tx materialized -> vide
trade/candle non-swap -> vide
```
## Cible 0.7.61 — meteora_damm_v2
Program id depuis la roadmap :
```text
cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
```
Nouvrir cette tranche quaprès clôture DAMM v1.
La tranche v2 peut réutiliser le template et des helpers privés, mais doit conserver ses propres éléments :
```text
decoder code
coverage entries
instruction enum
event mapping
synthetic tests
SQL validation
rapport
base dédiée
validation final.db merge
```
## Livrables attendus pour 0.7.60
Fichiers probables :
```text
kb_lib/src/dex/meteora_damm_v1.rs
kb_lib/src/dex_event_coverage.rs
kb_lib/src/dex_event_classification.rs
kb_lib/src/instruction_observation_index.rs
kb_lib/src/non_trade_event_materialization.rs
validation_sql/SQL_VALIDATION_METEORA_DAMM_V1_0_7_60.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_AFTER_DAMM_V1_0_7_60.sql
docs/reports/METEORA_DAMM_V1_EVENT_COVERAGE_REPORT.md
```
Mettre à jour les re-exports si des modules ou requêtes sont ajoutés :
```text
kb_lib/src/dex.rs
kb_lib/src/lib.rs
kb_lib/src/db.rs
```
## Note finale
Si la découverte corpus montre que DAMM v1 et v2 partagent une logique basse-niveau précise, créer des helpers privés communs.
Ne pas fusionner les deux protocoles dans un seul decoder, une seule coverage ou un seul rapport de clôture.

View File

@@ -0,0 +1,232 @@
<!-- file: docs/prompts/PROMPT_0_7_60_meteora_damm_next_dex.md -->
# Prompt — 0.7.60 Meteora DAMM v1 puis DAMM v2
## Décision
Ne pas fusionner Meteora DAMM v1 et Meteora DAMM v2 dans une seule tranche dimplémentation.
Utiliser des versions séparées :
```text
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Raison :
- `program_id` différents ;
- surfaces IDL/discriminators différentes ;
- corpus historiques et besoins de validation différents ;
- clôture SQL plus lisible ;
- risque réduit de faux positifs cross-version ;
- rollback plus simple si une version contient une hypothèse incorrecte.
Partage autorisé :
- helpers communs privés ;
- patterns communs de récupération fee/reward amounts ;
- conventions communes de coverage/tests ;
- structure commune de rapport ;
- template SQL commun.
Ne pas partager la classification de decoder dune manière qui masque les discriminators version-spécifiques ou les layouts propres à chaque programme.
## Contexte
`0.7.57 meteora_dlmm` est clos.
Les tranches intermédiaires planifiées avant DAMM sont maintenant :
```text
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
0.7.59 -> demo4_program_surface_discovery
```
Raison du changement : la régression PumpSwap/PumpFees a montré quune base DEX isolée ne suffit pas. Les futurs décodeurs doivent être validés à la fois sur une base dédiée et sur une base consolidée `final.db` issue du merger.
Surfaces Meteora connues :
```text
meteora_dbc -> clos 0.7.56
meteora_dlmm -> clos 0.7.57
meteora_damm_v1 -> 0.7.60
meteora_damm_v2 -> 0.7.61
meteora_vault -> plus tard, surface séparée
```
## Workflow obligatoire pour 0.7.60+
Pour chaque nouvelle tranche DEX :
1. Créer une base vide dédiée au DEX.
2. Backfiller le corpus DAMM v1 dans cette base dédiée.
3. Développer decoder/materializer sur cette base.
4. Clore les gates SQL DAMM v1 localement.
5. Fusionner la base dédiée dans une copie de `final.db` via le merger `0.7.58`.
6. Rejouer la base fusionnée avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
7. Lancer les validations globales anti-régression Pump/Raydium/Meteora.
8. Ne considérer la tranche close que si la base dédiée et la base fusionnée sont propres.
## Cible 0.7.60 — meteora_damm_v1
Program id depuis la roadmap :
```text
Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
```
Objectif principal :
```text
Full decode + full materialization pour toutes les instructions/events DAMM v1 disponibles depuis les IDL locales et les sources upstream.
```
Familles attendues :
```text
swap
pool_create
add_liquidity
remove_liquidity
lock/unlock liquidity si présent
fee/admin/config
lifecycle/migration si présent
```
Règles :
- Pas de decoded-only pour une entrée utile observée si elle peut être matérialisée sûrement.
- Ne pas créer de trade/candle depuis des non-swaps.
- Ne pas matérialiser les transactions failed.
- Ne pas agréger artificiellement les fees multi-mint.
- Utiliser `k_sol_fee_event_amounts` pour les legs fee fiables.
- Utiliser la récupération inner SPL transfer seulement avec allowlist explicite et tests.
- Conserver toutes les entrées IDL/upstream non observées dans la coverage avec `0/0` et proof status clair.
- Un decoder ne doit pas aborter toute une transaction multi-protocoles pour un payload secondaire tronqué/incompatible si lentrée peut être ignorée proprement.
## Sources à vérifier
Inspecter dabord le répertoire local :
```text
idls/
```
Puis comparer avec :
```text
Carbon decoders
Pinax/substreams-solana-idls
0xfnzero sol-parser-sdk / solana-streamer
ancien code local et rapports historiques du projet
samples Solscan / backfills Demo3
surfaces visibles dans Demo4 si 0.7.59 est disponible
```
Ne pas considérer les anciens résultats `0.7.36` ou `0.7.46` comme clôture finale. Revalider depuis le schéma courant et les règles actuelles de matérialisation.
## Plan de travail
1. Créer ou rafraîchir les entrées coverage `meteora_damm_v1`.
2. Vérifier le `program_id` et la surface IDL locale.
3. Étendre lenum/local classifier des discriminators.
4. Ajouter le naming dans `instruction_observation_index`.
5. Décoder toutes les instructions et tous les events Anchor disponibles.
6. Matérialiser swaps, liquidity, lifecycle, fee, reward/admin/orderbook si applicable.
7. Ajouter des tests synthétiques pour chaque instruction/event IDL, y compris non observé.
8. Ajouter le SQL de validation DAMM v1.
9. Rejouer sur base fraîche dédiée avec `forceDexDecode=yes`.
10. Fusionner la base dédiée vers `final.next.db` via `kb_db_merge`.
11. Rejouer `final.next.db`.
12. Lancer les gates cross-DEX.
13. Clore seulement si les gates locales et globales sont propres.
## Gates SQL obligatoires
Reprendre le pattern DLMM :
```text
fallback upstream pour entrées localement couvertes -> vide
instruction_name null/blank -> vide
decoded sans coverage -> vide
successful non-materialized without skip/policy -> vide
failed tx materialization -> vide
multi-target materialization -> vide
non-swap trade/candle -> vide
fee scalar parent without leg -> vide
orphan fee legs -> vide
coverage logical duplicates -> vide
watchlist sans backlog meteora_damm_v1
```
Ajouter les gates anti-régression globales après merge :
```text
successful non-materialized Pump/Raydium/Meteora expliqué ou vide
pure instruction_audit inattendu -> vide
decoder errors cross-surface -> vide
failed tx materialized -> vide
trade/candle non-swap -> vide
```
## Cible 0.7.61 — meteora_damm_v2
Program id depuis la roadmap :
```text
cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
```
Nouvrir cette tranche quaprès clôture DAMM v1.
La tranche v2 peut réutiliser le template et des helpers privés, mais doit conserver ses propres éléments :
```text
decoder code
coverage entries
instruction enum
event mapping
synthetic tests
SQL validation
rapport
base dédiée
validation final.db merge
```
## Livrables attendus pour 0.7.60
Fichiers probables :
```text
kb_lib/src/dex/meteora_damm_v1.rs
kb_lib/src/dex_event_coverage.rs
kb_lib/src/dex_event_classification.rs
kb_lib/src/instruction_observation_index.rs
kb_lib/src/non_trade_event_materialization.rs
validation_sql/SQL_VALIDATION_METEORA_DAMM_V1_0_7_60.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_AFTER_DAMM_V1_0_7_60.sql
docs/reports/METEORA_DAMM_V1_EVENT_COVERAGE_REPORT.md
```
Mettre à jour les re-exports si des modules ou requêtes sont ajoutés :
```text
kb_lib/src/dex.rs
kb_lib/src/lib.rs
kb_lib/src/db.rs
```
## Note finale
Si la découverte corpus montre que DAMM v1 et v2 partagent une logique basse-niveau précise, créer des helpers privés communs.
Ne pas fusionner les deux protocoles dans un seul decoder, une seule coverage ou un seul rapport de clôture.

View File

@@ -0,0 +1,247 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.48-raydium-cpmm.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.48` / Raydium CPMM event coverage
Reprise du projet `khadhroony-bobobot` après clôture de `0.7.48-pre`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.48-pre-event-coverage-report
```
Docs à fournir aussi :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
```
## État validé avant reprise
`0.7.48-pre` a ajouté et clôturé le checkpoint DB/reporting de couverture événementielle :
```text
k_sol_dex_event_coverage_entries
DexEventCoverageService
sync upstream registry -> coverage table
refresh local counts depuis k_sol_dex_decoded_events + tables métier existantes
summaries coverage dans LocalPipelineDiagnosticSummaryDto
summaries/counters coverage dans LocalPipelineValidationReportDto
profil validation 0.7.48-pre_event_coverage_db_checkpoint
profil exposé dans Demo Pipeline 2
```
Invariants maintenus :
```text
aucun decoder DEX modifié
aucun trade/candle créé par la couverture
aucun program_id promu sans corpus local
upstream Git/IDL = indice, pas preuve métier
failed transaction = audit-only
non-trade event = jamais trade/candle
```
## Décision de reprise
Commencer maintenant par Raydium avant Meteora.
Ordre courant :
```text
0.7.48 raydium_cpmm
0.7.49 raydium_clmm
0.7.50 pump_swap
0.7.51 pump_fun
0.7.52 meteora_dbc
0.7.53 meteora_dlmm upstream parity
0.7.54 meteora_damm_v1 upstream parity
0.7.55 meteora_damm_v2
0.7.56 phoenix_v1 audit-only completion
0.7.57 openbook_v2 audit-only completion
0.7.58 orca_whirlpools
0.7.59+ launch surfaces, candidats/historiques, validation consolidée
```
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
Pour `0.7.48`, commencer par Carbon + fnzero pour Raydium CPMM, puis comparer aux IDL complémentaires si disponibles.
## Objectif `0.7.48` — `raydium_cpmm`
Objectif : reprendre `raydium_cpmm` comme première tranche DEX/version après le checkpoint coverage.
À faire :
1. lister tous les discriminants/instructions/events `raydium_cpmm` depuis Carbon/fnzero/IDL ;
2. synchroniser/remplir `k_sol_dex_event_coverage_entries` pour `raydium-cpmm` ;
3. comparer listed/decoded/observed/materialized/trade_count via le rapport coverage ;
4. compléter le decoder spécialisé `raydium_cpmm` seulement pour les events CPMM confirmables ;
5. remplacer/nettoyer le fallback `upstream_git.instruction_match` quand un decoder local spécialisé couvre l'entrée ;
6. garder les events connus mais non observés en `upstream_git_mapped_unverified` ;
7. garder les events observés mais non matérialisés en audit-only/decoded ;
8. ne matérialiser que les non-trades déjà prouvés par corpus et compatibles avec les tables existantes ;
9. ne pas ajouter encore `k_sol_token_transfer_events` ou `k_sol_orderbook_events`, sauf besoin bloquant démontré ;
10. ne pas modifier les règles trade/candle sauf bug de faux positif prouvé.
## Events/familles à couvrir explicitement
Ne pas se limiter aux swaps.
Inclure dans l'audit coverage :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Pour `raydium_cpmm`, certaines familles seront probablement `-` ou `non applicable`, mais elles doivent être explicitement justifiées dans la coverage matrix ou la table.
## Règles fixes
- Un event non-trade ne produit jamais `trade_event`, metric ou candle.
- Une transaction failed reste audit, jamais trade/candle.
- Un discriminator upstream n'est pas une preuve métier.
- Un program id upstream n'est pas vérifié sans corpus local.
- Chaque decoder spécialisé doit remplacer le fallback `upstream_git.instruction_match` pour éviter les doublons.
- Tout event connu mais non observé reste `upstream_git_mapped_unverified`.
- Tout event observé mais non matérialisé reste audit-only ou decoded, pas materialized.
- Ne pas promouvoir de nouvelle table DB métier sans preuve que plusieurs DEX en auront besoin.
## Requêtes SQL utiles
Après sync/refresh coverage :
```sql
SELECT *
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium-cpmm'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
```sql
SELECT
decoder_code,
listed_entry_count,
decoded_entry_count,
observed_entry_count,
materialized_entry_count,
total_observed_count,
total_materialized_count,
trade_count,
audit_only_entry_count,
upstream_git_mapped_unverified_entry_count,
upstream_git_local_corpus_observed_entry_count,
upstream_git_local_corpus_materialized_entry_count
FROM (
SELECT
decoder_code,
COUNT(*) AS listed_entry_count,
SUM(CASE WHEN local_event_kind IS NOT NULL AND local_event_kind <> '' THEN 1 ELSE 0 END) AS decoded_entry_count,
SUM(CASE WHEN observed_count > 0 THEN 1 ELSE 0 END) AS observed_entry_count,
SUM(CASE WHEN materialized_count > 0 THEN 1 ELSE 0 END) AS materialized_entry_count,
COALESCE(SUM(observed_count), 0) AS total_observed_count,
COALESCE(SUM(materialized_count), 0) AS total_materialized_count,
COALESCE(SUM(trade_count), 0) AS trade_count,
SUM(CASE WHEN expected_db_target = 'k_sol_dex_decoded_events_only' THEN 1 ELSE 0 END) AS audit_only_entry_count,
SUM(CASE WHEN proof_status = 'upstream_git_mapped_unverified' THEN 1 ELSE 0 END) AS upstream_git_mapped_unverified_entry_count,
SUM(CASE WHEN proof_status = 'upstream_git_local_corpus_observed' THEN 1 ELSE 0 END) AS upstream_git_local_corpus_observed_entry_count,
SUM(CASE WHEN proof_status = 'upstream_git_local_corpus_materialized' THEN 1 ELSE 0 END) AS upstream_git_local_corpus_materialized_entry_count
FROM k_sol_dex_event_coverage_entries
GROUP BY decoder_code
)
WHERE decoder_code = 'raydium-cpmm';
```
Audit-only safety :
```sql
SELECT
de.protocol_name,
de.event_kind,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_cpmm'
AND (
de.event_kind LIKE '%audit%'
OR json_extract(de.payload_json, '$.eventActionability') IN ('non_trade_useful', 'informational', 'non_actionable_trade')
)
GROUP BY de.protocol_name, de.event_kind
ORDER BY trade_count DESC, de.event_kind;
```
## Contraintes de code
Conserver les règles du workspace :
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Livrables attendus pour `0.7.48`
1. delta archive avec uniquement les fichiers ajoutés/modifiés ;
2. mise à jour `README.md`, `ROADMAP.md`, `CHANGELOG.md` si la tranche avance ;
3. rapport de couverture `raydium_cpmm` ;
4. SQL de validation ;
5. tests verts :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```

View File

@@ -0,0 +1,338 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.50-raydium-launchpad.md -->
# khadhroony-bobobot `0.7.50` / Raydium Launchpad event coverage
Reprise du projet `khadhroony-bobobot` après clôture fonctionnelle de `0.7.49 raydium_clmm`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.49-raydium-clmm-final
```
Inclure les docs et SQL de validation produits en fin de `0.7.49`, notamment :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md
docs/RAYDIUM_CLMM_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_48.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_49_PRE23.sql
```
## État validé avant reprise
`0.7.48` a clôturé `raydium_cpmm`.
`0.7.49` a clôturé `raydium_clmm` avec les invariants suivants :
```text
Raydium CLMM decoder_code local = raydium_clmm
coverage synchronisée avec Carbon / Raydium IDL / Pinax / fnzero
45 entrées coverage CLMM listées
33 entrées CLMM décodées localement
33 entrées observées localement
25 entrées matérialisées localement
residual raydium_clmm.instruction_audit = 0
fallback upstream_git.instruction_match localement couvert = 0 après cleanup FK-safe
non-trade CLMM = jamais trade/candle
failed transaction = jamais matérialisée dans les tables métier
Program data CLMM préparé mais non promu sans corpus local observé
side effects SPL Token / Token-2022 restent transversaux, pas raydium_clmm.* directs
```
Dernière validation locale observée :
```text
cargo test -p kb_lib: ok
local pipeline replay: 2197 replayed, 0 decode skipped, 2197 ledger upserts, 1461 unsafe ledger rows, 1217 trades, 111 liquidity, 25 lifecycle, 4868 candle upserts, instructionObservations='19798'
```
## Décision de reprise
Commencer `0.7.50` par `raydium_launchpad`, avant Pump/Meteora.
Ordre strict Raydium proposé avant Pump :
```text
0.7.50 raydium_launchpad / Raydium LaunchLab-Launchpad surface
0.7.51 raydium_amm_v4
0.7.52 raydium_stable
0.7.53 raydium_pool_v4 audit / program-id decision, seulement si program id distinct et corpus exploitable
0.7.54 pump_swap
0.7.55 pump_fun
0.7.56 meteora_dbc
0.7.57 meteora_dlmm upstream parity
0.7.58 meteora_damm_v1 upstream parity
0.7.59 meteora_damm_v2
0.7.60 phoenix_v1 audit-only completion
0.7.61 openbook_v2 audit-only completion
0.7.62 orca_whirlpools
0.7.63+ launch surfaces, candidats/historiques, validation consolidée
```
`raydium_pool_v4` ne doit pas être promu automatiquement comme DEX/surface métier tant que son program id et son rôle exact n'ont pas été confirmés. Le fichier `raydium_pool_v4.json` de `sol-parser-sdk` doit être audité comme source IDL annexe, pas comme preuve métier.
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- copie locale fournie de `0xfnzero/sol-parser-sdk`, si présente dans l'archive de reprise
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
Pour `0.7.50 raydium_launchpad`, utiliser aussi explicitement :
```text
https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj#programIdl
```
et les filtres Solscan de type :
```text
https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
Solscan sert à trouver vite des signatures à backfiller. Solscan ne doit jamais être considéré comme preuve métier finale sans corpus local et validation SQL.
## Base de données de travail
Initialiser une nouvelle base SQLite dédiée à `0.7.50`.
Procédure attendue :
1. créer une nouvelle DB via `config.json` ou équivalent ;
2. démarrer `kb_demo_app` pour initialiser le schéma ;
3. backfiller des signatures ciblées par discriminant / instruction ;
4. backfiller des pools/comptes pertinents si la surface en expose ;
5. exécuter un replay local avec `forceDexDecode=yes` ;
6. relancer les SQL de coverage ;
7. ne promouvoir une entrée que si le corpus local confirme son sens métier.
## Objectif `0.7.50` — `raydium_launchpad`
Objectif : couvrir Raydium Launchpad/LaunchLab comme nouvelle surface Raydium après CPMM et CLMM.
À faire :
1. lire le code local existant lié à Raydium Launchpad, s'il existe ;
2. lister toutes les instructions/events depuis Carbon/fnzero/IDL/Pinax/Solscan Program IDL ;
3. synchroniser/remplir `k_sol_dex_event_coverage_entries` pour `raydium_launchpad` ;
4. vérifier `decoder_code` local en snake_case : `raydium_launchpad` ;
5. utiliser `k_sol_instruction_observations` pour inspecter les discriminants observés localement ;
6. utiliser Demo3 / Solscan `instruction=<discriminator>` pour trouver des signatures ciblées ;
7. backfiller les signatures via Demo2, idéalement par batch textarea ;
8. rejouer localement avec `forceDexDecode=yes` et `deferInstructionObservations=yes` ;
9. comparer listed/decoded/observed/materialized/trade_count via SQL coverage ;
10. compléter le decoder spécialisé seulement pour les entrées confirmées ;
11. supprimer/nettoyer `upstream_git.instruction_match` lorsque l'entrée est couverte localement ;
12. garder les entrées connues mais non observées en `upstream_git_unverified` ou `upstream_git_mapped_unverified` ;
13. garder les entrées observées mais non matérialisées en audit-only/decoded ;
14. ne matérialiser que les non-trades prouvés par corpus local et compatibles avec les tables existantes ;
15. ne modifier les règles trade/candle que si un faux positif est prouvé.
## Familles à auditer explicitement
Ne pas se limiter aux swaps.
Inclure dans la coverage :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Certaines familles peuvent être non applicables ou uniquement visibles comme side effects SPL Token / Token-2022. Elles doivent être explicitement justifiées dans `DEX_EVENT_COVERAGE_MATRIX.md`.
## Points d'attention hérités de CPMM/CLMM
- `decoder_code` local doit rester en `snake_case`.
- Les slugs upstream peuvent garder les tirets.
- `upstream Git/IDL/Solscan = indice, pas preuve métier`.
- `program_id` upstream non promu sans corpus local.
- Chaque decoder spécialisé doit remplacer le fallback `upstream_git.instruction_match` pour les entrées localement couvertes.
- Les side effects SPL Token (`mintTo`, `burn`, `transfer`, `transferChecked`, `closeAccount`) ne deviennent pas `raydium_launchpad.*` sans preuve qu'il s'agit d'instructions directes du programme Launchpad.
- Failed transaction = decoded/audit possible, jamais matérialisée métier.
- Non-trade event = jamais trade/candle.
- Pas de nouvelle table métier transversale sans preuve multi-DEX.
## Requêtes SQL minimales à produire
Créer un fichier :
```text
validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql
```
Inclure au minimum :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
local_event_kind,
discriminator_hex,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_launchpad'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Coverage summary :
```sql
SELECT
decoder_code,
COUNT(*) AS listed_entry_count,
SUM(CASE WHEN local_event_kind IS NOT NULL AND local_event_kind <> '' THEN 1 ELSE 0 END) AS decoded_entry_count,
SUM(CASE WHEN observed_count > 0 THEN 1 ELSE 0 END) AS observed_entry_count,
SUM(CASE WHEN materialized_count > 0 THEN 1 ELSE 0 END) AS materialized_entry_count,
COALESCE(SUM(observed_count), 0) AS total_observed_count,
COALESCE(SUM(materialized_count), 0) AS total_materialized_count,
COALESCE(SUM(trade_count), 0) AS trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_launchpad'
GROUP BY decoder_code;
```
Instruction observations :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_launchpad'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC, instruction_name;
```
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_launchpad'
GROUP BY de.event_kind
ORDER BY decoded_count DESC, de.event_kind;
```
```sql
SELECT
json_extract(payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(payload_json, '$.upstreamEntryName') AS entry_name,
json_extract(payload_json, '$.upstreamDiscriminatorHex') AS discriminator_hex,
COUNT(*) AS fallback_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'upstream_git'
AND event_kind = 'upstream_git.instruction_match'
AND json_extract(payload_json, '$.upstreamDecoderCode') = 'raydium_launchpad'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex
ORDER BY fallback_count DESC, entry_name;
```
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_launchpad'
AND tx.err_json IS NOT NULL
AND tx.err_json <> ''
AND tx.err_json <> 'null'
GROUP BY de.event_kind
ORDER BY trade_count DESC, decoded_count DESC;
```
## Contraintes de code
Conserver les règles du workspace :
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Livrables attendus pour `0.7.50`
1. delta archive avec uniquement les fichiers ajoutés/modifiés ;
2. mise à jour `README.md`, `ROADMAP.md`, `CHANGELOG.md` ;
3. rapport `docs/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md` ;
4. SQL `validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql` ;
5. tests verts :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## Question ouverte à traiter tôt dans `0.7.50`
Auditer `raydium_pool_v4.json` dans `sol-parser-sdk` :
- confirmer s'il correspond à un program id distinct ;
- confirmer s'il s'agit d'une surface Raydium Pool/Lending/Strategy différente de `raydium_amm_v4` ;
- décider si une version dédiée `0.7.53 raydium_pool_v4` est nécessaire ;
- ne pas modifier la roadmap comme surface finale tant que le program id n'est pas confirmé.

View File

@@ -0,0 +1,386 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.51-raydium-amm-v4.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.51` / Raydium AMM v4 event coverage
Reprise du projet `khadhroony-bobobot` après clôture de `0.7.50 raydium_launchpad` et re-vérification finale CPMM/CLMM.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.50-raydium-launchpad-final
```
Joindre aussi les docs et SQL de validation à jour :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md
docs/reports/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_AUDIT_CLEANUP_0_7_50_FINAL.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_50_RECHECK.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_50_RECHECK.sql
```
## État validé avant reprise
`0.7.50` a clôturé `raydium_launchpad` et consolidé les rechecks CPMM/CLMM.
Dernier replay local rapporté après cleanup final CPMM :
```text
1124 replayed
0 decode skipped
1124 ledger upserts
539 unsafe ledger rows
561 trades
50 liquidity
13 lifecycle
0 tokenAccount
2224 candle upserts
instructionObservations = 7010
resetDeleted = 1182
catalog = 37 tokens / 40 pools / 40 pairs
```
Points de clôture à préserver :
```text
raydium_launchpad : surface canonique, program id LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj
Launchpad trade_event matérialisé seulement quand corpus + successful tx le prouvent
Launchpad initialize* fournit le catalogue pool/pair, pas de faux trade/candle
CPMM 40f4bc78a7e9690a est raydium_cpmm.anchor_idl_instruction decoded-only
CPMM residual raydium_cpmm.instruction_audit 40f4bc78a7e9690a = vide après replay final
CPMM decoded event without coverage entry = vide après replay final
CPMM upstream_git.instruction_match fallback résiduel = vide
CPMM non-swap materialization gap hors failed tx = vide
CLMM residual instruction_audit / upstream fallback doivent rester vides
k_sol_instruction_observations reste une table technique, pas une table métier
Solscan instruction=<discriminator> est une aide de découverte, pas une preuve métier
```
Requêtes CPMM post-fix obligatoires avant d'ouvrir `0.7.51` :
```sql
SELECT
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS audit_count,
COUNT(DISTINCT transaction_id) AS tx_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'raydium_cpmm'
AND event_kind = 'raydium_cpmm.instruction_audit'
GROUP BY discriminator_hex
ORDER BY audit_count DESC, discriminator_hex;
```
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_cpmm'
AND ce.local_event_kind = de.event_kind
WHERE de.protocol_name = 'raydium_cpmm'
AND ce.id IS NULL
GROUP BY de.event_kind
ORDER BY decoded_count DESC, de.event_kind;
```
Ces deux requêtes doivent être vides après replay `forceDexDecode=yes`.
## Décision de reprise
Ouvrir une nouvelle tranche :
```text
0.7.51 raydium_amm_v4
```
Ne pas commencer par `raydium_pool_v4` comme nouveau decoder autonome tant que son program id et son rôle métier ne sont pas prouvés localement.
`raydium_pool_v4` doit être traité dans `0.7.51` comme une **source à auditer / comparer** avec `raydium_amm_v4`, pas comme version déjà décidée. La roadmap peut conserver une entrée de décision `raydium_pool_v4 audit / program-id decision`, mais cette entrée doit être reformulée comme décision conditionnelle :
```text
si raydium_pool_v4 correspond au même program id AMM v4 ou à un layout alternatif -> intégrer à raydium_amm_v4
si raydium_pool_v4 correspond à un autre program id / strategy / farm / pool wrapper -> créer une tranche dédiée seulement après corpus local
```
## Objectif `0.7.51` — `raydium_amm_v4`
Reprendre Raydium AMM v4 legacy au même niveau de couverture que CPMM/CLMM :
```text
swaps
pool lifecycle / pool_create
add_liquidity / remove_liquidity
fees / admin/config
open_orders / target_orders / serum/openbook side effects documentés
side effects SPL Token / Token-2022 documentés mais non promus comme raydium_amm_v4.* directs
fallback instruction_audit nettoyé quand une entrée locale spécialisée couvre l'instruction
coverage entries synchronisées et rafraîchies
```
Code local canonique :
```text
raydium_amm_v4
```
Program id canonique connu :
```text
675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
```
Solscan Program IDL / recherche par instruction :
```text
https://solscan.io/account/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8#programIdl
https://solscan.io/account/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
## Nouvelle base de travail
Démarrer `0.7.51` sur une base SQLite vide dédiée.
Avant le replay de validation complet, prévoir un corpus initial construit volontairement :
```text
1. Demo3 program_id = 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
2. Solscan Program IDL + instruction=<DISCRIMINATOR>
3. backfill Demo2 de signatures contenant des instructions AMM v4 variées
4. backfill de pools AMM v4 quand Demo3/Solscan fournit un AMM/pool account fiable
```
Ne pas interpréter l'absence de résultat Solscan comme absence on-chain définitive.
## Sources Git/IDL à utiliser systématiquement
Sources globales :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders
https://github.com/0xfnzero/solana-streamer
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idls
https://github.com/pinax-network/substreams-solana-idls/tree/main/src
https://github.com/hodlwarden/solana-tx-parser/tree/main/src
https://docs.vybenetwork.com/docs/available-dexs-amms
```
Sources spécifiques `raydium_amm_v4` à vérifier en priorité :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders/raydium-amm-v4-decoder
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/amm
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idl/raydium_amm_v4.json
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idls/raydium_amm_v4.json
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idl/raydium_pool_v4.json
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idls/raydium_pool_v4.json
https://solscan.io/account/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8#programIdl
```
## Vérification obligatoire `raydium_pool_v4`
Avant de coder une tranche séparée `raydium_pool_v4`, faire une vérification explicite :
```text
1. comparer idl/raydium_pool_v4.json et idls/raydium_pool_v4.json
2. comparer idl/raydium_amm_v4.json et idls/raydium_amm_v4.json
3. chercher si raydium_pool_v4 contient un program id explicite
4. comparer les instructions communes : initialize, initialize2, deposit, withdraw, swapBaseIn, swapBaseOut, monitorStep, admin/config
5. vérifier si raydium_pool_v4 décrit :
- le même Raydium AMM v4 program id 675kPX...
- un layout alternatif d'instruction
- un wrapper strategy / pool / farming / lending
- une ancienne ABI non directement liée au program id 675kPX...
6. ne pas promouvoir `raydium_pool_v4` sans corpus local :
- k_sol_instruction_observations
- decoded events locaux
- coverage local_event_kind
- absence de fallback upstream
```
Décision attendue dans `0.7.51` :
```text
Option A : raydium_pool_v4 = alias/source complémentaire de raydium_amm_v4 -> intégrer ses discriminants/layouts dans raydium_amm_v4 et supprimer la version roadmap autonome.
Option B : raydium_pool_v4 = autre program id / autre surface -> conserver une future version dédiée avec program id prouvé.
Option C : raydium_pool_v4 = IDL ambiguë / strategy wrapper sans corpus -> garder en audit roadmap, pas de decoder local.
```
## Règles fixes
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Invariants métier
```text
non-trade event = jamais trade/candle
failed transaction = audit-only / jamais matérialisée métier
upstream Git/IDL/Solscan = indice, pas preuve métier
program id upstream non promu sans corpus local
side effects SPL Token / Token-2022 restent transversaux sauf preuve multi-DEX et décision DB
instruction_audit et upstream_git.instruction_match doivent être nettoyés quand une entrée locale spécialisée couvre le discriminant
```
## Workflow conseillé
1. Créer une nouvelle base SQLite dédiée `0.7.51`.
2. Inventorier Carbon/fnzero/Pinax/Solscan Program IDL pour `raydium_amm_v4`.
3. Auditer `raydium_pool_v4` avant de décider si la roadmap garde une tranche dédiée.
4. Synchroniser `k_sol_dex_event_coverage_entries` avec `decoder_code = raydium_amm_v4`.
5. Utiliser Solscan `instruction=<discriminator>` pour obtenir rapidement des signatures non failed.
6. Backfill Demo2 signature/pool sur corpus varié.
7. Replay local avec :
```text
skipDexDecode = no
forceDexDecode = yes
deferInstructionObservations = yes
```
8. Vérifier :
```text
coverage listed/observed/materialized
residual instruction_audit
residual upstream_git.instruction_match
failed tx materialization = 0
non-trade trade_count = 0
trade/candle only for swap events validés
raydium_pool_v4 decision documented
```
## SQL de contrôle minimal `0.7.51`
Coverage AMM v4 :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
local_event_kind,
discriminator_hex,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_amm_v4'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Instruction observations :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_amm_v4'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC, instruction_name, discriminator_hex;
```
Residual audit :
```sql
SELECT
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS audit_count,
COUNT(DISTINCT transaction_id) AS tx_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'raydium_amm_v4'
AND event_kind = 'raydium_amm_v4.instruction_audit'
GROUP BY discriminator_hex
ORDER BY audit_count DESC, discriminator_hex;
```
Fallback upstream :
```sql
SELECT
json_extract(ug.payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(ug.payload_json, '$.upstreamEntryName') AS entry_name,
json_extract(ug.payload_json, '$.upstreamDiscriminatorHex') AS discriminator_hex,
json_extract(ug.payload_json, '$.upstreamSourceRepo') AS source_repo,
COUNT(*) AS fallback_count,
COUNT(DISTINCT ug.transaction_id) AS tx_count
FROM k_sol_dex_decoded_events ug
JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = json_extract(ug.payload_json, '$.upstreamDecoderCode')
AND ce.entry_name = json_extract(ug.payload_json, '$.upstreamEntryName')
AND ce.discriminator_hex = json_extract(ug.payload_json, '$.upstreamDiscriminatorHex')
AND ce.local_event_kind IS NOT NULL
AND ce.local_event_kind <> ''
WHERE ug.protocol_name = 'upstream_git'
AND ug.event_kind = 'upstream_git.instruction_match'
AND json_extract(ug.payload_json, '$.upstreamDecoderCode') = 'raydium_amm_v4'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex, source_repo
ORDER BY fallback_count DESC, entry_name;
```
Non-swap safety :
```sql
SELECT
de.event_kind,
ce.event_family,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_amm_v4'
AND ce.local_event_kind = de.event_kind
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_amm_v4'
GROUP BY de.event_kind, ce.event_family
HAVING ce.event_family <> 'swap'
AND COUNT(te.id) > 0
ORDER BY trade_count DESC, de.event_kind;
```
## Livrables attendus
```text
archive delta fichiers modifiés/ajoutés
README.md / ROADMAP.md / CHANGELOG.md mis à jour
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_AMM_V4_EVENT_COVERAGE_REPORT.md
docs/reports/RAYDIUM_POOL_V4_DECISION_NOTE.md
validation_sql/SQL_VALIDATION_RAYDIUM_AMM_V4_0_7_51.sql
```
Validation finale locale :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```

View File

@@ -0,0 +1,626 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.52-raydium-stable.md -->
# Prompt de reprise — `khadhroony-bobobot` — `0.7.52 raydium_stable_swap`
Reprise du projet `khadhroony-bobobot` après clôture de `0.7.51 raydium_amm_v4`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusquà :
```text
0.7.51-raydium-amm-v4-final
```
Joindre aussi les docs et SQL de validation à jour :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_AMM_V4_EVENT_COVERAGE_REPORT.md
docs/reports/RAYDIUM_POOL_V4_DECISION_NOTE.md
docs/VALIDATION_STATUS_0_7_51_FINAL.md
validation_sql/SQL_VALIDATION_RAYDIUM_AMM_V4_0_7_51.sql
```
## État validé avant reprise
`0.7.51` a clôturé `raydium_amm_v4`.
Validation locale finale rapportée :
```text
cargo test -p kb_lib
405 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings
OK
```
Dernier replay local `0.7.51` :
```text
195 replayed
0 decode skipped
195 ledger upserts
70 unsafe ledger rows
168 trades
7 liquidity
15 lifecycle
0 tokenAccount
668 candle upserts
instructionObservations = 2599
resetDeleted = 1578
catalog = 61 tokens / 65 pools / 65 pairs
```
Points de clôture AMM v4 à préserver :
```text
raydium_amm_v4.swap legacy = vide
decoded without coverage entry = vide
instruction_observations > 1 octet = vide
non-swap -> trade = vide
failed tx -> trade = vide
unexplained successful non-materialized events = vide
multi-target materialization = vide
pre_initialize lifecycle audit = 7 / 7
migrate_to_open_book = orderbook only
simulate_info = decoded-only
raydium_pool_v4 = audit-only / pas de decoder autonome
```
## Décision de reprise
Ouvrir une nouvelle tranche :
```text
0.7.52 raydium_stable_swap
```
Code local canonique :
```text
raydium_stable_swap
```
Program id canonique à utiliser comme hypothèse de départ :
```text
5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h
```
Important : upstream Git/IDL/Solscan est un indice, pas une preuve métier. Le program id doit être confirmé par corpus local via `k_sol_instruction_observations`, decoded events, coverage entries et absence de fallback upstream.
## Nouvelle base de travail
Démarrer `0.7.52` sur une base SQLite vide dédiée.
Avant le replay de validation complet, construire volontairement un corpus initial :
```text
1. Demo3 program_id = 5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h
2. Solscan non filtré + essais instruction=<DISCRIMINATOR>
3. backfill Demo2 de signatures contenant des instructions stable swap variées
4. backfill de pools stable swap quand Demo3/Solscan fournit un AMM/pool account fiable
```
Ne pas interpréter labsence de résultat Solscan comme absence on-chain définitive.
## Note Solscan importante
Pour `raydium_stable_swap`, il semble que Solscan ne dispose pas dun Program IDL exploitable sur :
```text
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h#programIdl
```
Donc le filtrage Solscan par instruction peut ne pas fonctionner avec les discriminants 8 octets Carbon/Pinax.
Il faut tester deux approches :
```text
1. Liens exploratoires courts : instruction=00, 01, 02, ...
2. Liens discriminants upstream 8 octets : instruction=<DISCRIMINATOR_HEX>
```
Solscan est une aide de découverte uniquement. La preuve métier reste locale : signatures backfillées, decoded events, instruction observations et coverage DB.
## Sources Git/IDL à utiliser systématiquement
Sources globales :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders
https://github.com/0xfnzero/solana-streamer
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idls
https://github.com/pinax-network/substreams-solana-idls/tree/main/src
https://github.com/hodlwarden/solana-tx-parser/tree/main/src
https://docs.vybenetwork.com/docs/available-dexs-amms
```
Sources spécifiques `raydium_stable_swap` à vérifier en priorité :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders/raydium-stable-swap-decoder
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/idl.json
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/instructions.rs
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/events.rs
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/accounts.rs
```
## Solscan — liens exploratoires
Base non filtrée :
```text
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?hide_spam=false&hide_failed=false&show_related=true&sort=desc
```
Base non filtrée sans related :
```text
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?hide_spam=false&hide_failed=false&show_related=false&sort=desc
```
### Essais courts `instruction=00..11`
Ces liens sont exploratoires. Ils ne prouvent pas que le program utilise des discriminants 1 octet ; ils servent seulement à tester le comportement Solscan quand aucun IDL nest présent.
```text
instruction=00
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=00&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=01
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=01&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=02
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=02&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=03
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=03&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=04
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=04&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=05
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=05&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=06
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=06&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=07
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=07&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=08
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=08&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=09
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=09&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0a
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0a&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0b
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0b&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0c
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0c&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0d
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0d&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0e
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0e&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0f
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0f&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=10
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=10&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=11
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=11&hide_spam=false&hide_failed=false&show_related=false&sort=desc
```
### Essais discriminants 8 octets Carbon/Pinax
À tester aussi, mais ne pas bloquer si Solscan ne filtre rien.
```text
initialize / afaf6d1f0d989bed
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=afaf6d1f0d989bed&hide_spam=false&hide_failed=false&show_related=false&sort=desc
pre_initialize / ff5c572dc6acec02
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=ff5c572dc6acec02&hide_spam=false&hide_failed=false&show_related=false&sort=desc
deposit / f223c68952e1f2b6
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=f223c68952e1f2b6&hide_spam=false&hide_failed=false&show_related=false&sort=desc
withdraw / b712469c946da122
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=b712469c946da122&hide_spam=false&hide_failed=false&show_related=false&sort=desc
swap_base_in / 2aec48a2f2182754
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=2aec48a2f2182754&hide_spam=false&hide_failed=false&show_related=false&sort=desc
swap_base_out / a3d29bd0af92d596
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=a3d29bd0af92d596&hide_spam=false&hide_failed=false&show_related=false&sort=desc
```
## Instructions/discriminants de départ à couvrir
À partir de Carbon stable swap, à vérifier contre Pinax :
```text
initialize afaf6d1f0d989bed pool_create / k_sol_pool_lifecycle_events
pre_initialize ff5c572dc6acec02 pool_create deprecated/partial / k_sol_pool_lifecycle_events si pool context suffisant
deposit f223c68952e1f2b6 liquidity_add / k_sol_liquidity_events
withdraw b712469c946da122 liquidity_remove / k_sol_liquidity_events
swap_base_in 2aec48a2f2182754 swap / k_sol_trade_events
swap_base_out a3d29bd0af92d596 swap / k_sol_trade_events
```
Si Pinax expose des discriminants numériques ou une ABI non Anchor, ne pas forcer les discriminants 8 octets. Le decoder local doit suivre le layout prouvé par corpus local.
## Objectif `0.7.52` — `raydium_stable_swap`
Reprendre Raydium Stable Swap au même niveau de couverture que CPMM/CLMM/AMM v4 :
```text
initialize / pre_initialize
pool lifecycle / pool_create
deposit / withdraw
swap_base_in / swap_base_out
fees / admin/config si présents dans IDL/events/accounts
OpenBook/Serum side effects documentés si présents
side effects SPL Token / Token-2022 documentés mais non promus comme raydium_stable_swap.* directs
fallback instruction_audit nettoyé quand une entrée locale spécialisée couvre linstruction
coverage entries synchronisées et rafraîchies
decoded-only explicitement expliqué quand la matérialisation métier est impossible
```
## Règles fixes
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Invariants métier
```text
non-trade event = jamais trade/candle
failed transaction = audit-only / jamais matérialisée métier
upstream Git/IDL/Solscan = indice, pas preuve métier
program id upstream non promu sans corpus local
side effects SPL Token / Token-2022 restent transversaux sauf preuve multi-DEX et décision DB
instruction_audit et upstream_git.instruction_match doivent être nettoyés quand une entrée locale spécialisée couvre le discriminant
observed_count ne doit pas obligatoirement égaler materialized_count
règle de clôture : observed_count = materialized_count + decoded_only_explained_count + failed_count
```
## Workflow conseillé
1. Créer une nouvelle base SQLite dédiée `0.7.52`.
2. Inventorier Carbon + Pinax pour `raydium_stable_swap`.
3. Vérifier explicitement le program id `5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h`.
4. Vérifier si les discriminants sont 8 octets Anchor-like, 1 octet, ou autre layout.
5. Synchroniser `k_sol_dex_event_coverage_entries` avec `decoder_code = raydium_stable_swap`.
6. Utiliser Solscan seulement comme aide exploratoire ; si le filtre instruction échoue, utiliser Demo3 program_id + signatures récentes/non filtrées.
7. Backfill Demo2 signature/pool sur corpus varié.
8. Replay local avec :
```text
skipDexDecode = no
forceDexDecode = yes
deferInstructionObservations = yes
```
9. Vérifier :
```text
coverage listed/observed/materialized
residual instruction_audit
residual upstream_git.instruction_match
decoded without coverage entry
failed tx materialization = 0
non-trade trade_count = 0
single-target materialization
trade/candle only for swap events validés
decoded-only explanations
```
## SQL de contrôle minimal `0.7.52`
Coverage stable swap :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
local_event_kind,
discriminator_hex,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_stable_swap'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Instruction observations :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_stable_swap'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC, instruction_name, discriminator_hex;
```
Residual audit :
```sql
SELECT
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS audit_count,
COUNT(DISTINCT transaction_id) AS tx_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'raydium_stable_swap'
AND event_kind = 'raydium_stable_swap.instruction_audit'
GROUP BY discriminator_hex
ORDER BY audit_count DESC, discriminator_hex;
```
Fallback upstream :
```sql
SELECT
json_extract(ug.payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(ug.payload_json, '$.upstreamEntryName') AS entry_name,
json_extract(ug.payload_json, '$.upstreamDiscriminatorHex') AS discriminator_hex,
json_extract(ug.payload_json, '$.upstreamSourceRepo') AS source_repo,
COUNT(*) AS fallback_count,
COUNT(DISTINCT ug.transaction_id) AS tx_count
FROM k_sol_dex_decoded_events ug
JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = json_extract(ug.payload_json, '$.upstreamDecoderCode')
AND ce.entry_name = json_extract(ug.payload_json, '$.upstreamEntryName')
AND ce.discriminator_hex = json_extract(ug.payload_json, '$.upstreamDiscriminatorHex')
AND ce.local_event_kind IS NOT NULL
AND ce.local_event_kind <> ''
WHERE ug.protocol_name = 'upstream_git'
AND ug.event_kind = 'upstream_git.instruction_match'
AND json_extract(ug.payload_json, '$.upstreamDecoderCode') = 'raydium_stable_swap'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex, source_repo
ORDER BY fallback_count DESC, entry_name;
```
Non-swap safety :
```sql
SELECT
de.event_kind,
ce.event_family,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_stable_swap'
AND ce.local_event_kind = de.event_kind
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
GROUP BY de.event_kind, ce.event_family
HAVING ce.event_family <> 'swap'
AND COUNT(te.id) > 0
ORDER BY trade_count DESC, de.event_kind;
```
Failed tx safety :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_failed_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
AND tx.err_json IS NOT NULL
AND tx.err_json <> ''
AND tx.err_json <> 'null'
GROUP BY de.event_kind
HAVING COUNT(te.id) > 0
ORDER BY trade_count DESC, de.event_kind;
```
Decoded without coverage :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_stable_swap'
AND ce.local_event_kind = de.event_kind
WHERE de.protocol_name = 'raydium_stable_swap'
AND ce.id IS NULL
GROUP BY de.event_kind
ORDER BY decoded_count DESC, de.event_kind;
```
Multi-target materialization :
```sql
SELECT
de.event_kind,
COUNT(DISTINCT de.id) AS decoded_count,
COUNT(DISTINCT te.id) AS trade_count,
COUNT(DISTINCT le.id) AS liquidity_count,
COUNT(DISTINCT pe.id) AS lifecycle_count,
COUNT(DISTINCT fe.id) AS fee_count,
COUNT(DISTINCT ae.id) AS admin_count,
COUNT(DISTINCT oe.id) AS orderbook_count,
(
CASE WHEN COUNT(DISTINCT te.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT le.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT pe.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT fe.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT ae.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT oe.id) > 0 THEN 1 ELSE 0 END
) AS materialized_target_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events pe
ON pe.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events ae
ON ae.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events oe
ON oe.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
GROUP BY de.event_kind
HAVING materialized_target_count > 1
ORDER BY materialized_target_count DESC, de.event_kind;
```
Unexplained successful non-materialized events :
```sql
SELECT
de.event_kind,
COUNT(*) AS unexplained_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events pe
ON pe.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events ae
ON ae.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events oe
ON oe.decoded_event_id = de.id
LEFT JOIN k_sol_token_account_events tae
ON tae.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
AND (
tx.err_json IS NULL
OR tx.err_json = ''
OR tx.err_json = 'null'
)
AND te.id IS NULL
AND le.id IS NULL
AND pe.id IS NULL
AND fe.id IS NULL
AND ae.id IS NULL
AND oe.id IS NULL
AND tae.id IS NULL
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipTradeReason')), '') = ''
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipLiquidityReason')), '') = ''
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipLifecycleReason')), '') = ''
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipCatalogReason')), '') = ''
GROUP BY de.event_kind
ORDER BY unexplained_count DESC, de.event_kind;
```
Materialization summary :
```sql
SELECT
de.event_kind,
COUNT(DISTINCT de.id) AS decoded_count,
COUNT(DISTINCT te.id) AS trade_count,
COUNT(DISTINCT le.id) AS liquidity_count,
COUNT(DISTINCT pe.id) AS lifecycle_count,
COUNT(DISTINCT fe.id) AS fee_count,
COUNT(DISTINCT ae.id) AS admin_count,
COUNT(DISTINCT oe.id) AS orderbook_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events pe
ON pe.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events ae
ON ae.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events oe
ON oe.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
GROUP BY de.event_kind
ORDER BY de.event_kind;
```
## Livrables attendus
```text
archive delta fichiers modifiés/ajoutés
README.md / ROADMAP.md / CHANGELOG.md mis à jour
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_STABLE_SWAP_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_STABLE_SWAP_0_7_52.sql
```
Validation finale locale :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## Critères de clôture `0.7.52`
```text
tous les discriminants stable swap connus sont listés en coverage
tous les discriminants stable swap connus sont observés localement ou explicitement marqués mapped_unverified
instruction_audit résiduel vide pour les discriminants couverts
fallback upstream_git.instruction_match résiduel vide pour les discriminants couverts
decoded without coverage vide
non-swap -> trade vide
failed tx -> trade vide
multi-target materialization vide
successful decoded-only events expliqués par skip*Reason
trade/candle uniquement pour swaps avec montants fiables
deposit/withdraw uniquement vers liquidity
initialize/pre_initialize uniquement vers lifecycle
simulate/transport éventuel reste decoded-only sauf preuve métier
```

View File

@@ -0,0 +1,130 @@
<!-- file: docs/reports/DEX_COVERAGE_GLOBAL_WATCHLIST_0_7_53.md -->
# DEX coverage global watchlist — `0.7.53`
## Objet
Ce rapport accompagne la clôture `0.7.53 pump_swap`. Il sépare les anomalies bloquantes des files de travail futures.
`pump_swap` est clos côté transaction/log decoder et matérialisation métier. Les lignes restantes de surveillance globale ne sont pas des erreurs PumpSwap.
## Résultat de clôture PumpSwap
Validation rapportée :
```text
cargo test -p kb_lib -> 421 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Replay élargi rapporté :
```text
1189 replayed
0 decode skipped
1189 ledger upserts
967 unsafe ledger rows
928 trades
13 liquidity
8 lifecycle
0 tokenAccount
3700 candle upserts
instructionObservations = 25724
resetDeleted = 5622
catalog = 76 tokens / 80 pools / 80 pairs
```
Checks PumpSwap attendus vides :
- decoded events sans coverage ;
- fallback `upstream_git` couvert localement ;
- successful trade candidates sans trade et sans raison explicite ;
- failed transaction matérialisée en business trade ;
- non-swap matérialisé en trade ;
- multi-target materialization.
`buy_exact_quote_in` :
```text
pump_swap_anchor_buy_event -> 168 decoded / 167 trades / 1 failed tx
instruction_bounds_only -> decoded-only, sans trade
```
## Non-régression Raydium
Les checks ciblés Raydium AMM v4 / CLMM / CPMM normalisés sont vides. Il n'y a pas de correction Raydium à inclure dans `0.7.53`.
Lecture correcte :
- `raydium_amm_v4.swap_base_in_v2` : observé et matérialisé dans le corpus courant ;
- `raydium_clmm.swap_v2` : observé et matérialisé dans le corpus courant ;
- `raydium_cpmm.swap_base_input` : observé et matérialisé dans le corpus courant ;
- les entrées `upstream_git_mapped_unverified` avec `observed_count=0` sont des entrées registry non observées, pas des régressions.
## Gaps locaux reportés
La requête globale `local decoded events without coverage` retourne des gaps Meteora connus et reportés :
```text
meteora_dlmm.swap
meteora_damm_v2.instruction_audit
meteora_damm_v2.swap
```
Décision : ne pas les corriger dans `0.7.53`. Ils seront repris dans les tranches Meteora futures.
## Backlog upstream observé
La file `upstream_git.instruction_match` indique les prochaines surfaces à prioriser. Au moment de la clôture :
| Priorité | Surface | Indice principal | Décision |
|---:|---|---|---|
| 1 | `pump_fees` | `get_fees` très fréquent | Prochaine tranche recommandée ; aucun trade/candle direct attendu. |
| 2 | `pump_fun` | creator fees, migrate, set/admin creator | Tranche launch/bonding séparée. |
| 3 | `jupiter_swap` | `route_v2`, `create_token_account`, `route` | Agrégateur/router ; éviter double-count DEX effectifs. |
| 4 | `dflow_aggregator_v4`, `onchain_labs_dex_v2` | swaps/route helpers | Surfaces secondaires après Pump/Meteora. |
| 5 | `orca_whirlpools` | faibles occurrences | À reprendre plus tard avec corpus dédié. |
## Observations non attribuées
Les observations avec `decoder_code` vide ne doivent pas être traitées comme des discriminants Anchor confirmés. Elles exigent d'abord :
1. inspection de `sample_signature` ;
2. extraction du `program_id` effectif ;
3. comparaison aux IDL locales `idls/` et aux sources Git ;
4. ajout d'un decoder ou d'un statut explicite seulement si le programme est identifié.
## Source IDL locale
Le répertoire `idls/` est désormais une source locale de savoir. Les IDL téléchargées depuis Solscan doivent être utilisées en plus des liens Git, avec la règle suivante : une IDL donne une surface possible, mais la matérialisation métier exige corpus, replay et SQL.
## Vérification `raydium_pool_v4.json`
Fichier Git vérifié : `0xfnzero/sol-parser-sdk/idls/raydium_pool_v4.json`.
Constats :
- la page GitHub annonce `3400` lignes / environ `101 KB` ;
- le fichier expose notamment `swapBaseIn`, `addLiquidity` et des comptes OpenBook/Serum (`OpenBookMarket`, `OpenBookBids`, `OpenBookAsks`, etc.) ;
- la chaîne du program id AMM v4 `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` n'apparaît pas dans la page GitHub consultée ;
- aucun fichier local `idls/raydium_*.json` ne porte le nom `raydium_pool_v4` ;
- les fichiers Raydium locaux présents sont `raydium_clmm`, `raydium_cpmm`, `raydium_launchlab` et `raydium_lock`.
Table locale :
| Fichier local | Name IDL | Address IDL | Taille | SHA-256 |
|---|---|---|---:|---|
| `idls/raydium_clmm.CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK.json` | `raydium_clmm` | `CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK` | 86240 | `d3f265adc9e4d7b1a28641444800a60bcdeb921ef136855fe8dea4532afa18bd` |
| `idls/raydium_cpmm.CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C.json` | `raydium_cp_swap` | `CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C` | 32066 | `5b709dfe7b0df67c9e29655307ae877244d3bb8022056ee01c754f0e36264d9c` |
| `idls/raydium_launchlab.LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj.json` | `raydium_launchpad` | `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj` | 68052 | `c1465a10f38912413f55f04a68536c989992add1b3d48cba86dca97212a482da` |
| `idls/raydium_lock.LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE.json` | `raydium_liquidity_locking` | absent | 10621 | `da45fd5eaf726e5e2ead7280c04588ebd4224d203304cdc8217b012b8130e1f1` |
Décision : `raydium_pool_v4.json` ne correspond à aucun fichier JSON local actuel. Il reste une source annexe d'audit AMM v4/strategy/wrapper à traiter plus tard, sans bloquer `0.7.53`.
## SQL associé
Voir :
```text
validation_sql/SQL_VALIDATION_DEX_COVERAGE_GLOBAL_0_7_53.sql
```

View File

@@ -0,0 +1,151 @@
<!-- file: docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md -->
# Note technique — `k_sol_fee_event_amounts` et policy fees — `0.7.56`
## Objectif
La table `k_sol_fee_events` était suffisante pour un fee mono-montant, mais insuffisante pour les cas multi-mint, multi-destination ou multi-composant. `0.7.56` ajoute donc `k_sol_fee_event_amounts` comme table de legs rattachée au parent fee.
## Modèle
```text
k_sol_fee_events
id
transaction_id
decoded_event_id
fee_token_mint nullable / vide si multi-leg
fee_amount_raw nullable / vide si multi-leg
payload_json
k_sol_fee_event_amounts
id
fee_event_id
transaction_id
decoded_event_id
leg_index
fee_component_kind
token_mint
amount_raw
source_account
destination_account
amount_source
payload_json
```
## Règles invariantes
1. Un parent fee scalaire avec `fee_token_mint + fee_amount_raw` doit toujours avoir un leg `0`.
2. Un parent multi-leg ou multi-mint ne doit pas agréger artificiellement ses montants dans le parent.
3. Les legs doivent pointer vers le même `transaction_id` et `decoded_event_id` que le parent.
4. Les legs doivent être supprimés/remplacés lors du replay/cleanup parent.
5. Les transactions failed ne doivent pas créer de parent ou leg fee métier.
6. Les bornes d'instruction (`maxAmount`, `minAmount`, `u64::MAX`) ne sont pas des montants exécutés.
## Sources de montant acceptées
| `amount_source` | Usage |
|---|---|
| `parent_fee_event_amount` | Leg généré automatiquement depuis un parent scalaire déjà fiable. |
| `fee_event_amounts` | Source explicite reconstruite par un matérialisateur spécialisé. |
| `inner_spl_transfer` | CPI SPL vérifié dans un matérialisateur spécialisé. |
| `lamport_balance_delta` | Delta lamports prouvé et contextualisé. |
| `allowlisted_inner_spl_transfer` | Recovery générique mais strictement allowlistée pour event kinds déjà validés. |
## Recovery allowlistée
La recovery `allowlisted_inner_spl_transfer` n'est pas une règle globale. Elle s'applique seulement aux event kinds explicitement autorisés dans le code. Cette restriction protège les futurs décodeurs : une nouvelle surface ne doit jamais créer des legs fee à partir de transferts internes tant que la sémantique n'a pas été inspectée.
Résultats de validation croisée en `0.7.56` :
| Base / surface | Effet observé |
|---|---|
| `meteora_dbc` | Aucun usage de l'allowlist générique ; chemins spécialisés DBC conservés. |
| `raydium_launchpad` | `212` parents enrichis en legs : `claim_creator_fee`, `claim_platform_fee`, `claim_platform_fee_from_vault`, `collect_fee`. |
| `raydium_cpmm` | `collect_creator_fee` enrichi ; `collect_fund_fee` / `collect_protocol_fee` explicités sans transfert exploitable. |
| `pump_swap` | `collect_coin_creator_fee` et un `transfer_creator_fees_to_pump_v2` enrichis ; autres cas zero/no-transfer explicités. |
| `pump_fees` | `crank_donation_fee_pda` et `sweep_buyback` enrichis ; events déjà scalaires conservés. |
## Contrôles SQL obligatoires
### Parent scalaire sans leg
```sql
SELECT
de.protocol_name,
de.event_kind,
tx.signature,
fee.id AS fee_event_id,
fee.fee_token_mint,
fee.fee_amount_raw,
fee.payload_json
FROM k_sol_fee_events fee
JOIN k_sol_dex_decoded_events de
ON de.id = fee.decoded_event_id
JOIN k_sol_chain_transactions tx
ON tx.id = fee.transaction_id
LEFT JOIN k_sol_fee_event_amounts fea
ON fea.fee_event_id = fee.id
WHERE COALESCE(TRIM(fee.fee_token_mint), '') <> ''
AND COALESCE(TRIM(fee.fee_amount_raw), '') <> ''
AND fea.id IS NULL
ORDER BY
de.protocol_name,
de.event_kind,
tx.signature
LIMIT 100;
```
Attendu : vide.
### Legs orphelins
```sql
SELECT
fea.id,
fea.fee_event_id,
fea.transaction_id,
fea.decoded_event_id
FROM k_sol_fee_event_amounts fea
LEFT JOIN k_sol_fee_events fee
ON fee.id = fea.fee_event_id
WHERE fee.id IS NULL;
```
Attendu : vide.
### Résumé parent/legs par event
```sql
SELECT
de.protocol_name,
de.event_kind,
COUNT(DISTINCT fee.id) AS fee_parent_count,
COUNT(DISTINCT CASE
WHEN COALESCE(TRIM(fee.fee_token_mint), '') <> ''
AND COALESCE(TRIM(fee.fee_amount_raw), '') <> ''
THEN fee.id
ELSE NULL
END) AS parent_with_scalar_amount_count,
COUNT(DISTINCT fea.id) AS fee_amount_leg_count,
MIN(tx.signature) AS sample_signature
FROM k_sol_fee_events fee
JOIN k_sol_dex_decoded_events de
ON de.id = fee.decoded_event_id
JOIN k_sol_chain_transactions tx
ON tx.id = fee.transaction_id
LEFT JOIN k_sol_fee_event_amounts fea
ON fea.fee_event_id = fee.id
GROUP BY
de.protocol_name,
de.event_kind
ORDER BY
de.protocol_name,
de.event_kind;
```
## Règles pour `0.7.57 meteora_dlmm`
- Les instructions `claim_fee`, `claim_fee2`, `withdraw_protocol_fee`, `zap_protocol_fee`, `CompositionFee`, `ClaimFee`, `ClaimFee2` doivent utiliser `k_sol_fee_event_amounts` dès qu'un montant/mint fiable est disponible.
- Les rewards (`claim_reward*`, `fund_reward`, `withdraw_ineligible_reward`) vont vers `k_sol_reward_events`, pas vers fees, sauf sémantique contraire prouvée.
- Les `composition_fee` de swap/liquidity ne doivent pas être double-comptés si déjà inclus dans le trade/liquidity effectif.
- Toute recovery générique doit être déclarée par policy explicite et tests synthétiques ; ne pas ajouter DLMM à l'allowlist sans audit par event kind.

View File

@@ -0,0 +1,161 @@
<!-- file: docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md -->
# Meteora DBC Event Coverage Report — `0.7.56 final`
## Statut final
La tranche `0.7.56 meteora_dbc` est clôturée.
Program id :
```text
dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN
```
Source locale prioritaire :
```text
idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json
```
Surface IDL : `28` instructions, `23` events Anchor, `9` accounts, `59` types.
## Résultat build/replay final
```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
0 tokenAccount
1056 candle upserts
instructionObservations = 7167
resetDeleted = 3583
catalog = 86 tokens / 60 pools / 60 pairs
```
Replay final recommandé pour reproduire :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
## Décisions métier verrouillées
### Swaps
- `meteora_dbc.swap` et `meteora_dbc.swap2` sont les seules entrées candidates trade/candle directes.
- Les trades/candles ne sont produits que si les montants exécutés et les mints base/quote sont fiables.
- Les montants de `swap2` doivent être dérivés du layout et/ou des CPI SPL effectifs ; ne pas utiliser naïvement les bornes d'instruction.
- Les events Anchor `EvtSwap` / `EvtSwap2` restent decoded-only s'ils ne portent pas un contexte mint/pair suffisant ou s'ils doublonnent l'instruction matérialisée.
### Lifecycle / migration / lockers
- `initialize_virtual_pool_with_spl_token` et `initialize_virtual_pool_with_token2022` alimentent lifecycle/catalog lorsque les comptes pool/base/quote/config sont fiables.
- `create_locker`, `migrate_meteora_damm_claim_lp_token`, `migrate_meteora_damm_lock_lp_token`, `migration_damm_v2*` et `migrate_meteora_damm*` sont lifecycle, pas liquidity artificielle.
- Les metadata-only restent decoded-only avec raison explicite si elles n'apportent pas de cible métier fiable.
### Admin/config
- `create_config`, `create_operator_account`, `close_*operator*`, metadata, `transfer_pool_creator` et events config/admin alimentent `k_sol_pool_admin_events` uniquement si l'acteur et la cible sont fiables.
- Les payloads génériques ou incomplets restent audit/decoded-only.
### Fees
- Les fees DBC utilisent le modèle parent+legs : `k_sol_fee_events` + `k_sol_fee_event_amounts`.
- Les maxima d'instruction (`maxAmount*`, `u64::MAX`, bornes de claim) ne sont pas des montants exécutés.
- Les montants fiables proviennent des CPI SPL, des legs explicitement reconstruits ou des lamport balance deltas prouvés.
- Les events Anchor fee sans mint restent decoded-only avec `skipFeeReason`.
- Les cas sans transfert réel portent `fee_instruction_has_no_actual_transfer` ou `fee_instruction_has_only_zero_amount_transfers`.
## Matérialisation fee finale
| Event kind | Fee parents | Parents scalaires | Amount legs | Décision |
|---|---:|---:|---:|---|
| `meteora_dbc.claim_creator_trading_fee` | 8 | 8 | 8 | Mono-leg fiable. |
| `meteora_dbc.claim_partner_pool_creation_fee` | 10 | 10 | 10 | Mono-leg fiable. |
| `meteora_dbc.claim_protocol_fee` | 10 | 10 | 10 | Mono-leg fiable. |
| `meteora_dbc.claim_protocol_pool_creation_fee` | 10 | 10 | 10 | Mono-leg/lamport delta fiable. |
| `meteora_dbc.claim_trading_fee` | 11 | 6 | 18 | Mix mono-leg et multi-leg ; parent non agrégé pour multi-leg. |
| `meteora_dbc.creator_withdraw_surplus` | 2 | 2 | 2 | Mono-leg fiable ; résiduels sans transfert réel explicités. |
| `meteora_dbc.partner_withdraw_surplus` | 9 | 9 | 9 | Mono-leg fiable. |
| `meteora_dbc.withdraw_leftover` | 10 | 10 | 10 | Mono-leg fiable. |
| `meteora_dbc.withdraw_migration_fee` | 9 | 9 | 9 | Fee, pas migration target ; mono-leg fiable. |
| `meteora_dbc.zap_protocol_fee` | 10 | 10 | 10 | Mono-leg fiable. |
| **Total `meteora_dbc`** | **89** | n/a | **96** | Parent+legs validé. |
## Socle `k_sol_fee_event_amounts`
La version `0.7.56` ajoute un modèle durable pour les fees composés :
- `k_sol_fee_events` est le parent logique unique lié au `decoded_event_id` ;
- `k_sol_fee_event_amounts` contient les legs de montants, avec `leg_index`, `fee_component_kind`, `token_mint`, `amount_raw`, comptes source/destination et `amount_source` ;
- un parent avec `fee_token_mint + fee_amount_raw` crée automatiquement un leg scalaire ;
- un parent multi-leg/multi-mint laisse les champs scalaires du parent vides et stocke tout dans les legs ;
- les deletes/replays nettoient les legs avant ou avec le parent ;
- la requête de contrôle `parent scalar without leg` doit rester vide.
Sources `amount_source` connues en fin de tranche :
```text
parent_fee_event_amount
fee_event_amounts
inner_spl_transfer
lamport_balance_delta
allowlisted_inner_spl_transfer
```
## Recovery fee allowlistée
La recovery `allowlisted_inner_spl_transfer` est volontairement non globale.
Elle a été testée sur anciennes bases pour enrichir les surfaces déjà connues :
| Surface testée | Résultat |
|---|---|
| `raydium_launchpad` | `claim_creator_fee`, `claim_platform_fee`, `claim_platform_fee_from_vault`, `collect_fee` enrichis en legs depuis CPI SPL. |
| `raydium_cpmm` | `collect_creator_fee` enrichi ; `collect_fund_fee` et `collect_protocol_fee` restent sans transfert réel exploitable dans le corpus testé. |
| `pump_swap` | `collect_coin_creator_fee` et certains `transfer_creator_fees_to_pump_v2` enrichis ; cas zero/no-transfer explicités. |
| `pump_fees` | `crank_donation_fee_pda` et `sweep_buyback` enrichis ; events déjà scalaires conservés. |
| `meteora_dbc` | Non concerné par l'allowlist générique ; DBC conserve ses chemins spécifiques. |
Règle pour les prochaines versions : tout nouveau decoder doit déclarer explicitement sa policy de récupération des montants fee. Aucun futur decoder ne doit hériter automatiquement de la recovery CPI SPL.
## Checks de fermeture
Les contrôles de fermeture exigés sont propres :
- fallback `upstream_git` `meteora_dbc` pour entrées couvertes localement : vide ;
- decoded `meteora_dbc` sans coverage : vide ;
- successful non-materialized sans `skip*Reason` ou policy explicite : vide ;
- failed tx avec materialization métier : vide ;
- multi-target materialization : vide ;
- non-swap DBC vers trade/candle : vide ;
- parent fee scalaire sans leg : vide ;
- legs fee orphelins : vide ;
- watchlist globale sans backlog dominant `meteora_dbc`.
## Fichiers de référence
```text
kb_lib/src/dex/meteora_dbc.rs
kb_lib/src/non_trade_event_materialization.rs
kb_lib/src/db/queries/fee_event_amount.rs
kb_lib/src/db/entities/fee_event_amount.rs
kb_lib/src/db/dtos/fee_event_amount.rs
validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql
docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md
docs/VALIDATION_STATUS_0_7_56_FINAL.md
docs/prompts/PROMPT_0_7_57_METEORA_DLMM_FULL_DECODE_MATERIALIZATION.md
```
## Décision
`0.7.56 meteora_dbc` est clôturé. La prochaine tranche est `0.7.57 meteora_dlmm` en full decode + full materialization.

View File

@@ -0,0 +1,182 @@
# Meteora DLMM event coverage report — 0.7.57 final
## Scope
Version `0.7.57` closes `meteora_dlmm` from the local IDL and the dedicated local corpus.
Target program:
```text
LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
```
Local IDL:
```text
idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json
```
Final inventoried surface:
```text
76 IDL instructions
30 Anchor events
12 accounts
```
The local corpus additionally identified discriminator `75c73e67068e1fcb` as `initialize_preset_parameter_v2`. This discriminator was not present in the local IDL under that spelling, but the transaction logs contain `Instruction: InitializePresetParameterV2`, the account layout is stable, and the instruction creates a 36-byte DLMM-owned preset parameter account through the system program.
## Final validation summary
```text
cargo test -p kb_lib -> 460 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
769 replayed
0 decode skipped
769 ledger upserts
646 unsafe ledger rows
106 trades
664 liquidity
1107 lifecycle
0 tokenAccount
424 candle upserts
instructionObservations = 8062
resetDeleted = 9898
catalog = 169 tokens / 218 pools / 218 pairs
```
## Closure checks
All blocking checks are clean:
```text
upstream_git fallback for locally covered meteora_dlmm entries -> empty
local instruction_audit observed -> 0
DLMM decoded events without coverage -> empty
successful non-materialized DLMM without explicit skip/policy -> empty
failed transaction business materialization -> empty
multi-target materialization -> empty
non-swap trade/candle safety -> empty
fee parent scalar without fee amount leg -> empty
orphan fee amount legs -> empty
limit/orderbook trade/candle double-count -> empty
logical duplicate coverage rows -> empty
```
The only coverage difference left is explained and non-blocking:
```text
close_bin_array observed 16 / materialized 14
14 successful transactions -> lifecycle materialized
2 failed transactions Custom 6015 -> decoded/audit only, no business materialization
```
## Materialization policy
### Trades and candles
Only instruction-level DLMM swaps can produce trades/candles:
```text
meteora_dlmm.swap
meteora_dlmm.swap2
meteora_dlmm.swap_exact_out
meteora_dlmm.swap_exact_out2
meteora_dlmm.swap_with_price_impact
meteora_dlmm.swap_with_price_impact2
```
Anchor `swap_event` and `swap2_evt` are materialized as lifecycle `swap_log` rows and never as trades/candles. This prevents double-counting when an instruction swap and an Anchor log describe the same user-visible swap.
### Liquidity and lifecycle
The following families are materialized when transactions are successful and context is reliable:
```text
add_liquidity*
remove_liquidity*
remove_all_liquidity
rebalance_liquidity
initialize_bin_array*
close_bin_array
go_to_a_bin*
initialize_position*
close_position*
increase_position_length*
decrease_position_length*
update_position_operator*
lb_pair_create_event
position_create_event
position_close_event
```
Position and bin lifecycle events are routed to `k_sol_pool_lifecycle_events` when the operation is structural rather than a direct liquidity amount delta.
### Fees
Fee parents are written to `k_sol_fee_events`. Amount legs are written to `k_sol_fee_event_amounts`.
Final observed amount-leg summary:
```text
claim_fee 64 parents / 64 legs
claim_fee2 63 parents / 88 legs
claim_fee_event 127 parents / 187 legs
claim_fee2_event 78 parents / 118 legs
composition_fee_event 51 parents / 63 legs
withdraw_protocol_fee 14 parents / 20 legs
zap_protocol_fee 13 parents / 13 legs
```
The inner SPL transfer recovery is explicitly allowlisted for DLMM fee event kinds. It is not inherited globally by future decoders.
### Rewards
Reward parents are written to `k_sol_reward_events`. Amounts are recovered only when a reliable inner SPL transfer or decoded amount is present.
Final observed scalar amount summary:
```text
claim_reward 15 parents / 1 scalar amount
claim_reward2 19 parents / 10 scalar amounts
claim_reward_event 34 parents / 25 scalar amounts
claim_reward2_event 19 parents / 10 scalar amounts
fund_reward 10 parents / 10 scalar amounts
fund_reward_event 10 parents / 10 scalar amounts
initialize_reward 9 parents / 0 amount
initialize_reward_event 9 parents / 0 amount
```
`initialize_reward` and `initialize_reward_event` remain without amount because they are configuration/initialization events, not executed reward transfers. No amount is fabricated from limits, bounds or configuration fields.
### Admin/config and orderbook
Admin/config events materialize to `k_sol_pool_admin_events`. Limit-order operations materialize to `k_sol_orderbook_events` and never to trade/candle tables.
Important promoted local corpus entry:
```text
75c73e67068e1fcb -> meteora_dlmm.initialize_preset_parameter_v2 -> k_sol_pool_admin_events
```
## Remaining non-observed surfaces
Non-observed IDL/account rows remain in coverage with `observed_count = 0` and `materialized_count = 0`. They are not blockers.
Examples:
```text
update_reward_duration
update_reward_funder
withdraw_ineligible_reward
migrate_position
account metadata rows
for_idl_type_generation_do_not_call
anchor_self_cpi_log registry row
```
## Decision
`0.7.57 meteora_dlmm` is closed. Do not add further DLMM Rust patches unless a new corpus proves a successful transaction that is decoded but not materialized and lacks an explicit skip/policy reason.
Next recommended work is not another DLMM patch: implement `0.7.58 sqlite_db_transaction_merger` first, then move `demo4_program_surface_discovery` to `0.7.59`. The merger is required to build a consolidated cross-DEX regression corpus before new surface discovery work.

View File

@@ -0,0 +1,134 @@
<!-- file: docs/reports/PUMP_FEES_EVENT_COVERAGE_REPORT.md -->
# Pump Fees event coverage report — 0.7.55 final
## Portée
Programme cible : `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ`.
Source locale prioritaire : `idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json`.
L'IDL locale couvre `29` instructions, `20` events Anchor, `9` accounts et `34` types. La tranche ajoute un decoder local maximal `pump_fees` depuis l'IDL locale, le registre Carbon partiel et les discriminators observés via Solscan/corpus.
## Décisions métier
- `pump_fees` est traité comme programme fee/config/accounting.
- Aucun `k_sol_trade_events` ni candle ne doit être créé pour `pump_fees` sans preuve transactionnelle stricte d'un swap autonome.
- `get_fees` reste decoded-only : il décrit un calcul/preview de fees, pas un paiement réalisé.
- Les claims social fee alimentent `k_sol_reward_events` seulement si transaction OK et montant/acteur/mint exploitables.
- Les flux donation/buyback alimentent `k_sol_fee_events` seulement si transaction OK et montant fiable.
- Les créations/configurations/autorités/tiers alimentent `k_sol_pool_lifecycle_events` ou `k_sol_pool_admin_events` selon classification.
- Les transactions failed restent decoded-only/audit-only.
## Résultat build/test
```text
cargo test -p kb_lib -> 431 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
## Replay final rapporté
```text
127 replayed
0 decode skipped
150 ledger upserts
125 unsafe ledger rows
4 trades
0 liquidity
115 lifecycle
0 tokenAccount
16 candle upserts
instructionObservations = 2234
resetDeleted = 1644
catalog = 11 tokens / 10 pools / 10 pairs
```
Les `4 trades` et `16 candle upserts` du replay proviennent d'autres surfaces du corpus local ; le contrôle anti-trade `pump_fees` est vide.
## Coverage local
### Instructions observées et couvertes
| Instruction | Discriminator | Observation principale | Matérialisation |
|---|---:|---:|---|
| `sweep_buyback` | `8a21cc26cfa19fe2` | `96` | `k_sol_fee_events` |
| `create_fee_sharing_config` | `c34e564c6f34fbd5` | `42` observations / `36` decoded | `k_sol_pool_lifecycle_events` |
| `update_fee_shares` | `bd0d8863bba4ed23` | `26` observations / `16` decoded | `k_sol_pool_admin_events` |
| `claim_social_fee_pda_v2` | `114df0863abc3595` | `25` | `k_sol_reward_events` |
| `update_fee_shares_v2` | `6ffb31064e4e6a12` | `19` | `k_sol_pool_admin_events` |
| `claim_social_fee_pda` | `e115fb85a11ec7e2` | `15` observations / `10` decoded | `k_sol_reward_events` |
| `crank_donation_fee_pda` | `dc0abda7a9111945` | `14` | `k_sol_fee_events` |
| `get_fees` | `e7257e55cf5b3f34` | `13` observations / `5` decoded | decoded-only |
| `transfer_fee_sharing_authority` | `ca0a4bc8a422d260` | `12` | `k_sol_pool_admin_events` |
| `initialize_fee_program_global` | `23d78254e9387ca7` | `1` | `k_sol_pool_lifecycle_events` |
Le discriminator `e445a52e51cb9a1d` est classé comme `pump_fees.anchor_self_cpi_log` transport Anchor self-CPI : `271` observations / `119` tx.
### Instructions IDL non observées mais programmées
Ces entrées n'ont pas de signature Solscan/corpus au moment de la clôture, mais restent décodables si des transactions futures apparaissent :
| Instruction | Discriminator | Classification | Target prévu |
|---|---:|---|---|
| `reset_fee_sharing_config_v2` | `a9f511d15e5bf880` | admin_config | `k_sol_pool_admin_events` |
| `set_authority` | `85fa25156ea31a79` | admin_config | `k_sol_pool_admin_events` |
| `set_claim_rate_limit` | `b9d39faed4315804` | audit | decoded-only |
| `set_disable_flags` | `c2d9702372de33be` | admin_config | `k_sol_pool_admin_events` |
| `set_social_claim_authority` | `9336b89a88edb999` | admin_config | `k_sol_pool_admin_events` |
### Anchor events IDL non observés mais testés synthétiquement
| Event Anchor | Discriminator | Statut |
|---|---:|---|
| `SetAuthorityEvent` | `12af8442d0c957f2` | decoder + test synthétique |
| `SetClaimRateLimitEvent` | `0d8f8febb5133328` | decoder + test synthétique |
| `SetDisableFlagsEvent` | `0508b3413137917e` | decoder + test synthétique |
| `SetSocialClaimAuthorityEvent` | `3c767f84ef34fe0e` | decoder + test synthétique |
### Discriminators Solscan hors IDL locale
Ces discriminators ont été trouvés par filtres Solscan, mais ne sont pas observés dans le corpus local final et ne sont pas dans l'IDL locale fournie. Ils restent conservés en coverage comme surfaces futures :
| Event | Discriminator | Statut |
|---|---:|---|
| `revoke_fee_sharing_authority_event` | `7217653c0ebe993e` | `upstream_git_mapped_unverified` |
| `transfer_fee_sharing_authority_event` | `7c8fc6f54db808ec` | `upstream_git_mapped_unverified` |
## Écarts observed/materialized
Les écarts `observed_count > materialized_count` sont expliqués par des transactions failed ou par une politique decoded-only. La requête `09b` documente notamment :
| Entrée | Observed | Materialized | Explication |
|---|---:|---:|---|
| `get_fees` | `5` | `0` | decoded-only volontaire |
| `claim_social_fee_pda_v2` | `25` | `21` | `4` failed decoded |
| `create_fee_sharing_config` | `36` | `33` | `3` failed decoded |
| `initialize_fee_config` | `5` | `2` | `3` failed decoded |
| `social_fee_pda_claimed` | `17` | `15` | `2` failed decoded |
| `crank_donation_fee_pda` | `14` | `12` | `2` failed decoded |
| `update_fee_shares_v2` | `19` | `17` | `2` failed decoded |
| `revoke_fee_sharing_authority` | `6` | `5` | `1` failed decoded |
La requête `06` confirme qu'il n'existe aucun successful non-materialized sans skip/policy explicite.
## Checks de fermeture
SQL dédié : `validation_sql/SQL_VALIDATION_PUMP_FEES_0_7_55.sql`.
Résultats de fermeture rapportés :
- fallback `upstream_git` `pump_fees` : vide ;
- `instruction_name` `pump_fees` vide : vide ;
- `event_family = unknown` ou vide pour instruction/event : vide ;
- decoded `pump_fees` sans coverage : vide ;
- fallback résiduel pour entrées couvertes localement : vide ;
- successful non-materialized sans skip/policy : vide ;
- failed transaction avec business materialization : vide ;
- multi-target materialization : vide ;
- anti-trade/candle direct `pump_fees` : vide ;
- watchlist globale : plus aucun `pump_fees`, reste seulement `jupiter_swap.route_v2` comme backlog ponctuel.
## Statut final
`0.7.55 pump_fees` est clôturé techniquement. Ne pas rouvrir `pump_fees`, `pump_fun`, `pump_swap` ou Raydium sans bug prouvé par SQL/code ou apparition d'un nouveau discriminant/corpus externe exploitable.

View File

@@ -0,0 +1,127 @@
<!-- file: docs/reports/PUMP_FUN_EVENT_COVERAGE_REPORT.md -->
# Pump.fun event coverage report — clôture `0.7.54`
## Statut du rapport
Ce rapport clôture la tranche `0.7.54 pump_fun` côté coverage, décodage local, matérialisation métier prudente et validation SQL.
Program id canonique :
```text
6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P
```
Source IDL locale prioritaire :
```text
idls/pump_fun.6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.json
```
## Sources utilisées
- `kb_lib/src/dex/pump_fun.rs` ;
- `kb_lib/src/dex_decode.rs` ;
- `kb_lib/src/trade_aggregation.rs` ;
- `kb_lib/src/trade_amount_resolution.rs` ;
- `kb_lib/src/dex_detection_route.rs` ;
- `kb_lib/src/dex_event_coverage.rs` ;
- `kb_lib/src/upstream_registry_generated.rs` ;
- `idls/pump_fun.6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.json` ;
- `validation_sql/SQL_VALIDATION_PUMP_FUN_0_7_54.sql` ;
- `validation_sql/SQL_VALIDATION_PUMP_FUN_MATERIALIZATION_0_7_54.sql` ;
- corpus SQLite bâti par backfills Demo3/signatures/pools et replay forcé.
## Couverture finale
L'IDL locale Pump.fun contient `40` instructions et `23` events Anchor. La tranche a ajouté la couverture locale des instructions/events connues, y compris les instructions IDL-only absentes du registre upstream initial :
- `add_quote_mint` ;
- `buy_exact_quote_in_v2` ;
- `buy_v2` ;
- `claim_cashback_v2` ;
- `collect_creator_fee_v2` ;
- `distribute_creator_fees_v2` ;
- `migrate_v2` ;
- `remove_quote_mint` ;
- `sell_v2` ;
- `set_virtual_quote_reserves` ;
- `update_buyback_config`.
Les events Anchor sont reconnus depuis `Program data:` et depuis le transport Anchor self-CPI/log `e445a52e51cb9a1d` quand présent.
## Règles de matérialisation finales
### Trades
| Source locale | Matérialisation | Règle |
|---|---|---|
| `pump_fun.buy` | `k_sol_trade_events` | directe si montants fiables |
| `pump_fun.sell` | `k_sol_trade_events` | directe si montants fiables |
| `pump_fun.buy_exact_sol_in` | `k_sol_trade_events` | directe ; les logs `Program data` tronqués sont exploités quand les montants exacts sont extractibles |
| `pump_fun.buy_v2` | non directe | instruction audit/coverage/routing uniquement |
| `pump_fun.sell_v2` | non directe | instruction audit/coverage/routing uniquement |
| `pump_fun.buy_exact_quote_in_v2` | non directe | instruction audit/coverage/routing uniquement |
| `pump_fun.trade_event` | `k_sol_trade_events` | source canonique des montants exécutés v2/exact quand corrélée sans ambiguïté |
Les `trade_event` déjà couverts par une instruction directe reçoivent un skip explicite afin d'éviter tout double-count.
### Non-trades
Les événements non-trade sont matérialisés uniquement vers leur table métier ciblée quand les comptes, acteurs et montants sont fiables :
- `k_sol_launch_events` pour create/migrate/graduate ;
- `k_sol_fee_events` pour creator fees, fee distribution et minimum fee ;
- `k_sol_reward_events` pour cashback, incentives et volume accumulators exploitables ;
- `k_sol_pool_admin_events` pour admin/config/creator/global authority ;
- `k_sol_pool_lifecycle_events` pour initialization/lifecycle.
Sinon, ils restent decoded-only/audit-only avec `skip*Reason` explicite. Les transactions failed ne produisent aucune matérialisation métier.
## Replay final rapporté
```text
1679 replayed
0 decode skipped
1679 ledger upserts
145 unsafe ledger rows
89 trades
0 liquidity
10 lifecycle
0 tokenAccount
348 candle upserts
instructionObservations = 13905
resetDeleted = 1112
catalog = 52 tokens / 50 pools / 50 pairs
```
## Matérialisation finale Pump.fun observée
```text
pump_fun.buy 17 trades
pump_fun.sell 25 trades
pump_fun.buy_exact_sol_in 15 trades
pump_fun.trade_event 25 trades
```
Les variantes v2/exact restent à `0` dans `k_sol_trade_events` par `decoded_event_id` d'instruction, ce qui est attendu : leur matérialisation canonique se fait via `pump_fun.trade_event`.
## Checks de fermeture SQL
Résultats finaux rapportés :
- `Q00` upstream fallback Pump.fun : vide ;
- `Q04` decoded Pump.fun sans coverage : vide ;
- `Q05` fallback upstream couvert localement : vide ;
- `Q06` successful non-materialized sans skip reason : vide ;
- `Q07` failed transaction materialization safety : vide ;
- `Q08` multi-target materialization safety : vide ;
- `Q11` trade candidates sans trade ni skip : vide ;
- `Q12` watchlist globale : plus de `pump_fun` ; restent `pump_fees`, `jupiter_swap` et `dflow_aggregator_v4`.
## Décisions de clôture
- `pump_fun` est clos côté decoder maximal local et validation corpus.
- Les prochaines interventions Pump.fun doivent être des corrections de bugs ou des adaptations à un changement externe prouvé.
- La suite logique est `0.7.55 pump_fees` sur nouvelle base SQLite.
- La politique reste : tout ce qui peut être décodé doit l'être ; tout ce qui peut être matérialisé de manière fiable doit l'être ; aucun trade/candle artificiel ne doit être créé.

View File

@@ -0,0 +1,168 @@
<!-- file: docs/reports/PUMP_SWAP_EVENT_COVERAGE_REPORT.md -->
# PumpSwap event coverage report — `0.7.53`
## Scope
- Version cible : `0.7.53`.
- Surface unique : `pump_swap`.
- Program id unique : `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA`.
- Phasage : une version = un `program_id`.
- `raydium_pool_v4.json` reste repoussé vers la fin du phasage et ne bloque pas cette tranche.
## Sources vérifiées / à vérifier pendant la fermeture
- `kb_lib/src/constants.rs`, notamment `PUMP_SWAP_PROGRAM_ID` et `SOLSCAN_ACCOUNT_SOURCES`.
- Registre upstream local généré : `kb_lib/src/upstream_registry_generated.rs`.
- Sources Git/IDL externes disponibles : Pump public docs / IDL, Carbon, fnzero, Pinax, HODL Warden si présents dans le registre.
- IDL locale : `idls/pump_swap.pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA.json`, téléchargée depuis Solscan et versionnée dans le workspace.
- Solscan IDL du program id PumpSwap si disponible.
- Corpus local Demo3 + backfills signature/pool.
- `k_sol_dex_event_coverage_entries` après replay forcé.
Les sources Git/IDL/Solscan sont des indices. La fermeture métier exige corpus local, replay et SQL.
## Couverture locale ajoutée
Le decoder local `kb_lib/src/dex/pump_swap.rs` ne se limite plus à `buy`/`sell`. Il reconnaît maintenant les discriminants dinstruction suivants et produit un event spécialisé `pump_swap.<entry_name>`.
| Entry | Kind | Discriminator | Target attendu | Matérialisation |
|---|---|---:|---|---|
| `admin_set_coin_creator` | instruction | `f228759149606968` | admin/config | decoded specialized non-trade |
| `admin_update_token_incentives` | instruction | `d10b7357d5177ccc` | reward/admin | decoded specialized non-trade |
| `buy` | instruction | `66063d1201daebea` | trade | trade/candle seulement depuis montants exacts |
| `buy_exact_quote_in` | instruction | `c62e1552b4d9e870` | trade conditionnel | matérialisé seulement si un `BuyEvent` Anchor exact est présent (`amountSource=pump_swap_anchor_buy_event`) ; sinon decoded-only `instruction_bounds_only` avec `skipTradeReason` |
| `claim_cashback` | instruction | `253a237ebe35e4c5` | reward | decoded specialized non-trade |
| `claim_token_incentives` | instruction | `1004471ccc01281b` | reward | decoded specialized non-trade |
| `close_user_volume_accumulator` | instruction | `f945a4da9667548a` | reward | decoded specialized non-trade |
| `collect_coin_creator_fee` | instruction | `a039592ab58b2b42` | fee | decoded specialized non-trade |
| `create_config` | instruction | `c9cff3724b6f2fbd` | admin/config | decoded specialized non-trade |
| `create_pool` | instruction | `e992d18ecf6840bc` | pool lifecycle | decoded specialized non-trade |
| `deposit` | instruction | `f223c68952e1f2b6` | liquidity add | decoded specialized non-trade |
| `disable` | instruction | `b9adbb5ad80feee9` | admin/config | decoded specialized non-trade |
| `extend_account` | instruction | `ea66c2cb96483ee5` | admin/config | decoded specialized non-trade |
| `init_user_volume_accumulator` | instruction | `5e06ca73ff60e8b7` | reward | decoded specialized non-trade |
| `migrate_pool_coin_creator` | instruction | `d0089f044aaf103a` | admin/migration | decoded specialized non-trade |
| `sell` | instruction | `33e685a4017f83ad` | trade | trade/candle seulement depuis montants exacts |
| `set_coin_creator` | instruction | `d295802dbc3a4eaf` | admin/config | decoded specialized non-trade |
| `set_reserved_fee_recipients` | instruction | `6faca2e87259d58e` | admin/config | decoded specialized non-trade |
| `set_reserved_fee_recipient` | instruction | `cfbdb247a77a44b4` | admin/config | local log proof only: `Instruction: SetReservedFeeRecipient` ; absent from checked Solscan IDL raw ; decoded specialized non-trade |
| `sync_user_volume_accumulator` | instruction | `561fc057a3574fee` | reward | decoded specialized non-trade |
| `toggle_cashback_enabled` | instruction | `7367e0ffbd5956c3` | admin/config | decoded specialized non-trade |
| `toggle_mayhem_mode` | instruction | `01096fd0641fffa3` | admin/config | decoded specialized non-trade |
| `transfer_creator_fees_to_pump` | instruction | `8b348655e4e56cf1` | fee | decoded specialized non-trade |
| `transfer_creator_fees_to_pump_v2` | instruction | `01214eb921432c5c` | fee | Solscan IDL proof + local log proof: `transfer_creator_fees_to_pump_v2` / `Instruction: TransferCreatorFeesToPumpV2` ; decoded specialized non-trade |
| `update_admin` | instruction | `a1b028d53cb8b3e4` | admin/config | decoded specialized non-trade |
| `update_buyback_config` | instruction | `fbe0ab92a01a71e9` | admin/config | Solscan IDL proof + local log proof: `update_buyback_config` / `Instruction: UpdateBuybackConfig` ; decoded specialized non-trade |
| `update_fee_config` | instruction | `68b867f258976b14` | admin/config | decoded specialized non-trade |
| `withdraw` | instruction | `b712469c946da122` | liquidity remove | decoded specialized non-trade |
## Upstream Program-data events à statut explicite
Ces events sont listés dans le registre upstream. Ils doivent apparaître avec un statut explicite dans la coverage DB après sync/replay. Ils ne doivent pas créer de doublons trade/candle tant que linstruction locale spécialisée couvre déjà le DEX effectif.
| Event | Discriminator | Statut `0.7.53` |
|---|---:|---|
| `admin_set_coin_creator_event` | `2ddc5d181961ac68` | upstream listed ; decoded-only/status explicite après replay |
| `admin_update_token_incentives_event` | `93fa6c78f71d43de` | upstream listed ; decoded-only/status explicite après replay |
| `buy_event` | `67f4521f2cf57777` | upstream listed ; audit/decoded-only to avoid duplicate trade |
| `claim_cashback_event` | `e2d6f62107f293e5` | upstream listed ; decoded-only/status explicite après replay |
| `claim_token_incentives_event` | `4facf631cd5bcee8` | upstream listed ; decoded-only/status explicite après replay |
| `close_user_volume_accumulator_event` | `929fbdac925838f4` | upstream listed ; decoded-only/status explicite après replay |
| `collect_coin_creator_fee_event` | `e8f5c2eeeada3a59` | upstream listed ; decoded-only/status explicite après replay |
| `create_config_event` | `6b34598137e25116` | upstream listed ; decoded-only/status explicite après replay |
| `create_pool_event` | `b1310cd2a076a774` | upstream listed ; decoded-only/status explicite après replay |
| `deposit_event` | `78f83d531f8e6b90` | upstream listed ; decoded-only/status explicite après replay |
| `disable_event` | `6bfdc14ce4ca1b68` | upstream listed ; decoded-only/status explicite après replay |
| `extend_account_event` | `6161d7905d92167c` | upstream listed ; decoded-only/status explicite après replay |
| `init_user_volume_accumulator_event` | `86240d48e86582d8` | upstream listed ; decoded-only/status explicite après replay |
| `migrate_pool_coin_creator_event` | `aadd52c793a5f72e` | upstream listed ; decoded-only/status explicite après replay |
| `reserved_fee_recipients_event` | `2bbcfa12dd4bbb5f` | upstream listed ; decoded-only/status explicite après replay |
| `sell_event` | `3e2f370aa503dc2a` | upstream listed ; audit/decoded-only to avoid duplicate trade |
| `set_bonding_curve_coin_creator_event` | `f2e7eb664163bdd3` | upstream listed ; decoded-only/status explicite après replay |
| `set_metaplex_coin_creator_event` | `966bc77b7ccf66e4` | upstream listed ; decoded-only/status explicite après replay |
| `sync_user_volume_accumulator_event` | `c57aa77c74515bff` | upstream listed ; decoded-only/status explicite après replay |
| `update_admin_event` | `e198ab57f63f42ea` | upstream listed ; decoded-only/status explicite après replay |
| `update_fee_config_event` | `5a1741233ef4bcd0` | upstream listed ; decoded-only/status explicite après replay |
| `withdraw_event` | `1609851aa02c47c0` | upstream listed ; decoded-only/status explicite après replay |
## Matérialisation
- `pump_swap.buy`, `pump_swap.sell` et `pump_swap.buy_exact_quote_in` peuvent alimenter `k_sol_trade_events`, mais seulement depuis des montants exacts.
- `pump_swap.buy_exact_quote_in` est matérialisé quand le log Anchor `BuyEvent` fournit `baseAmountOutRaw` et `userQuoteAmountInRaw` pour `ixName=buy_exact_quote_in`. Les rows `instruction_bounds_only` restent decoded-only avec `skipTradeReason` explicite.
- Les bornes dinstruction (`maxQuoteAmountIn`, `spendableQuoteAmountIn`, `minQuoteAmountOut`, `minBaseAmountOut`) ne sont pas considérées comme des montants exacts suffisants pour créer un trade/candle.
- La matérialisation doit passer par les résolutions exactes existantes : token transfer deltas, vault/account balance deltas ou autre source damount explicitement prouvée.
- Les transactions failed restent decoded-only via lactionability `failed_transaction`.
- Les non-trades restent hors `k_sol_trade_events` et hors `k_sol_pair_candles`.
## SQL de fermeture
Le fichier dédié est :
```text
validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql
```
Les requêtes danomalies attendues vides couvrent :
- fallback upstream résiduel sur instruction couverte localement ;
- failed tx avec trade ;
- non-swap avec trade ;
- decoded without coverage ;
- successful non-materialized inexpliqué ;
- multi-target materialization ;
- successful swap exploitable sans trade et sans raison explicite.
## Delta post-replay `0.7.53-pump_swap-delta-1`
Le replay local a révélé trois écarts corrigés par ce delta :
- `pump_swap.toggle_cashback_enabled` était classé à la fois `reward` et `admin`; il devient admin-only pour respecter linvariant single-target.
- `pump_swap.buy_exact_quote_in` réussi non matérialisé reçoit maintenant un `skipTradeReason` explicite et reste decoded-only tant que les montants exacts ne sont pas prouvés.
- `k_sol_instruction_observations.instruction_name` reçoit un mapping PumpSwap par discriminant pour que la requête de coverage locale ne sorte plus des noms vides. Le discriminant `e445a52e51cb9a1d` reste marqué comme transport technique Anchor self-CPI. Les trois discriminants initialement inconnus ne doivent plus sortir en `observed_unknown_*` : deux sont confirmés par le raw Solscan IDL et un reste conservé comme local-log-only.
`pump_swap.migrate_pool_coin_creator` est également forcé en admin/config, pas lifecycle, car il modifie lattribution coin creator et ne représente pas une migration de pool échangeable.
## Delta post-replay `0.7.53-pump_swap-delta-2`
- Les trois discriminants initialement inconnus (`01214eb921432c5c`, `fbe0ab92a01a71e9`, `cfbdb247a77a44b4`) ont été provisoirement couverts decoded-only pour supprimer les gaps locaux sans inventer de métier.
- `toggle_cashback_enabled` est corrigé aussi dans la famille coverage (`admin_config`) afin de refléter la matérialisation admin-only.
## Delta post-replay `0.7.53-pump_swap-delta-4`
- Le corpus local donne maintenant le nom métier via logs Anchor : `TransferCreatorFeesToPumpV2`, `UpdateBuybackConfig`, `SetReservedFeeRecipient`.
- Ces trois discriminants deviennent des instructions locales spécialisées : `pump_swap.transfer_creator_fees_to_pump_v2`, `pump_swap.update_buyback_config`, `pump_swap.set_reserved_fee_recipient`.
- Recomparaison raw Solscan IDL : `transfer_creator_fees_to_pump_v2` et `update_buyback_config` sont présents dans lIDL. `set_reserved_fee_recipient` nest pas listé dans ce raw ; il est gardé sur preuve log locale, possiblement instruction historique/supprimée ou non exposée par cette version IDL.
- `transfer_creator_fees_to_pump_v2` est fee/non-trade ; `update_buyback_config` et `set_reserved_fee_recipient` sont admin/config non-trade.
## Clôture finale `0.7.53`
La tranche est clôturée après les deltas de consolidation :
- `buy_exact_quote_in` route désormais vers la matérialisation pool/pair/trade quand `amountSource=pump_swap_anchor_buy_event`;
- les montants du `BuyEvent` sont normalisés par rapport à lordre local de la paire pour éviter les inversions base/quote ;
- les events Anchor PumpSwap sont décodés comme events autonomes audit-only ;
- `claim_token_incentives_event` possède un test synthétique de matérialisabilité reward si un corpus réussi apparaît ;
- `sync_user_volume_accumulator_event` reste implémenté mais non observé malgré un backfill élargi sur linstruction ;
- les tests synthétiques couvrent les instructions/events IDL non observés localement ;
- `cargo test -p kb_lib` a été validé à `421 passed / 0 failed` et clippy est OK côté utilisateur.
Résultats de validation rapportés après corpus élargi :
```text
pump_swap decoded without coverage = vide
pump_swap upstream fallback couvert localement = vide
successful trade candidates sans trade = vide
failed tx avec business trade = vide
non-swap matérialisé en trade = vide
multi-target materialization = vide
buy_exact_quote_in / pump_swap_anchor_buy_event = 168 decoded / 167 trades / 1 failed tx
```
Les fichiers de surveillance à conserver sont :
- `validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql` ;
- `validation_sql/SQL_VALIDATION_DEX_COVERAGE_GLOBAL_0_7_53.sql` ;
- `docs/reports/DEX_COVERAGE_GLOBAL_WATCHLIST_0_7_53.md`.

View File

@@ -0,0 +1,141 @@
<!-- file: docs/reports/RAYDIUM_AMM_V4_EVENT_COVERAGE_REPORT.md -->
# Raydium AMM v4 Event Coverage Report — `0.7.51-final`
## Scope
Tranche : `0.7.51 raydium_amm_v4`.
Program id canonique local :
```text
675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
```
Code local canonique :
```text
raydium_amm_v4
```
Cette tranche reprend AMM v4 legacy après `0.7.50 raydium_launchpad` et les rechecks CPMM/CLMM. Les sources Git/IDL/Solscan restent des indices ; les statuts observé/matérialisé proviennent du corpus local et du replay forcé.
## Sources inventoriées
Sources utilisées comme indices de coverage :
- Carbon : `decoders/raydium-amm-v4-decoder` ;
- Pinax : `src/raydium/amm` ;
- fnzero `sol-parser-sdk` : `idl/raydium_amm_v4.json` et `idls/raydium_amm_v4.json` ;
- fnzero `sol-parser-sdk` : `idl/raydium_pool_v4.json` et `idls/raydium_pool_v4.json`, audit comparatif uniquement ;
- Solscan Program IDL et recherche `instruction=<discriminator>` pour `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8`.
## Validation Rust et replay final
Validation locale rapportée :
```text
cargo test -p kb_lib -> 405 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Replay local final :
```text
195 replayed
0 decode skipped
195 ledger upserts
70 unsafe ledger rows
168 trades
7 liquidity
15 lifecycle
0 tokenAccount
668 candle upserts
instructionObservations = 2599
resetDeleted = 1578
catalog = 61 tokens / 65 pools / 65 pairs
```
## Coverage finale par discriminant
| Discriminant | Entrée | Famille | Local event kind | Cible DB | Observed | Materialized | Trade |
|---|---|---|---|---|---:|---:|---:|
| `00` | `initialize` | `pool_create` | `raydium_amm_v4.initialize` | `k_sol_pool_lifecycle_events` | 4 | 4 | 0 |
| `01` | `initialize2` | `pool_create` | `raydium_amm_v4.initialize2_pool` | `k_sol_pool_lifecycle_events` | 8 | 8 | 0 |
| `02` | `monitor_step` | `order_place` | `raydium_amm_v4.monitor_step` | `k_sol_orderbook_events` | 20 | 20 | 0 |
| `03` | `deposit` | `liquidity_add` | `raydium_amm_v4.deposit` | `k_sol_liquidity_events` | 10 | 5 | 0 |
| `04` | `withdraw` | `liquidity_remove` | `raydium_amm_v4.withdraw` | `k_sol_liquidity_events` | 3 | 2 | 0 |
| `05` | `migrate_to_open_book` | `order_place` | `raydium_amm_v4.migrate_to_open_book` | `k_sol_orderbook_events` | 6 | 6 | 0 |
| `06` | `set_params` | `admin_config` | `raydium_amm_v4.set_params` | `k_sol_pool_admin_events` | 1 | 1 | 0 |
| `07` | `withdraw_pnl` | `fee` | `raydium_amm_v4.withdraw_pnl` | `k_sol_fee_events` | 1 | 1 | 0 |
| `08` | `withdraw_srm` | `fee` | `raydium_amm_v4.withdraw_srm` | `k_sol_fee_events` | 2 | 1 | 0 |
| `09` | `swap_base_in` | `swap` | `raydium_amm_v4.swap_base_in` | `k_sol_trade_events` | 76 | 66 | 66 |
| `0a` | `pre_initialize` | `pool_create` | `raydium_amm_v4.pre_initialize` | `k_sol_pool_lifecycle_events` | 8 | 7 | 0 |
| `0b` | `swap_base_out` | `swap` | `raydium_amm_v4.swap_base_out` | `k_sol_trade_events` | 3 | 1 | 1 |
| `0c` | `simulate_info` | `cpi_transport` | `raydium_amm_v4.simulate_info` | `k_sol_dex_decoded_events_only` | 6 | 0 | 0 |
| `0d` | `admin_cancel_orders` | `order_cancel` | `raydium_amm_v4.admin_cancel_orders` | `k_sol_orderbook_events` | 22 | 22 | 0 |
| `0e` | `create_config_account` | `admin_config` | `raydium_amm_v4.create_config_account` | `k_sol_pool_admin_events` | 50 | 50 | 0 |
| `0f` | `update_config_account` | `admin_config` | `raydium_amm_v4.update_config_account` | `k_sol_pool_admin_events` | 6 | 6 | 0 |
| `10` | `swap_base_in_v2` | `swap` | `raydium_amm_v4.swap_base_in_v2` | `k_sol_trade_events` | 35 | 35 | 35 |
| `11` | `swap_base_out_v2` | `swap` | `raydium_amm_v4.swap_base_out_v2` | `k_sol_trade_events` | 7 | 7 | 7 |
Toutes les entrées ont `proof_status=upstream_git_local_corpus_materialized`, sauf `simulate_info`, qui reste volontairement `upstream_git_local_corpus_observed` / decoded-only.
## Matérialisation métier finale
| Event kind | Decoded | Trade | Liquidity | Lifecycle | Fee | Admin | Orderbook |
|---|---:|---:|---:|---:|---:|---:|---:|
| `raydium_amm_v4.admin_cancel_orders` | 22 | 0 | 0 | 0 | 0 | 0 | 22 |
| `raydium_amm_v4.create_config_account` | 50 | 0 | 0 | 0 | 0 | 50 | 0 |
| `raydium_amm_v4.deposit` | 10 | 0 | 5 | 0 | 0 | 0 | 0 |
| `raydium_amm_v4.initialize2_pool` | 8 | 0 | 0 | 8 | 0 | 0 | 0 |
| `raydium_amm_v4.migrate_to_open_book` | 6 | 0 | 0 | 0 | 0 | 0 | 6 |
| `raydium_amm_v4.monitor_step` | 20 | 0 | 0 | 0 | 0 | 0 | 20 |
| `raydium_amm_v4.pre_initialize` | 8 | 0 | 0 | 7 | 0 | 0 | 0 |
| `raydium_amm_v4.set_params` | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
| `raydium_amm_v4.simulate_info` | 6 | 0 | 0 | 0 | 0 | 0 | 0 |
| `raydium_amm_v4.swap_base_in` | 76 | 66 | 0 | 0 | 0 | 0 | 0 |
| `raydium_amm_v4.swap_base_in_v2` | 35 | 35 | 0 | 0 | 0 | 0 | 0 |
| `raydium_amm_v4.swap_base_out` | 3 | 1 | 0 | 0 | 0 | 0 | 0 |
| `raydium_amm_v4.swap_base_out_v2` | 7 | 7 | 0 | 0 | 0 | 0 | 0 |
| `raydium_amm_v4.update_config_account` | 6 | 0 | 0 | 0 | 0 | 6 | 0 |
| `raydium_amm_v4.withdraw` | 3 | 0 | 2 | 0 | 0 | 0 | 0 |
| `raydium_amm_v4.withdraw_pnl` | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
| `raydium_amm_v4.withdraw_srm` | 2 | 0 | 0 | 0 | 1 | 0 | 0 |
## Invariants validés
Les requêtes finales donnent `vide` pour :
- `raydium_amm_v4.swap` legacy ;
- decoded AMM v4 sans coverage entry ;
- observations AMM v4 dont `length(discriminator_hex) > 2` ;
- non-swap AMM v4 avec trade ;
- transaction failed AMM v4 avec trade ;
- event successful non matérialisé sans raison explicite ;
- event AMM v4 matérialisé vers plus d'une table métier principale.
## Gaps expliqués
Les écarts `observed_count > materialized_count` sont acceptés uniquement s'ils sont expliqués :
- `swap_base_in` / `swap_base_out` : decoded-only lorsque les deltas vault ou montants exploitables sont absents ;
- `deposit` / `withdraw` : non matérialisés lorsque le pool/pair catalogue ou les deltas nécessaires sont absents ;
- `withdraw_srm` : non matérialisé si le contexte fee exploitable est absent ;
- `pre_initialize` : 1 transaction failed ; les 7 transactions successful sont matérialisées en lifecycle audit minimal ;
- `simulate_info` : decoded-only assumé.
Pour `deposit`, le corpus final montre 5 événements matérialisés sur le pool catalogué `2dRNngAm729NzLbb1pzgHtfHvPqR4XHFmFyYK78EfEeX` / pair `FIDA/RAY`, et 5 événements decoded-only sur des pools absents du catalogue local.
## Décisions spécifiques
- `raydium_amm_v4.swap` est définitivement interdit : les swaps doivent rester spécialisés.
- `pre_initialize` est conservé pour les scans historiques, matérialisé comme lifecycle audit deprecated/partial, sans pair exploitable.
- `migrate_to_open_book`, `monitor_step` et `admin_cancel_orders` sont des side effects orderbook AMM v4, pas des trades OpenBook autonomes.
- `simulate_info` reste `k_sol_dex_decoded_events_only`.
- Les side effects SPL Token / Token-2022 restent transversaux.
- `raydium_pool_v4` n'est pas promu en decoder autonome dans `0.7.51`.
## Clôture
`0.7.51 raydium_amm_v4` est clôturable côté `kb_lib` sous réserve de conserver les rechecks CPMM/CLMM/Launchpad dans la validation globale de workspace lorsque la base utilisée les contient.

View File

@@ -0,0 +1,140 @@
<!-- file: docs/reports/RAYDIUM_CLMM_EVENT_COVERAGE_REPORT.md -->
# Rapport `0.7.49` — Raydium CLMM event coverage
## Résumé
La tranche `0.7.49` clôture la couverture fonctionnelle `raydium_clmm` sur le corpus local validé. Elle reprend CLMM après `0.7.48 raydium_cpmm` et applique la même méthode : inventaire upstream, corpus local, replay forcé, materialization contrôlée, suppression des fallbacks remplacés, validation SQL.
Validation locale observée après le dernier replay :
```text
local replay: 2197 replayed, 0 decode skipped, 2197 ledger upserts, 1461 unsafe ledger rows, 1217 trades, 111 liquidity, 25 lifecycle, 4868 candle upserts, instructionObservations=19798
catalog: 41 tokens, 63 pools, 63 pairs
```
Synthèse coverage :
```text
listed_entry_count = 45
decoded_entry_count = 33
observed_entry_count = 33
materialized_entry_count = 25
total_observed_count = 2560
total_materialized_count = 1367
trade_count = 1186
```
## Entrées couvertes
La tranche couvre `33` instructions locales CLMM observées et décodées, dont :
```text
swap
swap_v2
swap_router_base_in
open_position
open_position_v2
open_position_with_token22_nft
close_position
close_protocol_position
increase_liquidity
increase_liquidity_v2
decrease_liquidity
decrease_liquidity_v2
create_pool
create_customizable_pool
create_amm_config
create_dynamic_fee_config
update_amm_config
update_pool_status
create_operation_account
update_operation_account
create_support_mint_associated
collect_fund_fee
collect_protocol_fee
collect_remaining_rewards
initialize_reward
set_reward_params
transfer_reward_owner
update_reward_infos
open_limit_order
increase_limit_order
decrease_limit_order
close_limit_order
settle_limit_order
```
## Matérialisations validées
Les matérialisations sont limitées aux transactions réussies et aux familles déjà supportées par le modèle DB :
| Famille | Table | Règle |
|---|---|---|
| Swaps | `k_sol_trade_events` + candles | Uniquement `raydium_clmm.swap` / `raydium_clmm.swap_v2` quand les montants sont exploitables. |
| Liquidity / positions | `k_sol_liquidity_events` | Positions/liquidity prouvées par corpus, sans trade/candle. |
| Fees | `k_sol_fee_events` | Fees prouvées par corpus, sans trade/candle. |
| Rewards | `k_sol_reward_events` | Rewards prouvées par corpus, sans trade/candle. |
| Admin/config | `k_sol_pool_admin_events` | Config/admin prouvés par corpus, sans trade/candle. |
| Lifecycle | `k_sol_pool_lifecycle_events` | Pool creation prouvée par corpus, sans trade/candle. |
| Limit orders | `k_sol_orderbook_events` | Open/increase/decrease/close/settle matérialisés comme orderbook, jamais trade/candle. |
## Invariants validés
Les requêtes SQL finales valident :
```text
raydium_clmm.instruction_audit résiduel = 0
upstream_git.instruction_match localement couvert = 0
non-swap CLMM avec trade_count > 0 = 0
failed tx matérialisées = 0
```
Les fallbacks `upstream_git.instruction_match` localement couverts sont supprimés automatiquement, y compris quand `k_sol_instruction_observations.decoded_event_id` pointait encore vers une ligne fallback.
## Anchor / Program-data events non observés
Les `11` Anchor / `Program data` events CLMM ci-dessous restent listés en `upstream_git_unverified`, car aucun corpus local ne les observe encore comme event direct :
```text
collect_personal_fee_event a6ae69c051a15369
collect_protocol_fee_event ce57114f2d29d53d
config_change_event f7bd07776a705f97
create_personal_position_event 641e57f9c4df9ace
decrease_liquidity_event 3ade563a44325538
increase_liquidity_event 314f69d420221e54
liquidity_calculate_event ed7094e63954b4a2
liquidity_change_event 7ef0afce9e58996b
pool_created_event 195e4b2f7063353f
swap_event 40c6cde8260871e2
update_reward_infos_event 6d7fba4e724125ec
```
Le code est préparé pour les accueillir comme audit-only lorsquils seront observés dans un corpus local. Ils ne produisent pas de trade/candle par défaut.
## Sources utilisées
Les entrées ont été comparées aux sources Raydium CLMM suivantes :
```text
Solscan Program IDL CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
sevenlabs-hq/carbon raydium-clmm-decoder
pinax-network/substreams-solana-idls raydium/clmm
0xfnzero/sol-parser-sdk idl
```
Les sources upstream restent des indices. La promotion locale dépend du corpus local, du replay et des validations SQL.
## SQL final
La validation finale est dans :
```text
validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_49.sql
```
## Addendum `0.7.50-pre-r2` — source parity CLMM
La re-vérification CLMM ajoute `cpi_event` (`e445a52e51cb9a1d`) et `update_dynamic_fee_config` (`0707500802c784f0`) depuis Carbon. Les Program-data events CLMM reçoivent maintenant un `local_event_kind` et une famille explicite quand ils sont observables localement : `swap_event`, `pool_created_event`, `liquidity_change_event`, `create_personal_position_event`, `decrease_liquidity_event`, `increase_liquidity_event`, `collect_protocol_fee_event`, `config_change_event` et `update_reward_infos_event`.
`create_support_mint_associated` est matérialisable dans la nouvelle table `k_sol_token_account_events`. `liquidity_calculate_event` reste decoded-only car il représente un calcul/diagnostic et non une mutation de liquidité fiable. `swap_event` et `swap_router_base_in` restent également decoded-only : les trades matérialisés proviennent des instructions `swap` et `swap_v2`, ce qui évite les doublons de Program-data events et les routes sans pool direct.

View File

@@ -0,0 +1,130 @@
<!-- file: docs/reports/RAYDIUM_CLMM_UPSTREAM_COVERAGE_REVIEW_PRE19.md -->
# Raydium CLMM upstream coverage review — `0.7.49-pre.19`
## Scope
Decoder under review:
```text
raydium_clmm
program_id = CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
```
External sources checked for the local coverage registry:
```text
https://solscan.io/account/CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK#programIdl
https://github.com/sevenlabs-hq/carbon/tree/main/decoders/raydium-clmm-decoder
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/clmm
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
```
Notes:
- Solscan is used as discovery / IDL cross-check, not as final business proof.
- `sol-parser-sdk/idl/raydium_clmm.json` maps to `raydium/amm_v3_with_swapv2.json` and exposes the CLMM program address.
- `pinax-network/substreams-solana-idls` exposes Raydium CLMM under `src/raydium/clmm/v3`.
- `sevenlabs-hq/carbon` exposes a dedicated `raydium-clmm-decoder` crate.
## Local registry status
The local registry now lists:
```text
45 entries total:
- 33 instructions
- 11 Anchor/program-data events
- 1 program row
```
All 33 instruction entries have a `local_event_kind` mapping in `dex_event_coverage.rs`, `instruction_observation_index.rs`, `dex_decode.rs`, and `upstream_registry_generated.rs`.
The 11 event entries are listed as upstream facts and stay `upstream_git_unverified` until local corpus provides program-data/Anchor event proof.
## Instruction coverage matrix
| Entry | Discriminator | Family | Local event kind | Expected target | Status |
|---|---|---|---|---|---|
| close_limit_order | `4c7c800fd55725fa` | order_cancel | `raydium_clmm.close_limit_order` | `k_sol_orderbook_events` | decoded/materializable |
| open_limit_order | `9d20dab7471d1293` | order_place | `raydium_clmm.open_limit_order` | `k_sol_orderbook_events` | decoded/materializable |
| increase_limit_order | `b19059ecfaba7d63` | order_place | `raydium_clmm.increase_limit_order` | `k_sol_orderbook_events` | decoded/materializable |
| decrease_limit_order | `759d3c674231a300` | order_cancel | `raydium_clmm.decrease_limit_order` | `k_sol_orderbook_events` | decoded/materializable |
| close_position | `7b86510031446262` | position_close | `raydium_clmm.close_position` | `k_sol_liquidity_events` | decoded/materializable |
| close_protocol_position | `c975989055556cb2` | position_close | `raydium_clmm.close_protocol_position` | `k_sol_liquidity_events` | decoded/materializable |
| collect_fund_fee | `a78a4e95dfc2067e` | fee | `raydium_clmm.collect_fund_fee` | `k_sol_fee_events` | decoded/materializable |
| collect_protocol_fee | `8888fcddc2427e59` | fee | `raydium_clmm.collect_protocol_fee` | `k_sol_fee_events` | decoded/materializable |
| collect_remaining_rewards | `12eda6c52210d590` | reward | `raydium_clmm.collect_remaining_rewards` | `k_sol_reward_events` | decoded/materializable |
| create_amm_config | `8934edd4d7756c68` | admin_config | `raydium_clmm.create_amm_config` | `k_sol_pool_admin_events` | decoded/materializable |
| create_customizable_pool | `2b44d4a7592fa401` | pool_create | `raydium_clmm.create_customizable_pool` | `k_sol_pool_lifecycle_events` | decoded/materializable |
| create_dynamic_fee_config | `bd0eb5785576e33e` | admin_config | `raydium_clmm.create_dynamic_fee_config` | `k_sol_pool_admin_events` | decoded/materializable |
| create_operation_account | `3f5794216d230868` | unknown | `raydium_clmm.create_operation_account` | `k_sol_dex_decoded_events_only` | decoded/audit-only unless admin evidence is required |
| create_pool | `e992d18ecf6840bc` | pool_create | `raydium_clmm.create_pool` | `k_sol_pool_lifecycle_events` | decoded/materializable |
| create_support_mint_associated | `11fb415c88f20ea9` | account_create | `raydium_clmm.create_support_mint_associated` | `k_sol_token_account_events` | decoded; token-account materialization remains a later cross-DEX topic |
| decrease_liquidity | `a026d06f685b2c01` | liquidity_remove | `raydium_clmm.decrease_liquidity` | `k_sol_liquidity_events` | decoded/materializable |
| decrease_liquidity_v2 | `3a7fbc3e4f52c460` | liquidity_remove | `raydium_clmm.decrease_liquidity_v2` | `k_sol_liquidity_events` | decoded/materializable |
| increase_liquidity | `2e9cf3760dcdfbb2` | liquidity_add | `raydium_clmm.increase_liquidity` | `k_sol_liquidity_events` | decoded/materializable |
| increase_liquidity_v2 | `851d59df45eeb00a` | liquidity_add | `raydium_clmm.increase_liquidity_v2` | `k_sol_liquidity_events` | decoded/materializable |
| initialize_reward | `5f87c0c4f281e644` | reward | `raydium_clmm.initialize_reward` | `k_sol_reward_events` | decoded/materializable |
| open_position | `87802f4d0f98f031` | position_open | `raydium_clmm.open_position` | `k_sol_liquidity_events` | decoded/materializable |
| open_position_v2 | `4db84ad67056f1c7` | position_open | `raydium_clmm.open_position_v2` | `k_sol_liquidity_events` | decoded/materializable |
| open_position_with_token22_nft | `4dffae527d1dc92e` | position_open | `raydium_clmm.open_position_with_token22_nft` | `k_sol_liquidity_events` | decoded/materializable |
| set_reward_params | `7034a74b20c9d389` | reward | `raydium_clmm.set_reward_params` | `k_sol_reward_events` | decoded/materializable |
| settle_limit_order | `cd4e74215c691a60` | settle_funds | `raydium_clmm.settle_limit_order` | `k_sol_orderbook_events` | decoded/materializable |
| swap | `f8c69e91e17587c8` | swap | `raydium_clmm.swap` | `k_sol_trade_events` | decoded/materializable as trade |
| swap_router_base_in | `457d73daf5baf2c4` | swap | `raydium_clmm.swap_router_base_in` | `k_sol_trade_events` | decoded; observed but not promoted to trade without corpus proof |
| swap_v2 | `2b04ed0b1ac91e62` | swap | `raydium_clmm.swap_v2` | `k_sol_trade_events` | decoded/materializable as trade |
| transfer_reward_owner | `07160c53f22b3079` | reward | `raydium_clmm.transfer_reward_owner` | `k_sol_reward_events` | decoded/materializable |
| update_amm_config | `313cae889a1c74c8` | admin_config | `raydium_clmm.update_amm_config` | `k_sol_pool_admin_events` | decoded/materializable |
| update_operation_account | `7f467728bce33d07` | unknown | `raydium_clmm.update_operation_account` | `k_sol_dex_decoded_events_only` | decoded/audit-only unless admin evidence is required |
| update_pool_status | `82576c062ee0757b` | admin_config | `raydium_clmm.update_pool_status` | `k_sol_pool_admin_events` | decoded/materializable |
| update_reward_infos | `a3ace0340b9a6adf` | reward | `raydium_clmm.update_reward_infos` | `k_sol_reward_events` | decoded/materializable |
## Anchor/program-data event entries
These entries remain listed, but no local corpus row has observed them as direct CLMM decoded events in the current replay corpus:
| Event entry | Discriminator | Family | Expected target | Status |
|---|---|---|---|---|
| collect_personal_fee_event | `a6ae69c051a15369` | fee | `k_sol_fee_events` | upstream listed, local corpus unobserved |
| collect_protocol_fee_event | `ce57114f2d29d53d` | fee | `k_sol_fee_events` | upstream listed, local corpus unobserved |
| config_change_event | `f7bd07776a705f97` | admin_config | `k_sol_pool_admin_events` | upstream listed, local corpus unobserved |
| create_personal_position_event | `641e57f9c4df9ace` | unknown | `k_sol_dex_decoded_events_only` | upstream listed, local corpus unobserved |
| decrease_liquidity_event | `3ade563a44325538` | liquidity_remove | `k_sol_liquidity_events` | upstream listed, local corpus unobserved |
| increase_liquidity_event | `314f69d420221e54` | liquidity_add | `k_sol_liquidity_events` | upstream listed, local corpus unobserved |
| liquidity_calculate_event | `ed7094e63954b4a2` | unknown | `k_sol_dex_decoded_events_only` | upstream listed, local corpus unobserved |
| liquidity_change_event | `7ef0afce9e58996b` | unknown | `k_sol_dex_decoded_events_only` | upstream listed, local corpus unobserved |
| pool_created_event | `195e4b2f7063353f` | unknown | `k_sol_dex_decoded_events_only` | upstream listed, local corpus unobserved |
| swap_event | `40c6cde8260871e2` | swap | `k_sol_trade_events` | upstream listed, local corpus unobserved |
| update_reward_infos_event | `6d7fba4e724125ec` | reward | `k_sol_reward_events` | upstream listed, local corpus unobserved |
## Patch `pre.19`
Patch goal:
```text
Stop replay/backfill from leaving `upstream_git.instruction_match` rows when a local specialized decoder already covers the same upstream decoder + entry + discriminator.
```
New DB query:
```text
query_dex_decoded_events_delete_locally_covered_upstream_instruction_matches(database, upstream_decoder_code)
```
Called from:
```text
local_pipeline_replay.rs::refresh_event_coverage_best_effort
token_backfill.rs::refresh_event_coverage_best_effort
```
Expected validation after replay:
```text
raydium_clmm.instruction_audit residual query -> empty
upstream_git.instruction_match where upstreamDecoderCode = raydium_clmm -> empty
non-swap CLMM trade_count -> empty
failed CLMM materialization query -> empty
coverage summary remains populated around 45 listed / 33 decoded / 33 observed
```

View File

@@ -0,0 +1,84 @@
<!-- file: docs/reports/RAYDIUM_CPMM_CLMM_RECHECK_REPORT_0_7_50_PRE_R2.md -->
# Raydium CPMM/CLMM re-check report — `0.7.50-pre-r2`
## Scope
This report closes the post-Launchpad re-check for `raydium_cpmm` and `raydium_clmm` using the same discipline applied to `raydium_launchpad`:
- every observed discriminator must have a named local event kind or an explicit decoded-only decision;
- `event_family='unknown'` is not acceptable outside synthetic `program` rows;
- materializable events must target the matching business table;
- duplicate, transport-only or context-incomplete events remain `k_sol_dex_decoded_events_only` by design;
- failed transactions must not produce business materialization.
## Sources
The source comparison for this tranche is based on:
- Carbon `raydium-cpmm-decoder`;
- Carbon `raydium-clmm-decoder`;
- Pinax `substreams-solana-idls` Raydium CPMM/CLMM trees;
- Solscan Program IDL pages for CPMM and CLMM;
- `0xfnzero/sol-parser-sdk` Raydium IDL snapshots;
- local corpus replay results from the dedicated CPMM and CLMM databases.
## CPMM decision
`40f4bc78a7e9690a` is now coded as:
```text
local_event_kind = raydium_cpmm.anchor_idl_instruction
event_family = idl_management
expected_db_target = k_sol_dex_decoded_events_only
```
Manual inspection of the three local signatures showed Anchor IDL management logs:
- `IdlCreateAccount` on `Hi6MkRTkcgwBi1WpiiudGPHKLuaKXKamNgVsy6YqoQeMRnrkpGjNx75ymrY59tJ3NN1GCn6nrndz9thMmwALLcY`;
- `IdlCloseAccount` on `Kch9bYneKzyPg13txxpu151QHX4EgQhFqXUHxqYLXE3BbSrMt56bNMx9JbMAZzs4fbuCLLibHAtrRHdrn7u2VUD`;
- `IdlCreateAccount` on `fsKqwEAiRCQyXvCBjBX4XGzkZXyz4DeNL1Kdw9BeyGYYAcTKPEP9sP4WXVNB2FRkvBXc3YjuGhUcihLZm3Y7Znu`.
This is not a CPMM business instruction. It must not produce trade, candle, liquidity, fee, admin or lifecycle rows.
## CPMM expected post-replay invariants
After replay on the CPMM database:
- observed discriminator coverage gap should be empty;
- residual `raydium_cpmm.instruction_audit` should be empty;
- decoded event kinds without coverage should be empty;
- materialization shortfall should be empty after excluding `k_sol_dex_decoded_events_only` and failed transactions;
- `swap_event` remains decoded-only because canonical trades come from `swap_base_input` / `swap_base_output`.
## CLMM decision
CLMM has no remaining unknown family in the coverage matrix. The re-check keeps the following entries decoded-only by design:
- `raydium_clmm.swap_event`: Program-data corroboration of swaps; canonical trade materialization remains on `swap` / `swap_v2`.
- `raydium_clmm.swap_router_base_in`: router instruction; no single direct pool surface should be inferred without hop-level resolution.
- `raydium_clmm.liquidity_calculate_event`: calculation/diagnostic event.
- `raydium_clmm.close_position` and `raydium_clmm.close_protocol_position`: decoded, but not materialized unless a reliable pool/pair context is available.
- `raydium_clmm.cpi_event`: Anchor transport only.
Materialization was strengthened for CLMM liquidity events by accepting snake_case amount keys (`amount0_raw`, `amount1_raw`, `liquidity_raw`) and by resolving pool/pair context from sibling decoded events in the same transaction when the current decoded event carries useful amounts but lacks direct pair context.
## CLMM expected post-replay invariants
After replay on the CLMM database:
- observed discriminator coverage gap should be empty;
- residual `raydium_clmm.instruction_audit` should be empty;
- decoded event kinds without coverage should be empty;
- failed transactions should not produce business rows;
- the validation SQL must count `k_sol_token_account_events`, otherwise `create_support_mint_associated` is falsely reported as a materialization gap.
## Validation files
Use:
```text
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_50_PRE_R2.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_50_PRE_R2.sql
validation_sql/SQL_TRACE_RAYDIUM_CPMM_AUDIT_40F_0_7_50_PRE_R2.sql
```

View File

@@ -0,0 +1,214 @@
<!-- file: docs/reports/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md -->
# Rapport `0.7.48` — Raydium CPMM event coverage
## Scope
Tranche : `0.7.48`.
Decoder local : `raydium_cpmm`.
Programme : `CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C`.
Objectif : couvrir Raydium CPMM au-delà des swaps, avec preuve locale par backfill/replay SQL, sans modifier les règles trade/candle existantes et sans promouvoir de table métier transversale non nécessaire.
## Sources utilisées
Sources principales :
- Carbon `carbon-raydium-cpmm-decoder` ;
- fnzero `solana-streamer` / `sol-parser-sdk` IDL `raydium_cpmm.json` ;
- Raydium CP-Swap officiel ;
- Solscan page programme / Program IDL comme accélérateur de recherche de signatures, notamment via `instruction=<discriminator>`.
Règle retenue : Git/IDL/Solscan sont des indices de recherche. La preuve métier reste le corpus local backfillé puis rejoué.
## Entrées CPMM inventoriées
| Kind | Entrée | Discriminant | État final `0.7.48` |
|---|---|---|---|
| instruction | `close_permission_pda` | `9c5420764587467b` | connu upstream, non observé localement |
| instruction | `collect_creator_fee` | `1416567bc61cdb84` | décodé + matérialisé fee |
| instruction | `collect_fund_fee` | `a78a4e95dfc2067e` | décodé + matérialisé fee |
| instruction | `collect_protocol_fee` | `8888fcddc2427e59` | décodé + matérialisé fee |
| instruction | `create_amm_config` | `8934edd4d7756c68` | décodé + matérialisé admin/config |
| instruction | `create_permission_pda` | `878802d889a9b5ca` | décodé + matérialisé admin/config |
| instruction | `deposit` | `f223c68952e1f2b6` | décodé + matérialisé liquidity add |
| instruction | `initialize` | `afaf6d1f0d989bed` | décodé + matérialisé lifecycle |
| instruction | `initialize_with_permission` | `3f37fe4131b25979` | décodé + matérialisé lifecycle only |
| event | `lp_change_event` | `79a3cdc939da753c` | décodé + matérialisé liquidity bidirectionnelle |
| instruction | `swap_base_input` | `8fbe5adac41e33de` | décodé + trade matérialisé quand transaction OK |
| instruction | `swap_base_output` | `37d96256a34ab4ad` | décodé + trade matérialisé quand transaction OK |
| event | `swap_event` | `40c6cde8260871e2` | décodé audit-only, pas trade/candle |
| instruction | `update_amm_config` | `313cae889a1c74c8` | décodé + matérialisé admin/config |
| instruction | `update_pool_status` | `82576c062ee0757b` | connu upstream, non observé localement |
| instruction | `withdraw` | `b712469c946da122` | décodé + matérialisé liquidity remove |
## Décodage ajouté ou stabilisé
Le decoder spécialisé `raydium_cpmm` couvre maintenant :
- les swaps instruction-scoped `swap_base_input` / `swap_base_output` ;
- les events `Program data:` / Anchor CPI `swap_event` et `lp_change_event` ;
- les instructions lifecycle `initialize` / `initialize_with_permission` ;
- les instructions liquidity `deposit` / `withdraw` ;
- les fees `collect_creator_fee`, `collect_fund_fee`, `collect_protocol_fee` ;
- les instructions admin/config `create_amm_config`, `create_permission_pda`, `update_amm_config` ;
- les instructions connues mais non observées `close_permission_pda`, `update_pool_status` restent listées sans promotion métier.
Le fallback `upstream_git.instruction_match` ne doit plus apparaître pour les instructions CPMM couvertes localement.
## Matérialisation finale validée
Rejeu local validé après backfills ciblés Solscan + Demo Pipeline 2 :
| Event kind | Decoded | Table métier | Materialized | Trade count | Statut |
|---|---:|---|---:|---:|---|
| `raydium_cpmm.collect_creator_fee` | 4 | `k_sol_fee_events` | 4 | 0 | fee materialized |
| `raydium_cpmm.collect_fund_fee` | 7 | `k_sol_fee_events` | 7 | 0 | fee materialized |
| `raydium_cpmm.collect_protocol_fee` | 15 | `k_sol_fee_events` | 15 | 0 | fee materialized |
| `raydium_cpmm.create_amm_config` | 6 | `k_sol_pool_admin_events` | 6 | 0 | admin materialized |
| `raydium_cpmm.create_permission_pda` | 4 | `k_sol_pool_admin_events` | 4 | 0 | admin materialized |
| `raydium_cpmm.deposit` | 11 | `k_sol_liquidity_events` | 11 | 0 | liquidity add materialized |
| `raydium_cpmm.initialize` | 5 | `k_sol_pool_lifecycle_events` | 5 | 0 | lifecycle materialized |
| `raydium_cpmm.initialize_with_permission` | 4 | `k_sol_pool_lifecycle_events` | 4 | 0 | lifecycle only |
| `raydium_cpmm.lp_change_event` | 25 | `k_sol_liquidity_events` | 25 | 0 | liquidity materialized, `changeType` bidirectionnel |
| `raydium_cpmm.swap_base_input` | 750 | `k_sol_trade_events` | 482 | 482 | trade materialized for OK/actionable tx |
| `raydium_cpmm.swap_base_output` | 25 | `k_sol_trade_events` | 17 | 17 | trade materialized for OK/actionable tx |
| `raydium_cpmm.swap_event` | 529 | `k_sol_dex_decoded_events_only` | 0 | 0 | audit-only, no duplicate trade |
| `raydium_cpmm.update_amm_config` | 13 | `k_sol_pool_admin_events` | 13 | 0 | admin materialized |
| `raydium_cpmm.withdraw` | 14 | `k_sol_liquidity_events` | 14 | 0 | liquidity remove materialized |
| `raydium_cpmm.instruction_audit` | 3 | `k_sol_dex_decoded_events_only` | 0 | 0 | unknown audit-only |
Replay final observé :
```text
1124 replayed
561 trades
50 liquidity
9 lifecycle
2224 candle upserts
```
Le total liquidity correspond à :
```text
deposit 11
withdraw 14
lp_change_event 25
-------------------
total 50
```
## `lp_change_event`
`lp_change_event` est un event bidirectionnel :
- `changeType = 0` : add/deposit liquidity ;
- `changeType = 1` : remove/withdraw liquidity.
La coverage statique utilise donc `event_family = liquidity`, pas `liquidity_add`. La matérialisation résout le sens au niveau payload. Les events qui ne contiennent pas directement les mints sont enrichis via le contexte pool/pair local ou via le sibling `deposit` / `withdraw` déjà matérialisé dans la même transaction/replay.
Validation finale :
```text
changeType 0 -> 11 decoded / 11 liquidity / 0 trade
changeType 1 -> 14 decoded / 14 liquidity / 0 trade
```
## `initialize_with_permission`
`initialize_with_permission` est traité comme pool lifecycle only.
Validation finale :
```text
raydium_cpmm.initialize 5 decoded / 5 lifecycle / 0 admin / 0 trade
raydium_cpmm.initialize_with_permission 4 decoded / 4 lifecycle / 0 admin / 0 trade
```
Le cleanup de matérialisation supprime les anciennes lignes admin dérivées si elles existent déjà dans la base.
## Entrées non observées
Solscan avec filtre `instruction=` n'a pas retourné de transaction locale utile pour :
- `close_permission_pda` / `9c5420764587467b` ;
- `update_pool_status` / `82576c062ee0757b`.
Ces entrées restent donc :
```text
upstream_git_mapped_unverified
```
Absence Solscan ne signifie pas absence on-chain absolue, surtout si l'index UI ne couvre pas tout l'historique. Cela suffit cependant pour ne pas les promouvoir sans corpus local.
## Instruction audit inconnue
Le discriminator suivant a été observé localement :
```text
40f4bc78a7e9690a
```
Il produit actuellement `raydium_cpmm.instruction_audit` avec `tradeCandidate=false` / `candleCandidate=false`. Il n'est pas nommé dans la tranche `0.7.48`, faute de preuve upstream/corpus suffisante.
## Recherche Solscan retenue
La page programme Solscan et l'onglet Program IDL sont utiles pour accélérer la recherche :
```text
https://solscan.io/account/CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C#programIdl
```
Le filtre `instruction=<discriminator>` est documenté comme méthode pratique de découverte de signatures à backfiller localement, par exemple :
```text
https://solscan.io/account/CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C?instruction=f223c68952e1f2b6&instruction=b712469c946da122&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
Solscan reste une aide de recherche, pas une source de vérité métier.
## Table technique ajoutée
`k_sol_instruction_observations` est ajoutée comme table technique d'index local. Elle permet de retrouver les signatures observées par `decoder_code`, `instruction_name` et `discriminator_hex`, sans créer de nouvelle table métier.
Exemple :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_cpmm'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC;
```
## Invariants validés
- `swap_event` ne produit aucun trade/candle.
- `deposit`, `withdraw`, `lp_change_event`, fees, admin/config et lifecycle gardent `trade_count=0`.
- Les transactions failed restent non matérialisées en trade/candle.
- Les side effects SPL Token / Token-2022 (`burn`, `transfer`, `transferChecked`, `closeAccount`) restent hors decoder métier CPMM direct et devront passer par une future table transversale si plusieurs DEX le justifient.
- Aucun program id n'est promu sans corpus local.
## État de clôture
`0.7.48 raydium_cpmm` est clôturable avec deux entrées connues mais non observées :
```text
close_permission_pda
update_pool_status
```
La prochaine tranche fonctionnelle est `0.7.49 raydium_clmm`.
## Addendum `0.7.50-pre-r2` — cpi_event et audit `40f4bc78a7e9690a`
La re-vérification CPMM ajoute explicitement `cpi_event` à la matrice coverage locale avec le discriminant Carbon `e445a52e51cb9a1d`. Cette entrée est un transport Anchor/CPI et reste `k_sol_dex_decoded_events_only`.
Le discriminant observé localement `40f4bc78a7e9690a` est classé comme `raydium_cpmm.anchor_idl_instruction`, avec `event_family=idl_management` et `expected_db_target=k_sol_dex_decoded_events_only`. Les signatures inspectées montrent `Program log: Instruction: IdlCreateAccount` et `Program log: Instruction: IdlCloseAccount` sur le compte `anchor:idl`; il ne correspond donc pas au `cpi_event` Carbon et ne doit pas être matérialisé dans les tables métier.
Trace SQL ajouté : `validation_sql/SQL_TRACE_RAYDIUM_CPMM_AUDIT_40F_0_7_50_PRE_R2.sql` liste les signatures, slots, index d'instruction, comptes et données associées à `40f4bc78a7e9690a`.

View File

@@ -0,0 +1,74 @@
<!-- file: docs/reports/RAYDIUM_CPMM_UPSTREAM_COVERAGE_REVIEW_PRE22.md -->
# Raydium CPMM upstream coverage review — 0.7.49-pre.22
## Scope
Compared local `raydium_cpmm` coverage against the currently referenced upstream surfaces:
- Solscan program IDL for `CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C`.
- `sevenlabs-hq/carbon` `raydium-cpmm-decoder`.
- `0xfnzero/sol-parser-sdk` `idl/raydium_cpmm.json`.
- `pinax-network/substreams-solana-idls` `src/raydium/cpmm`.
- Raydium official `raydium-cp-swap` source.
## Local CPMM coverage entries
Local registry currently lists 16 `raydium_cpmm` entries:
### Instructions
- `close_permission_pda``9c5420764587467b`
- `collect_creator_fee``1416567bc61cdb84`
- `collect_fund_fee``a78a4e95dfc2067e`
- `collect_protocol_fee``8888fcddc2427e59`
- `create_amm_config``8934edd4d7756c68`
- `create_permission_pda``878802d889a9b5ca`
- `deposit``f223c68952e1f2b6`
- `initialize``afaf6d1f0d989bed`
- `initialize_with_permission``3f37fe4131b25979`
- `swap_base_input``8fbe5adac41e33de`
- `swap_base_output``37d96256a34ab4ad`
- `update_amm_config``313cae889a1c74c8`
- `update_pool_status``82576c062ee0757b`
- `withdraw``b712469c946da122`
### Anchor / Program-data events
- `lp_change_event``79a3cdc939da753c`
- `swap_event``40c6cde8260871e2`
## Upstream comparison
Carbon `raydium-cpmm-decoder` exposes the same 14 instruction modules and the two event-like discriminator entries, `lp_change_event` and `swap_event`.
`sol-parser-sdk` `idl/raydium_cpmm.json` exposes the core CPMM instruction set (`createAmmConfig`, `updateAmmConfig`, `updatePoolStatus`, `collectProtocolFee`, `collectFundFee`, `initialize`, `deposit`, `withdraw`, `swapBaseInput`, `swapBaseOutput`) and IDL events `LpChangeEvent` and `SwapEvent`. The local registry also includes the permission and creator-fee entries present in Carbon / Raydium source.
The official Raydium `raydium-cp-swap` source lists the CPMM program ID and the main program instructions including admin/config, fee collection, permission PDA, initialize, initialize with permission, deposit, withdraw, swap base input, and swap base output.
## Finding
No missing CPMM instruction/event discriminator was identified relative to the reviewed Carbon / Raydium / fnzero / Pinax surfaces available during this check.
## Current local caveat
CPMM remains covered by the earlier 0.7.48 tranche. The useful final validation remains DB-side:
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
local_event_kind,
discriminator_hex,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_cpmm'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Any future upstream addition should appear as a new entry in Carbon/Solscan/IDL and should be added to `upstream_registry_generated.rs`, `known_local_event_kind` only after local decoder support exists, and then validated with local corpus evidence.

View File

@@ -0,0 +1,233 @@
<!-- file: docs/reports/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md -->
# Raydium Launchpad event coverage report — `0.7.50`
## Scope
`0.7.50` opens the `raydium_launchpad` tranche after the functional closure of `0.7.49 raydium_clmm`.
Local canonical decoder/surface code:
```text
raydium_launchpad
```
Canonical program id:
```text
LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj
```
The legacy local name `raydium_launchlab` is not kept in the public Rust API. Coverage rows, upstream registry rows, launch origin entries, and support matrix rows use `raydium_launchpad`.
## Sources used
Primary source hints for this tranche:
- Carbon decoder registry/source: `sevenlabs-hq/carbon/decoders/raydium-launchpad-decoder`.
- Solscan Program IDL/account page: `https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj#programIdl`.
- fnzero IDL sources: `sol-parser-sdk` / `solana-program-idls` listings, including `raydium_launchpad.json` and separate `raydium_pool_v4.json` as an audit-only source.
- Raydium SDK Launchpad examples for account-shape hints only.
These sources are not treated as final business proof. Promotion still requires local corpus observation and SQL validation.
## Bootstrap implementation delta
Implemented in this delta:
- `RAYDIUM_LAUNCHPAD_PROGRAM_ID` added as the canonical public constant.
- Upstream generated registry rows normalized from `raydium_launchlab` to `raydium_launchpad`.
- Built-in launch surface code normalized to `raydium_launchpad`.
- DEX support/catalog entries normalized to `raydium_launchpad`.
- Raydium instruction audit fallback now recognizes Launchpad program id.
- Launchpad mapped instruction fallback added for locally listed Launchpad discriminators.
- Coverage target override keeps Launchpad rows `decoded_events_only` until corpus promotion.
- SQL validation file added for the `0.7.50` tranche.
## Listed Launchpad entries
The local upstream registry now lists one program entry plus the following 26 discriminator entries.
| Entry kind | Entry name | Discriminator | Initial family | Initial DB target |
|---|---:|---:|---|---|
| instruction | `buy_exact_in` | `faea0d7bd59c13ec` | swap | decoded_events_only |
| instruction | `buy_exact_out` | `18d3742869039938` | swap | decoded_events_only |
| instruction | `claim_creator_fee` | `1a618acb84ab8dfc` | fee | decoded_events_only |
| instruction | `claim_platform_fee` | `9c27d0874ced3d48` | fee | decoded_events_only |
| instruction | `claim_platform_fee_from_vault` | `75f1c6a8f8da501d` | fee | decoded_events_only |
| event | `claim_vested_event` | `15c2725778d3e220` | fee/vesting audit | decoded_events_only |
| instruction | `claim_vested_token` | `3121681ebd9d4f23` | fee/vesting audit | decoded_events_only |
| instruction | `collect_fee` | `3cadf767045d8230` | fee | decoded_events_only |
| instruction | `collect_migrate_fee` | `ffba96dfeb76c9ba` | fee/migration audit | decoded_events_only |
| instruction | `create_config` | `c9cff3724b6f2fbd` | admin_config | decoded_events_only |
| instruction | `create_platform_config` | `b05ac4affd71dc14` | admin_config | decoded_events_only |
| instruction | `create_vesting_account` | `81b2020dd9ace6da` | account_create/vesting audit | decoded_events_only |
| event | `create_vesting_event` | `96980bb334d2bf7d` | account_create/vesting audit | decoded_events_only |
| instruction | `initialize` | `afaf6d1f0d989bed` | pool_create/launch | decoded_events_only |
| instruction | `initialize_v2` | `4399af27da102620` | pool_create/launch | decoded_events_only |
| instruction | `initialize_with_token_2022` | `25be7ede2c9aab11` | pool_create/launch | decoded_events_only |
| instruction | `migrate_to_amm` | `cf52c091fecf91df` | migration | decoded_events_only |
| instruction | `migrate_to_cpswap` | `885cc8671cda908c` | migration | decoded_events_only |
| event | `pool_create_event` | `97d7e20976a173ae` | pool_create | decoded_events_only |
| instruction | `remove_platform_curve_param` | `1b1e3ea95de01891` | admin_config | decoded_events_only |
| instruction | `sell_exact_in` | `9527de9bd37c981a` | swap | decoded_events_only |
| instruction | `sell_exact_out` | `5fc8472208090ba6` | swap | decoded_events_only |
| event | `trade_event` | `bddb7fd34ee661ee` | swap | decoded_events_only |
| instruction | `update_config` | `1d9efcbf0a53db63` | admin_config | decoded_events_only |
| instruction | `update_platform_config` | `c33c4c81922d438f` | admin_config | decoded_events_only |
| instruction | `update_platform_curve_param` | `8a908afadc800439` | admin_config | decoded_events_only |
Notes:
- The buy/sell instruction account hints currently use account index `4` as candidate pool account and indexes `9`/`10` as candidate token mints, based on Carbon/Raydium Launchpad account shape hints. This is an audit helper, not a materialization proof.
- Fee/admin/migration/vesting entries intentionally do not infer pool/token accounts until corpus confirms the account semantics.
- Program-data transport is represented by `cpi_event`; embedded events are decoded by their own discriminators and materialized only when their event family has a validated target.
## Family audit matrix
| Family | Launchpad status in `0.7.50` final | Decision |
|---|---|---|
| swap | `trade_event` materialized as trades/candles; buy/sell instructions materialized as launch breadcrumbs. | No duplicate trades from instruction breadcrumbs. |
| pool_create | `initialize`, `initialize_v2`, `initialize_with_token_2022`, `pool_create_event`. | Pool lifecycle/catalogue materialized when transaction succeeded. |
| add_liquidity | No direct Launchpad entry confirmed. | Non-applicable unless local corpus proves direct Launchpad liquidity instruction. |
| remove_liquidity | No direct Launchpad liquidity remove entry confirmed. | Non-applicable unless local corpus proves direct Launchpad liquidity instruction. |
| position_open | No direct Launchpad position instruction confirmed. | Non-applicable. |
| position_close | No direct Launchpad position instruction confirmed. | Non-applicable. |
| fee | claim/collect fee entries listed. | Fee table materialization enabled for observed successful transactions. |
| reward | No direct reward instruction confirmed. | Non-applicable unless local corpus proves otherwise. |
| admin/config | create/update config and platform curve/config entries listed. | Pool admin materialization enabled for observed successful transactions. |
| mint | Token minting may appear as SPL Token/Token-2022 side effect. | Not `raydium_launchpad.*` without direct program proof. |
| burn | Token burn may appear as SPL Token/Token-2022 side effect. | Not `raydium_launchpad.*` without direct program proof. |
| transfer | Transfers are expected as SPL Token/Token-2022 side effects. | Not `raydium_launchpad.*` without direct program proof. |
| account_create / vesting | `create_vesting_account`, `create_platform_vesting_account`, vesting events. | Launch event materialization enabled for observed successful transactions; unobserved events remain mapped. |
| account_close | No direct Launchpad account close confirmed. | Non-applicable. |
| wrap_sol | No direct Launchpad wrap SOL confirmed. | Side effect only unless corpus proves direct instruction. |
| unwrap_sol | No direct Launchpad unwrap SOL confirmed. | Side effect only unless corpus proves direct instruction. |
| order_place | No orderbook surface confirmed. | Non-applicable. |
| order_cancel | No orderbook surface confirmed. | Non-applicable. |
| order_fill | No orderbook surface confirmed. | Non-applicable. |
| consume_events | No orderbook surface confirmed. | Non-applicable. |
| settle_funds | No orderbook surface confirmed. | Non-applicable. |
| vault_deposit | No direct vault deposit confirmed. | Non-applicable. |
| vault_withdraw | No direct vault withdraw confirmed. | Non-applicable. |
| lock | No direct lock confirmed. | Non-applicable. |
| unlock | No direct unlock confirmed. | Non-applicable. |
| launch | initialize/pool_create path listed. | Decode/audit only. |
| migration | `migrate_to_amm`, `migrate_to_cpswap`, `collect_migrate_fee` listed. | Decode/audit only. Destination DEX materialization must be proven locally. |
| stake | No direct stake confirmed. | Non-applicable. |
| unstake | No direct unstake confirmed. | Non-applicable. |
| unknown/unmapped audit | `raydium_launchpad.instruction_audit` retained for unmatched program instructions. | Must trend toward zero for locally covered discriminators after backfill/replay. |
## SQL validation expectations
After targeted backfill and replay:
1. `k_sol_dex_event_coverage_entries` should contain the Launchpad program entry and discriminator entries.
2. Mapped entries should have `local_event_kind = raydium_launchpad.<entry_name>` and initial `proof_status = upstream_git_mapped_unverified` until observed.
3. Locally observed instructions should increment `k_sol_instruction_observations` for `decoder_code = raydium_launchpad`.
4. `upstream_git.instruction_match` fallback rows for `upstreamDecoderCode = raydium_launchpad` should be zero for locally covered instruction discriminators.
5. `raydium_launchpad.*` rows must not produce trades/candles unless a later corpus-backed patch explicitly promotes a specific event.
6. Failed transactions may be decoded/audited, but must not be materialized in trade/candle tables.
Validation file:
```text
validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql
```
## Suggested targeted Solscan discovery loop
For each discriminator:
```text
https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
Then:
1. copy a small batch of recent non-failed signatures;
2. backfill through Demo2 textarea batch;
3. replay with `forceDexDecode=yes` and `deferInstructionObservations=yes`;
4. run the validation SQL;
5. promote only entries whose local payload and account semantics are proven.
## `raydium_pool_v4.json` audit status
The current workspace archive does not contain a local `raydium_pool_v4.json` copy. External fnzero IDL listings expose a separate `raydium_pool_v4.json` beside `raydium_launchpad.json`, but this delta does not confirm its program id or business role.
Decision for `0.7.50`:
- do not promote `raydium_pool_v4` as a DEX/surface;
- keep `0.7.53 raydium_pool_v4 audit / program-id decision` conditional;
- require program id confirmation and local corpus before any roadmap promotion.
## Current limitations
This delta was prepared from the provided archive only. No live RPC backfill, fresh SQLite replay, `cargo fmt`, `cargo test`, or `cargo clippy` could be executed in the current environment because the Rust toolchain is unavailable here. The SQL and code paths are prepared for local validation in the normal project environment.
## Local corpus snapshot from first 0.7.50 backfill
Observed after targeted Demo2 backfills and pool backfill on a fresh 0.7.50 DB:
- coverage listed entries: `27`;
- decoded/local mapped entries: `26`;
- observed entries: `21`;
- materialized entries: `0`;
- total observed coverage count: `672`;
- total materialized count: `0`;
- trade count: `0`;
- residual `upstream_git.instruction_match` for `raydium_launchpad`: `0`;
- residual `raydium_launchpad.instruction_audit`: `287`;
- residual audit discriminators: `e445a52e51cb9a1d` (`276`), `9247ad4562130f6a` (`10`), `a25b92c75d85eaed` (`1`).
The `e445a52e51cb9a1d` selector is handled as Anchor self-CPI event transport. It is not promoted as a Raydium Launchpad business instruction. The two low-count residual discriminators remain local-corpus audit-only until an IDL/upstream mapping is confirmed.
## pre3 correction — Demo3 preset and Launchpad pool catalog
The first replay after pre2 confirmed that Anchor self-CPI selector `e445a52e51cb9a1d` carries Launchpad `trade_event` (`bddb7fd34ee661ee`) and `pool_create_event` (`97d7e20976a173ae`). pre3 therefore decodes those two self-CPI event rows as direct `raydium_launchpad.*` events instead of leaving them under `raydium_launchpad.instruction_audit`. `trade_event` remains audit/decoded-only and is still not promoted to `k_sol_trade_events` or candles.
pre3 also fixes the Launchpad `initialize`, `initialize_v2` and `initialize_with_token_2022` account mapping using the Carbon account shape: `pool_state` index 5, `base_mint` index 6 and `quote_mint` index 7. These initialize rows are now routed to business-level pool detection as `raydium_launchpad` bonding-curve pools with pending status, which should allow pool `6HLQPoLrzX6LqePRiXQ1GGs2Dd9K3dp9VhTSHBugYzzZ` to appear in the local catalog after a forced replay when its initialize transaction is present locally.
Demo3 now exposes a `Raydium Launchpad` preset with program id `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj`.
## Final `0.7.50` closure snapshot
Validated closure state reported by local replay:
- `cargo test -p kb_lib`: 404 passed, 0 failed.
- Local replay: 437 replayed, 437 ledger upserts, 30 unsafe ledger rows, 256 trades, 115 lifecycle rows, 1024 candle upserts, 6205 instruction observations.
- Launchpad catalogue: 58 tokens, 58 pools, 58 pairs after replay.
- Coverage normalization: no ambiguous `unknown` family remains; only the synthetic `program` row may have an empty family.
- `trade_event`: 260 decoded, 250 successful materialized trades; 10 failed transactions intentionally not materialized.
- `buy_exact_*` / `sell_exact_*`: materialized as `k_sol_launch_events` swap-instruction breadcrumbs, not as trades.
- `cpi_event`: kept as `cpi_transport` / decoded-only; embedded events are decoded by direct event discriminator.
- Successful `trade_event` rows without materialized `k_sol_trade_events`: zero.
Post-closure recheck assets added:
- `validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_50_PRE_R2.sql`
- `validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_50_PRE_R2.sql`
- `docs/SOLSCAN_ACCOUNT_SOURCE_MATRIX.md`
- `kb_lib::SOLSCAN_ACCOUNT_SOURCES`
## Final cleanup note — CPMM residual audit after 0.7.50 recheck
During the 0.7.50 post-Launchpad recheck, the CPMM residual audit query still showed three `raydium_cpmm.instruction_audit` rows for discriminator `40f4bc78a7e9690a` even though the same discriminator is now locally mapped as `raydium_cpmm.anchor_idl_instruction`.
The final cleanup patch makes the deletion FK-safe by unlinking `k_sol_instruction_observations.decoded_event_id` before deleting the legacy audit rows. It also repeats the CPMM cleanup after coverage refresh and refreshes coverage again if rows were removed.
Expected final state after replay:
```text
raydium_cpmm.instruction_audit / 40f4bc78a7e9690a = 0
raydium_cpmm decoded events without coverage row = 0
raydium_cpmm.anchor_idl_instruction remains decoded-only / idl_management
```
Validation SQL:
```text
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_AUDIT_CLEANUP_0_7_50_FINAL.sql
```

View File

@@ -0,0 +1,56 @@
<!-- file: docs/reports/RAYDIUM_POOL_V4_DECISION_NOTE.md -->
# Raydium Pool v4 Decision Note — `0.7.51`
## Décision courte
`raydium_pool_v4` ne doit pas être ouvert comme decoder autonome dans `0.7.51`.
Statut retenu :
```text
Option C — IDL ambiguë / strategy-pool wrapper sans corpus local suffisant.
```
Conséquence : `raydium_pool_v4` reste une source d'audit/comparaison pour `raydium_amm_v4`. Toute promotion en tranche dédiée exige un program id prouvé localement, des observations dans `k_sol_instruction_observations`, des decoded events locaux et une absence de fallback upstream inexpliqué.
## Comparaison synthétique
| Source | Nom / rôle constaté | Indices structurants | Décision locale |
|---|---|---|---|
| `idl/raydium_amm_v4.json` | `raydium_amm` | Instructions AMM v4 legacy : `initialize`, `initialize2`, `deposit`, `withdraw`, `swapBaseIn`, `swapBaseOut`, `monitorStep`, `setParams`. | Source principale pour `raydium_amm_v4`. |
| `idls/raydium_amm_v4.json` | `raydium_amm` | Variante parallèle à comparer ligne à ligne avec `idl/`. | Source principale complémentaire. |
| `idl/raydium_pool_v4.json` | `Raydium Liquidity Pool V4` | Entrées orientées stratégie/pool wrapper : `initializeStrategy`, comptes `strategyState`, `strategyAuthority`, `lendingProgramId`; contient aussi des noms comme `swapBaseIn`. | Audit uniquement. Ne pas promouvoir. |
| `idls/raydium_pool_v4.json` | `Raydium Liquidity Pool V4` | Même famille de signaux que `idl/raydium_pool_v4.json` à vérifier localement. | Audit uniquement. |
## Raisons de non-promotion
1. `raydium_pool_v4` ne prouve pas encore un program id local autonome dans le workspace.
2. La présence de noms communs (`swapBaseIn`, comptes OpenBook) ne suffit pas à conclure que la surface est le program id AMM v4 canonique `675kPX...`.
3. Les entrées `initializeStrategy`, `strategyState`, `strategyAuthority` et `lendingProgramId` indiquent un rôle potentiellement distinct : strategy, wrapper, pool manager, lending ou ancienne ABI composite.
4. Aucune ligne locale `k_sol_instruction_observations` / `k_sol_dex_decoded_events` / `k_sol_dex_event_coverage_entries.local_event_kind` ne justifie une tranche autonome au moment de l'ouverture `0.7.51`.
## Règle de décision future
- Si `raydium_pool_v4` correspond finalement au même program id AMM v4 ou à un layout alternatif compatible, intégrer les discriminants/layouts validés dans `raydium_amm_v4`.
- Si `raydium_pool_v4` correspond à un autre program id / wrapper / strategy / lending surface, créer une tranche dédiée seulement après corpus local.
- Si l'IDL reste ambiguë, conserver l'entrée en roadmap comme audit conditionnel sans decoder runtime.
## SQL local attendu avant toute promotion
Une future promotion doit au minimum montrer :
```sql
SELECT
decoder_code,
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code IN ('raydium_amm_v4', 'raydium_pool_v4')
GROUP BY decoder_code, instruction_name, discriminator_hex
ORDER BY decoder_code, observed_count DESC;
```
Puis une preuve de decoded events locaux, de coverage entries mappées et d'absence de fallback upstream résiduel.

View File

@@ -0,0 +1,164 @@
<!-- file: docs/reports/RAYDIUM_STABLE_SWAP_EVENT_COVERAGE_REPORT.md -->
# Raydium Stable Swap event coverage report — 0.7.52 final
## Scope
`0.7.52` closes the `raydium_stable_swap` tranche after `0.7.51 raydium_amm_v4`.
Canonical local decoder code:
```text
raydium_stable_swap
```
Canonical program id validated by local corpus:
```text
5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h
```
Stable Swap is handled as a Raydium legacy AMM-style program with a one-byte instruction discriminator layout. Anchor-like 8-byte discriminants remain upstream discovery evidence only and are not business proof.
## Final implementation status
Implemented and locally validated:
- `kb_lib/src/dex/raydium_stable_swap.rs`.
- `RaydiumStableSwapDecoder` re-exported through `kb_lib/src/dex.rs` and `kb_lib/src/lib.rs`.
- Stable Swap route in `DexDecodeService` before generic Raydium instruction-audit preservation.
- One-byte Stable Swap instruction observation support.
- Coverage entries for all locally observed Stable Swap discriminants `00..0d`.
- Materialization into lifecycle/liquidity/fee/admin/orderbook/trade tables when the local corpus proves a safe target.
- Swap materialization from exact vault balance deltas only.
- Validation SQL in `validation_sql/SQL_VALIDATION_RAYDIUM_STABLE_SWAP_0_7_52.sql`.
## Instruction surface
| entry | discriminator | family | final target | local event kind | final status |
|---|---:|---|---|---|---|
| `initialize` | `00` | `pool_create` | `k_sol_pool_lifecycle_events` | `raydium_stable_swap.initialize` | observed/materialized when context complete |
| `init_model_data` | `01` | `model_setup` | decoded-only | `raydium_stable_swap.init_model_data` | observed decoded-only / explained |
| `update_model_data` | `02` | `admin_config` | `k_sol_pool_admin_events` | `raydium_stable_swap.update_model_data` | observed/materialized |
| `deposit` | `03` | `liquidity_add` | `k_sol_liquidity_events` | `raydium_stable_swap.deposit` | observed/materialized |
| `withdraw` | `04` | `liquidity_remove` | `k_sol_liquidity_events` | `raydium_stable_swap.withdraw` | observed/materialized |
| `monitor_step` | `05` | `order_place` | `k_sol_orderbook_events` | `raydium_stable_swap.monitor_step` | observed/materialized |
| `set_params` | `06` | `admin_config` | `k_sol_pool_admin_events` | `raydium_stable_swap.set_params` | observed/materialized |
| `withdraw_pnl` | `07` | `fee` | `k_sol_fee_events` | `raydium_stable_swap.withdraw_pnl` | observed/materialized |
| `withdraw_srm` | `08` | `fee` | `k_sol_fee_events` | `raydium_stable_swap.withdraw_srm` | observed/materialized when context complete |
| `swap_base_in` | `09` | `swap` | `k_sol_trade_events` only from vault deltas | `raydium_stable_swap.swap_base_in` | observed, materialized for successful swaps with exact deltas |
| `pre_initialize` | `0a` | `pool_create` | decoded-only or lifecycle when complete | `raydium_stable_swap.pre_initialize` | observed decoded-only / explained in current corpus |
| `swap_base_out` | `0b` | `swap` | `k_sol_trade_events` only from vault deltas | `raydium_stable_swap.swap_base_out` | observed, materialized for successful swaps with exact deltas |
| `simulate_info` | `0c` | `cpi_transport` | decoded-only | `raydium_stable_swap.simulate_info` | observed decoded-only / explained |
| `admin_cancel_orders` | `0d` | `orderbook_admin` | `k_sol_orderbook_events` | `raydium_stable_swap.admin_cancel_orders` | observed/materialized when context complete |
| `swap_event` | `40c6cde8260871e2` | `cpi_transport` | decoded-only | `raydium_stable_swap.swap_event` | upstream mapped, not observed in local corpus |
## Swap amount policy
Stable Swap instruction arguments are retained as instruction bounds, but they are not sufficient for trade/candle materialization:
```text
swap_base_in:
amountInRaw = exact input argument
minimumAmountOutRaw = slippage lower bound, not exact output
swap_base_out:
amountOutRaw = requested output argument
maxAmountInRaw = slippage upper bound, not exact input
```
Therefore, `swap_base_in` and `swap_base_out` materialize as trades/candles only when exact base/quote amounts are inferred from vault balance deltas:
```text
amountSource = stable_swap_vault_balance_delta
```
Instruction-bound-only swaps remain decoded-only:
```text
amountSource = stable_swap_instruction_bounds_only
tradeCandidate = false
candleCandidate = false
```
For failed transactions the skip reasons are:
```text
skipTradeReason = failed_transaction
skipCandleReason = failed_transaction
```
For successful transactions where exact vault deltas cannot be proven, the expected skip reason is:
```text
stable_swap_exact_amounts_unresolved
```
The final local corpus has no successful unresolved Stable Swap swap.
## Final local validation snapshot
Latest confirmed local commands:
```text
cargo test -p kb_lib
407 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
cargo clippy -p kb_lib --all-targets -- -D warnings
ok
```
Latest replay snapshot:
```text
replayed=298
decode_skipped=0
ledger_upserts=298
unsafe_ledger_rows=258
trades=290
liquidity=16
lifecycle=4
token_account=0
candle_upserts=1160
instructionObservations=5317
resetDeleted=1059
catalog=40 tokens / 59 pools / 59 pairs
```
Stable Swap swap closure:
| event kind | amount source | tx status | decoded | trades |
|---|---|---|---:|---:|
| `raydium_stable_swap.swap_base_in` | `stable_swap_instruction_bounds_only` | failed | 27 | 0 |
| `raydium_stable_swap.swap_base_in` | `stable_swap_vault_balance_delta` | success | 171 | 171 |
| `raydium_stable_swap.swap_base_out` | `stable_swap_instruction_bounds_only` | failed | 2 | 0 |
| `raydium_stable_swap.swap_base_out` | `stable_swap_vault_balance_delta` | success | 4 | 4 |
UI smoke evidence after the vault-delta correction:
```text
pair 27, timeframe 60s -> 70 candles
pair 30, timeframe 60s -> 44 candles
```
## Final invariant status
Validated as clean on the local corpus:
- residual `raydium_stable_swap.instruction_audit`: empty;
- residual `upstream_git.instruction_match` for covered local entries: empty;
- decoded-without-coverage: empty;
- non-swap materialized as trade: empty;
- failed transaction materialized as business trade: empty;
- multi-target materialization: empty;
- successful non-materialized swaps without skip reason: empty;
- Stable Swap successful swaps with `stable_swap_vault_balance_delta`: `trade_count = decoded_count`;
- Stable Swap instruction-bound-only swaps: failed only, `trade_count = 0`.
## Closure decision
`0.7.52 raydium_stable_swap` is closed for the currently observed local corpus.
The decoder has detected all locally observed Stable Swap instruction discriminants, materialized every event that can safely be materialized, and preserved non-materializable/failed events as decoded-only with explicit reasons.
Future work is not a blocker for `0.7.52` and should be handled as a later tranche if a new local corpus reveals additional discriminants or a direct, reliable `swap_event` path.

View File

@@ -0,0 +1,219 @@
# SQLite DB Transaction Merger — 0.7.58
## Statut
`0.7.58` introduit un outil CLI de fusion de corpus SQLite transactionnels pour construire une base consolidée de non-régression (`final.db` ou `final.next.db`) à partir de bases dédiées par DEX/surface.
Le merger ne lance pas de RPC, ne backfille pas, ne redécode pas et ne matérialise pas pendant la fusion. Il copie seulement le corpus brut nécessaire au replay local.
## Emplacement
```text
kb_tools/
Cargo.toml
src/bin/kb_db_merge.rs
```
Le package `kb_tools` est membre du workspace principal.
## Commandes types
Dry-run sur un output cible :
```bash
cargo run -p kb_tools --bin kb_db_merge -- \
--output ./final.next.db \
--input ./final.db \
--input ./corpus/pump_swap.db \
--input ./corpus/pump_fees.db \
--mode raw-corpus \
--dry-run
```
Merge réel dans une nouvelle base :
```bash
cargo run -p kb_tools --bin kb_db_merge -- \
--output ./final.next.db \
--input ./final.db \
--input ./corpus/new_dex.db \
--mode raw-corpus \
--replace-output
```
Merge dans une copie explicite de `final.db` :
```bash
cargo run -p kb_tools --bin kb_db_merge -- \
--merge-into-copy-of ./final.db \
--output ./final.next.db \
--input ./corpus/new_dex.db \
--mode raw-corpus \
--replace-output
```
## Modes
### `raw-corpus`
Mode par défaut.
Copie uniquement :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
Les tables décodées ou matérialisées ne sont pas copiées, car leur contenu dépend de la version active des decoders/materializers et doit être reconstruit par replay local.
### `signatures-only`
Alimente `k_sol_db_merge_signature_staging` avec `source_id`, `signature`, `slot` et `source_transaction_id`.
Ce mode sert à auditer ou préparer des backfills contrôlés sans copier les transactions complètes.
### `full-copy-safe`
Le mode est exposé dans le CLI mais reste explicitement refusé dans `0.7.58`. Il ne doit devenir utilisable que si les versions de schéma, les versions logiques des decoders et les remappages de foreign keys sont prouvés compatibles.
## Tables de provenance
Le schéma `kb_lib` ajoute :
```text
k_sol_db_merge_sources
k_sol_db_merge_transactions
k_sol_db_merge_conflicts
k_sol_db_merge_signature_staging
```
Ces tables permettent de relier chaque ligne copiée ou ignorée à sa source et de journaliser les conflits au lieu décraser silencieusement.
## Déduplication
Lidentité canonique est :
```text
signature
```
Règles :
- signature absente de loutput : copie transaction + instructions enfants ;
- signature déjà présente et identique : provenance `duplicate_skipped` ;
- signature déjà présente mais différente : insertion dans `k_sol_db_merge_conflicts` ;
- `--conflict-policy fail` : arrêt au premier conflit journalisé ;
- `--conflict-policy prefer-complete` : remplacement uniquement si le corpus entrant obtient un score de complétude supérieur ;
- `--conflict-policy record` : journalisation sans remplacement.
## Inspection de schéma
Chaque source est inspectée avant traitement :
```sql
SELECT name, sql FROM sqlite_master WHERE type = 'table';
PRAGMA table_info(k_sol_chain_transactions);
PRAGMA table_info(k_sol_chain_instructions);
```
Pour `raw-corpus`, une source est refusée si elle ne contient pas les tables et colonnes minimales nécessaires au replay local.
Les erreurs mentionnent :
```text
source DB
missing table ou missing column
mode demandé
```
## Replay attendu après merge
Après merge réel de `final.next.db`, rejouer localement avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Objectif : reconstruire toutes les tables dérivées avec les decoders/materializers courants et détecter les régressions cross-surface.
## SQL de validation
Fichiers ajoutés :
```text
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
```
Gates minimaux merge :
- aucune signature dupliquée ;
- aucune instruction orpheline ;
- aucune relation parent/child orpheline ;
- conflits listés et classifiés ;
- provenance source lisible.
Gates minimaux anti-régression après replay :
- surfaces closes Pump/Raydium/Meteora présentes dans le rollup ;
- failed transactions sans matérialisation actionable ;
- non-swap sans trade ;
- résidus decoded-without-target explicitement classés ;
- sentinelle PumpSwap/PumpFees pour les transactions cross-surface.
## Workflow futur
Pour chaque nouveau DEX ou surface :
1. créer une base vide dédiée ;
2. backfiller les signatures/pools nécessaires ;
3. développer decoder/materializer sur cette base ;
4. clore avec les SQL propres du DEX ;
5. fusionner dans `final.next.db` ;
6. rejouer `final.next.db` avec `forceDexDecode=yes` ;
7. lancer les validations globales ;
8. promouvoir seulement si les gates sont propres.
## Surfaces à vérifier en non-régression
Minimum actif pour `0.7.58` :
```text
pump_swap
pump_fun
pump_fees
raydium_cpmm
raydium_clmm
raydium_amm_v4
raydium_stable_swap
raydium_launchpad
meteora_dbc
meteora_dlmm
```
Règle decoder associée : un payload tronqué ou incompatible sur une surface secondaire ne doit pas aborter la transaction entière si lentrée peut être ignorée proprement. Préférer `Ok(None)` + observation/debug contrôlé pour les payloads tronqués connus ; conserver `Err` pour corruption critique ou incohérence interne.
## Clôture attendue
La tranche peut être clôturée seulement après :
```text
cargo test -p kb_lib
cargo test -p kb_tools
cargo clippy -p kb_lib -- -D warnings
cargo clippy -p kb_tools -- -D warnings
```
Puis :
- dry-run merge lisible ;
- merge réel multi-source OK ;
- pas de duplicate signatures ;
- pas dinstructions orphelines ;
- conflits journalisés ;
- replay local de `final.next.db` OK ;
- validation anti-régression Pump/Raydium/Meteora exécutée et documentée.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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