v0.1.0-pre.073
This commit is contained in:
@@ -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. L’objectif 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 qu’un event ou program id est vérifié sans corpus local.
|
||||
@@ -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 d’events, 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 n’est 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 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.
|
||||
|
||||
## 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.
|
||||
@@ -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 l’ancienne 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 :
|
||||
|
||||
- l’ancienne 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 qu’elles 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
|
||||
```
|
||||
|
||||
L’objectif n’est pas de valider directement un DEX unique. L’objectif est de créer un registre générique permettant d’indexer les `program_id`, discriminants d’instructions, discriminants d’events, noms d’instructions, 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 qu’elles 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 n’est 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 qu’elle n’a 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 qu’il 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 l’arborescence 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 qu’un `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
|
||||
@@ -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
|
||||
```
|
||||
150
olddocs/archivekbobobot/docs/prompts/PROMPT_0_7_53_PUMP_SWAP.md
Normal file
150
olddocs/archivekbobobot/docs/prompts/PROMPT_0_7_53_PUMP_SWAP.md
Normal 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 l’entré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 d’instruction 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 d’erreurs 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 d’audit 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.
|
||||
```
|
||||
272
olddocs/archivekbobobot/docs/prompts/PROMPT_0_7_54_PUMP_FUN.md
Normal file
272
olddocs/archivekbobobot/docs/prompts/PROMPT_0_7_54_PUMP_FUN.md
Normal 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 l’archive 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 l’Anchor `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 d’une 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`.
|
||||
|
||||
L’objectif n’est 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 l’ancienne 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 d’abord 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 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`.
|
||||
|
||||
## 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 l’instruction représente réellement des frais exploitables ;
|
||||
- `k_sol_pool_admin_events` si c’est de la configuration/admin/creator ;
|
||||
- `k_sol_reward_events` uniquement si c’est 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 c’est 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 s’ils 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 l’archive fournie :
|
||||
|
||||
1. identifier les fichiers existants liés à `pump_fun`, `pump_fees`, upstream registry, coverage, materialization ;
|
||||
2. chercher dans `idls/**` s’il 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.
|
||||
347
olddocs/archivekbobobot/docs/prompts/PROMPT_0_7_55_PUMP_FEES.md
Normal file
347
olddocs/archivekbobobot/docs/prompts/PROMPT_0_7_55_PUMP_FEES.md
Normal 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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
```
|
||||
@@ -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 l’output 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 l’output 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 d’erreur doit indiquer :
|
||||
|
||||
```text
|
||||
source DB
|
||||
missing table
|
||||
missing column
|
||||
mode demandé
|
||||
```
|
||||
|
||||
## Stratégie de copie
|
||||
|
||||
Algorithme recommandé :
|
||||
|
||||
1. Créer ou initialiser l’output 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 l’output : 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 d’un 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 l’entré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 d’une 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é n’empê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 d’instructions 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.
|
||||
@@ -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
|
||||
```
|
||||
@@ -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 l’output 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 l’output 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 d’erreur doit indiquer :
|
||||
|
||||
```text
|
||||
source DB
|
||||
missing table
|
||||
missing column
|
||||
mode demandé
|
||||
```
|
||||
|
||||
## Stratégie de copie
|
||||
|
||||
Algorithme recommandé :
|
||||
|
||||
1. Créer ou initialiser l’output 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 l’output : 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 d’un 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 l’entré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 d’une 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é n’empê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 d’instructions 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.
|
||||
@@ -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 d’abord la création d’une base consolidée `final.db`.
|
||||
|
||||
Cette base consolidée doit permettre à Demo4 d’explorer :
|
||||
|
||||
```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 d’accounts/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 d’observation, 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 n’apparaissent 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 l’entré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 d’affichages 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.
|
||||
@@ -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
|
||||
```
|
||||
@@ -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 d’abord la création d’une base consolidée `final.db`.
|
||||
|
||||
Cette base consolidée doit permettre à Demo4 d’explorer :
|
||||
|
||||
```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 d’accounts/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 d’observation, 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 n’apparaissent 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 l’entré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 d’affichages 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.
|
||||
@@ -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
|
||||
```
|
||||
@@ -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 d’implé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 d’une 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é qu’une 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 l’entrée peut être ignorée proprement.
|
||||
|
||||
## Sources à vérifier
|
||||
|
||||
Inspecter d’abord 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 l’enum/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
|
||||
```
|
||||
|
||||
N’ouvrir cette tranche qu’aprè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.
|
||||
@@ -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 d’implé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 d’une 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é qu’une 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 l’entrée peut être ignorée proprement.
|
||||
|
||||
## Sources à vérifier
|
||||
|
||||
Inspecter d’abord 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 l’enum/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
|
||||
```
|
||||
|
||||
N’ouvrir cette tranche qu’aprè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.
|
||||
@@ -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
|
||||
```
|
||||
@@ -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é.
|
||||
@@ -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
|
||||
```
|
||||
@@ -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 l’absence de résultat Solscan comme absence on-chain définitive.
|
||||
|
||||
## Note Solscan importante
|
||||
|
||||
Pour `raydium_stable_swap`, il semble que Solscan ne dispose pas d’un 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 n’est 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 l’instruction
|
||||
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
|
||||
```
|
||||
Reference in New Issue
Block a user