# 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= 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=&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=` ; 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 ```