From 8b09e82b3b0ce51d15899fb708165273d5d55dd6 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Sun, 31 May 2026 16:43:19 +0200 Subject: [PATCH] 0.7.47-1FE5 --- CHANGELOG.md | 9 +- Cargo.toml | 10 +- DB_EVENT_MODEL_REVIEW.md | 291 + DEX_DECODER_MATRIX.md | 204 + DEX_EVENT_COVERAGE_MATRIX.md | 232 + ...SION_PROMPT_0.7.47_1FE5_CONTINUATION_V2.md | 191 + ...SESSION_PROMPT_0.7.47_EVENT_COVERAGE_V3.md | 155 + ...SESSION_PROMPT_0.7.47_UPSTREAM_REGISTRY.md | 249 + README.md | 50 + ROADMAP.md | 64 + kb_demo_app/frontend/demo3.html | 74 +- .../ts/bindings/Demo3UpstreamRegistryEntry.ts | 54 + .../bindings/Demo3UpstreamRegistryPayload.ts | 15 + .../bindings/Demo3UpstreamRegistryResult.ts | 21 + .../Demo3UpstreamRegistrySearchRequest.ts | 34 + .../bindings/Demo3UpstreamRegistrySummary.ts | 58 + kb_demo_app/frontend/ts/demo3.ts | 48 +- kb_demo_app/package.json | 2 +- kb_demo_app/src/demo3.rs | 233 + kb_demo_app/src/lib.rs | 1 + kb_demo_app/tauri.conf.json | 2 +- kb_lib/src/constants.rs | 208 +- kb_lib/src/dex.rs | 8 + kb_lib/src/dex/openbook_v2.rs | 1591 ++ kb_lib/src/dex/phoenix_v1.rs | 1325 ++ kb_lib/src/dex_catalog.rs | 1 - kb_lib/src/dex_decode.rs | 381 +- kb_lib/src/dex_detect.rs | 14 + kb_lib/src/dex_detection_route.rs | 117 +- kb_lib/src/dex_event_classification.rs | 40 + kb_lib/src/dex_support_matrix.rs | 1197 +- kb_lib/src/launch_origin.rs | 11 +- kb_lib/src/lib.rs | 186 +- kb_lib/src/local_pipeline_replay.rs | 29 +- kb_lib/src/onchain_dex_pair_discovery.rs | 1006 +- kb_lib/src/upstream_registry.rs | 58 + kb_lib/src/upstream_registry_generated.rs | 15595 ++++++++++++++++ kb_lib/src/upstream_registry_match.rs | 651 + kb_lib/src/upstream_registry_types.rs | 177 + 39 files changed, 24260 insertions(+), 332 deletions(-) create mode 100644 DB_EVENT_MODEL_REVIEW.md create mode 100644 DEX_DECODER_MATRIX.md create mode 100644 DEX_EVENT_COVERAGE_MATRIX.md create mode 100644 NEXT_SESSION_PROMPT_0.7.47_1FE5_CONTINUATION_V2.md create mode 100644 NEXT_SESSION_PROMPT_0.7.47_EVENT_COVERAGE_V3.md create mode 100644 NEXT_SESSION_PROMPT_0.7.47_UPSTREAM_REGISTRY.md create mode 100644 kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryEntry.ts create mode 100644 kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryPayload.ts create mode 100644 kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryResult.ts create mode 100644 kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySearchRequest.ts create mode 100644 kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySummary.ts create mode 100644 kb_lib/src/dex/openbook_v2.rs create mode 100644 kb_lib/src/dex/phoenix_v1.rs create mode 100644 kb_lib/src/upstream_registry.rs create mode 100644 kb_lib/src/upstream_registry_generated.rs create mode 100644 kb_lib/src/upstream_registry_match.rs create mode 100644 kb_lib/src/upstream_registry_types.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 0148499..ec604f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,4 +79,11 @@ 0.7.46 - Meteora DAMM v1 events : extension conservatoire du decoder `meteora_damm_v1` à partir du mapping upstream Git decoder source `meteora-pools-decoder` et du corpus local fourni pour les discriminants observés `07a68aabceabecf4`, `3095dc823d0b09b2`, `856d2cb338ee7221`, `a9204f8988e84689`, `3657a51345e3dae0` et `1513d02bed3eff57` ; ajout des events create_pool, add/remove liquidity, claim_fee, create_lock_escrow et lock_liquidity ; ajout des exports publics associés ; raccordement de la persistance DEX et de la classification non-trade ; passage du replay local à `dex_decode.v0.7.46.damm_v1_events1`. Le programme Meteora Vault reste seulement référencé comme compte/programme associé quand il apparaît dans les comptes DAMM v1 ; aucun `program_id` vault n’est marqué vérifié sans corpus direct dédié. 0.7.46-demo3 - Correction ciblée de Demo3 pour la découverte/backfill : ajout d’un décodage léger des instructions `meteora_damm_v1` connues par discriminant upstream Git dans `onchain_dex_pair_discovery`, classification instruction-scoped prioritaire pour éviter qu’un `Swap` soit classé `add_liquidity` à cause de logs mixtes de transaction, filtrage `target_event` strict sur les surfaces explicites, conservation des transactions mixtes quand un target explicite est demandé malgré `excludeSwaps`, et ajout des cibles UI `create_lock_escrow` / `lock_liquidity`. 0.7.46-demo3-paged - Amélioration Demo3 discovery : pagination `getSignaturesForAddress` via `before_signature` / `until_signature`, scan de plusieurs adresses source dans une seule requête, déduplication des signatures multi-pool, compteur de pages, curseurs `next_before` par adresse et ordre de traitement `newest_first` / `oldest_first` pour constituer un corpus depuis les premières signatures d’un pool sans promouvoir de nouveau `program_id`. -0.7.46-final - Renommage documentaire et payload des anciens statuts/fonctions liés au dépôt source vers une terminologie générique `upstream_git_*` : `proofStatus` utilise désormais `upstream_git_local_corpus_observed`, `upstream_git_mapped_unverified` et `upstream_git_layout_unverified`; les payloads DAMM v1 utilisent `upstreamInstructionName`; la documentation prépare `0.7.47` comme Upstream Git Registry / DEX discovery preparation au lieu d’une tranche DAMM v2 immédiate. +0.7.46-final - Renommage documentaire et payload des anciens statuts/fonctions liés au dépôt source vers une terminologie générique `upstream_git_*` : `proofStatus` utilise désormais `upstream_git_local_corpus_observed`, `upstream_git_mapped_unverified` et `upstream_git_layout_unverified`; les payloads DAMM v1 utilisent `upstreamInstructionName`; la documentation prépare `0.7.47` comme Upstream Git Registry / DEX discovery preparation au lieu d’une tranche DAMM v2 immédiate. + +0.7.47 - Upstream Git Registry / DEX discovery preparation : ajout d’un registre générique `upstream_git` pour indexer `program_id`, discriminants d’instructions/events, noms d’entrées et familles de programmes depuis Carbon et sources Git/IDL externes ; extension Demo3 aux targets multi-surfaces, orderbook, burn/mint/transfer/wrap/unwrap/stake ; ajout de groupes de signatures réussies/échouées pour alimenter Demo2 ; maintien strict de l’invariant : aucune entrée upstream Git ne produit trade/candle sans decoder spécialisé et corpus local. +0.7.47-openbook-v2-audit - Ajout d’un decoder local `openbook_v2` audit-only : instructions `place_order`, `cancel_order_by_client_order_id`, `consume_events`, `settle_funds`, `close_open_orders_account`; cleanup du fallback `upstream_git.instruction_match`; extraction audit des `Program return` et `Program data`; mapping des logs `FillLog`, `OpenOrdersPositionLog`, `TotalOrderFillEvent`, `SettleFundsLog`; aucune matérialisation trade/candle. +0.7.47-phoenix-v1-audit - Ajout d’un decoder local `phoenix_v1` audit-only : `order_place`, `order_cancel`, `funds_withdraw`, `log`; parsing strict des instructions log `0x0f`; décodage audit du header Phoenix log et des events `Reduce`, `Place`, `TimeInForce`; correction du mapping `PlaceMultiplePostOnlyOrders` tag `0x10`; aucune matérialisation trade/candle. +0.7.47-doc-matrix - Révision documentaire : ajout d’une matrice DEX dédiée, ajout explicite des sources Git/IDL à consulter, et redécoupage du plan `0.7.48+` en un DEX/version par tranche afin d’éviter les lots “tous events/tous decoders” trop larges. + +0.7.47-doc-event-coverage - Ajout d'une matrice événementielle complémentaire `DEX_EVENT_COVERAGE_MATRIX.md` pour suivre, par DEX/version, les familles `swap`, `pool_create`, `liquidity`, `position`, `fee`, `reward`, `admin/config`, `mint`, `burn`, `transfer`, `account_create/close`, `wrap/unwrap`, `orderbook`, `vault`, `lock/unlock`, `launch` et `migration`; ajout de `DB_EVENT_MODEL_REVIEW.md` pour clarifier que `k_sol_dex_decoded_events` suffit à l'audit-only mais que des tables transversales sont nécessaires pour exploiter transfers, orderbook, vault, launch/migration et coverage upstream en requêtes métier. diff --git a/Cargo.toml b/Cargo.toml index c0d4211..1a7a8f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ ] [workspace.package] -version = "0.7.46" +version = "0.7.47" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-bobobot" @@ -31,16 +31,15 @@ reqwest = { version = "^0.13", default-features = false, features = ["charset", rustls = { version = "^0.23", features = ["aws-lc-rs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1.0", features = [] } -solana-account-decoder-client-types = { version = ">=4.0.0-rc.1", features = ["zstd"] } +solana-account-decoder-client-types = { version = "^4.0", features = ["zstd"] } solana-address-lookup-table-interface = { version = "^3.1", features = ["serde"] } -solana-client = { version = ">=4.0.0-rc.0", features = [] } solana-compute-budget-interface = { version = "^3.0", features = ["borsh", "serde"] } solana-rpc-client-api = { version = ">=4.0.0-rc.0", features = [] } -solana-rpc-client-types = { version = ">=4.0.0-rc.0", features = [] } +#solana-rpc-client-types = { version = "^4.0", features = [] } solana-sdk = { version = "^4.0", features = ["full"] } solana-sdk-ids = { version = "^3.1", features = [] } solana-system-interface = { version = "^3.2", features = ["alloc", "serde", "std"] } -solana-transaction-status-client-types = { version = ">=4.0.0-rc.1", features = [] } +solana-transaction-status-client-types = { version = "^4.0", features = [] } spl-associated-token-account-interface = { version = "^2.0", features = ["borsh"] } spl-memo-interface = { version = "^2.1", features = [] } spl-token-interface = { version = "^3.0", features = [] } @@ -89,3 +88,4 @@ single_match = "allow" manual_unwrap_or_default = "allow" manual_find = "allow" explicit_counter_loop = "allow" +get_first = "allow" diff --git a/DB_EVENT_MODEL_REVIEW.md b/DB_EVENT_MODEL_REVIEW.md new file mode 100644 index 0000000..22eee8c --- /dev/null +++ b/DB_EVENT_MODEL_REVIEW.md @@ -0,0 +1,291 @@ +# Database Event Model Review — `khadhroony-bobobot` `0.7.47-1FE5` + +## Conclusion courte + +La base actuelle est **suffisante pour continuer le décodage exhaustif en audit-only**, parce que `k_sol_dex_decoded_events` garde les events décodés avec `payload_json`. + +La base actuelle est **partiellement insuffisante pour exploiter tous les events en requêtes métier**, parce que certaines familles importantes n’ont pas encore de tables dédiées ou de modèle normalisé : + +- transfers SPL / Token-2022 ; +- token account create/close ; +- wrap/unwrap SOL ; +- orderbook orders/fills/settlements ; +- vault deposit/withdraw ; +- launch/migration ; +- lock/unlock LP ; +- staking/unstaking ; +- coverage matrix persistée par discriminator/event. + +## Ce qui existe déjà + +D’après le README, le modèle contient déjà notamment : + +- `k_sol_chain_transactions`; +- `k_sol_chain_instructions`; +- `k_sol_dex_decoded_events`; +- `k_sol_trade_events`; +- `k_sol_liquidity_events`; +- `k_sol_pool_lifecycle_events`; +- `k_sol_fee_events`; +- `k_sol_reward_events`; +- `k_sol_pool_admin_events`; +- `k_sol_token_mint_events`; +- `k_sol_token_burn_events`; +- `k_sol_transaction_classifications`; +- `k_sol_protocol_candidates`; +- `k_sol_dex_decode_replay_ledger`. + +Ces tables couvrent déjà les besoins principaux : + +| Besoin | Couverture actuelle | +|---|---| +| Stockage brut/audit de tout event décodé | Oui, via `k_sol_dex_decoded_events.payload_json`. | +| Trades/candles | Oui. | +| Liquidity/lifecycle/fee/reward/admin | Oui, au moins structurellement. | +| Mint/burn | Oui, structurellement. | +| Replay/skip sûr | Oui, via ledger. | +| Event coverage attendu vs observé | Non ou seulement implicite. | +| Transfers/token account lifecycle | Non spécialisé. | +| Orderbook events | Non spécialisé. | +| Vault events | Non spécialisé. | +| Launch/migration | Non spécialisé ou dispersé. | + +## Ne pas modifier la DB trop vite + +Il ne faut pas créer une table pour chaque DEX ou chaque event upstream. + +La bonne stratégie : + +1. Décoder tout ce qu’on peut en `k_sol_dex_decoded_events`. +2. Ajouter `eventFamily`, `eventSemanticKind`, `eventActionability`, `proofStatus`, `sourceRepo`, `sourcePath`. +3. Matérialiser seulement les familles prouvées et utiles. +4. Ajouter des tables transversales uniquement quand plusieurs DEX en ont besoin. + +## Ajouts DB recommandés + +### 1. `k_sol_dex_event_coverage_entries` + +But : stocker ce qui est **attendu/listé** depuis les sources upstream, même si non observé. + +Colonnes conceptuelles : + +```text +id +decoder_code +program_id +program_family +surface_kind +source_repo +source_path +entry_kind -- instruction/event/account/log/program_data +entry_name +discriminator_hex +discriminator_len +event_family -- swap/burn/mint/admin/etc. +expected_db_target +proof_status +local_event_kind +observed_count +materialized_count +trade_count +first_signature +last_signature +notes +created_at +updated_at +``` + +Rôle : rendre la couverture objectivable. Exemple : “Carbon liste 42 instructions Raydium CPMM, notre code en décode 18, 4 sont matérialisées”. + +### 2. `k_sol_token_transfer_events` + +But : matérialiser les transfers significatifs hors trade. + +Colonnes conceptuelles : + +```text +id +transaction_id +instruction_id +decoded_event_id +signature +slot +program_id +token_program_id +mint +source_token_account +destination_token_account +source_owner +destination_owner +amount_raw +amount_ui +transfer_kind -- transfer, transfer_checked, routed_transfer, vault_transfer +reason -- audit_only, vault_movement, migration, settlement, unknown +payload_json +``` + +Important : ne pas créer de trade depuis cette table. Elle sert au risque/analyse. + +### 3. `k_sol_token_account_events` + +But : suivre create/close/init ATA/token accounts. + +```text +id +transaction_id +instruction_id +decoded_event_id +signature +slot +event_kind -- create_ata, init_account, close_account, wrap_sol, unwrap_sol +account_address +mint +owner +token_program_id +lamports_delta +payload_json +``` + +Cela aide à comprendre WSOL wrap/unwrap, close accounts, cleanup bots, préparation de trades. + +### 4. `k_sol_orderbook_events` + +But : stocker OpenBook/Phoenix et autres CLOB sans les confondre avec swaps AMM. + +```text +id +transaction_id +instruction_id +decoded_event_id +signature +slot +protocol_name +market_account +event_kind -- order_place, order_cancel, order_fill, settle_funds, consume_events, open_orders_create, open_orders_close +side +price_lots +base_lots +quote_lots +maker +taker +client_order_id +raw_event_name +interpretation_status +payload_json +``` + +Les fills ne deviennent `trade_events` que quand maker/taker, base/quote, lots/decimals et sens économique sont validés. + +### 5. `k_sol_vault_events` + +But : suivre vault deposit/withdraw, Meteora Vault, Kamino/Vault-like programs. + +```text +id +transaction_id +instruction_id +decoded_event_id +signature +slot +protocol_name +vault_account +event_kind -- deposit, withdraw, claim, rebalance, update_config +mint_a +mint_b +amount_a_raw +amount_b_raw +owner +payload_json +``` + +### 6. `k_sol_launch_events` + +But : séparer launch/bonding/migration du DEX effectif. + +```text +id +transaction_id +instruction_id +decoded_event_id +signature +slot +launch_protocol +event_kind -- create, buy, sell, migrate, graduate, initialize_curve, close_curve +token_mint +curve_account +migration_target_program +migration_pool +quote_mint +amount_token_raw +amount_quote_raw +payload_json +``` + +### 7. `k_sol_liquidity_lock_events` + +But : traiter LP lock/unlock explicitement. + +```text +id +transaction_id +instruction_id +decoded_event_id +signature +slot +protocol_name +pool_id +pair_id +lock_account +owner +event_kind -- create_lock, lock, unlock, extend_lock, close_lock +lp_mint +lp_amount_raw +unlock_time +payload_json +``` + +## Alternative minimaliste + +Si on veut éviter trop de migrations immédiates, le minimum à ajouter d’abord est : + +1. `k_sol_dex_event_coverage_entries`; +2. `k_sol_token_transfer_events`; +3. `k_sol_orderbook_events`. + +Les autres tables peuvent attendre. + +## Impact sur le plan des versions + +Chaque version DEX doit répondre à deux questions : + +### Couverture decoder + +- A-t-on listé tous les events upstream ? +- A-t-on un decoder audit pour chaque discriminator connu ? +- Les events non observés sont-ils marqués `upstream_git_mapped_unverified` ? + +### Couverture DB + +- L’event peut-il rester dans `k_sol_dex_decoded_events` ? +- Doit-il être matérialisé dans une table existante ? +- Faut-il une table transversale nouvelle ? +- Une table nouvelle peut-elle servir à plusieurs DEX ? + +## Décision pratique pour `0.7.48` + +Avant de reprendre `raydium_cpmm`, faire une micro-tranche DB/doc : + +```text +0.7.48-pre — event coverage + DB model checkpoint +``` + +Objectif : + +- ajouter ou documenter `k_sol_dex_event_coverage_entries`; +- ne pas encore ajouter toutes les tables métier ; +- produire un rapport par DEX : + - listed events, + - decoded events, + - materialized events, + - missing DB target, + - trade_count invariant. diff --git a/DEX_DECODER_MATRIX.md b/DEX_DECODER_MATRIX.md new file mode 100644 index 0000000..0e6d596 --- /dev/null +++ b/DEX_DECODER_MATRIX.md @@ -0,0 +1,204 @@ +# DEX Decoder Matrix — `khadhroony-bobobot` `0.7.47-1FE5` + +Cette matrice complète `kb_lib/src/dex_support_matrix.rs`. Elle documente **ce qui est fait**, **ce qui reste à faire**, et **le niveau de preuve attendu** par DEX/version. + +## Règle de lecture + +| Statut | Sens | +|---|---| +| `supported` | Decoder local actif et matérialisation métier possible sur corpus validé. | +| `partial` | Decoder partiel ou surface partielle : des events existent, mais la couverture n’est pas complète. | +| `audit-only` | Decoder local spécialisé, mais aucun trade/candle/matérialisation marché. | +| `planned` | Program id ou surface connue, mais decoder non prioritaire ou non activé. | +| `to_verify` | Source externe ou candidat : aucun statut vérifié sans corpus local. | +| `ignored/historical` | À conserver pour historique ou compatibilité, mais non prioritaire. | + +## Sources upstream à comparer + +- Carbon decoders : `https://github.com/sevenlabs-hq/carbon/tree/main/decoders` +- Solana Streamer : `https://github.com/0xfnzero/solana-streamer` +- Sol Parser SDK IDLs : `https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl` +- Pinax Substreams Solana IDLs : `https://github.com/pinax-network/substreams-solana-idls/tree/main/src` +- HODL Warden Solana Tx Parser : `https://github.com/hodlwarden/solana-tx-parser/tree/main/src` +- OpenBook v2 : `https://github.com/openbook-dex/openbook-v2` +- Phoenix on-chain MM : `https://github.com/all-in-one-blockchain/phoenix-onchain-mm` +- Vybe DEX/AMM support list : `https://docs.vybenetwork.com/docs/available-dexs-amms` + +## Matrice prioritaire DEX/version + +| Ordre | DEX/version | État actuel | Fait | Reste à faire | +|---:|---|---|---|---| +| 1 | `raydium_cpmm` | `supported` | Swaps matérialisés ; premiers non-swaps prouvés (`initialize`, `withdraw`, `collect_creator_fee`) ; trades/candles OK. | Comparer tous les discriminants Carbon/IDL ; compléter fees/admin/lifecycle ; rejouer sur base dédiée ; vérifier absence d’audits orphelins. | +| 2 | `raydium_clmm` | `supported` | Swaps `swap`/`swap_v2` ; events positions/liquidité prouvés ; matérialisation non-trade existante. | Repasser tous les events Carbon/IDL : open/close position, rewards, protocol fees, Token-2022 ; compléter audit → materialized si corpus. | +| 3 | `pump_swap` | `supported` | `buy`/`sell` décodés et matérialisés ; trade/candle OK. | Ajouter tous les events Carbon/Solana Streamer : cashback, fee, volume accumulator, admin/config ; conserver les non-trades hors candles. | +| 4 | `pump_fun` | `partial / launch_surface` | Création/token launch partiellement décodée ; intégrée au pipeline de listings. | Traiter tous les events Pump.fun disponibles : buy/sell/migrate/create/update ; séparer bonding/launch de DEX effectif ; valider migration vers PumpSwap. | +| 5 | `meteora_dbc` | `partial` | Swaps/instruction audits observés ; Demo3 donne du corpus. | Couverture complète DBC : launch/bonding curve, swap, migration, config/admin, fees ; matérialiser seulement ce qui est prouvé. | +| 6 | `meteora_dlmm` | `supported` | Couverture avancée validée en `0.7.45` : swaps, liquidity, positions, lifecycle, fees ; non-trade matérialisé. | Résoudre les audits résiduels non mappés ; comparer Carbon/IDL pour events rewards/admin restants ; revalidation base neuve. | +| 7 | `meteora_damm_v1` | `supported / partial events` | Couverture `0.7.46` : swap, create_pool, add/remove liquidity, claim_fee, create_lock_escrow, lock_liquidity. | Vérifier les surfaces upstream non observées ; améliorer rattachement pool/pair pour remove_liquidity non matérialisés ; revalidation stricte. | +| 8 | `meteora_damm_v2` | `partial` | `swap`, `instruction_audit`, registry/discriminants et corpus Demo3 existent. | Couvrir tous les events Carbon/source : create pool, liquidity, fees, dynamic config, admin ; déterminer actionability des swaps ; matérialiser si montants fiables. | +| 9 | `phoenix_v1` | `audit-only` | Decoder local audit-only ; `log_audit`, order place/cancel, withdraw ; parsing strict `0x0f`; events `Reduce`, `Place`, `TimeInForce` observés ; `trade_count=0`. | Terminer tous les events Git : `Fill`, `FillSummary`, `Fee`, `Evict`, `ExpiredOrder`, etc. ; ajouter counts/flags audit ; seulement ensuite étudier trade materialization. | +| 10 | `openbook_v2` | `audit-only` | Decoder local audit-only ; instructions order/cancel/consume/settle ; `Program data` mappé : `FillLog`, `OpenOrdersPositionLog`, `TotalOrderFillEvent`, `SettleFundsLog`; `trade_count=0`. | Vérifier layouts fill/out et sens maker/taker/base/quote ; ajouter table audit éventuelle ; ne matérialiser trades qu’après validation du sens économique. | +| 11 | `orca_whirlpools` | `partial` | Premier decoder historique présent ; swaps/create_pool partiels. | Comparer Carbon/IDL complet ; couvrir liquidity, positions, fees/rewards, tick arrays ; valider swaps exploitables et non-trades. | +| 12 | `raydium_launchlab` | `planned launch` | Entrée canonique locale LaunchLab/Launchpad ; program id connu localement. | Décoder launch/migration ; ne pas confondre avec CPMM/CLMM/AMM v4 ; rattacher aux pools tradables. | +| 13 | `meteora_vault` | `to_verify` | Présent comme indice upstream / compte associé. | Corpus direct obligatoire ; decoder séparé si events vault réels ; aucune promotion via DAMM indirect. | +| 14 | `fluxbeam` | `partial/to_verify` | Decoder initial existant ; Demo3 peut produire des candidats. | Vérifier source/IDL ; compléter swap, pool, liquidity, fees/admin ; matérialisation uniquement après corpus. | +| 15 | `dexlab` | `partial/to_verify` | Decoder initial historique ; ancienne entrée beta supprimée. | Reconfirmer program id/source ; décoder events disponibles ; distinguer DexLab natif et liens OpenBook/market. | +| 16 | `lifinity_amm_v2` | `to_verify` | Program id listé par sources externes/Vybe ; pas de corpus concluant. | Trouver IDL/source ; Demo3 par program/market ; audit-only d’abord. | +| 17 | `stabble_stable_swap` / `stabble_weighted_swap` | `to_verify` | Program ids/indices via sources externes ; candidats Demo3 observables. | Source/IDL + corpus + decoder audit-only ; déterminer surface AMM et montants exploitables. | +| 18 | `bonkswap` | `to_verify` | Program id/Carbon/Vybe selon registre ; swaps candidats possibles. | Vérifier program id, source et corpus ; décoder tous events ; pas de trade sans montants. | +| 19 | `boop` / `boop_fun` | `to_verify / launch` | Entrée de découverte. | Séparer launch surface et swap effectif ; corpus + source obligatoire. | +| 20 | `moonshot` / `moonit` | `to_verify / launch` | Moonshot buy/sell observés via upstream candidates ; Moonit launch attribution historique. | Source/IDL + migration + rattachement pools ; éviter heuristiques seules. | +| 21 | `heaven` | `to_verify` | Program id/candidat ajouté en matrice. | Vérifier s’il est launch, AMM ou les deux ; corpus dédié. | +| 22 | `printr` | `to_verify` | Preset Demo3 ajouté ; candidats observables. | Source/IDL, discriminants, corpus, decoder audit-only. | +| 23 | `metadao_*` | `to_verify` | Presets spécifiques : launchpad, bid wall, futarchy, AMM. | Traiter par programme séparé ; ne pas utiliser mint ids comme program ids ; corpus obligatoire. | +| 24 | `raydium_stable_swap` | `planned/historical` | Entrée conservée. | Reprendre uniquement si corpus réel ; stable AMM séparé de CPMM/CLMM. | +| 25 | `jupiter_*`, `dflow_aggregator_v4`, `okx_dex` | `aggregator_router` | Registry/discovery pour contexte transactionnel. | Ne pas matérialiser en DEX direct ; utiliser pour routeSource/routing/context. | + +## Checklist obligatoire par DEX/version + +Pour chaque DEX ou version, la tranche doit fermer les points suivants : + +- [ ] Source Git/IDL recensée. +- [ ] Tous les `program_id` vérifiés localement ou marqués `to_verify`. +- [ ] Tous les discriminants d’instructions listés. +- [ ] Tous les discriminants d’events/logs listés. +- [ ] Demo3 corpus constitué. +- [ ] Demo2 backfill de signatures réussies. +- [ ] Replay forcé sur base `0.7.47+`. +- [ ] SQL : decoded events par kind. +- [ ] SQL : `trade_count=0` pour audit-only. +- [ ] SQL : trade/candle uniquement si montants exploitables. +- [ ] Cleanup `upstream_git.instruction_match` si decoder spécialisé local. +- [ ] Décision finale : `audit-only`, `materialized`, `partial`, ou `to_verify`. + +## Notes de matérialisation + +Un event peut devenir `materialized` uniquement si : + +1. la transaction est `OK` ; +2. les comptes nécessaires sont identifiés ; +3. les mints sont fiables ; +4. les montants sont fiables ; +5. le sens base/quote est validé ; +6. les requêtes SQL prouvent l’absence de faux trades/candles ; +7. les tests et clippy sont verts. + + +## Annexe — snapshot de `kb_lib/src/dex_support_matrix.rs` (`1FE5`) + +| Code | Rôle | Surface | Program id status | Observed | Decoded | Materialized | Status | Skip reason | +|---|---|---|---|---:|---:|---:|---|---| +| `pump_fun` | `launch_surface` | `launch` | `known` | non | oui | oui | `partial` | launch_surface_requires_migration_linking_before_live_trading | +| `pump_swap` | `dex_effective` | `AMM` | `known` | oui | oui | oui | `supported` | | +| `raydium_cpmm` | `dex_effective` | `AMM` | `known` | oui | oui | oui | `supported` | | +| `raydium_clmm` | `dex_effective` | `CLMM` | `known` | oui | oui | oui | `supported` | | +| `raydium_amm_v4` | `dex_effective` | `AMM` | `known` | oui | oui | oui | `supported` | | +| `raydium_launchlab` | `launch_surface` | `launch` | `known` | non | non | non | `planned` | decoder_and_materialization_not_enabled | +| `raydium_liquidity_locking` | `to_verify` | `liquidity_locking` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `raydium_router` | `aggregator_router` | `router` | `known` | non | non | non | `partial` | router_not_materialized_as_direct_trade_surface | +| `raydium_stable_swap` | `dex_effective` | `AMM` | `known` | non | non | non | `planned` | deprecated_program_not_prioritized | +| `meteora_dlmm` | `dex_effective` | `DLMM` | `known` | oui | oui | oui | `supported` | | +| `meteora_dlc` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | surface_and_program_id_to_verify | +| `meteora_damm_v1` | `dex_effective` | `AMM` | `known` | oui | oui | non | `partial` | meteora_damm_v1_swap_without_amount_payload | +| `meteora_damm_v2` | `dex_effective` | `AMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay | +| `meteora_dbc` | `dex_effective` | `bonding_curve` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay | +| `orca_whirlpools` | `dex_effective` | `CLMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay | +| `fluxbeam` | `dex_effective` | `AMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay | +| `dexlab` | `dex_effective` | `AMM` | `known` | non | oui | oui | `partial` | not_observed_in_0_7_28_replay | +| `bags` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify | +| `letsbonk` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify | +| `bonk` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify | +| `bonk_fun` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify | +| `okx_dex` | `aggregator_router` | `aggregator` | `to_verify` | non | non | non | `planned` | program_id_to_verify | +| `boop_fun` | `launch_surface` | `launch` | `to_verify` | non | non | non | `planned` | program_id_to_verify | +| `moonshot` | `launch_surface` | `launch` | `to_verify` | non | non | non | `planned` | historical_entities_py_program_id_requires_corpus_verification | +| `believe` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify | +| `metadao` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | umbrella_surface_programs_split_into_specific_discovery_targets | +| `metadao_launchpad_v0_7_0` | `to_verify` | `launch` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification | +| `metadao_bid_wall_v0_7_0` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification | +| `metadao_futarchy_v0_6_0` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification | +| `metadao_amm_v0_5_0` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | official_metadao_program_id_requires_local_corpus_verification | +| `printr` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | solscan_program_label_requires_local_corpus_verification | +| `zora` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | solscan_program_label_requires_local_corpus_verification | +| `moonit` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify | +| `launchbeam` | `launch_surface` | `launch` | `unknown` | non | non | non | `planned` | program_id_to_verify | +| `heaven` | `launch_surface` | `launch` | `to_verify` | non | non | non | `planned` | program_id_to_verify | +| `gavel` | `to_verify` | `auction` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `pump_fees` | `to_verify` | `fee_program` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `meteora_pools` | `dex_effective` | `AMM` | `alias_of_meteora_damm_v1` | non | non | non | `to_verify` | program_id_alias_held_by_meteora_damm_v1 | +| `dflow_aggregator_v4` | `aggregator_router` | `aggregator` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `drift_v2` | `to_verify` | `perps` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `jupiter_swap` | `aggregator_router` | `aggregator` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `jupiter_dca` | `aggregator_router` | `dca` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `jupiter_limit_order` | `aggregator_router` | `limit_order` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `jupiter_limit_order_2` | `aggregator_router` | `limit_order` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `jupiter_perpetuals` | `to_verify` | `perps` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `jupiter_lend` | `to_verify` | `lending` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `kamino_lending` | `to_verify` | `lending` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `kamino_vault` | `to_verify` | `vault` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `kamino_farms` | `to_verify` | `farms` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `kamino_limit_order` | `to_verify` | `limit_order` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `marginfi_v2` | `to_verify` | `lending` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `onchain_labs_dex_v1` | `dex_effective` | `AMM` | `alias_of_okx_dex` | non | non | non | `to_verify` | program_id_alias_held_by_okx_dex | +| `onchain_labs_dex_v2` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `pancake_swap` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `vertigo` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `virtuals` | `launch_surface` | `launch` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `wavebreak` | `dex_effective` | `AMM` | `to_verify` | non | non | non | `to_verify` | upstream_git_program_id_requires_local_corpus_verification | +| `aldrin` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `aldrin_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `crema` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `cropper` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `lifinity_v1` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `lifinity_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `mercurial` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `orca_v1` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `orca_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `phoenix` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `saber` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `saber_decimals` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `openbook_v2` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `fox` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `sanctum_infinity` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `saros` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `stabble_stable_swap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `stabble_weighted_swap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `stepn` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `solayer` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `penguin` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `sanctum` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `one_dex` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `solfi` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `bonkswap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `guacswap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `invariant` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `oasis` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `token_swap` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `helium_network` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `marinade_liquid_staking` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `francium_yield_pools` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `marinade_governance` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `serum_dao` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `port_finance` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `solend_classic` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `hyperspace_nft_amm` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `magic_eden_nft_amm` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `raydium_staking_early` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `orca_aquafarm_v1` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `quarry_merge_mining` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | historical_entities_py_program_id_requires_corpus_verification | +| `goosefx_v1` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `obric_v2` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `ondo_global_market` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `scorch` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `zerofi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `manifest_clob` | `to_verify` | `orderbook` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `alphaq` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `goonfi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `goonfi_v2` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `byreal` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `bisonfi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `fusionamm` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `woofi` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `aquifer` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `humidifi` | `to_verify` | `unknown` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | +| `solfi_v2` | `to_verify` | `AMM` | `to_verify` | non | non | non | `to_verify` | vybe_supported_dex_amm_requires_local_corpus_and_decoder_source | diff --git a/DEX_EVENT_COVERAGE_MATRIX.md b/DEX_EVENT_COVERAGE_MATRIX.md new file mode 100644 index 0000000..9d7ca69 --- /dev/null +++ b/DEX_EVENT_COVERAGE_MATRIX.md @@ -0,0 +1,232 @@ +# DEX Event Coverage Matrix — `khadhroony-bobobot` `0.7.47-1FE5` + +Cette matrice complète `DEX_DECODER_MATRIX.md`. + +La matrice précédente répondait à la question : **quel DEX/version est couvert ?** + +Cette matrice répond à la question : **quels events/instructions doivent être décodés, audit-only ou matérialisés ?** + +## Principe + +L’objectif n’est plus seulement de décoder les swaps. L’objectif est de décoder le maximum d’événements disponibles dans les sources Git/IDL et dans le corpus local, parce que certains événements non-trade peuvent influencer une décision de trading : + +- perte ou ajout de liquidité ; +- burn de tokens ou de LP ; +- mint anormal ; +- lock/unlock de liquidité ; +- close account / fermeture de position ; +- admin/config changes ; +- fees/rewards ; +- migration launch → DEX ; +- market/orderbook activity ; +- vault deposit/withdraw ; +- changement de market cap ou de supply dérivée. + +Un event peut donc être important même s’il ne produit jamais de `trade_event` ou de candle. + +## Règle de couverture + +Pour chaque DEX/version, on doit viser trois niveaux : + +| Niveau | Description | +|---|---| +| `listed` | L’event/instruction existe dans une source Git/IDL/Carbon/Vybe/autre. | +| `decoded_audit` | Le code local reconnaît l’event et le persiste dans `k_sol_dex_decoded_events` avec payload structuré ou audit-only. | +| `materialized` | L’event alimente une table métier spécialisée : trade, liquidity, lifecycle, fee, reward, admin, mint, burn, orderbook, vault, launch/migration, etc. | + +Ne pas sauter directement de `listed` à `materialized`. + +## Univers minimal d’events à suivre + +Cette liste doit devenir la grille commune pour toutes les tranches `0.7.48+`. + +| Famille | Exemples | Impact possible | Table actuelle / cible | +|---|---|---|---| +| `swap/trade` | swap, buy, sell, route swap, exact in/out | Prix, volume, candles | `k_sol_trade_events`, `k_sol_pair_metrics`, `k_sol_pair_candles` | +| `pool_create` | initialize, create_pool, initialize_market | Découverte pool/pair | `k_sol_pool_lifecycle_events`, `k_sol_pools`, `k_sol_pairs` | +| `liquidity_add` | add_liquidity, deposit liquidity, bootstrap | Profondeur, risque, market cap indirect | `k_sol_liquidity_events` | +| `liquidity_remove` | remove_liquidity, withdraw liquidity | Rug/liquidity drain | `k_sol_liquidity_events` | +| `position_open` | open_position, init_position | CLMM/DLMM state | `k_sol_pool_lifecycle_events` ou future `k_sol_position_events` | +| `position_close` | close_position, close_position_if_empty | Sortie de LP, risque | `k_sol_pool_lifecycle_events` ou future `k_sol_position_events` | +| `fee` | claim_fee, collect_protocol_fee, collect_creator_fee | Rentabilité, activité pool | `k_sol_fee_events` | +| `reward` | claim_reward, fund_reward, update_reward | Incitations, farming | `k_sol_reward_events` | +| `admin/config` | set_config, update_fee, pause, whitelist, authority change | Risque protocole/pool | `k_sol_pool_admin_events` | +| `mint` | token mint, LP mint, position NFT mint | Supply, launch, LP | `k_sol_token_mint_events` + future token activity | +| `burn` | token burn, LP burn, position NFT burn | Supply, LP burn, risque/réassurance | `k_sol_token_burn_events` + future token activity | +| `transfer` | SPL transfer, Token-2022 transfer, routed transfer | Flux wallet/vault, whale movement | future `k_sol_token_transfer_events` | +| `account_create` | ATA create, token account init | Préparation trade/wallet/vault | future `k_sol_token_account_events` | +| `account_close` | close token account, close open orders | Sortie position/wallet cleanup | future `k_sol_token_account_events` ou `k_sol_orderbook_events` | +| `wrap/unwrap` | wrap SOL, unwrap SOL, close WSOL ATA | Routing, PnL, trade prep | future token account/activity | +| `order_place` | place_order, post_only, IOC | Orderbook pressure | future `k_sol_orderbook_events` | +| `order_cancel` | cancel_order, cancel_all, reduce order | Changement intention | future `k_sol_orderbook_events` | +| `order_fill` | FillLog, fill event, trade event | Trade réel orderbook | future `k_sol_orderbook_events`; trade seulement après validation économique | +| `settle_funds` | settle_funds, withdraw funds | Finalisation CLOB | future `k_sol_orderbook_events` | +| `consume_events` | crank/event queue processing | Orderbook fill/out | future `k_sol_orderbook_events` | +| `vault_deposit` | deposit into vault | TVL/risque | future `k_sol_vault_events` | +| `vault_withdraw` | withdraw from vault | TVL drain | future `k_sol_vault_events` | +| `lock` | lock_liquidity, create_lock_escrow | LP lock/risk | `k_sol_pool_lifecycle_events` ou future lock table | +| `unlock` | unlock, release escrow | Risque de retrait LP | future lock/lifecycle | +| `launch` | create bonding curve, launch pool | Origine token | future `k_sol_launch_events` | +| `migration` | migrate to DEX, migrate liquidity | Passage launch → tradable | future `k_sol_launch_events`, pool origins | +| `stake/unstake` | stake LP/token, unstake | Incentives/withdraw risk | future staking/reward events | +| `oracle/price` | oracle update, price account update | Pricing/risk | future oracle/context events | +| `unknown` | unmapped discriminator | Dette de décodage | `k_sol_dex_decoded_events` audit-only | + +## Matrice de couverture par DEX/version + +Légende : + +- `M` = matérialisé déjà ou historiquement validé ; +- `A` = audit-only local ; +- `P` = partiel / doit être complété ; +- `L` = listé upstream, non validé localement ; +- `-` = non applicable connu ; +- `?` = à vérifier. + +| DEX/version | swap | pool create | liq add/remove | position | fee/reward | admin/config | mint/burn | transfer/account | orderbook | vault | launch/migration | état immédiat | +|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---| +| `raydium_cpmm` | M | P | P | - | P | P | ? | ? | - | - | ? | Reprendre en `0.7.48`, comparer tous events Carbon/IDL/fnzero. | +| `raydium_clmm` | M | P | M/P | M/P | P | P | P | ? | - | - | ? | Reprendre en `0.7.49`, compléter positions/rewards/fees/admin. | +| `pump_swap` | M | P | P | - | P | P | ? | P | - | - | P | Reprendre en `0.7.50`, couvrir buy/sell/cashback/fee/volume/admin. | +| `pump_fun` | P | P | - | - | ? | P | P | P | - | - | M/P | Reprendre en `0.7.51`, launch/bonding/migration/buy/sell/create/update. | +| `meteora_dbc` | P | P | P | - | P | P | P | ? | - | P | M/P | Reprendre en `0.7.52`, séparer bonding, swap, migration, config, fees. | +| `meteora_dlmm` | M | M | M | M | M/P | P | ? | ? | - | ? | ? | Reprendre en `0.7.53` pour exhaustive upstream + audits résiduels. | +| `meteora_damm_v1` | M/P | M | M/P | - | M/P | P | ? | ? | - | P | ? | Reprendre en `0.7.54`, vérifier toutes surfaces upstream non observées. | +| `meteora_damm_v2` | P | P | L/P | - | L/P | L/P | ? | ? | - | P | ? | Reprendre en `0.7.55`, decoder tous events Carbon/source. | +| `phoenix_v1` | A | A/P | - | - | A/P | A/P | - | A/P | A | - | - | Continuer audit des events Git, pas de trade/candle. | +| `openbook_v2` | A | A/P | - | - | A/P | A/P | - | A/P | A | - | - | Audit-only avancé, matérialisation orderbook future. | +| `orca_whirlpools` | P | P | L/P | L/P | L/P | L/P | P | ? | - | - | ? | Reprendre en `0.7.58`, IDL complet + corpus dédié. | +| `raydium_launchlab` | - | P | ? | - | ? | P | P | P | - | - | P | Launch/migration après DEX effectifs. | +| `bonkswap` | L | L | L | - | L | L | ? | ? | - | - | L | Vérifier source/corpus. | +| `moonshot` | L/P | P | ? | - | ? | P | P | P | - | - | P | Séparer launch, buy/sell, migration. | +| `heaven` | L/P | L/P | L/P | - | L/P | L/P | P | P | - | ? | P | Vérifier AMM vs launch. | +| `goosefx_v1` | L/P | L/P | L/P | ? | ? | ? | ? | ? | ? | ? | ? | Vybe/Demo3 candidates ; source nécessaire. | +| `obric_v2` | L/P | L/P | ? | ? | ? | ? | ? | ? | ? | ? | ? | Bon candidat après sources. | +| `solfi_v2` | L/P | L/P | ? | ? | ? | ? | ? | ? | ? | ? | ? | Bon candidat après sources. | + +## Points critiques manquants dans l’ancienne matrice + +### `burn` + +`burn` doit être une famille de première classe, pas seulement une sous-note. Il peut signaler : + +- burn de LP tokens ; +- burn de supply token ; +- fermeture ou destruction indirecte de position ; +- réduction du risque de dump si le burn est réel et vérifié ; +- au contraire, faux signal si le burn ne concerne pas la bonne mint ou si le compte propriétaire est ambigu. + +Action : ajouter `burn` à toutes les checklists DEX et aux diagnostics de couverture. + +### `transfer` + +Les transfers ne sont pas des trades par défaut, mais ils sont nécessaires pour : + +- repérer vault movements ; +- détecter migration / liquidity routing ; +- comprendre des orderbook settle/fill ; +- analyser whale movement ou sortie de pool. + +Action : prévoir une table dédiée plutôt que tout stocker uniquement dans `payload_json`. + +### `account close/create` + +Les close/create ATA sont utiles pour détecter : + +- fin de route WSOL ; +- sortie de position ; +- cleanup après swap ; +- close open-orders account ; +- activité de bots. + +Action : famille dédiée `token_account` / `account_lifecycle`. + +## Checklist exhaustive par DEX + +Pour chaque DEX/version, la tranche doit remplir un tableau événementiel : + +| Colonne | Description | +|---|---| +| `source_repo` | Git/IDL/source utilisée. | +| `source_path` | Chemin exact du fichier source. | +| `decoder_code` | Code interne/upstream. | +| `program_id` | Program id ou `to_verify`. | +| `entry_kind` | `instruction`, `event`, `account`, `log`, `program_data`. | +| `entry_name` | Nom source exact. | +| `discriminator_hex` | Discriminator ou tag. | +| `discriminator_len` | Longueur en octets. | +| `event_family` | Famille commune : swap, burn, admin, order_fill, etc. | +| `local_event_kind` | Event local produit. | +| `local_status` | `not_implemented`, `audit_only`, `decoded`, `materialized`. | +| `db_target` | Table cible ou `k_sol_dex_decoded_events_only`. | +| `proof_status` | Statut upstream/local. | +| `observed_count` | Count local après replay. | +| `materialized_count` | Count table métier. | +| `trade_count` | Count trades générés, doit être 0 sauf swap validé. | +| `notes` | Ambiguïtés, layout, corpus, reste à faire. | + +## Requêtes SQL génériques de couverture + +### Couverture decoded events par programme + +```sql +SELECT + protocol_name, + event_kind, + program_id, + json_extract(payload_json, '$.upstreamEntryName') AS upstream_entry_name, + json_extract(payload_json, '$.upstreamDiscriminatorHex') AS upstream_discriminator_hex, + COUNT(*) AS n +FROM k_sol_dex_decoded_events +GROUP BY + protocol_name, + event_kind, + program_id, + upstream_entry_name, + upstream_discriminator_hex +ORDER BY protocol_name, n DESC; +``` + +### Sécurité trades pour 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.event_kind LIKE '%_audit' + OR de.protocol_name IN ('upstream_git', 'phoenix_v1', 'openbook_v2') +GROUP BY de.protocol_name, de.event_kind +ORDER BY trade_count DESC; +``` + +### Vérifier burn/mint présents dans decoded payloads + +```sql +SELECT + protocol_name, + event_kind, + json_extract(payload_json, '$.eventLifecycleKind') AS lifecycle, + json_extract(payload_json, '$.eventActionability') AS actionability, + COUNT(*) AS n +FROM k_sol_dex_decoded_events +WHERE event_kind LIKE '%burn%' + OR event_kind LIKE '%mint%' + OR lifecycle IN ('burn', 'mint') +GROUP BY protocol_name, event_kind, lifecycle, actionability +ORDER BY n DESC; +``` + +## Décision + +À partir de maintenant, une tranche DEX n’est pas complète si elle ne liste que les swaps. Elle doit explicitement indiquer : + +- events source listés ; +- events décodés audit-only ; +- events matérialisés ; +- events volontairement non implémentés ; +- events non observés localement ; +- trous de DB éventuels. diff --git a/NEXT_SESSION_PROMPT_0.7.47_1FE5_CONTINUATION_V2.md b/NEXT_SESSION_PROMPT_0.7.47_1FE5_CONTINUATION_V2.md new file mode 100644 index 0000000..3d8fb6c --- /dev/null +++ b/NEXT_SESSION_PROMPT_0.7.47_1FE5_CONTINUATION_V2.md @@ -0,0 +1,191 @@ +# 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 +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. diff --git a/NEXT_SESSION_PROMPT_0.7.47_EVENT_COVERAGE_V3.md b/NEXT_SESSION_PROMPT_0.7.47_EVENT_COVERAGE_V3.md new file mode 100644 index 0000000..8b552e7 --- /dev/null +++ b/NEXT_SESSION_PROMPT_0.7.47_EVENT_COVERAGE_V3.md @@ -0,0 +1,155 @@ +# 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 +DEX_DECODER_MATRIX.md +DEX_EVENT_COVERAGE_MATRIX.md +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. diff --git a/NEXT_SESSION_PROMPT_0.7.47_UPSTREAM_REGISTRY.md b/NEXT_SESSION_PROMPT_0.7.47_UPSTREAM_REGISTRY.md new file mode 100644 index 0000000..4f413a9 --- /dev/null +++ b/NEXT_SESSION_PROMPT_0.7.47_UPSTREAM_REGISTRY.md @@ -0,0 +1,249 @@ +# 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-whirlpool +fluxbeam +lifinity-amm-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 diff --git a/README.md b/README.md index 703dcd8..c718b52 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,44 @@ Ce document reflète le point de reprise `0.7.43-E5C` et l’état de consolidation atteint après `0.7.45` pour `meteora_dlmm`. La version Cargo a évolué ensuite à `0.7.46` côté workspace. Le lot Meteora initialement ouvert en bloc a été redécoupé : `meteora_dlmm` est traité séparément, puis la suite reprend `meteora_damm_v1`, `meteora_damm_v2` et `meteora_dbc` un par un. + +## État de reprise actuel `0.7.47-1FE5` + +Le point de reprise courant n’est plus `0.7.43-E5C`. La branche de travail actuelle est `0.7.47-1FE5` : le registre upstream Git est en place, OpenBook v2 et Phoenix v1 disposent de decoders locaux **audit-only**, et la suite doit être conduite par DEX/version au lieu de tenter tous les events en une seule session. + +Les nouveaux chemins audit-only doivent rester non matérialisants : aucun event OpenBook v2 ou Phoenix v1 ne doit produire de trade, metric ou candle tant que le sens économique complet n’est pas validé. + +Voir aussi : + +- `DEX_DECODER_MATRIX.md` pour la matrice DEX détaillée ; +- `ROADMAP.md` pour le plan révisé `0.7.48` à `0.7.61` ; +- `CHANGELOG.md` pour les tranches `0.7.47-*`. + + +## Sources upstream Git / IDL à utiliser en `0.7.47+` + +Les sources externes ci-dessous sont des **indices de décodage**, pas des preuves métier. Elles servent à extraire des `program_id`, discriminants, IDL, layouts et noms d’instructions/events, mais toute promotion locale doit rester conditionnée à : + +1. observation Demo3 ; +2. backfill Demo2 ; +3. replay local sur la base de travail ; +4. requêtes SQL de validation ; +5. invariants : aucun faux trade, aucune fausse candle, aucun `program_id` promu sans corpus. + +Sources prioritaires : + +| Source | Usage attendu | +|---|---| +| `https://github.com/sevenlabs-hq/carbon/tree/main/decoders` | Source principale de discriminants, instructions et events multi-protocoles. | +| `https://github.com/0xfnzero/solana-streamer` | Source complémentaire pour PumpFun, PumpSwap, Bonk et Raydium CPMM. | +| `https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl` | IDL complémentaires pour programmes Solana supportés par parser SDK. | +| `https://github.com/pinax-network/substreams-solana-idls/tree/main/src` | IDL et layouts additionnels à comparer au registre local. | +| `https://github.com/hodlwarden/solana-tx-parser/tree/main/src` | Décodage transactionnel complémentaire et conventions de mapping. | +| `https://github.com/openbook-dex/openbook-v2` | Source officielle OpenBook v2 : programme, IDL et logs. | +| `https://github.com/all-in-one-blockchain/phoenix-onchain-mm` | Source Phoenix/MM complémentaire pour corpus et intégration. | +| `https://docs.vybenetwork.com/docs/available-dexs-amms` | Source de découverte de DEX/AMM supportés par Vybe, à traiter comme index externe non vérifié localement. | + + ## 1. Objectif L’objectif opérationnel est de construire progressivement une application capable de : @@ -388,3 +426,15 @@ La version `0.7.47` n’est plus dédiée à un seul DEX. Elle doit introduire u Les entrées de ce registre sont des indices de découverte, pas des preuves métier. Elles doivent être marquées `upstream_git_unverified` ou `upstream_git_mapped_unverified` tant qu’elles ne sont pas confirmées par Demo3, backfill, replay local et requêtes SQL. Le registre sert à accélérer la constitution de corpus pour les DEX et surfaces suivantes : Meteora DAMM v2/DBC/Vault, Raydium Launchpad/Stable/Locking, Orca Whirlpools, FluxBeam, DexLab, Lifinity AMM v2, Phoenix/OpenBook, Stabble, BonkSwap, Boop, Moonshot, Heaven, Wavebreak, Vertigo, Virtuals, Pancake Swap, OKX DEX, Jupiter/Kamino/Drift et autres programmes utiles à la découverte. + + +## Note 0.7.47-1FE5 — Event coverage et modèle DB + +La matrice DEX/version doit être complétée par une matrice événementielle exhaustive. Le projet ne vise pas seulement les swaps : les events `burn`, `mint`, `transfer`, `account_close`, `lock/unlock`, `vault_deposit/withdraw`, `admin/config`, `order_fill`, `settle_funds`, `launch` et `migration` peuvent influencer une décision de trading. + +Voir : + +- `DEX_DECODER_MATRIX.md` pour le statut par DEX/version ; +- `DEX_EVENT_COVERAGE_MATRIX.md` pour les familles d'events à couvrir ; +- `DB_EVENT_MODEL_REVIEW.md` pour les ajouts DB à envisager avant `0.7.48+`. + diff --git a/ROADMAP.md b/ROADMAP.md index b6069e2..be9ba3f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,6 +2,55 @@ # khadhroony-bobobot — Roadmap +## 0.7.47-1FE5 — Décision de planification : ne plus viser “tous les events en une session” + +La phase `0.7.47` a montré que l’objectif “réimplémenter tous les décodeurs Carbon et toutes les sources en un seul bloc” est trop large. Le plan est donc redécoupé en **un DEX/version par tranche**, avec une matrice documentaire dédiée : `DEX_DECODER_MATRIX.md`. + +Règles de planification : + +- chaque DEX/version doit avoir sa propre phase de corpus ; +- chaque phase doit lister explicitement les sources Git/IDL consultées ; +- tous les events/instructions disponibles dans les sources doivent être inventoriés, même si seuls certains deviennent matérialisés ; +- le statut par event doit rester séparé : `upstream_git_unverified`, `upstream_git_mapped_unverified`, `upstream_git_local_corpus_observed`, `audit-only`, `materialized` ; +- un decoder local spécialisé peut remplacer `upstream_git.instruction_match`, mais ne doit pas créer de trade/candle sans validation de montants et de sens économique ; +- OpenBook v2 et Phoenix v1 restent `audit-only` à ce stade, malgré leurs layouts partiellement décodés. + +### Sources upstream obligatoires à vérifier + +| Source | Usage | +|---|---| +| `https://github.com/sevenlabs-hq/carbon/tree/main/decoders` | Source principale des decoders multi-protocoles. | +| `https://github.com/0xfnzero/solana-streamer` | Source complémentaire PumpFun/PumpSwap/Bonk/Raydium CPMM. | +| `https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl` | IDL complémentaires. | +| `https://github.com/pinax-network/substreams-solana-idls/tree/main/src` | IDL et layouts additionnels. | +| `https://github.com/hodlwarden/solana-tx-parser/tree/main/src` | Parsers transactionnels complémentaires. | +| `https://github.com/openbook-dex/openbook-v2` | Source officielle OpenBook v2. | +| `https://github.com/all-in-one-blockchain/phoenix-onchain-mm` | Source Phoenix/MM complémentaire. | +| `https://docs.vybenetwork.com/docs/available-dexs-amms` | Source externe de découverte DEX/AMM, non vérifiante. | + +### Plan révisé `0.7.48` à `0.7.61` + +| Version cible | Scope | Objectif de clôture | +|---|---|---| +| `0.7.48` | `raydium_cpmm` | Reprendre tous les discriminants/events depuis Carbon/Solana Streamer ; vérifier swaps, liquidity, fees/admin ; confirmer matérialisation trade/candle et non-trade. | +| `0.7.49` | `raydium_clmm` | Couvrir toutes les instructions CLMM : swaps, positions, liquidity, fees/rewards, Token-2022 ; valider matérialisation non-trade. | +| `0.7.50` | `pump_swap` | Couvrir `buy/sell` et tous les events auxiliaires disponibles : fees, cashback, volume accumulator, admin/config. | +| `0.7.51` | `pump_fun` | Traiter launch/bonding/migration ; séparer création token, buy/sell bonding, migration vers DEX effectif. | +| `0.7.52` | `meteora_dbc` | Couverture DBC : bonding curve, swap, migration, launch attribution, fees/admin, non-trade. | +| `0.7.53` | `meteora_dlmm` | Audit final de parité avec sources Git/IDL ; fermer ou documenter les audits résiduels. | +| `0.7.54` | `meteora_damm_v1` | Parité upstream complète ; résoudre les cas non matérialisés faute de pool/pair quand possible. | +| `0.7.55` | `meteora_damm_v2` | Couverture DAMM v2 complète : create, swap, liquidity, fees/admin/config ; décider trade actionability. | +| `0.7.56` | `phoenix_v1` | Finir tous les events Git disponibles en audit ; préparer mais ne pas activer trade materialization. | +| `0.7.57` | `openbook_v2` | Finir layouts logs/events ; définir conditions futures de trade/candle sans les activer par défaut. | +| `0.7.58` | `orca_whirlpools` | Reprendre Whirlpools depuis IDL/source : swaps, pools, positions, liquidity, fees/rewards. | +| `0.7.59` | Launch surfaces | Raydium LaunchLab/Launchpad, PumpFun migration, Moonshot/Moonit, Boop, Heaven, Bags, LetsBonk. | +| `0.7.60` | DEX historiques / candidats | FluxBeam, DexLab, Lifinity, Stabble, BonkSwap, GooseFX, Obric, SolFi, etc. par corpus. | +| `0.7.61` | Validation consolidée | Rejouer une base neuve multi-DEX, vérifier matrice, zéro faux trade/candle, rapport de couverture par DEX/event. | + +Ce plan remplace les anciens regroupements larges `0.7.50+` qui mélangeaient plusieurs DEX dans une même version. + + + ## 1. Objet du projet `khadhroony-bobobot` est un workspace Rust destiné à la détection, l’observation, l’analyse de patterns et, à terme, à l’exécution semi-automatisée d’achats/ventes de tokens sur la blockchain Solana. @@ -1188,6 +1237,21 @@ Familles prioritaires à indexer en premier : Aucun de ces programmes ne doit être marqué `verified_by_corpus` uniquement parce qu’il existe dans un dépôt Git externe. + +### 6.079B. Version `0.7.48-pre` — Event coverage et checkpoint DB + +Objectif : éviter de limiter la matrice aux DEX/versions et imposer une couverture événementielle exhaustive avant la reprise DEX par DEX. + +À faire : + +- maintenir `DEX_EVENT_COVERAGE_MATRIX.md` en plus de `DEX_DECODER_MATRIX.md` ; +- lister pour chaque DEX/version tous les events/instructions/logs connus depuis Carbon, fnzero, IDL, Pinax, HODL Warden, OpenBook, Phoenix et Vybe ; +- inclure explicitement les familles non-trade : `burn`, `mint`, `transfer`, `account_create`, `account_close`, `wrap_sol`, `unwrap_sol`, `lock`, `unlock`, `vault_deposit`, `vault_withdraw`, `admin/config`, `fee`, `reward`, `launch`, `migration` ; +- vérifier si la DB actuelle suffit ou si une table transversale doit être ajoutée ; +- prioriser `k_sol_dex_event_coverage_entries`, puis `k_sol_token_transfer_events` et `k_sol_orderbook_events` ; +- ne pas créer de trade/candle depuis ces nouveaux chemins sans validation économique et corpus. + + ### 6.080. Version `0.7.48` — `meteora_damm_v2` séparé Objectif : reprendre `meteora_damm_v2` comme DEX effectif séparé après disponibilité du registre upstream Git. diff --git a/kb_demo_app/frontend/demo3.html b/kb_demo_app/frontend/demo3.html index 0bae2da..828dc52 100644 --- a/kb_demo_app/frontend/demo3.html +++ b/kb_demo_app/frontend/demo3.html @@ -138,13 +138,85 @@ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
Leave all unchecked for generic discovery. Check several surfaces to scan once and keep candidates matching any selected target.
-
Use this to find corpus signatures for non-swap decoders without promoting unverified events.
+
Use this to find corpus signatures for non-swap decoders without promoting unverified events. Leave all unchecked to request target='any'.
diff --git a/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryEntry.ts b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryEntry.ts new file mode 100644 index 0000000..dd5bcca --- /dev/null +++ b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryEntry.ts @@ -0,0 +1,54 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +/** + * One upstream registry entry exposed through Demo3. + */ +export type Demo3UpstreamRegistryEntry = { +/** + * Repository name or bootstrap locator that produced the entry. + */ +sourceRepo: string | null, +/** + * Repository-relative path or bootstrap path that produced the entry. + */ +sourcePath: string | null, +/** + * Stable decoder code used by the registry. + */ +decoderCode: string, +/** + * Optional Solana program id when already known by the source entry. + */ +programId: string | null, +/** + * Program family used to group related programs. + */ +programFamily: string, +/** + * Surface kind such as AMM, CLMM, launch, aggregator or core Solana. + */ +surfaceKind: string, +/** + * Entry kind: instruction, event, account or program. + */ +entryKind: string, +/** + * Source-level entry name. + */ +entryName: string, +/** + * Optional discriminator bytes encoded as lowercase hexadecimal. + */ +discriminatorHex: string | null, +/** + * Optional discriminator byte length. + */ +discriminatorLen: number | null, +/** + * Current proof status. + */ +proofStatus: string, +/** + * Notes that preserve uncertainty and validation requirements. + */ +notes: string, }; diff --git a/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryPayload.ts b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryPayload.ts new file mode 100644 index 0000000..18793bc --- /dev/null +++ b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryPayload.ts @@ -0,0 +1,15 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Demo3UpstreamRegistryResult } from "./Demo3UpstreamRegistryResult"; + +/** + * Payload returned by the Demo3 upstream registry command. + */ +export type Demo3UpstreamRegistryPayload = { +/** + * Pretty JSON representation of the registry result. + */ +resultJson: string, +/** + * Structured registry result. + */ +result: Demo3UpstreamRegistryResult, }; diff --git a/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryResult.ts b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryResult.ts new file mode 100644 index 0000000..462851b --- /dev/null +++ b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistryResult.ts @@ -0,0 +1,21 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Demo3UpstreamRegistryEntry } from "./Demo3UpstreamRegistryEntry"; +import type { Demo3UpstreamRegistrySearchRequest } from "./Demo3UpstreamRegistrySearchRequest"; +import type { Demo3UpstreamRegistrySummary } from "./Demo3UpstreamRegistrySummary"; + +/** + * Structured upstream registry result exposed through Demo3. + */ +export type Demo3UpstreamRegistryResult = { +/** + * Normalized request used by kb_lib. + */ +request: Demo3UpstreamRegistrySearchRequest, +/** + * Registry summary. + */ +summary: Demo3UpstreamRegistrySummary, +/** + * Matching entries. + */ +entries: Array, }; diff --git a/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySearchRequest.ts b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySearchRequest.ts new file mode 100644 index 0000000..837ed31 --- /dev/null +++ b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySearchRequest.ts @@ -0,0 +1,34 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +/** + * Search request for the static upstream registry exposed through Demo3. + */ +export type Demo3UpstreamRegistrySearchRequest = { +/** + * Optional decoder-code filter. + */ +decoderCode: string | null, +/** + * Optional program-id filter. + */ +programId: string | null, +/** + * Optional program-family filter. + */ +programFamily: string | null, +/** + * Optional surface-kind filter. + */ +surfaceKind: string | null, +/** + * Optional entry-kind filter. + */ +entryKind: string | null, +/** + * Optional proof-status filter. + */ +proofStatus: string | null, +/** + * Optional maximum number of entries to return. + */ +limit: number | null, }; diff --git a/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySummary.ts b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySummary.ts new file mode 100644 index 0000000..b9e5fd2 --- /dev/null +++ b/kb_demo_app/frontend/ts/bindings/Demo3UpstreamRegistrySummary.ts @@ -0,0 +1,58 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +/** + * Summary of the upstream registry snapshot exposed through Demo3. + */ +export type Demo3UpstreamRegistrySummary = { +/** + * Total static registry entry count before filtering. + */ +totalEntryCount: number, +/** + * Returned entry count after filtering. + */ +returnedEntryCount: number, +/** + * Number of entries that have a program id. + */ +entriesWithProgramIdCount: number, +/** + * Number of entries that have a discriminator. + */ +entriesWithDiscriminatorCount: number, +/** + * Number of program-level seed entries. + */ +programEntryCount: number, +/** + * Number of instruction entries. + */ +instructionEntryCount: number, +/** + * Number of event entries. + */ +eventEntryCount: number, +/** + * Number of account entries. + */ +accountEntryCount: number, +/** + * Number of entries still unverified from upstream Git or seed data. + */ +upstreamGitUnverifiedCount: number, +/** + * Number of entries mapped into decoders but not locally observed. + */ +upstreamGitMappedUnverifiedCount: number, +/** + * Number of entries observed in the local corpus. + */ +upstreamGitLocalCorpusObservedCount: number, +/** + * Number of entries materialized in local business tables. + */ +upstreamGitLocalCorpusMaterializedCount: number, +/** + * Number of layout entries still unverified locally. + */ +upstreamGitLayoutUnverifiedCount: number, }; diff --git a/kb_demo_app/frontend/ts/demo3.ts b/kb_demo_app/frontend/ts/demo3.ts index dec385e..10d9403 100644 --- a/kb_demo_app/frontend/ts/demo3.ts +++ b/kb_demo_app/frontend/ts/demo3.ts @@ -36,6 +36,22 @@ const presets: Demo3Preset[] = [ { label: "Meteora DBC", dexCode: "meteora_dbc", programId: "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN", description: "Meteora DBC." }, { label: "Orca Whirlpools", dexCode: "orca_whirlpools", programId: "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc", description: "Orca Whirlpools CLMM." }, { label: "FluxBeam", dexCode: "fluxbeam", programId: "FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X", description: "FluxBeam." }, + { label: "GooseFX V1 (Vybe)", dexCode: "goosefx_v1", programId: "GAMMA7meSFWaBXF25oSUgmGRwaW6sCMFLmBNiMSdbHVT", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Obric V2 (Vybe)", dexCode: "obric_v2", programId: "obriQD1zbpyLz95G5n7nJe6a4DPjpFwa5XYPoNm113y", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Ondo Global Market (Vybe)", dexCode: "ondo_global_market", programId: "XzTT4XB8m7sLD2xi6snefSasaswsKCxx5Tifjondogm", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Scorch (Vybe)", dexCode: "scorch", programId: "SCoRcH8c2dpjvcJD6FiPbCSQyQgu3PcUAWj2Xxx3mqn", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "ZeroFi (Vybe)", dexCode: "zerofi", programId: "ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Manifest CLOB (Vybe)", dexCode: "manifest_clob", programId: "MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms", description: "Entrée Vybe orderbook; à vérifier par corpus local." }, + { label: "AlphaQ (Vybe)", dexCode: "alphaq", programId: "ALPHAQmeA7bjrVuccPsYPiCvsi428SNwte66Srvs4pHA", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Goonfi (Vybe)", dexCode: "goonfi", programId: "goonERTdGsjnkZqWuVjs73BZ3Pb9qoCUdBUL17BnS5j", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Goonfi V2 (Vybe)", dexCode: "goonfi_v2", programId: "goonuddtQRrWqqn5nFyczVKaie28f3kDkHWkHtURSLE", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Byreal (Vybe)", dexCode: "byreal", programId: "REALQqNEomY6cQGZJUGwywTBD2UmDT32rZcNnfxQ5N2", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "BisonFi (Vybe)", dexCode: "bisonfi", programId: "BiSoNHVpsVZW2F7rx2eQ59yQwKxzU5NvBcmKshCSUypi", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "FusionAMM (Vybe)", dexCode: "fusionamm", programId: "fUSioN9YKKSa3CUC2YUc4tPkHJ5Y6XW1yz8y6F7qWz9", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Woofi (Vybe)", dexCode: "woofi", programId: "WooFif76YGRNjk1pA8wCsN67aQsD9f9iLsz4NcJ1AVb", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Aquifer (Vybe)", dexCode: "aquifer", programId: "AQU1FRd7papthgdrwPTTq5JacJh8YtwEXaBfKU3bTz45", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "Humidifi (Vybe)", dexCode: "humidifi", programId: "9H6tua7jkLhdm3w8BvgpTn5LZNU7g4ZynDmCiNN3q6Rp", description: "Entrée Vybe; à vérifier par corpus local." }, + { label: "SolFi V2 (Vybe)", dexCode: "solfi_v2", programId: "SV2EYYJyRz2YhfXwXnhNAevDEui5Q6yrfyo13WtupPF", description: "Entrée Vybe; à vérifier par corpus local." }, { label: "DexLab", dexCode: "dexlab", programId: "DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N", description: "DexLab Swap/Pool." }, { label: "Aldrin (historical)", dexCode: "aldrin", programId: "AMM55ShdkoGRB5jVYPjWziwk8m5MpwyDgsMWHaMSQWH6", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Aldrin V2 (historical)", dexCode: "aldrin_v2", programId: "CURVGoZn8zycx6FXwwevgBTB2gVvdbGTEpvMJDbgs2t4", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, @@ -49,7 +65,6 @@ const presets: Demo3Preset[] = [ { label: "Phoenix (historical)", dexCode: "phoenix", programId: "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Saber (historical)", dexCode: "saber", programId: "SSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZ", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "OpenBook V2 (historical)", dexCode: "openbook_v2", programId: "opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "OpenBook (historical)", dexCode: "openbook", programId: "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Fox (historical)", dexCode: "fox", programId: "HyhpEq587ANShDdbx1mP4dTmDZC44CXWft29oYQXDb53", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Sanctum Infinity (historical)", dexCode: "sanctum_infinity", programId: "5ocnV1qiCgaQR8Jb8xWnVbApfaygJ8tNoZfgPwsgx9kx", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Saros (historical)", dexCode: "saros", programId: "SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, @@ -70,15 +85,8 @@ const presets: Demo3Preset[] = [ { label: "Invariant (historical)", dexCode: "invariant", programId: "HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Token Swap (historical)", dexCode: "token_swap", programId: "SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Helium Network (historical)", dexCode: "helium_network", programId: "treaf4wWBBty3fHdyBpo35Mz84M8k3heKXmjmi9vFt5", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "Raydium Legacy V2 (historical)", dexCode: "raydium_legacy_v2", programId: "27haf8L6oxUeXrHrgEgsexjSY5hbVUWEmvv9Nyxg8vQv", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "Raydium Legacy V3 (historical)", dexCode: "raydium_legacy_v3", programId: "7quYqsZdpWSZ3qgDextersDqoKjZy7aCgwHBBfRb7KPt", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "Serum V3 (historical)", dexCode: "serum_v3", programId: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "Mango Private Pools (historical)", dexCode: "mango_private_pools", programId: "AtdP2iyfh6xBGwVZzHvY73E7uKKkZBTH2siHh3ZuEf1P", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Marinade Liquid Staking (historical)", dexCode: "marinade_liquid_staking", programId: "MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "Step Finance Pools (historical)", dexCode: "step_finance_pools", programId: "StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Francium Yield Pools (historical)", dexCode: "francium_yield_pools", programId: "FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "Cropper Legacy (historical)", dexCode: "cropper_legacy", programId: "CyZuD7RPDcrqCGbNvzrNVs1zpCQehqp7SuXB7rdFKSzo", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "Dexlab Beta (historical)", dexCode: "dexlab_beta", programId: "9qvG1zP8ZzY1sTnExx7mkyxhW1063YHVYZxMYz2HkM4m", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Marinade Governance (historical)", dexCode: "marinade_governance", programId: "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Serum DAO (historical)", dexCode: "serum_dao", programId: "SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Port Finance (historical)", dexCode: "port_finance", programId: "Port7uDYB3wk6GJAw4KT1WpTeMtSu9bTcChBHkX2LfR", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, @@ -88,10 +96,12 @@ const presets: Demo3Preset[] = [ { label: "Raydium Staking Early (historical)", dexCode: "raydium_staking_early", programId: "EhhTKczWMGQt46ynNeRX1WfeagwwJd7ufHvCDjRxjo5Q", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Orca Aquafarm V1 (historical)", dexCode: "orca_aquafarm_v1", programId: "82yxjeMsvaURa4MbZZ7WZZHfobirZYkH1zF8fmeGtyaQ", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, { label: "Quarry Merge Mining (historical)", dexCode: "quarry_merge_mining", programId: "QMNeHCGYnLVDn1icRAfQZpjPLBNkfGbSKRB83G5d8KB", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "SWAB Finance Beta (historical)", dexCode: "swab_finance_beta", programId: "SWABxNGyxEBVoNRGn6RvYBt5UqercSE5PBHuJeYXYHq", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "CRAFT Early (historical)", dexCode: "craft_early", programId: "CrAFTUv7zKXBaS5471aBiARBu6x7nP4rDzr8xwBewbr1", description: "Program id historique importé depuis entities.py; à vérifier par corpus." }, - { label: "metaDAO", dexCode: "metadao", programId: "", description: "DEX à vérifier. Aucun program id n'est inventé." }, - { label: "Printr", dexCode: "printr", programId: "", description: "DEX à vérifier. Aucun program id n'est inventé." }, + { label: "Printr", dexCode: "printr", programId: "T8HsGYv7sMk3kTnyaRqZrbRPuntYzdh12evXBkprint", description: "Candidat Printr; à vérifier par corpus local." }, + { label: "metaDAO — umbrella (manual)", dexCode: "metadao", programId: "", description: "Umbrella MetaDAO. Choisir de préférence une surface spécifique ci-dessous." }, + { label: "metaDAO Launchpad v0.7.0", dexCode: "metadao_launchpad_v0_7_0", programId: "moontUzsdepotRGe5xsfip7vLPTJnVuafqdUWexVnPM", description: "Programme MetaDAO officiel candidat; à vérifier par corpus local." }, + { label: "metaDAO Bid Wall v0.7.0", dexCode: "metadao_bid_wall_v0_7_0", programId: "WALL8ucBuUyL46QYxwYJjidaFYhdvxUFrgvBxPshERx", description: "Programme MetaDAO officiel candidat; à vérifier par corpus local." }, + { label: "metaDAO Futarchy v0.6.0", dexCode: "metadao_futarchy_v0_6_0", programId: "FUTARELBfJfQ8RDGhg1wdhddq1odMAJUePHFuBYfUxKq", description: "Programme MetaDAO officiel candidat; à vérifier par corpus local." }, + { label: "metaDAO AMM v0.5.0", dexCode: "metadao_amm_v0_5_0", programId: "AMMJdEiCCa8mdugg6JPF7gFirmmxisTfDJoSNSUi5zDJ", description: "Programme MetaDAO officiel candidat; à vérifier par corpus local." }, ]; let lastResultJson = ""; @@ -109,6 +119,16 @@ function valueOrNull(value: string): string | null { return trimmed === "" ? null : trimmed; } +function invalidBase58Characters(value: string): string[] { + const invalid = new Set(); + for (const character of value.trim()) { + if (!/^[1-9A-HJ-NP-Za-km-z]$/.test(character)) { + invalid.add(character); + } + } + return Array.from(invalid); +} + function isSolanaAddressLike(value: string): boolean { const trimmed = value.trim(); if (trimmed.length < 32 || trimmed.length > 44) { @@ -161,6 +181,10 @@ function validateOnchainRequest(request: Demo3OnchainDexDiscoveryRequest): void validateOptionalSignature(request.beforeSignature, "Before signature"); validateOptionalSignature(request.untilSignature, "Until signature"); if (request.programId !== null && !isSolanaAddressLike(request.programId)) { + const invalidCharacters = invalidBase58Characters(request.programId); + if (invalidCharacters.length > 0) { + throw new Error(`Program id filter must be a valid Solana base58 program id. Invalid character(s): ${invalidCharacters.join(", ")}.`); + } throw new Error("Program id filter must be a valid Solana program id, or empty when using a preset that resolves it."); } } diff --git a/kb_demo_app/package.json b/kb_demo_app/package.json index d46529f..2d85fff 100644 --- a/kb_demo_app/package.json +++ b/kb_demo_app/package.json @@ -1,7 +1,7 @@ { "name": "kb-demo-app", "private": true, - "version": "0.7.46", + "version": "0.7.47", "type": "module", "scripts": { "dev": "vite", diff --git a/kb_demo_app/src/demo3.rs b/kb_demo_app/src/demo3.rs index 6db513b..a1e90ec 100644 --- a/kb_demo_app/src/demo3.rs +++ b/kb_demo_app/src/demo3.rs @@ -285,6 +285,239 @@ pub(crate) async fn demo3_search_local_dex_corpus( }) } +/// Search request for the static upstream registry exposed through Demo3. +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, TS)] +#[ts(export, export_to = "../frontend/ts/bindings/Demo3UpstreamRegistrySearchRequest.ts")] +#[serde(rename_all = "camelCase")] +pub(crate) struct Demo3UpstreamRegistrySearchRequest { + /// Optional decoder-code filter. + pub decoder_code: std::option::Option, + /// Optional program-id filter. + pub program_id: std::option::Option, + /// Optional program-family filter. + pub program_family: std::option::Option, + /// Optional surface-kind filter. + pub surface_kind: std::option::Option, + /// Optional entry-kind filter. + pub entry_kind: std::option::Option, + /// Optional proof-status filter. + pub proof_status: std::option::Option, + /// Optional maximum number of entries to return. + pub limit: std::option::Option, +} + +/// Payload returned by the Demo3 upstream registry command. +#[derive(Clone, Debug, serde::Serialize, TS)] +#[ts(export, export_to = "../frontend/ts/bindings/Demo3UpstreamRegistryPayload.ts")] +#[serde(rename_all = "camelCase")] +pub(crate) struct Demo3UpstreamRegistryPayload { + /// Pretty JSON representation of the registry result. + pub result_json: std::string::String, + /// Structured registry result. + pub result: Demo3UpstreamRegistryResult, +} + +/// Structured upstream registry result exposed through Demo3. +#[derive(Clone, Debug, serde::Serialize, TS)] +#[ts(export, export_to = "../frontend/ts/bindings/Demo3UpstreamRegistryResult.ts")] +#[serde(rename_all = "camelCase")] +pub(crate) struct Demo3UpstreamRegistryResult { + /// Normalized request used by kb_lib. + pub request: Demo3UpstreamRegistrySearchRequest, + /// Registry summary. + pub summary: Demo3UpstreamRegistrySummary, + /// Matching entries. + pub entries: std::vec::Vec, +} + +/// Summary of the upstream registry snapshot exposed through Demo3. +#[derive(Clone, Debug, serde::Serialize, TS)] +#[ts(export, export_to = "../frontend/ts/bindings/Demo3UpstreamRegistrySummary.ts")] +#[serde(rename_all = "camelCase")] +pub(crate) struct Demo3UpstreamRegistrySummary { + /// Total static registry entry count before filtering. + #[ts(type = "number")] + pub total_entry_count: usize, + /// Returned entry count after filtering. + #[ts(type = "number")] + pub returned_entry_count: usize, + /// Number of entries that have a program id. + #[ts(type = "number")] + pub entries_with_program_id_count: usize, + /// Number of entries that have a discriminator. + #[ts(type = "number")] + pub entries_with_discriminator_count: usize, + /// Number of program-level seed entries. + #[ts(type = "number")] + pub program_entry_count: usize, + /// Number of instruction entries. + #[ts(type = "number")] + pub instruction_entry_count: usize, + /// Number of event entries. + #[ts(type = "number")] + pub event_entry_count: usize, + /// Number of account entries. + #[ts(type = "number")] + pub account_entry_count: usize, + /// Number of entries still unverified from upstream Git or seed data. + #[ts(type = "number")] + pub upstream_git_unverified_count: usize, + /// Number of entries mapped into decoders but not locally observed. + #[ts(type = "number")] + pub upstream_git_mapped_unverified_count: usize, + /// Number of entries observed in the local corpus. + #[ts(type = "number")] + pub upstream_git_local_corpus_observed_count: usize, + /// Number of entries materialized in local business tables. + #[ts(type = "number")] + pub upstream_git_local_corpus_materialized_count: usize, + /// Number of layout entries still unverified locally. + #[ts(type = "number")] + pub upstream_git_layout_unverified_count: usize, +} + +/// One upstream registry entry exposed through Demo3. +#[derive(Clone, Debug, serde::Serialize, TS)] +#[ts(export, export_to = "../frontend/ts/bindings/Demo3UpstreamRegistryEntry.ts")] +#[serde(rename_all = "camelCase")] +pub(crate) struct Demo3UpstreamRegistryEntry { + /// Repository name or bootstrap locator that produced the entry. + pub source_repo: std::option::Option, + /// Repository-relative path or bootstrap path that produced the entry. + pub source_path: std::option::Option, + /// Stable decoder code used by the registry. + pub decoder_code: std::string::String, + /// Optional Solana program id when already known by the source entry. + pub program_id: std::option::Option, + /// Program family used to group related programs. + pub program_family: std::string::String, + /// Surface kind such as AMM, CLMM, launch, aggregator or core Solana. + pub surface_kind: std::string::String, + /// Entry kind: instruction, event, account or program. + pub entry_kind: std::string::String, + /// Source-level entry name. + pub entry_name: std::string::String, + /// Optional discriminator bytes encoded as lowercase hexadecimal. + pub discriminator_hex: std::option::Option, + /// Optional discriminator byte length. + pub discriminator_len: std::option::Option, + /// Current proof status. + pub proof_status: std::string::String, + /// Notes that preserve uncertainty and validation requirements. + pub notes: std::string::String, +} + +/// Searches the static upstream registry from Demo3. +#[tauri::command] +pub(crate) fn demo3_search_upstream_registry( + request: Demo3UpstreamRegistrySearchRequest, +) -> Result { + let service = kb_lib::UpstreamRegistryService::new(); + let lib_request = to_lib_upstream_registry_request(&request); + let lib_result = service.search(&lib_request); + let ui_result = from_lib_upstream_registry_result(lib_result); + let result_json_result = serde_json::to_string_pretty(&ui_result); + let result_json = match result_json_result { + Ok(result_json) => result_json, + Err(error) => { + return Err(format!("cannot serialize upstream registry result: {}", error)); + }, + }; + return Ok(Demo3UpstreamRegistryPayload { + result_json, + result: ui_result, + }); +} + +fn to_lib_upstream_registry_request( + request: &Demo3UpstreamRegistrySearchRequest, +) -> kb_lib::UpstreamRegistrySearchRequestDto { + return kb_lib::UpstreamRegistrySearchRequestDto { + decoder_code: normalize_optional_text(request.decoder_code.clone()), + program_id: normalize_optional_text(request.program_id.clone()), + program_family: normalize_optional_text(request.program_family.clone()), + surface_kind: normalize_optional_text(request.surface_kind.clone()), + entry_kind: normalize_optional_text(request.entry_kind.clone()), + proof_status: normalize_optional_text(request.proof_status.clone()), + limit: match request.limit { + Some(limit) => Some(limit as usize), + None => None, + }, + }; +} + +fn from_lib_upstream_registry_result( + result: kb_lib::UpstreamRegistrySearchResultDto, +) -> Demo3UpstreamRegistryResult { + let mut entries = std::vec::Vec::new(); + for entry in result.entries { + entries.push(from_lib_upstream_registry_entry(entry)); + } + return Demo3UpstreamRegistryResult { + request: from_lib_upstream_registry_request(result.request), + summary: from_lib_upstream_registry_summary(result.summary), + entries, + }; +} + +fn from_lib_upstream_registry_request( + request: kb_lib::UpstreamRegistrySearchRequestDto, +) -> Demo3UpstreamRegistrySearchRequest { + return Demo3UpstreamRegistrySearchRequest { + decoder_code: request.decoder_code, + program_id: request.program_id, + program_family: request.program_family, + surface_kind: request.surface_kind, + entry_kind: request.entry_kind, + proof_status: request.proof_status, + limit: match request.limit { + Some(limit) => Some(limit as u32), + None => None, + }, + }; +} + +fn from_lib_upstream_registry_summary( + summary: kb_lib::UpstreamRegistrySummaryDto, +) -> Demo3UpstreamRegistrySummary { + return Demo3UpstreamRegistrySummary { + total_entry_count: summary.total_entry_count, + returned_entry_count: summary.returned_entry_count, + entries_with_program_id_count: summary.entries_with_program_id_count, + entries_with_discriminator_count: summary.entries_with_discriminator_count, + program_entry_count: summary.program_entry_count, + instruction_entry_count: summary.instruction_entry_count, + event_entry_count: summary.event_entry_count, + account_entry_count: summary.account_entry_count, + upstream_git_unverified_count: summary.upstream_git_unverified_count, + upstream_git_mapped_unverified_count: summary.upstream_git_mapped_unverified_count, + upstream_git_local_corpus_observed_count: summary + .upstream_git_local_corpus_observed_count, + upstream_git_local_corpus_materialized_count: summary + .upstream_git_local_corpus_materialized_count, + upstream_git_layout_unverified_count: summary.upstream_git_layout_unverified_count, + }; +} + +fn from_lib_upstream_registry_entry( + entry: kb_lib::UpstreamRegistryEntryDto, +) -> Demo3UpstreamRegistryEntry { + return Demo3UpstreamRegistryEntry { + source_repo: entry.source_repo, + source_path: entry.source_path, + decoder_code: entry.decoder_code, + program_id: entry.program_id, + program_family: entry.program_family, + surface_kind: entry.surface_kind, + entry_kind: entry.entry_kind, + entry_name: entry.entry_name, + discriminator_hex: entry.discriminator_hex, + discriminator_len: entry.discriminator_len, + proof_status: entry.proof_status, + notes: entry.notes, + }; +} + fn to_lib_search_request( request: &Demo3LocalDexCorpusSearchRequest, ) -> kb_lib::LocalDexCorpusSearchRequestDto { diff --git a/kb_demo_app/src/lib.rs b/kb_demo_app/src/lib.rs index 312eda6..3a1253f 100644 --- a/kb_demo_app/src/lib.rs +++ b/kb_demo_app/src/lib.rs @@ -125,6 +125,7 @@ pub async fn run() -> Result<(), kb_lib::Error> { stop_ws_clients, crate::demo3::open_demo3_window, crate::demo3::demo3_search_local_dex_corpus, + crate::demo3::demo3_search_upstream_registry, crate::demo3::demo3_discover_onchain_dex_pairs, crate::demo3old::open_demo3old_window, crate::demo3old::demo3old_search_local_dex_corpus, diff --git a/kb_demo_app/tauri.conf.json b/kb_demo_app/tauri.conf.json index da1971a..825885a 100644 --- a/kb_demo_app/tauri.conf.json +++ b/kb_demo_app/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "kb-demo-app", - "version": "0.7.46", + "version": "0.7.47", "identifier": "com.sasedev.kb-demo-app", "build": { "beforeDevCommand": "npm run dev", diff --git a/kb_lib/src/constants.rs b/kb_lib/src/constants.rs index 12626bc..bc3d5bc 100644 --- a/kb_lib/src/constants.rs +++ b/kb_lib/src/constants.rs @@ -18,6 +18,9 @@ pub const ASSOCIATED_TOKEN_PROGRAM_ID: &str = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25e /// @see solana_sdk_ids::address_lookup_table::ID pub const ADDRESS_LOOKUP_TABLE_PROGRAM_ID: &str = "AddressLookupTab1e1111111111111111111111111"; +/// SPL Memo program id. ("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"). +pub const MEMO_PROGRAM_ID: &str = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"; + /// BPF Loader program identifier. ("BPFLoader1111111111111111111111111111111111"). /// @see solana_sdk_ids::bpf_loader_deprecated::ID pub const BPF_LOADER_DEPRECATED_PROGRAM_ID: &str = "BPFLoader1111111111111111111111111111111111"; @@ -164,6 +167,57 @@ pub const DEXLAB_PROGRAM_ID: &str = "DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6 /// FluxBeam program id. ("FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X"). pub const FLUXBEAM_PROGRAM_ID: &str = "FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X"; +/// GooseFX v1 program id from Vybe supported DEX/AMM documentation. +pub const GOOSEFX_V1_PROGRAM_ID: &str = "GAMMA7meSFWaBXF25oSUgmGRwaW6sCMFLmBNiMSdbHVT"; + +/// Obric v2 program id from Vybe supported DEX/AMM documentation. +pub const OBRIC_V2_PROGRAM_ID: &str = "obriQD1zbpyLz95G5n7nJe6a4DPjpFwa5XYPoNm113y"; + +/// Ondo Global Market program id from Vybe supported DEX/AMM documentation. +pub const ONDO_GLOBAL_MARKET_PROGRAM_ID: &str = "XzTT4XB8m7sLD2xi6snefSasaswsKCxx5Tifjondogm"; + +/// Scorch program id from Vybe supported DEX/AMM documentation. +pub const SCORCH_PROGRAM_ID: &str = "SCoRcH8c2dpjvcJD6FiPbCSQyQgu3PcUAWj2Xxx3mqn"; + +/// ZeroFi program id from Vybe supported DEX/AMM documentation. +pub const ZEROFI_PROGRAM_ID: &str = "ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY"; + +/// Manifest CLOB program id from Vybe supported DEX/AMM documentation. +pub const MANIFEST_CLOB_PROGRAM_ID: &str = "MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms"; + +/// AlphaQ program id from Vybe supported DEX/AMM documentation. +pub const ALPHAQ_PROGRAM_ID: &str = "ALPHAQmeA7bjrVuccPsYPiCvsi428SNwte66Srvs4pHA"; + +/// Goonfi program id from Vybe supported DEX/AMM documentation. +pub const GOONFI_PROGRAM_ID: &str = "goonERTdGsjnkZqWuVjs73BZ3Pb9qoCUdBUL17BnS5j"; + +/// Goonfi v2 program id from Vybe supported DEX/AMM documentation. +pub const GOONFI_V2_PROGRAM_ID: &str = "goonuddtQRrWqqn5nFyczVKaie28f3kDkHWkHtURSLE"; + +/// Byreal program id from Vybe supported DEX/AMM documentation. +pub const BYREAL_PROGRAM_ID: &str = "REALQqNEomY6cQGZJUGwywTBD2UmDT32rZcNnfxQ5N2"; + +/// BisonFi program id from Vybe supported DEX/AMM documentation. +pub const BISONFI_PROGRAM_ID: &str = "BiSoNHVpsVZW2F7rx2eQ59yQwKxzU5NvBcmKshCSUypi"; + +/// FusionAMM program id from Vybe supported DEX/AMM documentation. +pub const FUSIONAMM_PROGRAM_ID: &str = "fUSioN9YKKSa3CUC2YUc4tPkHJ5Y6XW1yz8y6F7qWz9"; + +/// Woofi program id from Vybe supported DEX/AMM documentation. +pub const WOOFI_PROGRAM_ID: &str = "WooFif76YGRNjk1pA8wCsN67aQsD9f9iLsz4NcJ1AVb"; + +/// Aquifer program id from Vybe supported DEX/AMM documentation. +pub const AQUIFER_PROGRAM_ID: &str = "AQU1FRd7papthgdrwPTTq5JacJh8YtwEXaBfKU3bTz45"; + +/// Humidifi program id from Vybe supported DEX/AMM documentation. +pub const HUMIDIFI_PROGRAM_ID: &str = "9H6tua7jkLhdm3w8BvgpTn5LZNU7g4ZynDmCiNN3q6Rp"; + +/// SolFi v2 program id from Vybe supported DEX/AMM documentation. +pub const SOLFI_V2_PROGRAM_ID: &str = "SV2EYYJyRz2YhfXwXnhNAevDEui5Q6yrfyo13WtupPF"; + +/// Gavel program id extracted from upstream Git decoder source. +pub const GAVEL_PROGRAM_ID: &str = "srAMMzfVHVAtgSJc8iH6CfKzuWuUTzLHVCE81QU1rgi"; + /// Meteora DAMM v1 program id. ("Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB"). pub const METEORA_DAMM_V1_PROGRAM_ID: &str = "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB"; @@ -178,32 +232,17 @@ pub const METEORA_DBC_PROGRAM_ID: &str = "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4Du /// DLMM = Dynamic Liquidity Market Maker. pub const METEORA_DLMM_PROGRAM_ID: &str = "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo"; -/// MetaDAO META active token mint identifier from MetaDAO documentation. -pub const METADAO_META_MINT_ID: &str = "METAwkXcqyXKy1AtsSgJ8JiUHwGCafnZL38n3vYmeta"; - -/// MetaDAO METAC legacy token mint identifier from MetaDAO documentation. -pub const METADAO_METAC_LEGACY_MINT_ID: &str = "METADDFL6wWMWEoKTFJwcThTbUmtarRJZjRpzUvkxhr"; - -/// MetaDAO-linked P2P token mint candidate observed on Solscan. -/// -/// This is a token mint, not a DEX program id. It is exposed for discovery only. -pub const METADAO_P2P_MINT_ID: &str = "P2PXup1ZvMpCDkJn3PQxtBYgxeCSfH39SFeurGSmeta"; - /// MetaDAO Launchpad v0.7.0 program id from MetaDAO documentation and Solscan. -pub const METADAO_LAUNCHPAD_V0_7_0_PROGRAM_ID: &str = - "moontUzsdepotRGe5xsfip7vLPTJnVuafqdUWexVnPM"; +pub const METADAO_LAUNCHPAD_V0_7_0_PROGRAM_ID: &str = "moontUzsdepotRGe5xsfip7vLPTJnVuafqdUWexVnPM"; /// MetaDAO Bid Wall v0.7.0 program id from MetaDAO documentation. -pub const METADAO_BID_WALL_V0_7_0_PROGRAM_ID: &str = - "WALL8ucBuUyL46QYxwYJjidaFYhdvxUFrgvBxPshERx"; +pub const METADAO_BID_WALL_V0_7_0_PROGRAM_ID: &str = "WALL8ucBuUyL46QYxwYJjidaFYhdvxUFrgvBxPshERx"; /// MetaDAO Futarchy v0.6.0 program id from MetaDAO documentation. -pub const METADAO_FUTARCHY_V0_6_0_PROGRAM_ID: &str = - "FUTARELBfJfQ8RDGhg1wdhddq1odMAJUePHFuBYfUxKq"; +pub const METADAO_FUTARCHY_V0_6_0_PROGRAM_ID: &str = "FUTARELBfJfQ8RDGhg1wdhddq1odMAJUePHFuBYfUxKq"; /// MetaDAO AMM v0.5.0 program id from MetaDAO documentation. -pub const METADAO_AMM_V0_5_0_PROGRAM_ID: &str = - "AMMJdEiCCa8mdugg6JPF7gFirmmxisTfDJoSNSUi5zDJ"; +pub const METADAO_AMM_V0_5_0_PROGRAM_ID: &str = "AMMJdEiCCa8mdugg6JPF7gFirmmxisTfDJoSNSUi5zDJ"; /// Printr program id candidate observed on Solscan. /// @@ -224,6 +263,9 @@ pub const PUMP_FUN_PROGRAM_ID: &str = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF /// PumpSwap / PumpAMM program id. ("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"). pub const PUMP_SWAP_PROGRAM_ID: &str = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"; +/// Pump Fees program id extracted from upstream Git decoder source. +pub const PUMP_FEES_PROGRAM_ID: &str = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"; + /// Raydium AmmV4 program id. ("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"). pub const RAYDIUM_AMM_V4_PROGRAM_ID: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"; @@ -233,7 +275,7 @@ pub const RAYDIUM_CLMM_PROGRAM_ID: &str = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7gr /// Raydium CPMM mainnet program id. ("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"). pub const RAYDIUM_CPMM_PROGRAM_ID: &str = "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"; -/// Raydium LaunchLab program id. ("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj"). +/// Raydium LaunchLab / Launchpad program id. ("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj"). pub const RAYDIUM_LAUNCHLAB_PROGRAM_ID: &str = "LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj"; /// Raydium AMM routing program id. ("routeUGWgWzqBWFcrCfv8tritsqukccJPu3q5GPP3xS"). @@ -242,6 +284,132 @@ pub const RAYDIUM_AMM_ROUTING_PROGRAM_ID: &str = "routeUGWgWzqBWFcrCfv8tritsqukc /// Raydium Stable Swap AMM program id, deprecated. ("5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h"). pub const RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID: &str = "5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h"; +/// Bonkswap program id extracted from upstream Git decoder source. +pub const BONKSWAP_PROGRAM_ID: &str = "BSwp6bEBihVLdqJRKGgzjcGLHkcTuzmSo1TQkHepzH8p"; + +/// Boop program id extracted from upstream Git decoder source. +pub const BOOP_PROGRAM_ID: &str = "boop8hVGQGqehUK2iVEMEnMrL5RbjywRzHKBmBE7ry4"; + +/// DFlow Aggregator v4 program id extracted from upstream Git decoder source. +pub const DFLOW_AGGREGATOR_V4_PROGRAM_ID: &str = "DF1ow4tspfHX9JwWJsAb9epbkA8hmpSEAtxXy1V27QBH"; + +/// Drift v2 program id extracted from upstream Git decoder source. +pub const DRIFT_V2_PROGRAM_ID: &str = "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"; + +/// Heaven program id extracted from upstream Git decoder source. +pub const HEAVEN_PROGRAM_ID: &str = "HEAVENoP2qxoeuF8Dj2oT1GHEnu49U5mJYkdeC8BAX2o"; + +/// Jupiter Swap program id extracted from upstream Git decoder source. +pub const JUPITER_SWAP_PROGRAM_ID: &str = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"; + +/// Jupiter DCA program id extracted from upstream Git decoder source. +pub const JUPITER_DCA_PROGRAM_ID: &str = "DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M"; + +/// Jupiter Lend program id extracted from upstream Git decoder source. +pub const JUPITER_LEND_PROGRAM_ID: &str = "jupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC"; + +/// Jupiter Limit Order program id extracted from upstream Git decoder source. +pub const JUPITER_LIMIT_ORDER_PROGRAM_ID: &str = "jupoNjAxXgZ4rjzxzPMP4oxduvQsQtZzyknqvzYNrNu"; + +/// Jupiter Limit Order 2 program id extracted from upstream Git decoder source. +pub const JUPITER_LIMIT_ORDER_2_PROGRAM_ID: &str = "j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X"; + +/// Jupiter Perpetuals program id extracted from upstream Git decoder source. +pub const JUPITER_PERPETUALS_PROGRAM_ID: &str = "PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu"; + +/// Kamino Farms program id extracted from upstream Git decoder source. +pub const KAMINO_FARMS_PROGRAM_ID: &str = "FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr"; + +/// Kamino Lending program id extracted from upstream Git decoder source. +pub const KAMINO_LENDING_PROGRAM_ID: &str = "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"; + +/// Kamino Limit Order program id extracted from upstream Git decoder source. +pub const KAMINO_LIMIT_ORDER_PROGRAM_ID: &str = "LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF"; + +/// Kamino Vault program id extracted from upstream Git decoder source. +pub const KAMINO_VAULT_PROGRAM_ID: &str = "kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr"; + +/// Lifinity AMM v2 program id extracted from upstream Git decoder source. +pub const LIFINITY_AMM_V2_PROGRAM_ID: &str = "2wT8Yq49kHgDzXuPxZSaeLaH1qbmGXtEyPy64bL7aD3c"; + +/// Marginfi v2 program id extracted from upstream Git decoder source. +pub const MARGINFI_V2_PROGRAM_ID: &str = "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA"; + +/// Marinade Finance program id extracted from upstream Git decoder source. +pub const MARINADE_FINANCE_PROGRAM_ID: &str = "MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD"; + +/// Meteora Vault program id extracted from upstream Git decoder source. +pub const METEORA_VAULT_PROGRAM_ID: &str = "24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi"; + +/// Moonshot program id extracted from upstream Git decoder source. +pub const MOONSHOT_PROGRAM_ID: &str = "MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG"; + +/// OKX DEX program id extracted from upstream Git decoder source. +pub const OKX_DEX_PROGRAM_ID: &str = "6m2CDdhRgxpH4WjvdzxAYbGxwdGUz5MziiL5jek2kBma"; + +/// Onchain Labs DEX v2 program id extracted from upstream Git decoder source. +pub const ONCHAIN_LABS_DEX_V2_PROGRAM_ID: &str = "proVF4pMXVaYqmy4NjniPh4pqKNfMmsihgd4wdkCX3u"; + +/// OpenBook v2 program id extracted from upstream Git decoder source. +pub const OPENBOOK_V2_PROGRAM_ID: &str = "opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb"; + +/// Pancake Swap program id extracted from upstream Git decoder source. +pub const PANCAKE_SWAP_PROGRAM_ID: &str = "HpNfyc2Saw7RKkQd8nEL4khUcuPhQ7WwY1B2qjx8jxFq"; + +/// Phoenix v1 program id extracted from upstream Git decoder source. +pub const PHOENIX_V1_PROGRAM_ID: &str = "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY"; + +/// Raydium Liquidity Locking program id extracted from upstream Git decoder source. +pub const RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID: &str = + "LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE"; + +/// Sharky program id extracted from upstream Git decoder source. +pub const SHARKY_PROGRAM_ID: &str = "SHARKobtfF1bHhxD2eqftjHBdVSCbKo9JtgK71FhELP"; + +/// Solayer Restaking program id extracted from upstream Git decoder source. +pub const SOLAYER_RESTAKING_PROGRAM_ID: &str = "sSo1iU21jBrU9VaJ8PJib1MtorefUV4fzC9GURa2KNn"; + +/// Stabble stable-swap program id extracted from upstream Git decoder source. +pub const STABBLE_STABLE_SWAP_PROGRAM_ID: &str = "swapNyd8XiQwJ6ianp9snpu4brUqFxadzvHebnAXjJZ"; + +/// Stabble weighted-swap program id extracted from upstream Git decoder source. +pub const STABBLE_WEIGHTED_SWAP_PROGRAM_ID: &str = "swapFpHZwjELNnjvThjajtiVmkz3yPQEHjLtka2fwHW"; + +/// Swig program id extracted from upstream Git decoder source. +pub const SWIG_PROGRAM_ID: &str = "swigypWHEksbC64pWKwah1WTeh9JXwx8H1rJHLdbQMB"; + +/// Vertigo program id extracted from upstream Git decoder source. +pub const VERTIGO_PROGRAM_ID: &str = "vrTGoBuy5rYSxAfV3jaRJWHH6nN9WK4NRExGxsk1bCJ"; + +/// Virtuals program id extracted from upstream Git decoder source. +pub const VIRTUALS_PROGRAM_ID: &str = "5U3EU2ubXtK84QcRjWVmYt9RaDyA8gKxdUrPFXmZyaki"; + +/// Wavebreak program id extracted from upstream Git decoder source. +pub const WAVEBREAK_PROGRAM_ID: &str = "waveQX2yP3H1pVU8djGvEHmYg8uamQ84AuyGtpsrXTF"; + +/// Zeta program id extracted from upstream Git decoder source. +pub const ZETA_PROGRAM_ID: &str = "ZETAxsqBRek56DhiGXrn75yj2NHU3aYUnxvHXpkf3aD"; + +/// Circle Message Transmitter v2 program id extracted from upstream Git decoder source. +pub const CIRCLE_MESSAGE_TRANSMITTER_V2_PROGRAM_ID: &str = + "CCTPV2Sm4AdWt5296sk4P66VBZ7bEhcARwFaaS9YPbeC"; + +/// Circle Token Messenger v2 program id extracted from upstream Git decoder source. +pub const CIRCLE_TOKEN_MESSENGER_V2_PROGRAM_ID: &str = + "CCTPV2vPZJS2u2BBsUoscuikbYjnpFmbFsvVuJdgUMQe"; + +/// MPL Token Metadata program id extracted from upstream Git decoder source. +pub const MPL_TOKEN_METADATA_PROGRAM_ID: &str = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"; + +/// MPL Core program id extracted from upstream Git decoder source. +pub const MPL_CORE_PROGRAM_ID: &str = "CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d"; + +/// Bubblegum program id extracted from upstream Git decoder source. +pub const BUBBLEGUM_PROGRAM_ID: &str = "BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY"; + +/// Solana Name Service program id extracted from upstream Git decoder source. +pub const NAME_SERVICE_PROGRAM_ID: &str = "namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX"; + /// Known Solana arbitrage/sandwich bot program id observed in local corpus. /// /// This is not treated as a DEX program. It is used only to tag protocol diff --git a/kb_lib/src/dex.rs b/kb_lib/src/dex.rs index 872d531..5f0d95e 100644 --- a/kb_lib/src/dex.rs +++ b/kb_lib/src/dex.rs @@ -8,7 +8,9 @@ mod meteora_damm_v1; mod meteora_damm_v2; mod meteora_dbc; mod meteora_dlmm; +mod openbook_v2; mod orca_whirlpools; +mod phoenix_v1; mod pump_fun; mod pump_swap; mod raydium_amm_v4; @@ -47,10 +49,16 @@ pub use meteora_dlmm::MeteoraDlmmLiquidityDecoded; pub use meteora_dlmm::MeteoraDlmmPoolLifecycleDecoded; pub use meteora_dlmm::MeteoraDlmmRewardDecoded; pub use meteora_dlmm::MeteoraDlmmSwapDecoded; +pub use openbook_v2::OpenBookV2AuditDecoded; +pub use openbook_v2::OpenBookV2DecodedEvent; +pub use openbook_v2::OpenBookV2Decoder; pub use orca_whirlpools::OrcaWhirlpoolsCreatePoolDecoded; pub use orca_whirlpools::OrcaWhirlpoolsDecodedEvent; pub use orca_whirlpools::OrcaWhirlpoolsDecoder; pub use orca_whirlpools::OrcaWhirlpoolsSwapDecoded; +pub use phoenix_v1::PhoenixV1AuditDecoded; +pub use phoenix_v1::PhoenixV1DecodedEvent; +pub use phoenix_v1::PhoenixV1Decoder; pub use pump_fun::PumpFunCreateV2TokenDecoded; pub use pump_fun::PumpFunDecodedEvent; pub use pump_fun::PumpFunDecoder; diff --git a/kb_lib/src/dex/openbook_v2.rs b/kb_lib/src/dex/openbook_v2.rs new file mode 100644 index 0000000..adef9b7 --- /dev/null +++ b/kb_lib/src/dex/openbook_v2.rs @@ -0,0 +1,1591 @@ +// file: kb_lib/src/dex/openbook_v2.rs + +//! OpenBook v2 audit-only transaction decoder. +//! +//! This decoder promotes upstream-registry discriminator matches for OpenBook v2 +//! into protocol-specific audit events. It intentionally does not create trades, +//! candles, pools or materialized orderbook rows. + +/// Decoded OpenBook v2 audit event. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct OpenBookV2AuditDecoded { + /// Parent transaction id. + pub transaction_id: i64, + /// Parent instruction id. + pub instruction_id: i64, + /// Transaction signature. + pub signature: std::string::String, + /// Program id. + pub program_id: std::string::String, + /// Protocol-specific audit event kind. + pub event_kind: std::string::String, + /// Upstream instruction name. + pub upstream_entry_name: std::string::String, + /// Upstream discriminator hex. + pub upstream_discriminator_hex: std::option::Option, + /// Optional market/state account candidate. + pub market_account: std::option::Option, + /// Optional token A/base mint observed from transaction metadata. + pub token_a_mint: std::option::Option, + /// Optional token B/quote mint observed from transaction metadata. + pub token_b_mint: std::option::Option, + /// Decoded audit payload. + pub payload_json: serde_json::Value, +} + +/// Decoded OpenBook v2 event. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub enum OpenBookV2DecodedEvent { + /// Audit-only instruction event. + Audit(OpenBookV2AuditDecoded), +} + +/// OpenBook v2 audit-only decoder. +#[derive(Debug, Clone, Default)] +pub struct OpenBookV2Decoder; + +impl OpenBookV2Decoder { + /// Creates a new decoder. + pub fn new() -> Self { + return Self; + } + + /// Decodes OpenBook v2 instructions into audit-only events. + pub fn decode_transaction( + &self, + transaction: &crate::ChainTransactionDto, + instructions: &[crate::ChainInstructionDto], + ) -> Result, crate::Error> { + let transaction_id = match transaction.id { + Some(transaction_id) => transaction_id, + None => { + return Err(crate::Error::InvalidState(format!( + "chain transaction '{}' has no internal id", + transaction.signature + ))); + }, + }; + let transaction_json_result = + serde_json::from_str::(transaction.transaction_json.as_str()); + let transaction_json = match transaction_json_result { + Ok(transaction_json) => transaction_json, + Err(error) => { + return Err(crate::Error::Json(format!( + "cannot parse transaction_json for signature '{}': {}", + transaction.signature, error + ))); + }, + }; + let log_messages = extract_log_messages(&transaction_json); + let openbook_log_audit = extract_openbook_v2_log_audit(log_messages.as_slice()); + let token_mints = extract_distinct_token_mints(&transaction_json); + let mut decoded_events = std::vec::Vec::new(); + for instruction in instructions { + let program_id = match instruction.program_id.as_ref() { + Some(program_id) => program_id, + None => continue, + }; + if program_id.as_str() != crate::OPENBOOK_V2_PROGRAM_ID { + continue; + } + let instruction_id = match instruction.id { + Some(instruction_id) => instruction_id, + None => continue, + }; + let data_base58 = parse_instruction_data_base58(instruction.data_json.as_deref()); + let registry_match = + crate::upstream_registry_match::upstream_registry_match_instruction_data( + program_id.as_str(), + data_base58.as_deref(), + ); + let registry_match = match registry_match { + Some(registry_match) => registry_match, + None => continue, + }; + if registry_match.decoder_code.as_str() != "openbook-v2" { + continue; + } + let accounts = parse_instruction_accounts_vec(instruction.accounts_json.as_str()); + let event_kind = openbook_v2_audit_event_kind(registry_match.entry_name.as_str()); + let market_account = + candidate_market_account(registry_match.entry_name.as_str(), accounts.as_slice()); + let token_a_mint = token_mints.get(0).cloned(); + let token_b_mint = token_mints.get(1).cloned(); + let payload_json = build_openbook_v2_audit_payload( + transaction, + instruction, + ®istry_match, + data_base58.as_deref(), + accounts, + log_messages.as_slice(), + &openbook_log_audit, + token_mints.as_slice(), + event_kind, + market_account.as_deref(), + ); + decoded_events.push(crate::OpenBookV2DecodedEvent::Audit( + crate::OpenBookV2AuditDecoded { + transaction_id, + instruction_id, + signature: transaction.signature.clone(), + program_id: program_id.clone(), + event_kind: event_kind.to_string(), + upstream_entry_name: registry_match.entry_name.clone(), + upstream_discriminator_hex: registry_match.discriminator_hex.clone(), + market_account, + token_a_mint, + token_b_mint, + payload_json, + }, + )); + } + return Ok(decoded_events); + } +} + +fn openbook_v2_audit_event_kind(entry_name: &str) -> &'static str { + match entry_name { + "place_order" => return "openbook_v2.order_place_audit", + "place_take_order" => return "openbook_v2.order_place_audit", + "cancel_order" => return "openbook_v2.order_cancel_audit", + "cancel_order_by_client_order_id" => return "openbook_v2.order_cancel_audit", + "cancel_all_orders" => return "openbook_v2.order_cancel_audit", + "consume_events" => return "openbook_v2.consume_events_audit", + "settle_funds" => return "openbook_v2.settle_funds_audit", + "create_market" => return "openbook_v2.market_create_audit", + "close_market" => return "openbook_v2.close_market_audit", + "create_open_orders_account" => return "openbook_v2.open_orders_create_audit", + "create_open_orders_indexer" => return "openbook_v2.open_orders_create_audit", + "close_open_orders_account" => return "openbook_v2.open_orders_close_audit", + _ => return "openbook_v2.instruction_audit", + } +} + +fn candidate_market_account( + entry_name: &str, + accounts: &[std::string::String], +) -> std::option::Option { + let index = match entry_name { + "place_order" => 1_usize, + "place_take_order" => 1_usize, + "cancel_order" => 1_usize, + "cancel_order_by_client_order_id" => 1_usize, + "cancel_all_orders" => 1_usize, + "consume_events" => 0_usize, + "settle_funds" => 3_usize, + "create_market" => 0_usize, + "close_market" => 0_usize, + "create_open_orders_account" => 1_usize, + "create_open_orders_indexer" => 1_usize, + "close_open_orders_account" => 1_usize, + _ => return None, + }; + return accounts.get(index).cloned(); +} + +fn build_openbook_v2_audit_payload( + transaction: &crate::ChainTransactionDto, + instruction: &crate::ChainInstructionDto, + registry_match: &crate::UpstreamRegistryEntryDto, + data_base58: std::option::Option<&str>, + accounts: std::vec::Vec, + log_messages: &[std::string::String], + openbook_log_audit: &OpenBookV2LogAudit, + token_mints: &[std::string::String], + event_kind: &str, + market_account: std::option::Option<&str>, +) -> serde_json::Value { + let transaction_error = nullable_optional_json_string(transaction.err_json.as_deref()); + let failed = !transaction_error.is_null(); + let account_count = accounts.len(); + let expected_instruction_log_name = + openbook_v2_instruction_log_name(registry_match.entry_name.as_str()); + let scoped_program_return_records = openbook_program_return_records_for_instruction( + openbook_log_audit, + expected_instruction_log_name.as_str(), + ); + let scoped_program_return_record_json = + openbook_program_return_records_to_json(scoped_program_return_records.as_slice()); + let scoped_program_return_u64_values = + openbook_program_return_u64_values(scoped_program_return_records.as_slice()); + let scoped_program_return_i64_values = + openbook_program_return_i64_values(scoped_program_return_records.as_slice()); + let scoped_program_data_records = openbook_program_data_records_for_instruction( + openbook_log_audit, + expected_instruction_log_name.as_str(), + ); + let scoped_program_data_record_json = + openbook_program_data_records_to_json(scoped_program_data_records.as_slice()); + let scoped_program_data_discriminator_hex_values = + openbook_program_data_discriminator_hex_values(scoped_program_data_records.as_slice()); + let scoped_program_data_event_log_names = + openbook_program_data_event_log_names(scoped_program_data_records.as_slice()); + let transaction_program_return_record_json = openbook_program_return_records_to_json( + openbook_log_audit.program_return_records.as_slice(), + ); + let transaction_program_data_record_json = + openbook_program_data_records_to_json(openbook_log_audit.program_data_records.as_slice()); + let consume_events_audit = build_consume_events_audit( + event_kind, + scoped_program_return_records.as_slice(), + scoped_program_return_u64_values.as_slice(), + scoped_program_return_i64_values.as_slice(), + scoped_program_data_records.as_slice(), + scoped_program_data_discriminator_hex_values.as_slice(), + scoped_program_data_event_log_names.as_slice(), + ); + + let mut payload = serde_json::Map::new(); + payload.insert("decoder".to_string(), serde_json::Value::String("openbook_v2".to_string())); + payload.insert("auditOnly".to_string(), serde_json::Value::Bool(true)); + payload.insert("eventKind".to_string(), serde_json::Value::String(event_kind.to_string())); + payload.insert( + "signature".to_string(), + serde_json::Value::String(transaction.signature.clone()), + ); + payload.insert("slot".to_string(), openbook_json_value(transaction.slot)); + payload.insert("transactionFailed".to_string(), serde_json::Value::Bool(failed)); + payload.insert("transactionError".to_string(), transaction_error); + payload.insert("instructionId".to_string(), openbook_json_value(instruction.id)); + payload.insert( + "instructionIndex".to_string(), + openbook_json_value(instruction.instruction_index), + ); + payload.insert( + "innerInstructionIndex".to_string(), + openbook_json_value(instruction.inner_instruction_index), + ); + payload.insert( + "parentInstructionId".to_string(), + openbook_json_value(instruction.parent_instruction_id), + ); + payload.insert("stackHeight".to_string(), openbook_json_value(instruction.stack_height)); + payload.insert("programId".to_string(), openbook_json_value(instruction.program_id.clone())); + payload + .insert("programName".to_string(), openbook_json_value(instruction.program_name.clone())); + payload.insert("accounts".to_string(), openbook_json_value(accounts)); + payload.insert("accountCount".to_string(), openbook_json_value(account_count)); + payload.insert("dataBase58".to_string(), openbook_json_value(data_base58)); + payload.insert("marketAccountCandidate".to_string(), openbook_json_value(market_account)); + payload.insert("observedTokenMints".to_string(), openbook_json_value(token_mints)); + payload.insert( + "openbookInstructionLogNames".to_string(), + openbook_json_value(openbook_log_audit.instruction_names.clone()), + ); + payload.insert( + "openbookExpectedInstructionLogName".to_string(), + serde_json::Value::String(expected_instruction_log_name), + ); + payload.insert( + "openbookProgramReturnRecords".to_string(), + serde_json::Value::Array(scoped_program_return_record_json), + ); + payload.insert( + "openbookProgramReturnU64LeValues".to_string(), + openbook_json_value(scoped_program_return_u64_values), + ); + payload.insert( + "openbookProgramReturnI64LeValues".to_string(), + openbook_json_value(scoped_program_return_i64_values), + ); + payload.insert( + "openbookProgramReturnRecordCount".to_string(), + openbook_json_value(scoped_program_return_records.len()), + ); + payload.insert( + "openbookProgramDataRecords".to_string(), + serde_json::Value::Array(scoped_program_data_record_json), + ); + payload.insert( + "openbookProgramDataDiscriminatorHexValues".to_string(), + openbook_json_value(scoped_program_data_discriminator_hex_values), + ); + payload.insert( + "openbookProgramDataEventLogNames".to_string(), + openbook_json_value(scoped_program_data_event_log_names), + ); + payload.insert( + "openbookProgramDataRecordCount".to_string(), + openbook_json_value(scoped_program_data_records.len()), + ); + payload.insert( + "openbookTransactionProgramReturnRecords".to_string(), + serde_json::Value::Array(transaction_program_return_record_json), + ); + payload.insert( + "openbookTransactionProgramReturnRecordCount".to_string(), + openbook_json_value(openbook_log_audit.program_return_records.len()), + ); + payload.insert( + "openbookTransactionProgramDataRecords".to_string(), + serde_json::Value::Array(transaction_program_data_record_json), + ); + payload.insert( + "openbookTransactionProgramDataRecordCount".to_string(), + openbook_json_value(openbook_log_audit.program_data_records.len()), + ); + payload.insert("consumeEventsAudit".to_string(), consume_events_audit); + payload.insert( + "upstreamSourceRepo".to_string(), + openbook_json_value(registry_match.source_repo.clone()), + ); + payload.insert( + "upstreamSourcePath".to_string(), + openbook_json_value(registry_match.source_path.clone()), + ); + payload.insert( + "upstreamDecoderCode".to_string(), + serde_json::Value::String(registry_match.decoder_code.clone()), + ); + payload.insert( + "upstreamProgramFamily".to_string(), + serde_json::Value::String(registry_match.program_family.clone()), + ); + payload.insert( + "upstreamSurfaceKind".to_string(), + serde_json::Value::String(registry_match.surface_kind.clone()), + ); + payload.insert( + "upstreamEntryKind".to_string(), + serde_json::Value::String(registry_match.entry_kind.clone()), + ); + payload.insert( + "upstreamEntryName".to_string(), + serde_json::Value::String(registry_match.entry_name.clone()), + ); + payload.insert( + "upstreamDiscriminatorHex".to_string(), + openbook_json_value(registry_match.discriminator_hex.clone()), + ); + payload.insert( + "upstreamDiscriminatorLen".to_string(), + openbook_json_value(registry_match.discriminator_len), + ); + payload.insert( + "upstreamProofStatus".to_string(), + serde_json::Value::String(registry_match.proof_status.clone()), + ); + payload.insert("upstreamNotes".to_string(), openbook_json_value(registry_match.notes.clone())); + payload.insert("logMessages".to_string(), openbook_json_value(log_messages)); + payload.insert("tradeCandidate".to_string(), serde_json::Value::Bool(false)); + payload.insert("candleCandidate".to_string(), serde_json::Value::Bool(false)); + payload.insert("nonTradeUseful".to_string(), serde_json::Value::Bool(true)); + payload.insert( + "skipTradeReason".to_string(), + serde_json::Value::String("openbook_v2_audit_only_orderbook_decoder".to_string()), + ); + payload.insert( + "skipCandleReason".to_string(), + serde_json::Value::String("openbook_v2_audit_only_orderbook_decoder".to_string()), + ); + return serde_json::Value::Object(payload); +} + +fn openbook_json_value(value: T) -> serde_json::Value { + let serialized = serde_json::to_value(value); + match serialized { + Ok(serialized) => return serialized, + Err(_) => return serde_json::Value::Null, + } +} + +#[derive(Debug, Clone, Default)] +struct OpenBookV2LogAudit { + instruction_names: std::vec::Vec, + program_return_records: std::vec::Vec, + program_data_records: std::vec::Vec, +} + +#[derive(Debug, Clone)] +struct OpenBookV2ProgramReturnRecord { + instruction_log_name: std::option::Option, + program_id: std::string::String, + data_base64: std::string::String, + decoded_len: usize, + u64_le: std::option::Option, + i64_le: std::option::Option, +} + +#[derive(Debug, Clone)] +struct OpenBookV2ProgramDataRecord { + instruction_log_name: std::option::Option, + data_base64: std::string::String, + decoded_len: usize, + discriminator_hex: std::option::Option, + event_log_name: std::option::Option, + event_log_mapping_status: std::string::String, + event_log_payload_status: std::string::String, + event_log_payload_json: std::option::Option, + payload_len: usize, +} + +fn extract_openbook_v2_log_audit(log_messages: &[std::string::String]) -> OpenBookV2LogAudit { + let mut audit = OpenBookV2LogAudit::default(); + let mut current_instruction_log_name: std::option::Option = None; + for log_message in log_messages { + let instruction_log_name = + collect_openbook_v2_instruction_log_name(&mut audit, log_message.as_str()); + if let Some(instruction_log_name) = instruction_log_name { + current_instruction_log_name = Some(instruction_log_name); + continue; + } + collect_openbook_v2_program_return_record( + &mut audit, + log_message.as_str(), + current_instruction_log_name.as_deref(), + ); + collect_openbook_v2_program_data_record( + &mut audit, + log_message.as_str(), + current_instruction_log_name.as_deref(), + ); + } + return audit; +} + +fn collect_openbook_v2_instruction_log_name( + audit: &mut OpenBookV2LogAudit, + log_message: &str, +) -> std::option::Option { + let prefix = "Program log: Instruction: "; + let name = match log_message.strip_prefix(prefix) { + Some(name) => name.trim(), + None => return None, + }; + if name.is_empty() { + return None; + } + if !audit.instruction_names.iter().any(|existing| return existing == name) { + audit.instruction_names.push(name.to_string()); + } + return Some(name.to_string()); +} + +fn collect_openbook_v2_program_return_record( + audit: &mut OpenBookV2LogAudit, + log_message: &str, + current_instruction_log_name: std::option::Option<&str>, +) { + let prefix = "Program return: "; + let payload = match log_message.strip_prefix(prefix) { + Some(payload) => payload.trim(), + None => return, + }; + let mut parts = payload.split_whitespace(); + let program_id = match parts.next() { + Some(program_id) => program_id, + None => return, + }; + if program_id != crate::OPENBOOK_V2_PROGRAM_ID { + return; + } + let data_base64 = match parts.next() { + Some(data_base64) => data_base64, + None => return, + }; + let decoded_bytes = decode_base64_standard(data_base64); + let decoded_len = decoded_bytes.as_ref().map_or(0_usize, |bytes| return bytes.len()); + let decoded_le = decoded_bytes + .as_ref() + .and_then(|bytes| return decode_le_prefix(bytes.as_slice())); + let (u64_le, i64_le) = match decoded_le { + Some((u64_le, i64_le)) => (Some(u64_le), Some(i64_le)), + None => (None, None), + }; + audit.program_return_records.push(OpenBookV2ProgramReturnRecord { + instruction_log_name: current_instruction_log_name.map(|value| return value.to_string()), + program_id: program_id.to_string(), + data_base64: data_base64.to_string(), + decoded_len, + u64_le, + i64_le, + }); +} + +fn collect_openbook_v2_program_data_record( + audit: &mut OpenBookV2LogAudit, + log_message: &str, + current_instruction_log_name: std::option::Option<&str>, +) { + let prefix = "Program data: "; + let data_base64 = match log_message.strip_prefix(prefix) { + Some(data_base64) => data_base64.trim(), + None => return, + }; + if data_base64.is_empty() { + return; + } + let decoded_bytes = decode_base64_standard(data_base64); + let decoded_len = decoded_bytes.as_ref().map_or(0_usize, |bytes| return bytes.len()); + let discriminator_hex = decoded_bytes + .as_ref() + .and_then(|bytes| return decode_discriminator_hex(bytes.as_slice())); + let event_log_name = discriminator_hex.as_deref().and_then(|discriminator_hex| { + return openbook_program_data_event_log_name(discriminator_hex); + }); + let event_log_mapping_status = match event_log_name.as_ref() { + Some(_) => "upstream_git_source_mapped_unverified", + None => "upstream_git_source_unmapped", + }; + let payload_len = decoded_len.saturating_sub(8); + let (event_log_payload_json, event_log_payload_status) = + decode_openbook_program_data_event_payload(event_log_name, decoded_bytes.as_deref()); + audit.program_data_records.push(OpenBookV2ProgramDataRecord { + instruction_log_name: current_instruction_log_name.map(|value| return value.to_string()), + data_base64: data_base64.to_string(), + decoded_len, + discriminator_hex, + event_log_name: event_log_name.map(|value| return value.to_string()), + event_log_mapping_status: event_log_mapping_status.to_string(), + event_log_payload_status: event_log_payload_status.to_string(), + event_log_payload_json, + payload_len, + }); +} + +fn build_consume_events_audit( + event_kind: &str, + scoped_program_return_records: &[OpenBookV2ProgramReturnRecord], + scoped_program_return_u64_values: &[u64], + scoped_program_return_i64_values: &[i64], + scoped_program_data_records: &[OpenBookV2ProgramDataRecord], + scoped_program_data_discriminator_hex_values: &[std::string::String], + scoped_program_data_event_log_names: &[std::string::String], +) -> serde_json::Value { + if event_kind != "openbook_v2.consume_events_audit" { + return serde_json::Value::Null; + } + let mut value = serde_json::Map::new(); + value.insert("auditOnly".to_string(), serde_json::Value::Bool(true)); + value.insert("instructionLogCount".to_string(), openbook_json_value(1_usize)); + value.insert( + "programReturnRecordCount".to_string(), + openbook_json_value(scoped_program_return_records.len()), + ); + value.insert( + "programReturnU64LeValues".to_string(), + openbook_json_value(scoped_program_return_u64_values), + ); + value.insert( + "programReturnI64LeValues".to_string(), + openbook_json_value(scoped_program_return_i64_values), + ); + value.insert( + "programDataRecordCount".to_string(), + openbook_json_value(scoped_program_data_records.len()), + ); + value.insert( + "programDataDiscriminatorHexValues".to_string(), + openbook_json_value(scoped_program_data_discriminator_hex_values), + ); + value.insert( + "programDataEventLogNames".to_string(), + openbook_json_value(scoped_program_data_event_log_names), + ); + value.insert( + "programDataRecords".to_string(), + serde_json::Value::Array(openbook_program_data_records_to_json( + scoped_program_data_records, + )), + ); + value.insert( + "interpretationStatus".to_string(), + serde_json::Value::String("audit_only_unverified".to_string()), + ); + value.insert( + "notes".to_string(), + serde_json::Value::String("OpenBook v2 consume_events return/log/program-data captured for corpus analysis only; not materialized as fills, trades, or candles.".to_string()), + ); + return serde_json::Value::Object(value); +} + +fn openbook_program_return_records_for_instruction( + openbook_log_audit: &OpenBookV2LogAudit, + expected_instruction_log_name: &str, +) -> std::vec::Vec { + let mut records = std::vec::Vec::new(); + for record in &openbook_log_audit.program_return_records { + let instruction_log_name = match record.instruction_log_name.as_ref() { + Some(instruction_log_name) => instruction_log_name, + None => continue, + }; + if instruction_log_name.as_str() != expected_instruction_log_name { + continue; + } + records.push(record.clone()); + } + return records; +} + +fn openbook_program_data_records_for_instruction( + openbook_log_audit: &OpenBookV2LogAudit, + expected_instruction_log_name: &str, +) -> std::vec::Vec { + let mut records = std::vec::Vec::new(); + for record in &openbook_log_audit.program_data_records { + let instruction_log_name = match record.instruction_log_name.as_ref() { + Some(instruction_log_name) => instruction_log_name, + None => continue, + }; + if instruction_log_name.as_str() != expected_instruction_log_name { + continue; + } + records.push(record.clone()); + } + return records; +} + +fn openbook_program_data_records_to_json( + records: &[OpenBookV2ProgramDataRecord], +) -> std::vec::Vec { + let mut values = std::vec::Vec::new(); + for record in records { + let mut value = serde_json::Map::new(); + value.insert( + "instructionLogName".to_string(), + openbook_json_value(record.instruction_log_name.clone()), + ); + value.insert( + "dataBase64".to_string(), + serde_json::Value::String(record.data_base64.clone()), + ); + value.insert("decodedLen".to_string(), openbook_json_value(record.decoded_len)); + value.insert( + "discriminatorHex".to_string(), + openbook_json_value(record.discriminator_hex.clone()), + ); + value + .insert("eventLogName".to_string(), openbook_json_value(record.event_log_name.clone())); + value.insert( + "eventLogMappingStatus".to_string(), + serde_json::Value::String(record.event_log_mapping_status.clone()), + ); + value.insert( + "eventLogPayloadStatus".to_string(), + serde_json::Value::String(record.event_log_payload_status.clone()), + ); + value.insert( + "eventLogPayload".to_string(), + openbook_json_value(record.event_log_payload_json.clone()), + ); + value.insert("payloadLen".to_string(), openbook_json_value(record.payload_len)); + values.push(serde_json::Value::Object(value)); + } + return values; +} + +fn openbook_program_data_event_log_name( + discriminator_hex: &str, +) -> std::option::Option<&'static str> { + match discriminator_hex { + "8dbaa8fc6c8d485e" => return Some("DepositLog"), + "9617299498a2d740" => return Some("FillLog"), + "7da7b6f6f903394d" => return Some("TakerSignatureLog"), + "d157d4eca43a3c75" => return Some("MarketMetaDataLog"), + "08eb303aae4c9c69" => return Some("TotalOrderFillEvent"), + "3582975c6d399170" => return Some("SetDelegateLog"), + "0a32f075ed43e6e9" => return Some("SettleFundsLog"), + "d2f21a4d5e30ff3d" => return Some("SweepFeesLog"), + "c4f99421a8e44906" => return Some("OpenOrdersPositionLog"), + _ => return None, + } +} + +fn openbook_program_data_event_log_names( + records: &[OpenBookV2ProgramDataRecord], +) -> std::vec::Vec { + let mut values = std::vec::Vec::new(); + for record in records { + let event_log_name = match record.event_log_name.as_ref() { + Some(event_log_name) => event_log_name, + None => continue, + }; + if values + .iter() + .any(|existing: &std::string::String| return existing == event_log_name) + { + continue; + } + values.push(event_log_name.clone()); + } + return values; +} + +macro_rules! openbook_read_or_none { + ($value:expr) => { + match $value { + Some(value) => value, + None => return None, + } + }; +} + +struct OpenBookV2BytesReader<'a> { + bytes: &'a [u8], + offset: usize, +} + +impl<'a> OpenBookV2BytesReader<'a> { + fn new(bytes: &'a [u8]) -> Self { + return Self { bytes, offset: 0_usize }; + } + + fn read_u8(&mut self) -> std::option::Option { + if self.offset >= self.bytes.len() { + return None; + } + let value = self.bytes[self.offset]; + self.offset += 1; + return Some(value); + } + + fn read_bool(&mut self) -> std::option::Option { + let value = match self.read_u8() { + Some(value) => value, + None => return None, + }; + return Some(value != 0_u8); + } + + fn read_u32_le(&mut self) -> std::option::Option { + if self.offset + 4_usize > self.bytes.len() { + return None; + } + let mut raw = [0_u8; 4]; + let mut index = 0_usize; + while index < 4_usize { + raw[index] = self.bytes[self.offset + index]; + index += 1; + } + self.offset += 4_usize; + return Some(u32::from_le_bytes(raw)); + } + + fn read_u64_le(&mut self) -> std::option::Option { + if self.offset + 8_usize > self.bytes.len() { + return None; + } + let mut raw = [0_u8; 8]; + let mut index = 0_usize; + while index < 8_usize { + raw[index] = self.bytes[self.offset + index]; + index += 1; + } + self.offset += 8_usize; + return Some(u64::from_le_bytes(raw)); + } + + fn read_i64_le(&mut self) -> std::option::Option { + if self.offset + 8_usize > self.bytes.len() { + return None; + } + let mut raw = [0_u8; 8]; + let mut index = 0_usize; + while index < 8_usize { + raw[index] = self.bytes[self.offset + index]; + index += 1; + } + self.offset += 8_usize; + return Some(i64::from_le_bytes(raw)); + } + + fn read_u128_le(&mut self) -> std::option::Option { + if self.offset + 16_usize > self.bytes.len() { + return None; + } + let mut raw = [0_u8; 16]; + let mut index = 0_usize; + while index < 16_usize { + raw[index] = self.bytes[self.offset + index]; + index += 1; + } + self.offset += 16_usize; + return Some(u128::from_le_bytes(raw)); + } + + fn read_pubkey_string(&mut self) -> std::option::Option { + if self.offset + 32_usize > self.bytes.len() { + return None; + } + let mut raw = [0_u8; 32]; + let mut index = 0_usize; + while index < 32_usize { + raw[index] = self.bytes[self.offset + index]; + index += 1; + } + self.offset += 32_usize; + return Some(solana_sdk::pubkey::Pubkey::new_from_array(raw).to_string()); + } + + fn read_option_pubkey_string( + &mut self, + ) -> std::option::Option> { + let tag = match self.read_u8() { + Some(tag) => tag, + None => return None, + }; + if tag == 0_u8 { + return Some(None); + } + if tag != 1_u8 { + return None; + } + let pubkey = match self.read_pubkey_string() { + Some(pubkey) => pubkey, + None => return None, + }; + return Some(Some(pubkey)); + } +} + +fn decode_openbook_program_data_event_payload( + event_log_name: std::option::Option<&str>, + decoded_bytes: std::option::Option<&[u8]>, +) -> (std::option::Option, &'static str) { + let event_log_name = match event_log_name { + Some(event_log_name) => event_log_name, + None => return (None, "upstream_git_source_unmapped"), + }; + let decoded_bytes = match decoded_bytes { + Some(decoded_bytes) => decoded_bytes, + None => return (None, "base64_decode_failed"), + }; + if decoded_bytes.len() < 8_usize { + return (None, "decoded_len_too_short"); + } + let payload = &decoded_bytes[8_usize..]; + let decoded_payload = match event_log_name { + "FillLog" => decode_openbook_fill_log_payload(payload), + "TotalOrderFillEvent" => decode_openbook_total_order_fill_event_payload(payload), + "SettleFundsLog" => decode_openbook_settle_funds_log_payload(payload), + "OpenOrdersPositionLog" => decode_openbook_open_orders_position_log_payload(payload), + "DepositLog" => decode_openbook_deposit_log_payload(payload), + "TakerSignatureLog" => decode_openbook_taker_signature_log_payload(payload), + "SweepFeesLog" => decode_openbook_sweep_fees_log_payload(payload), + _ => return (None, "unsupported_event_log_layout_unverified"), + }; + match decoded_payload { + Some(decoded_payload) => { + return (Some(decoded_payload), "decoded_from_upstream_git_source_layout_unverified"); + }, + None => return (None, "layout_decode_failed_unverified"), + } +} + +fn decode_openbook_fill_log_payload(bytes: &[u8]) -> std::option::Option { + let mut reader = OpenBookV2BytesReader::new(bytes); + let mut value = serde_json::Map::new(); + value.insert("eventLogName".to_string(), openbook_json_value("FillLog")); + value.insert( + "market".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "takerSide".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u8())), + ); + value.insert( + "makerSlot".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u8())), + ); + value.insert( + "makerOut".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_bool())), + ); + value.insert( + "timestamp".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "seqNum".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "maker".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "makerClientOrderId".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "makerFee".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "makerTimestamp".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "taker".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "takerClientOrderId".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "takerFeeCeil".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "priceLots".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_i64_le())), + ); + value.insert( + "quantityBaseLots".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_i64_le())), + ); + value.insert( + "interpretationStatus".to_string(), + openbook_json_value("audit_only_layout_decoded_unverified"), + ); + return Some(serde_json::Value::Object(value)); +} + +fn decode_openbook_total_order_fill_event_payload( + bytes: &[u8], +) -> std::option::Option { + let mut reader = OpenBookV2BytesReader::new(bytes); + let mut value = serde_json::Map::new(); + value.insert("eventLogName".to_string(), openbook_json_value("TotalOrderFillEvent")); + value.insert( + "side".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u8())), + ); + value.insert( + "taker".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "totalQuantityPaid".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "totalQuantityReceived".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "fees".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "interpretationStatus".to_string(), + openbook_json_value("audit_only_layout_decoded_unverified"), + ); + return Some(serde_json::Value::Object(value)); +} + +fn decode_openbook_settle_funds_log_payload( + bytes: &[u8], +) -> std::option::Option { + let mut reader = OpenBookV2BytesReader::new(bytes); + let mut value = serde_json::Map::new(); + value.insert("eventLogName".to_string(), openbook_json_value("SettleFundsLog")); + value.insert( + "openOrdersAccount".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "baseNative".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "quoteNative".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "referrerRebate".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + let referrer = match reader.read_option_pubkey_string() { + Some(referrer) => referrer, + None => return None, + }; + value.insert("referrer".to_string(), openbook_json_value(referrer)); + value.insert( + "interpretationStatus".to_string(), + openbook_json_value("audit_only_layout_decoded_unverified"), + ); + return Some(serde_json::Value::Object(value)); +} + +fn decode_openbook_open_orders_position_log_payload( + bytes: &[u8], +) -> std::option::Option { + let mut reader = OpenBookV2BytesReader::new(bytes); + let mut value = serde_json::Map::new(); + value.insert("eventLogName".to_string(), openbook_json_value("OpenOrdersPositionLog")); + value.insert( + "owner".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "openOrdersAccountNum".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u32_le())), + ); + value.insert( + "market".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "bidsBaseLots".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_i64_le())), + ); + value.insert( + "bidsQuoteLots".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_i64_le())), + ); + value.insert( + "asksBaseLots".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_i64_le())), + ); + value.insert( + "baseFreeNative".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "quoteFreeNative".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "lockedMakerFees".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "referrerRebatesAvailable".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + let maker_volume = openbook_read_or_none!(reader.read_u128_le()); + let taker_volume = openbook_read_or_none!(reader.read_u128_le()); + value.insert("makerVolumeRaw".to_string(), openbook_json_value(maker_volume.to_string())); + value.insert("takerVolumeRaw".to_string(), openbook_json_value(taker_volume.to_string())); + value.insert( + "interpretationStatus".to_string(), + openbook_json_value("audit_only_layout_decoded_unverified"), + ); + return Some(serde_json::Value::Object(value)); +} + +fn decode_openbook_deposit_log_payload(bytes: &[u8]) -> std::option::Option { + let mut reader = OpenBookV2BytesReader::new(bytes); + let mut value = serde_json::Map::new(); + value.insert("eventLogName".to_string(), openbook_json_value("DepositLog")); + value.insert( + "openOrdersAccount".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "signer".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "baseAmount".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "quoteAmount".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "interpretationStatus".to_string(), + openbook_json_value("audit_only_layout_decoded_unverified"), + ); + return Some(serde_json::Value::Object(value)); +} + +fn decode_openbook_taker_signature_log_payload( + bytes: &[u8], +) -> std::option::Option { + let mut reader = OpenBookV2BytesReader::new(bytes); + let mut value = serde_json::Map::new(); + value.insert("eventLogName".to_string(), openbook_json_value("TakerSignatureLog")); + value.insert( + "market".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "seqNum".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "interpretationStatus".to_string(), + openbook_json_value("audit_only_layout_decoded_unverified"), + ); + return Some(serde_json::Value::Object(value)); +} + +fn decode_openbook_sweep_fees_log_payload(bytes: &[u8]) -> std::option::Option { + let mut reader = OpenBookV2BytesReader::new(bytes); + let mut value = serde_json::Map::new(); + value.insert("eventLogName".to_string(), openbook_json_value("SweepFeesLog")); + value.insert( + "market".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "amount".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_u64_le())), + ); + value.insert( + "receiver".to_string(), + openbook_json_value(openbook_read_or_none!(reader.read_pubkey_string())), + ); + value.insert( + "interpretationStatus".to_string(), + openbook_json_value("audit_only_layout_decoded_unverified"), + ); + return Some(serde_json::Value::Object(value)); +} + +fn openbook_program_data_discriminator_hex_values( + records: &[OpenBookV2ProgramDataRecord], +) -> std::vec::Vec { + let mut values = std::vec::Vec::new(); + for record in records { + let discriminator_hex = match record.discriminator_hex.as_ref() { + Some(discriminator_hex) => discriminator_hex, + None => continue, + }; + if values + .iter() + .any(|existing: &std::string::String| return existing == discriminator_hex) + { + continue; + } + values.push(discriminator_hex.clone()); + } + return values; +} + +fn openbook_program_return_records_to_json( + records: &[OpenBookV2ProgramReturnRecord], +) -> std::vec::Vec { + let mut values = std::vec::Vec::new(); + for record in records { + values.push(serde_json::json!({ + "instructionLogName": record.instruction_log_name.clone(), + "programId": record.program_id.clone(), + "dataBase64": record.data_base64.clone(), + "decodedLen": record.decoded_len, + "u64Le": record.u64_le, + "i64Le": record.i64_le, + })); + } + return values; +} + +fn openbook_program_return_u64_values( + records: &[OpenBookV2ProgramReturnRecord], +) -> std::vec::Vec { + let mut values = std::vec::Vec::new(); + for record in records { + if let Some(value) = record.u64_le { + values.push(value); + } + } + return values; +} + +fn openbook_program_return_i64_values( + records: &[OpenBookV2ProgramReturnRecord], +) -> std::vec::Vec { + let mut values = std::vec::Vec::new(); + for record in records { + if let Some(value) = record.i64_le { + values.push(value); + } + } + return values; +} + +fn openbook_v2_instruction_log_name(entry_name: &str) -> std::string::String { + let mut name = std::string::String::new(); + let mut capitalize_next = true; + for character in entry_name.chars() { + if character == '_' { + capitalize_next = true; + continue; + } + if capitalize_next { + for upper in character.to_uppercase() { + name.push(upper); + } + capitalize_next = false; + continue; + } + name.push(character); + } + return name; +} + +fn decode_base64_standard(encoded: &str) -> std::option::Option> { + use base64::Engine as _; + let decoded = base64::engine::general_purpose::STANDARD.decode(encoded.as_bytes()); + match decoded { + Ok(decoded) => return Some(decoded), + Err(_) => return None, + } +} + +fn decode_discriminator_hex(bytes: &[u8]) -> std::option::Option { + if bytes.len() < 8 { + return None; + } + let mut output = std::string::String::new(); + let mut index = 0_usize; + while index < 8 { + output.push_str(format!("{:02x}", bytes[index]).as_str()); + index += 1; + } + return Some(output); +} + +fn decode_le_prefix(bytes: &[u8]) -> std::option::Option<(u64, i64)> { + if bytes.len() < 8 { + return None; + } + let mut raw = [0_u8; 8]; + let mut index = 0_usize; + while index < 8 { + raw[index] = bytes[index]; + index += 1; + } + return Some((u64::from_le_bytes(raw), i64::from_le_bytes(raw))); +} + +fn nullable_optional_json_string(value: std::option::Option<&str>) -> serde_json::Value { + let value = match value { + Some(value) => value, + None => return serde_json::Value::Null, + }; + let trimmed = value.trim(); + if trimmed.is_empty() || trimmed == "null" { + return serde_json::Value::Null; + } + let parsed = serde_json::from_str::(trimmed); + match parsed { + Ok(parsed) => return parsed, + Err(_) => return serde_json::Value::String(trimmed.to_string()), + } +} + +fn parse_instruction_accounts_vec(accounts_json: &str) -> std::vec::Vec { + let accounts_result = serde_json::from_str::>(accounts_json); + match accounts_result { + Ok(accounts) => return accounts, + Err(_) => return std::vec::Vec::new(), + } +} + +fn parse_instruction_data_base58( + data_json: std::option::Option<&str>, +) -> std::option::Option { + let data_json = match data_json { + Some(data_json) => data_json, + None => return None, + }; + let data_result = serde_json::from_str::(data_json); + match data_result { + Ok(data) => return Some(data), + Err(_) => { + if data_json.trim().is_empty() { + return None; + } + return Some(data_json.to_string()); + }, + } +} + +fn extract_log_messages( + transaction_json: &serde_json::Value, +) -> std::vec::Vec { + let mut logs = std::vec::Vec::new(); + let log_values = transaction_json + .pointer("/meta/logMessages") + .and_then(|value| return value.as_array()); + let log_values = match log_values { + Some(log_values) => log_values, + None => return logs, + }; + for value in log_values { + if let Some(text) = value.as_str() { + logs.push(text.to_string()); + } + } + return logs; +} + +fn extract_distinct_token_mints( + transaction_json: &serde_json::Value, +) -> std::vec::Vec { + let mut mints = std::vec::Vec::new(); + collect_token_balance_mints(&mut mints, transaction_json.pointer("/meta/preTokenBalances")); + collect_token_balance_mints(&mut mints, transaction_json.pointer("/meta/postTokenBalances")); + return mints; +} + +fn collect_token_balance_mints( + mints: &mut std::vec::Vec, + value: std::option::Option<&serde_json::Value>, +) { + let value = match value { + Some(value) => value, + None => return, + }; + let items = match value.as_array() { + Some(items) => items, + None => return, + }; + for item in items { + let mint = item.get("mint").and_then(|value| return value.as_str()); + let mint = match mint { + Some(mint) => mint, + None => continue, + }; + if mints.iter().any(|existing| return existing == mint) { + continue; + } + mints.push(mint.to_string()); + } +} + +#[cfg(test)] +mod tests { + #[test] + fn maps_openbook_v2_core_instruction_names_to_audit_event_kinds() { + assert_eq!( + super::openbook_v2_audit_event_kind("place_order"), + "openbook_v2.order_place_audit" + ); + assert_eq!( + super::openbook_v2_audit_event_kind("consume_events"), + "openbook_v2.consume_events_audit" + ); + assert_eq!( + super::openbook_v2_audit_event_kind("settle_funds"), + "openbook_v2.settle_funds_audit" + ); + assert_eq!( + super::openbook_v2_audit_event_kind("close_open_orders_account"), + "openbook_v2.open_orders_close_audit" + ); + } + + #[test] + fn unknown_openbook_v2_instruction_remains_instruction_audit() { + assert_eq!( + super::openbook_v2_audit_event_kind("unknown_future_instruction"), + "openbook_v2.instruction_audit" + ); + } + + #[test] + fn openbook_log_audit_extracts_instruction_scoped_program_return_u64() { + let logs = vec![ + "Program log: Instruction: ConsumeEvents".to_string(), + "Program return: opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb TgAAAAAAAAA=".to_string(), + ]; + let audit = super::extract_openbook_v2_log_audit(logs.as_slice()); + let consume_records = + super::openbook_program_return_records_for_instruction(&audit, "ConsumeEvents"); + assert_eq!(audit.instruction_names, vec!["ConsumeEvents".to_string()]); + assert_eq!( + super::openbook_program_return_u64_values(consume_records.as_slice()), + vec![78_u64] + ); + assert_eq!( + super::openbook_program_return_i64_values(consume_records.as_slice()), + vec![78_i64] + ); + assert_eq!(audit.program_return_records.len(), 1); + } + + #[test] + fn openbook_log_audit_filters_returns_by_instruction_name() { + let logs = vec![ + "Program log: Instruction: PlaceOrder".to_string(), + "Program return: opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb AQAAAAAAAAA=".to_string(), + "Program log: Instruction: ConsumeEvents".to_string(), + "Program return: opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb TgAAAAAAAAA=".to_string(), + ]; + let audit = super::extract_openbook_v2_log_audit(logs.as_slice()); + let place_records = + super::openbook_program_return_records_for_instruction(&audit, "PlaceOrder"); + let consume_records = + super::openbook_program_return_records_for_instruction(&audit, "ConsumeEvents"); + assert_eq!( + super::openbook_program_return_u64_values(place_records.as_slice()), + vec![1_u64] + ); + assert_eq!( + super::openbook_program_return_u64_values(consume_records.as_slice()), + vec![78_u64] + ); + } + + #[test] + fn consume_events_audit_is_null_for_non_consume_event() { + let value = super::build_consume_events_audit( + "openbook_v2.settle_funds_audit", + &[], + &[], + &[], + &[], + &[], + &[], + ); + assert!(value.is_null()); + } + + #[test] + fn openbook_v2_instruction_log_name_maps_snake_case_to_anchor_case() { + assert_eq!(super::openbook_v2_instruction_log_name("consume_events"), "ConsumeEvents"); + assert_eq!( + super::openbook_v2_instruction_log_name("cancel_order_by_client_order_id"), + "CancelOrderByClientOrderId" + ); + } + + #[test] + fn openbook_log_audit_extracts_instruction_scoped_program_data() { + let logs = vec![ + "Program log: Instruction: ConsumeEvents".to_string(), + "Program data: AQIDBAUGBwg=".to_string(), + ]; + let audit = super::extract_openbook_v2_log_audit(logs.as_slice()); + let records = super::openbook_program_data_records_for_instruction(&audit, "ConsumeEvents"); + assert_eq!(records.len(), 1); + assert_eq!(records[0].decoded_len, 8); + assert_eq!(records[0].payload_len, 0); + assert_eq!(records[0].discriminator_hex.as_deref(), Some("0102030405060708")); + } + + #[test] + fn openbook_log_audit_filters_program_data_by_instruction_name() { + let logs = vec![ + "Program log: Instruction: PlaceOrder".to_string(), + "Program data: AQIDBAUGBwg=".to_string(), + "Program log: Instruction: ConsumeEvents".to_string(), + "Program data: CQgHBgUEAwI=".to_string(), + ]; + let audit = super::extract_openbook_v2_log_audit(logs.as_slice()); + let place_records = + super::openbook_program_data_records_for_instruction(&audit, "PlaceOrder"); + let consume_records = + super::openbook_program_data_records_for_instruction(&audit, "ConsumeEvents"); + assert_eq!( + super::openbook_program_data_discriminator_hex_values(place_records.as_slice()), + vec!["0102030405060708".to_string()] + ); + assert_eq!( + super::openbook_program_data_discriminator_hex_values(consume_records.as_slice()), + vec!["0908070605040302".to_string()] + ); + } + + #[test] + fn openbook_program_data_maps_known_log_discriminators() { + assert_eq!( + super::openbook_program_data_event_log_name("9617299498a2d740"), + Some("FillLog") + ); + assert_eq!( + super::openbook_program_data_event_log_name("08eb303aae4c9c69"), + Some("TotalOrderFillEvent") + ); + assert_eq!( + super::openbook_program_data_event_log_name("c4f99421a8e44906"), + Some("OpenOrdersPositionLog") + ); + assert_eq!( + super::openbook_program_data_event_log_name("0a32f075ed43e6e9"), + Some("SettleFundsLog") + ); + assert_eq!(super::openbook_program_data_event_log_name("ffffffffffffffff"), None); + } + + #[test] + fn openbook_log_audit_program_data_records_include_event_log_name() { + let logs = vec![ + "Program log: Instruction: ConsumeEvents".to_string(), + "Program data: lhcplJii10AAAAAAAAAAAAAAAAA=".to_string(), + ]; + let audit = super::extract_openbook_v2_log_audit(logs.as_slice()); + let records = super::openbook_program_data_records_for_instruction(&audit, "ConsumeEvents"); + assert_eq!(records.len(), 1); + assert_eq!(records[0].discriminator_hex.as_deref(), Some("9617299498a2d740")); + assert_eq!(records[0].event_log_name.as_deref(), Some("FillLog")); + assert_eq!( + records[0].event_log_mapping_status.as_str(), + "upstream_git_source_mapped_unverified" + ); + assert_eq!( + super::openbook_program_data_event_log_names(records.as_slice()), + vec!["FillLog".to_string()] + ); + } + + #[test] + fn openbook_program_data_payload_decodes_total_order_fill_event_layout() { + let mut bytes = vec![0x08, 0xeb, 0x30, 0x3a, 0xae, 0x4c, 0x9c, 0x69]; + bytes.push(1_u8); + let mut taker = [0_u8; 32]; + taker[0] = 7_u8; + bytes.extend_from_slice(&taker); + bytes.extend_from_slice(&11_u64.to_le_bytes()); + bytes.extend_from_slice(&22_u64.to_le_bytes()); + bytes.extend_from_slice(&3_u64.to_le_bytes()); + let (decoded, status) = super::decode_openbook_program_data_event_payload( + Some("TotalOrderFillEvent"), + Some(bytes.as_slice()), + ); + assert_eq!(status, "decoded_from_upstream_git_source_layout_unverified"); + let decoded = match decoded { + Some(decoded) => decoded, + None => panic!("expected decoded TotalOrderFillEvent payload"), + }; + assert_eq!(decoded.get("side").and_then(|value| return value.as_u64()), Some(1_u64)); + assert_eq!( + decoded.get("totalQuantityPaid").and_then(|value| return value.as_u64()), + Some(11_u64) + ); + assert_eq!( + decoded.get("totalQuantityReceived").and_then(|value| return value.as_u64()), + Some(22_u64) + ); + assert_eq!(decoded.get("fees").and_then(|value| return value.as_u64()), Some(3_u64)); + } + + #[test] + fn openbook_program_data_record_json_includes_payload_status_and_payload() { + let logs = vec![ + "Program log: Instruction: PlaceOrder".to_string(), + "Program data: COswOq5MnGkBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAAAAABYAAAAAAAAAAwAAAAAAAAA=".to_string(), + ]; + let audit = super::extract_openbook_v2_log_audit(logs.as_slice()); + let records = super::openbook_program_data_records_for_instruction(&audit, "PlaceOrder"); + assert_eq!(records.len(), 1); + let json_records = super::openbook_program_data_records_to_json(records.as_slice()); + let first_record = match json_records.get(0) { + Some(first_record) => first_record, + None => panic!("expected program data json record"), + }; + assert_eq!( + first_record.get("eventLogName").and_then(|value| return value.as_str()), + Some("TotalOrderFillEvent") + ); + assert_eq!( + first_record + .get("eventLogPayloadStatus") + .and_then(|value| return value.as_str()), + Some("decoded_from_upstream_git_source_layout_unverified") + ); + assert_eq!( + first_record + .pointer("/eventLogPayload/totalQuantityPaid") + .and_then(|value| return value.as_u64()), + Some(11_u64) + ); + } +} diff --git a/kb_lib/src/dex/phoenix_v1.rs b/kb_lib/src/dex/phoenix_v1.rs new file mode 100644 index 0000000..88c134c --- /dev/null +++ b/kb_lib/src/dex/phoenix_v1.rs @@ -0,0 +1,1325 @@ +// file: kb_lib/src/dex/phoenix_v1.rs + +//! Phoenix v1 audit-only transaction decoder. +//! +//! This decoder promotes upstream-registry discriminator matches for Phoenix v1 +//! into protocol-specific audit events. It intentionally does not create trades, +//! candles, pools or materialized orderbook rows. + +/// Decoded Phoenix v1 audit event. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct PhoenixV1AuditDecoded { + /// Parent transaction id. + pub transaction_id: i64, + /// Parent instruction id. + pub instruction_id: i64, + /// Transaction signature. + pub signature: std::string::String, + /// Program id. + pub program_id: std::string::String, + /// Protocol-specific audit event kind. + pub event_kind: std::string::String, + /// Upstream instruction name. + pub upstream_entry_name: std::string::String, + /// Upstream discriminator hex. + pub upstream_discriminator_hex: std::option::Option, + /// Optional market/state account candidate. + pub market_account: std::option::Option, + /// Optional token A/base mint observed from transaction metadata. + pub token_a_mint: std::option::Option, + /// Optional token B/quote mint observed from transaction metadata. + pub token_b_mint: std::option::Option, + /// Decoded audit payload. + pub payload_json: serde_json::Value, +} + +/// Decoded Phoenix v1 event. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub enum PhoenixV1DecodedEvent { + /// Audit-only instruction event. + Audit(PhoenixV1AuditDecoded), +} + +/// Phoenix v1 audit-only decoder. +#[derive(Debug, Clone, Default)] +pub struct PhoenixV1Decoder; + +impl PhoenixV1Decoder { + /// Creates a new decoder. + pub fn new() -> Self { + return Self; + } + + /// Decodes Phoenix v1 instructions into audit-only events. + pub fn decode_transaction( + &self, + transaction: &crate::ChainTransactionDto, + instructions: &[crate::ChainInstructionDto], + ) -> Result, crate::Error> { + let transaction_id = match transaction.id { + Some(transaction_id) => transaction_id, + None => { + return Err(crate::Error::InvalidState(format!( + "chain transaction '{}' has no internal id", + transaction.signature + ))); + }, + }; + let transaction_json_result = + serde_json::from_str::(transaction.transaction_json.as_str()); + let transaction_json = match transaction_json_result { + Ok(transaction_json) => transaction_json, + Err(error) => { + return Err(crate::Error::Json(format!( + "cannot parse transaction_json for signature '{}': {}", + transaction.signature, error + ))); + }, + }; + let log_messages = extract_log_messages(&transaction_json); + let token_mints = extract_distinct_token_mints(&transaction_json); + let mut decoded_events = std::vec::Vec::new(); + for instruction in instructions { + let program_id = match instruction.program_id.as_ref() { + Some(program_id) => program_id, + None => continue, + }; + if program_id.as_str() != crate::PHOENIX_V1_PROGRAM_ID { + continue; + } + let instruction_id = match instruction.id { + Some(instruction_id) => instruction_id, + None => continue, + }; + let data_base58 = parse_instruction_data_base58(instruction.data_json.as_deref()); + let registry_match = + crate::upstream_registry_match::upstream_registry_match_instruction_data( + program_id.as_str(), + data_base58.as_deref(), + ); + let registry_match = match registry_match { + Some(registry_match) => registry_match, + None => continue, + }; + if registry_match.decoder_code.as_str() != "phoenix-v1" { + continue; + } + let accounts = parse_instruction_accounts_vec(instruction.accounts_json.as_str()); + let event_kind = phoenix_v1_audit_event_kind(registry_match.entry_name.as_str()); + let market_account = phoenix_v1_candidate_market_account( + registry_match.entry_name.as_str(), + accounts.as_slice(), + ); + let token_a_mint = token_mints.first().cloned(); + let token_b_mint = token_mints.get(1).cloned(); + let payload_json = build_phoenix_v1_audit_payload( + transaction, + instruction, + ®istry_match, + data_base58.as_deref(), + accounts, + log_messages.as_slice(), + token_mints.as_slice(), + event_kind, + market_account.as_deref(), + ); + decoded_events.push(crate::PhoenixV1DecodedEvent::Audit( + crate::PhoenixV1AuditDecoded { + transaction_id, + instruction_id, + signature: transaction.signature.clone(), + program_id: program_id.clone(), + event_kind: event_kind.to_string(), + upstream_entry_name: registry_match.entry_name.clone(), + upstream_discriminator_hex: registry_match.discriminator_hex.clone(), + market_account, + token_a_mint, + token_b_mint, + payload_json, + }, + )); + } + return Ok(decoded_events); + } +} + +fn phoenix_v1_audit_event_kind(entry_name: &str) -> &'static str { + match entry_name { + "swap" => return "phoenix_v1.swap_audit", + "swap_with_free_funds" => return "phoenix_v1.swap_audit", + "place_limit_order" => return "phoenix_v1.order_place_audit", + "place_limit_order_with_free_funds" => return "phoenix_v1.order_place_audit", + "place_multiple_post_only_orders" => return "phoenix_v1.order_place_audit", + "place_multiple_post_only_orders_with_free_funds" => { + return "phoenix_v1.order_place_audit"; + }, + "reduce_order" => return "phoenix_v1.order_reduce_audit", + "reduce_order_with_free_funds" => return "phoenix_v1.order_reduce_audit", + "cancel_all_orders" => return "phoenix_v1.order_cancel_audit", + "cancel_all_orders_with_free_funds" => return "phoenix_v1.order_cancel_audit", + "cancel_up_to" => return "phoenix_v1.order_cancel_audit", + "cancel_up_to_with_free_funds" => return "phoenix_v1.order_cancel_audit", + "cancel_multiple_orders_by_id" => return "phoenix_v1.order_cancel_audit", + "cancel_multiple_orders_by_id_with_free_funds" => { + return "phoenix_v1.order_cancel_audit"; + }, + "deposit_funds" => return "phoenix_v1.funds_deposit_audit", + "withdraw_funds" => return "phoenix_v1.funds_withdraw_audit", + "request_seat" => return "phoenix_v1.seat_request_audit", + "request_seat_authorized" => return "phoenix_v1.seat_request_audit", + "log" => return "phoenix_v1.log_audit", + "initialize_market" => return "phoenix_v1.market_create_audit", + "collect_fees" => return "phoenix_v1.collect_fees_audit", + "change_fee_recipient" => return "phoenix_v1.admin_audit", + "change_market_status" => return "phoenix_v1.admin_audit", + "change_seat_status" => return "phoenix_v1.admin_audit", + "claim_authority" => return "phoenix_v1.admin_audit", + "name_successor" => return "phoenix_v1.admin_audit", + "evict_seat" => return "phoenix_v1.admin_audit", + "force_cancel_orders" => return "phoenix_v1.admin_audit", + _ => return "phoenix_v1.instruction_audit", + } +} + +fn phoenix_v1_candidate_market_account( + entry_name: &str, + accounts: &[std::string::String], +) -> std::option::Option { + let index = match entry_name { + "swap" => 0_usize, + "swap_with_free_funds" => 0_usize, + "place_limit_order" => 0_usize, + "place_limit_order_with_free_funds" => 0_usize, + "place_multiple_post_only_orders" => 0_usize, + "place_multiple_post_only_orders_with_free_funds" => 0_usize, + "reduce_order" => 0_usize, + "reduce_order_with_free_funds" => 0_usize, + "cancel_all_orders" => 0_usize, + "cancel_all_orders_with_free_funds" => 0_usize, + "cancel_up_to" => 0_usize, + "cancel_up_to_with_free_funds" => 0_usize, + "cancel_multiple_orders_by_id" => 0_usize, + "cancel_multiple_orders_by_id_with_free_funds" => 0_usize, + "deposit_funds" => 0_usize, + "withdraw_funds" => 0_usize, + "request_seat" => 0_usize, + "request_seat_authorized" => 0_usize, + "log" => 0_usize, + "initialize_market" => 0_usize, + "collect_fees" => 0_usize, + _ => return accounts.get(0).cloned(), + }; + return accounts.get(index).cloned(); +} + +fn build_phoenix_v1_audit_payload( + transaction: &crate::ChainTransactionDto, + instruction: &crate::ChainInstructionDto, + registry_match: &crate::UpstreamRegistryEntryDto, + data_base58: std::option::Option<&str>, + accounts: std::vec::Vec, + log_messages: &[std::string::String], + token_mints: &[std::string::String], + event_kind: &str, + market_account: std::option::Option<&str>, +) -> serde_json::Value { + let transaction_error = nullable_optional_json_string(transaction.err_json.as_deref()); + let failed = !transaction_error.is_null(); + let account_count = accounts.len(); + let instruction_data_prefix = phoenix_instruction_data_prefix(data_base58); + let phoenix_log_instruction_audit = decode_phoenix_log_instruction_data(data_base58); + let phoenix_log_audit = extract_phoenix_log_audit(log_messages); + let mut payload = serde_json::Map::new(); + payload.insert("decoder".to_string(), phoenix_json_value("phoenix_v1")); + payload.insert("auditOnly".to_string(), serde_json::Value::Bool(true)); + payload.insert("eventKind".to_string(), phoenix_json_value(event_kind)); + payload.insert("signature".to_string(), phoenix_json_value(transaction.signature.clone())); + payload.insert("slot".to_string(), phoenix_json_value(transaction.slot)); + payload.insert("transactionFailed".to_string(), serde_json::Value::Bool(failed)); + payload.insert("transactionError".to_string(), transaction_error); + payload.insert("instructionId".to_string(), phoenix_json_value(instruction.id)); + payload.insert( + "instructionIndex".to_string(), + phoenix_json_value(instruction.instruction_index), + ); + payload.insert( + "innerInstructionIndex".to_string(), + phoenix_json_value(instruction.inner_instruction_index), + ); + payload.insert( + "parentInstructionId".to_string(), + phoenix_json_value(instruction.parent_instruction_id), + ); + payload.insert("stackHeight".to_string(), phoenix_json_value(instruction.stack_height)); + payload.insert("programId".to_string(), phoenix_json_value(instruction.program_id.clone())); + payload.insert("programName".to_string(), phoenix_json_value(instruction.program_name.clone())); + payload.insert("accounts".to_string(), phoenix_json_value(accounts)); + payload.insert("accountCount".to_string(), phoenix_json_value(account_count)); + payload.insert("dataBase58".to_string(), phoenix_json_value(data_base58)); + payload + .insert("instructionDataPrefix".to_string(), phoenix_json_value(instruction_data_prefix)); + payload.insert( + "phoenixLogInstructionAudit".to_string(), + phoenix_json_value(phoenix_log_instruction_audit), + ); + payload.insert("marketAccountCandidate".to_string(), phoenix_json_value(market_account)); + payload.insert("observedTokenMints".to_string(), phoenix_json_value(token_mints)); + payload.insert( + "phoenixInstructionLogNames".to_string(), + phoenix_json_value(phoenix_log_audit.instruction_log_names), + ); + payload.insert( + "phoenixLogProgramDataRecords".to_string(), + phoenix_json_value(phoenix_log_audit.program_data_records), + ); + payload.insert( + "phoenixLogProgramDataRecordCount".to_string(), + phoenix_json_value(phoenix_log_audit.program_data_record_count), + ); + payload.insert( + "upstreamSourceRepo".to_string(), + phoenix_json_value(registry_match.source_repo.clone()), + ); + payload.insert( + "upstreamSourcePath".to_string(), + phoenix_json_value(registry_match.source_path.clone()), + ); + payload.insert( + "upstreamDecoderCode".to_string(), + phoenix_json_value(registry_match.decoder_code.clone()), + ); + payload.insert( + "upstreamProgramFamily".to_string(), + phoenix_json_value(registry_match.program_family.clone()), + ); + payload.insert( + "upstreamSurfaceKind".to_string(), + phoenix_json_value(registry_match.surface_kind.clone()), + ); + payload.insert( + "upstreamEntryKind".to_string(), + phoenix_json_value(registry_match.entry_kind.clone()), + ); + payload.insert( + "upstreamEntryName".to_string(), + phoenix_json_value(registry_match.entry_name.clone()), + ); + payload.insert( + "upstreamDiscriminatorHex".to_string(), + phoenix_json_value(registry_match.discriminator_hex.clone()), + ); + payload.insert( + "upstreamDiscriminatorLen".to_string(), + phoenix_json_value(registry_match.discriminator_len), + ); + payload.insert( + "upstreamProofStatus".to_string(), + phoenix_json_value(registry_match.proof_status.clone()), + ); + payload.insert("upstreamNotes".to_string(), phoenix_json_value(registry_match.notes.clone())); + payload.insert("logMessages".to_string(), phoenix_json_value(log_messages)); + payload.insert("tradeCandidate".to_string(), serde_json::Value::Bool(false)); + payload.insert("candleCandidate".to_string(), serde_json::Value::Bool(false)); + payload.insert("nonTradeUseful".to_string(), serde_json::Value::Bool(true)); + payload.insert("interpretationStatus".to_string(), phoenix_json_value("audit_only_unverified")); + payload.insert( + "skipTradeReason".to_string(), + phoenix_json_value("phoenix_v1_audit_only_orderbook_decoder"), + ); + payload.insert( + "skipCandleReason".to_string(), + phoenix_json_value("phoenix_v1_audit_only_orderbook_decoder"), + ); + return serde_json::Value::Object(payload); +} + +#[derive(Debug, Clone, serde::Serialize)] +#[serde(rename_all = "camelCase")] +struct PhoenixLogInstructionAudit { + status: std::string::String, + decoded_len: std::option::Option, + log_instruction_tag: std::option::Option, + header_event_tag: std::option::Option, + current_instruction_tag: std::option::Option, + current_instruction_tag_hex: std::option::Option, + current_instruction_name: std::option::Option, + unknown_current_instruction_tag: bool, + sequence_number: std::option::Option, + timestamp: std::option::Option, + slot: std::option::Option, + market: std::option::Option, + signer: std::option::Option, + total_events: std::option::Option, + parsed_event_count: usize, + event_type_names: std::vec::Vec, + events: std::vec::Vec, + interpretation_status: std::string::String, +} + +#[derive(Debug, Clone, serde::Serialize)] +#[serde(rename_all = "camelCase")] +struct PhoenixLogInstructionEventAudit { + offset: usize, + event_tag: u8, + event_name: std::option::Option, + decoded_len: usize, + payload_status: std::string::String, + payload: serde_json::Value, +} + +fn decode_phoenix_log_instruction_data( + data_base58: std::option::Option<&str>, +) -> std::option::Option { + let data_base58 = match data_base58 { + Some(data_base58) => data_base58, + None => return None, + }; + let decoded_result = bs58::decode(data_base58).into_vec(); + let decoded = match decoded_result { + Ok(decoded) => decoded, + Err(_) => { + return Some(PhoenixLogInstructionAudit { + status: "base58_decode_failed".to_string(), + decoded_len: None, + log_instruction_tag: None, + header_event_tag: None, + current_instruction_tag: None, + current_instruction_tag_hex: None, + current_instruction_name: None, + unknown_current_instruction_tag: false, + sequence_number: None, + timestamp: None, + slot: None, + market: None, + signer: None, + total_events: None, + parsed_event_count: 0_usize, + event_type_names: std::vec::Vec::new(), + events: std::vec::Vec::new(), + interpretation_status: "audit_only_unverified".to_string(), + }); + }, + }; + if decoded.first().copied() != Some(15_u8) { + return Some(PhoenixLogInstructionAudit { + status: "not_phoenix_log_instruction".to_string(), + decoded_len: Some(decoded.len()), + log_instruction_tag: decoded.first().copied(), + header_event_tag: None, + current_instruction_tag: None, + current_instruction_tag_hex: None, + current_instruction_name: None, + unknown_current_instruction_tag: false, + sequence_number: None, + timestamp: None, + slot: None, + market: None, + signer: None, + total_events: None, + parsed_event_count: 0_usize, + event_type_names: std::vec::Vec::new(), + events: std::vec::Vec::new(), + interpretation_status: "audit_only_unverified".to_string(), + }); + } + if decoded.len() < 93_usize { + return Some(PhoenixLogInstructionAudit { + status: "phoenix_log_instruction_truncated".to_string(), + decoded_len: Some(decoded.len()), + log_instruction_tag: decoded.first().copied(), + header_event_tag: decoded.get(1_usize).copied(), + current_instruction_tag: decoded.get(2_usize).copied(), + current_instruction_tag_hex: decoded.get(2_usize).copied().map(phoenix_byte_hex), + current_instruction_name: decoded + .get(2_usize) + .copied() + .and_then(phoenix_instruction_tag_name) + .map(std::string::ToString::to_string), + unknown_current_instruction_tag: decoded + .get(2_usize) + .copied() + .map(|tag| return phoenix_instruction_tag_name(tag).is_none()) + .unwrap_or(false), + sequence_number: None, + timestamp: None, + slot: None, + market: None, + signer: None, + total_events: None, + parsed_event_count: 0_usize, + event_type_names: std::vec::Vec::new(), + events: std::vec::Vec::new(), + interpretation_status: "audit_only_unverified".to_string(), + }); + } + let current_instruction_tag = decoded.get(2_usize).copied(); + let current_instruction_name = current_instruction_tag + .and_then(phoenix_instruction_tag_name) + .map(std::string::ToString::to_string); + let unknown_current_instruction_tag = + current_instruction_tag.is_some() && current_instruction_name.is_none(); + let mut offset = 93_usize; + let mut events = std::vec::Vec::new(); + let mut event_type_names = std::vec::Vec::new(); + while offset < decoded.len() { + let parsed = parse_phoenix_log_instruction_event(decoded.as_slice(), offset); + let parsed = match parsed { + Some(parsed) => parsed, + None => { + events.push(PhoenixLogInstructionEventAudit { + offset, + event_tag: decoded[offset], + event_name: phoenix_market_event_tag_name(decoded[offset]) + .map(std::string::ToString::to_string), + decoded_len: decoded.len() - offset, + payload_status: "truncated_or_unmapped_market_event".to_string(), + payload: phoenix_json_value(serde_json::Map::< + std::string::String, + serde_json::Value, + >::new()), + }); + break; + }, + }; + if let Some(event_name) = parsed.event_name.as_ref() { + if !event_type_names.iter().any(|known| return known == event_name) { + event_type_names.push(event_name.clone()); + } + } + offset += parsed.decoded_len; + events.push(parsed); + } + return Some(PhoenixLogInstructionAudit { + status: "decoded_phoenix_log_instruction_header_unverified".to_string(), + decoded_len: Some(decoded.len()), + log_instruction_tag: decoded.get(0_usize).copied(), + header_event_tag: decoded.get(1_usize).copied(), + current_instruction_tag, + current_instruction_tag_hex: current_instruction_tag.map(phoenix_byte_hex), + current_instruction_name, + unknown_current_instruction_tag, + sequence_number: read_u64_le(decoded.as_slice(), 3_usize), + timestamp: read_i64_le(decoded.as_slice(), 11_usize), + slot: read_u64_le(decoded.as_slice(), 19_usize), + market: read_pubkey_base58(decoded.as_slice(), 27_usize), + signer: read_pubkey_base58(decoded.as_slice(), 59_usize), + total_events: read_u16_le(decoded.as_slice(), 91_usize), + parsed_event_count: events.len(), + event_type_names, + events, + interpretation_status: "audit_only_layout_decoded_unverified".to_string(), + }); +} + +fn parse_phoenix_log_instruction_event( + bytes: &[u8], + offset: usize, +) -> std::option::Option { + let tag = match bytes.get(offset) { + Some(tag) => *tag, + None => return None, + }; + let event_name = phoenix_market_event_tag_name(tag).map(std::string::ToString::to_string); + let event_len = match phoenix_market_event_serialized_len(tag) { + Some(event_len) => event_len, + None => { + return Some(PhoenixLogInstructionEventAudit { + offset, + event_tag: tag, + event_name, + decoded_len: 1_usize, + payload_status: "unmapped_market_event_tag".to_string(), + payload: phoenix_json_value(serde_json::Map::< + std::string::String, + serde_json::Value, + >::new()), + }); + }, + }; + if bytes.len() < offset + event_len { + return None; + } + let payload = decode_phoenix_market_event_payload(tag, bytes, offset); + return Some(PhoenixLogInstructionEventAudit { + offset, + event_tag: tag, + event_name, + decoded_len: event_len, + payload_status: "decoded_from_upstream_source_layout_unverified".to_string(), + payload, + }); +} + +fn decode_phoenix_market_event_payload(tag: u8, bytes: &[u8], offset: usize) -> serde_json::Value { + let mut payload = serde_json::Map::new(); + payload.insert( + "interpretationStatus".to_string(), + phoenix_json_value("audit_only_layout_decoded_unverified"), + ); + payload.insert("eventName".to_string(), phoenix_json_value(phoenix_market_event_tag_name(tag))); + match tag { + 2_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "makerId".to_string(), + phoenix_json_value(read_pubkey_base58(bytes, offset + 3_usize)), + ); + payload.insert( + "orderSequenceNumber".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 35_usize)), + ); + payload.insert( + "priceInTicks".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 43_usize)), + ); + payload.insert( + "baseLotsFilled".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 51_usize)), + ); + payload.insert( + "baseLotsRemaining".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 59_usize)), + ); + }, + 3_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "orderSequenceNumber".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 3_usize)), + ); + payload.insert( + "clientOrderId".to_string(), + phoenix_json_value(read_u128_le_string(bytes, offset + 11_usize)), + ); + payload.insert( + "priceInTicks".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 27_usize)), + ); + payload.insert( + "baseLotsPlaced".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 35_usize)), + ); + }, + 4_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "orderSequenceNumber".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 3_usize)), + ); + payload.insert( + "priceInTicks".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 11_usize)), + ); + payload.insert( + "baseLotsRemoved".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 19_usize)), + ); + payload.insert( + "baseLotsRemaining".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 27_usize)), + ); + }, + 5_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "makerId".to_string(), + phoenix_json_value(read_pubkey_base58(bytes, offset + 3_usize)), + ); + payload.insert( + "orderSequenceNumber".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 35_usize)), + ); + payload.insert( + "priceInTicks".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 43_usize)), + ); + payload.insert( + "baseLotsEvicted".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 51_usize)), + ); + }, + 6_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "clientOrderId".to_string(), + phoenix_json_value(read_u128_le_string(bytes, offset + 3_usize)), + ); + payload.insert( + "totalBaseLotsFilled".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 19_usize)), + ); + payload.insert( + "totalQuoteLotsFilled".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 27_usize)), + ); + payload.insert( + "totalFeeInQuoteLots".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 35_usize)), + ); + }, + 7_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "feesCollectedInQuoteLots".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 3_usize)), + ); + }, + 8_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "orderSequenceNumber".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 3_usize)), + ); + payload.insert( + "lastValidSlot".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 11_usize)), + ); + payload.insert( + "lastValidUnixTimestampInSeconds".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 19_usize)), + ); + }, + 9_u8 => { + payload.insert( + "index".to_string(), + phoenix_json_value(read_u16_le(bytes, offset + 1_usize)), + ); + payload.insert( + "makerId".to_string(), + phoenix_json_value(read_pubkey_base58(bytes, offset + 3_usize)), + ); + payload.insert( + "orderSequenceNumber".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 35_usize)), + ); + payload.insert( + "priceInTicks".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 43_usize)), + ); + payload.insert( + "baseLotsRemoved".to_string(), + phoenix_json_value(read_u64_le(bytes, offset + 51_usize)), + ); + }, + _ => {}, + } + return serde_json::Value::Object(payload); +} + +fn phoenix_market_event_serialized_len(tag: u8) -> std::option::Option { + match tag { + 2_u8 => return Some(67_usize), + 3_u8 => return Some(43_usize), + 4_u8 => return Some(35_usize), + 5_u8 => return Some(59_usize), + 6_u8 => return Some(43_usize), + 7_u8 => return Some(11_usize), + 8_u8 => return Some(27_usize), + 9_u8 => return Some(59_usize), + _ => return None, + } +} + +fn phoenix_market_event_tag_name(tag: u8) -> std::option::Option<&'static str> { + match tag { + 0_u8 => return Some("Uninitialized"), + 1_u8 => return Some("Header"), + 2_u8 => return Some("Fill"), + 3_u8 => return Some("Place"), + 4_u8 => return Some("Reduce"), + 5_u8 => return Some("Evict"), + 6_u8 => return Some("FillSummary"), + 7_u8 => return Some("Fee"), + 8_u8 => return Some("TimeInForce"), + 9_u8 => return Some("ExpiredOrder"), + _ => return None, + } +} + +fn phoenix_instruction_tag_name(tag: u8) -> std::option::Option<&'static str> { + match tag { + 0_u8 => return Some("Swap"), + 1_u8 => return Some("SwapWithFreeFunds"), + 2_u8 => return Some("PlaceLimitOrder"), + 3_u8 => return Some("PlaceLimitOrderWithFreeFunds"), + 4_u8 => return Some("ReduceOrder"), + 5_u8 => return Some("ReduceOrderWithFreeFunds"), + 6_u8 => return Some("CancelAllOrders"), + 7_u8 => return Some("CancelAllOrdersWithFreeFunds"), + 8_u8 => return Some("CancelUpTo"), + 9_u8 => return Some("CancelUpToWithFreeFunds"), + 10_u8 => return Some("CancelMultipleOrdersById"), + 11_u8 => return Some("CancelMultipleOrdersByIdWithFreeFunds"), + 12_u8 => return Some("WithdrawFunds"), + 13_u8 => return Some("DepositFunds"), + 14_u8 => return Some("RequestSeat"), + 15_u8 => return Some("Log"), + 16_u8 => return Some("PlaceMultiplePostOnlyOrders"), + 17_u8 => return Some("PlaceMultiplePostOnlyOrdersWithFreeFunds"), + 100_u8 => return Some("InitializeMarket"), + 101_u8 => return Some("ClaimAuthority"), + 102_u8 => return Some("NameSuccessor"), + 103_u8 => return Some("ChangeMarketStatus"), + 104_u8 => return Some("ChangeSeatStatus"), + 105_u8 => return Some("RequestSeatAuthorized"), + 106_u8 => return Some("EvictSeat"), + 107_u8 => return Some("ForceCancelOrders"), + 108_u8 => return Some("CollectFees"), + 109_u8 => return Some("ChangeFeeRecipient"), + _ => return None, + } +} + +fn read_u16_le(bytes: &[u8], offset: usize) -> std::option::Option { + if bytes.len() < offset + 2_usize { + return None; + } + let mut buffer = [0_u8; 2]; + buffer.copy_from_slice(&bytes[offset..offset + 2_usize]); + return Some(u16::from_le_bytes(buffer)); +} + +fn read_u64_le(bytes: &[u8], offset: usize) -> std::option::Option { + if bytes.len() < offset + 8_usize { + return None; + } + let mut buffer = [0_u8; 8]; + buffer.copy_from_slice(&bytes[offset..offset + 8_usize]); + return Some(u64::from_le_bytes(buffer)); +} + +fn read_i64_le(bytes: &[u8], offset: usize) -> std::option::Option { + if bytes.len() < offset + 8_usize { + return None; + } + let mut buffer = [0_u8; 8]; + buffer.copy_from_slice(&bytes[offset..offset + 8_usize]); + return Some(i64::from_le_bytes(buffer)); +} + +fn read_u128_le_string(bytes: &[u8], offset: usize) -> std::option::Option { + if bytes.len() < offset + 16_usize { + return None; + } + let mut buffer = [0_u8; 16]; + buffer.copy_from_slice(&bytes[offset..offset + 16_usize]); + return Some(u128::from_le_bytes(buffer).to_string()); +} + +fn read_pubkey_base58(bytes: &[u8], offset: usize) -> std::option::Option { + if bytes.len() < offset + 32_usize { + return None; + } + return Some(bs58::encode(&bytes[offset..offset + 32_usize]).into_string()); +} + +#[derive(Debug, Clone, Default, serde::Serialize)] +#[serde(rename_all = "camelCase")] +struct PhoenixLogAudit { + instruction_log_names: std::vec::Vec, + program_data_records: std::vec::Vec, + program_data_record_count: usize, +} + +#[derive(Debug, Clone, serde::Serialize)] +#[serde(rename_all = "camelCase")] +struct PhoenixProgramDataRecord { + instruction_log_name: std::option::Option, + data_base64: std::string::String, + decoded_len: std::option::Option, + discriminator_hex: std::option::Option, + payload_len: std::option::Option, + interpretation_status: std::string::String, +} + +fn extract_phoenix_log_audit(log_messages: &[std::string::String]) -> PhoenixLogAudit { + let mut audit = PhoenixLogAudit::default(); + let mut current_instruction_log_name: std::option::Option = None; + for log_message in log_messages { + let maybe_name = collect_phoenix_instruction_log_name(log_message.as_str()); + if let Some(name) = maybe_name { + current_instruction_log_name = Some(name.clone()); + audit.instruction_log_names.push(name); + continue; + } + let maybe_record = parse_phoenix_program_data_record( + log_message.as_str(), + current_instruction_log_name.as_deref(), + ); + if let Some(record) = maybe_record { + audit.program_data_records.push(record); + } + } + audit.program_data_record_count = audit.program_data_records.len(); + return audit; +} + +fn collect_phoenix_instruction_log_name( + log_message: &str, +) -> std::option::Option { + let prefix = "Program log: Instruction: "; + if !log_message.starts_with(prefix) { + return None; + } + let name = &log_message[prefix.len()..]; + if name.is_empty() { + return None; + } + return Some(name.to_string()); +} + +fn parse_phoenix_program_data_record( + log_message: &str, + instruction_log_name: std::option::Option<&str>, +) -> std::option::Option { + let prefix = "Program data: "; + if !log_message.starts_with(prefix) { + return None; + } + let data_base64 = log_message[prefix.len()..].trim(); + if data_base64.is_empty() { + return None; + } + let decoded_result = base64_decode_standard(data_base64); + let (decoded_len, discriminator_hex, payload_len, status) = match decoded_result { + Some(decoded) => { + let discriminator = if decoded.len() >= 8_usize { + Some(hex_encode_lower(&decoded[0_usize..8_usize])) + } else { + None + }; + let payload_len = + if decoded.len() >= 8_usize { Some(decoded.len() - 8_usize) } else { None }; + ( + Some(decoded.len()), + discriminator, + payload_len, + "audit_only_unmapped_program_data", + ) + }, + None => (None, None, None, "base64_decode_failed"), + }; + return Some(PhoenixProgramDataRecord { + instruction_log_name: instruction_log_name.map(std::string::ToString::to_string), + data_base64: data_base64.to_string(), + decoded_len, + discriminator_hex, + payload_len, + interpretation_status: status.to_string(), + }); +} + +fn phoenix_json_value(value: T) -> serde_json::Value { + let serialized = serde_json::to_value(value); + match serialized { + Ok(serialized) => return serialized, + Err(_) => return serde_json::Value::Null, + } +} + +fn nullable_optional_json_string(value: std::option::Option<&str>) -> serde_json::Value { + match value { + Some(value) => { + if value.is_empty() || value == "null" { + return serde_json::Value::Null; + } + return serde_json::Value::String(value.to_string()); + }, + None => return serde_json::Value::Null, + } +} + +fn parse_instruction_data_base58( + data_json: std::option::Option<&str>, +) -> std::option::Option { + let data_json = match data_json { + Some(data_json) => data_json, + None => return None, + }; + let value_result = serde_json::from_str::(data_json); + let value = match value_result { + Ok(value) => value, + Err(_) => return None, + }; + if let Some(text) = value.as_str() { + return Some(text.to_string()); + } + if let Some(text) = value.get("data").and_then(serde_json::Value::as_str) { + return Some(text.to_string()); + } + return None; +} + +fn parse_instruction_accounts_vec(data: &str) -> std::vec::Vec { + let value_result = serde_json::from_str::(data); + let value = match value_result { + Ok(value) => value, + Err(_) => return std::vec::Vec::new(), + }; + let array = match value.as_array() { + Some(array) => array, + None => return std::vec::Vec::new(), + }; + let mut accounts = std::vec::Vec::new(); + for account in array { + if let Some(text) = account.as_str() { + accounts.push(text.to_string()); + continue; + } + if let Some(pubkey) = account.get("pubkey").and_then(serde_json::Value::as_str) { + accounts.push(pubkey.to_string()); + continue; + } + } + return accounts; +} + +fn phoenix_instruction_data_prefix( + data_base58: std::option::Option<&str>, +) -> std::option::Option { + let data_base58 = match data_base58 { + Some(data_base58) => data_base58, + None => return None, + }; + let decoded_result = bs58::decode(data_base58).into_vec(); + let decoded = match decoded_result { + Ok(decoded) => decoded, + Err(_) => return None, + }; + let end = std::cmp::min(decoded.len(), 8_usize); + return Some(hex_encode_lower(&decoded[0_usize..end])); +} + +fn extract_log_messages(value: &serde_json::Value) -> std::vec::Vec { + let mut logs = std::vec::Vec::new(); + collect_log_messages_from_value(value, &mut logs); + return logs; +} + +fn collect_log_messages_from_value( + value: &serde_json::Value, + logs: &mut std::vec::Vec, +) { + match value { + serde_json::Value::Array(array) => { + for item in array { + collect_log_messages_from_value(item, logs); + } + }, + serde_json::Value::Object(object) => { + for (key, child) in object { + if key == "logMessages" { + if let Some(array) = child.as_array() { + for item in array { + if let Some(text) = item.as_str() { + logs.push(text.to_string()); + } + } + } + } + collect_log_messages_from_value(child, logs); + } + }, + _ => {}, + } +} + +fn extract_distinct_token_mints(value: &serde_json::Value) -> std::vec::Vec { + let mut mints = std::vec::Vec::new(); + collect_token_mints(value, &mut mints); + return mints; +} + +fn collect_token_mints(value: &serde_json::Value, mints: &mut std::vec::Vec) { + match value { + serde_json::Value::Array(array) => { + for item in array { + collect_token_mints(item, mints); + } + }, + serde_json::Value::Object(object) => { + for (key, child) in object { + if key == "mint" { + if let Some(mint) = child.as_str() { + if !mints.iter().any(|known| return known == mint) { + mints.push(mint.to_string()); + } + } + } + collect_token_mints(child, mints); + } + }, + _ => {}, + } +} + +fn base64_decode_standard(input: &str) -> std::option::Option> { + use base64::Engine; + let decoded_result = base64::engine::general_purpose::STANDARD.decode(input.as_bytes()); + match decoded_result { + Ok(decoded) => return Some(decoded), + Err(_) => return None, + } +} + +fn hex_encode_lower(bytes: &[u8]) -> std::string::String { + let mut output = std::string::String::new(); + for byte in bytes { + output.push_str(format!("{byte:02x}").as_str()); + } + return output; +} + +fn phoenix_byte_hex(value: u8) -> std::string::String { + return format!("{value:02x}"); +} + +#[cfg(test)] +mod tests { + fn phoenix_instruction_with_data(data: &[u8]) -> std::string::String { + return bs58::encode(data).into_string(); + } + + #[test] + fn classifies_phoenix_v1_core_orderbook_entries_as_audit_only() { + assert_eq!(super::phoenix_v1_audit_event_kind("swap"), "phoenix_v1.swap_audit"); + assert_eq!( + super::phoenix_v1_audit_event_kind("place_limit_order"), + "phoenix_v1.order_place_audit" + ); + assert_eq!( + super::phoenix_v1_audit_event_kind("cancel_up_to_with_free_funds"), + "phoenix_v1.order_cancel_audit" + ); + assert_eq!( + super::phoenix_v1_audit_event_kind("deposit_funds"), + "phoenix_v1.funds_deposit_audit" + ); + } + + #[test] + fn extracts_short_phoenix_instruction_data_prefix() { + let data = phoenix_instruction_with_data(&[0x02_u8, 0xaa, 0xbb]); + let prefix = super::phoenix_instruction_data_prefix(Some(data.as_str())); + assert_eq!(prefix.as_deref(), Some("02aabb")); + } + + #[test] + fn decodes_phoenix_log_instruction_header_and_market_events() { + let mut data = std::vec::Vec::new(); + data.push(15_u8); + data.push(1_u8); + data.push(2_u8); + data.extend_from_slice(&11_u64.to_le_bytes()); + data.extend_from_slice(&(-2_i64).to_le_bytes()); + data.extend_from_slice(&33_u64.to_le_bytes()); + data.extend_from_slice(&[1_u8; 32]); + data.extend_from_slice(&[2_u8; 32]); + data.extend_from_slice(&2_u16.to_le_bytes()); + data.push(3_u8); + data.extend_from_slice(&0_u16.to_le_bytes()); + data.extend_from_slice(&44_u64.to_le_bytes()); + data.extend_from_slice(&55_u128.to_le_bytes()); + data.extend_from_slice(&66_u64.to_le_bytes()); + data.extend_from_slice(&77_u64.to_le_bytes()); + data.push(6_u8); + data.extend_from_slice(&1_u16.to_le_bytes()); + data.extend_from_slice(&88_u128.to_le_bytes()); + data.extend_from_slice(&99_u64.to_le_bytes()); + data.extend_from_slice(&111_u64.to_le_bytes()); + data.extend_from_slice(&7_u64.to_le_bytes()); + let encoded = phoenix_instruction_with_data(data.as_slice()); + let audit = super::decode_phoenix_log_instruction_data(Some(encoded.as_str())); + let audit = match audit { + Some(audit) => audit, + None => panic!("expected phoenix log instruction audit"), + }; + assert_eq!(audit.status.as_str(), "decoded_phoenix_log_instruction_header_unverified"); + assert_eq!(audit.log_instruction_tag, Some(15)); + assert_eq!(audit.header_event_tag, Some(1)); + assert_eq!(audit.current_instruction_tag, Some(2)); + assert_eq!(audit.current_instruction_tag_hex.as_deref(), Some("02")); + assert_eq!(audit.current_instruction_name.as_deref(), Some("PlaceLimitOrder")); + assert!(!audit.unknown_current_instruction_tag); + assert_eq!(audit.sequence_number, Some(11)); + assert_eq!(audit.timestamp, Some(-2)); + assert_eq!(audit.slot, Some(33)); + assert_eq!(audit.total_events, Some(2)); + assert_eq!(audit.parsed_event_count, 2); + assert_eq!(audit.event_type_names, vec!["Place".to_string(), "FillSummary".to_string()]); + assert_eq!(audit.events[0].event_name.as_deref(), Some("Place")); + assert_eq!(audit.events[1].event_name.as_deref(), Some("FillSummary")); + } + + #[test] + fn serializes_phoenix_log_instruction_audit_with_camel_case_fields() { + let mut data = std::vec::Vec::new(); + data.push(15_u8); + data.push(1_u8); + data.push(2_u8); + data.extend_from_slice(&11_u64.to_le_bytes()); + data.extend_from_slice(&22_i64.to_le_bytes()); + data.extend_from_slice(&33_u64.to_le_bytes()); + data.extend_from_slice(&[1_u8; 32]); + data.extend_from_slice(&[2_u8; 32]); + data.extend_from_slice(&0_u16.to_le_bytes()); + let encoded = phoenix_instruction_with_data(data.as_slice()); + let audit = super::decode_phoenix_log_instruction_data(Some(encoded.as_str())); + let audit = match audit { + Some(audit) => audit, + None => panic!("expected phoenix log instruction audit"), + }; + let value = super::phoenix_json_value(audit); + assert!(value.get("currentInstructionName").is_some()); + assert!(value.get("current_instruction_name").is_none()); + assert_eq!( + value.get("currentInstructionName").and_then(serde_json::Value::as_str), + Some("PlaceLimitOrder") + ); + assert_eq!(value.get("totalEvents").and_then(serde_json::Value::as_u64), Some(0_u64)); + } + + #[test] + fn non_log_instruction_data_is_not_decoded_as_phoenix_log_header() { + let data = phoenix_instruction_with_data(&[2_u8, 0_u8, 0_u8, 0_u8, 0_u8]); + let audit = super::decode_phoenix_log_instruction_data(Some(data.as_str())); + let audit = match audit { + Some(audit) => audit, + None => panic!("expected phoenix audit status"), + }; + assert_eq!(audit.status.as_str(), "not_phoenix_log_instruction"); + assert_eq!(audit.log_instruction_tag, Some(2_u8)); + assert_eq!(audit.current_instruction_tag, None); + assert_eq!(audit.current_instruction_tag_hex, None); + assert_eq!(audit.current_instruction_name, None); + assert!(!audit.unknown_current_instruction_tag); + assert_eq!(audit.total_events, None); + assert_eq!(audit.parsed_event_count, 0_usize); + assert_eq!(audit.event_type_names.len(), 0_usize); + } + + #[test] + fn truncated_log_instruction_is_reported_separately() { + let data = phoenix_instruction_with_data(&[15_u8, 1_u8, 2_u8]); + let audit = super::decode_phoenix_log_instruction_data(Some(data.as_str())); + let audit = match audit { + Some(audit) => audit, + None => panic!("expected phoenix truncated log status"), + }; + assert_eq!(audit.status.as_str(), "phoenix_log_instruction_truncated"); + assert_eq!(audit.log_instruction_tag, Some(15_u8)); + assert_eq!(audit.current_instruction_tag, Some(2_u8)); + assert_eq!(audit.current_instruction_tag_hex.as_deref(), Some("02")); + assert_eq!(audit.current_instruction_name.as_deref(), Some("PlaceLimitOrder")); + assert!(!audit.unknown_current_instruction_tag); + assert_eq!(audit.total_events, None); + assert_eq!(audit.parsed_event_count, 0_usize); + } + + #[test] + fn maps_known_phoenix_current_instruction_tags_from_source_enum() { + assert_eq!(super::phoenix_instruction_tag_name(14_u8), Some("RequestSeat")); + assert_eq!(super::phoenix_instruction_tag_name(16_u8), Some("PlaceMultiplePostOnlyOrders")); + assert_eq!( + super::phoenix_instruction_tag_name(17_u8), + Some("PlaceMultiplePostOnlyOrdersWithFreeFunds") + ); + assert_eq!(super::phoenix_instruction_tag_name(106_u8), Some("EvictSeat")); + assert_eq!(super::phoenix_instruction_tag_name(107_u8), Some("ForceCancelOrders")); + assert_eq!(super::phoenix_instruction_tag_name(108_u8), Some("CollectFees")); + assert_eq!(super::phoenix_instruction_tag_name(109_u8), Some("ChangeFeeRecipient")); + } + + #[test] + fn maps_phoenix_log_current_instruction_tag_16() { + let mut data = std::vec::Vec::new(); + data.push(15_u8); + data.push(1_u8); + data.push(16_u8); + data.extend_from_slice(&11_u64.to_le_bytes()); + data.extend_from_slice(&22_i64.to_le_bytes()); + data.extend_from_slice(&33_u64.to_le_bytes()); + data.extend_from_slice(&[1_u8; 32]); + data.extend_from_slice(&[2_u8; 32]); + data.extend_from_slice(&0_u16.to_le_bytes()); + let encoded = phoenix_instruction_with_data(data.as_slice()); + let audit = super::decode_phoenix_log_instruction_data(Some(encoded.as_str())); + let audit = match audit { + Some(audit) => audit, + None => panic!("expected phoenix log instruction audit"), + }; + assert_eq!(audit.current_instruction_tag, Some(16_u8)); + assert_eq!(audit.current_instruction_tag_hex.as_deref(), Some("10")); + assert_eq!(audit.current_instruction_name.as_deref(), Some("PlaceMultiplePostOnlyOrders")); + assert!(!audit.unknown_current_instruction_tag); + } + + #[test] + fn exposes_unknown_phoenix_current_instruction_tag_without_guessing_name() { + let mut data = std::vec::Vec::new(); + data.push(15_u8); + data.push(1_u8); + data.push(250_u8); + data.extend_from_slice(&11_u64.to_le_bytes()); + data.extend_from_slice(&22_i64.to_le_bytes()); + data.extend_from_slice(&33_u64.to_le_bytes()); + data.extend_from_slice(&[1_u8; 32]); + data.extend_from_slice(&[2_u8; 32]); + data.extend_from_slice(&0_u16.to_le_bytes()); + let encoded = phoenix_instruction_with_data(data.as_slice()); + let audit = super::decode_phoenix_log_instruction_data(Some(encoded.as_str())); + let audit = match audit { + Some(audit) => audit, + None => panic!("expected phoenix log instruction audit"), + }; + assert_eq!(audit.status.as_str(), "decoded_phoenix_log_instruction_header_unverified"); + assert_eq!(audit.current_instruction_tag, Some(250_u8)); + assert_eq!(audit.current_instruction_tag_hex.as_deref(), Some("fa")); + assert_eq!(audit.current_instruction_name, None); + assert!(audit.unknown_current_instruction_tag); + let value = super::phoenix_json_value(audit); + assert_eq!( + value.get("currentInstructionTagHex").and_then(serde_json::Value::as_str), + Some("fa") + ); + assert_eq!( + value.get("unknownCurrentInstructionTag").and_then(serde_json::Value::as_bool), + Some(true) + ); + } + + #[test] + fn parses_phoenix_program_data_audit_record() { + let record = + super::parse_phoenix_program_data_record("Program data: AQIDBAUGBwgJCg==", Some("Log")); + let record = match record { + Some(record) => record, + None => panic!("expected program data record"), + }; + assert_eq!(record.instruction_log_name.as_deref(), Some("Log")); + assert_eq!(record.decoded_len, Some(10)); + assert_eq!(record.discriminator_hex.as_deref(), Some("0102030405060708")); + assert_eq!(record.payload_len, Some(2)); + } +} diff --git a/kb_lib/src/dex_catalog.rs b/kb_lib/src/dex_catalog.rs index 948d771..623f5a8 100644 --- a/kb_lib/src/dex_catalog.rs +++ b/kb_lib/src/dex_catalog.rs @@ -124,7 +124,6 @@ mod tests { fn planned_launch_surfaces_are_present_but_disabled() { let codes = [ "raydium_launchlab", - "raydium_launchpad", "letsbonk", "boop_fun", "moonshot", diff --git a/kb_lib/src/dex_decode.rs b/kb_lib/src/dex_decode.rs index f62ba0b..970cfb9 100644 --- a/kb_lib/src/dex_decode.rs +++ b/kb_lib/src/dex_decode.rs @@ -20,6 +20,8 @@ pub struct DexDecodeService { meteora_damm_v2_decoder: crate::MeteoraDammV2Decoder, fluxbeam_decoder: crate::FluxbeamDecoder, dexlab_decoder: crate::DexlabDecoder, + openbook_v2_decoder: crate::OpenBookV2Decoder, + phoenix_v1_decoder: crate::PhoenixV1Decoder, } impl DexDecodeService { @@ -40,6 +42,8 @@ impl DexDecodeService { meteora_damm_v2_decoder: crate::MeteoraDammV2Decoder::new(), fluxbeam_decoder: crate::FluxbeamDecoder::new(), dexlab_decoder: crate::DexlabDecoder::new(), + openbook_v2_decoder: crate::OpenBookV2Decoder::new(), + phoenix_v1_decoder: crate::PhoenixV1Decoder::new(), }; } @@ -163,6 +167,36 @@ impl DexDecodeService { if let Err(error) = append_result { return Err(error); } + let append_result = append_persisted_events_result( + &mut persisted, + self.decode_and_persist_openbook_v2_audit_events(&transaction, &instructions) + .await, + ); + if let Err(error) = append_result { + return Err(error); + } + let append_result = append_persisted_events_result( + &mut persisted, + self.decode_and_persist_phoenix_v1_audit_events(&transaction, &instructions) + .await, + ); + if let Err(error) = append_result { + return Err(error); + } + + let decoded_instruction_ids = decoded_instruction_ids_from_persisted_events(&persisted); + let append_result = append_persisted_events_result( + &mut persisted, + self.decode_and_persist_upstream_registry_matches( + &transaction, + &instructions, + &decoded_instruction_ids, + ) + .await, + ); + if let Err(error) = append_result { + return Err(error); + } return Ok(persisted); } @@ -218,9 +252,46 @@ impl DexDecodeService { if let Err(error) = cleanup_result { return Err(error); } + let cleanup_result = self + .delete_replaced_upstream_registry_match( + transaction_id, + instruction_id, + protocol_name, + event_kind, + ) + .await; + if let Err(error) = cleanup_result { + return Err(error); + } return Ok(materialized); } + async fn delete_replaced_upstream_registry_match( + &self, + transaction_id: i64, + instruction_id: i64, + protocol_name: &str, + event_kind: &str, + ) -> Result<(), crate::Error> { + if protocol_name == crate::UPSTREAM_REGISTRY_PROTOCOL_NAME { + return Ok(()); + } + if event_kind == crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND { + return Ok(()); + } + let delete_result = crate::query_dex_decoded_events_delete_by_key( + self.database.as_ref(), + transaction_id, + Some(instruction_id), + crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND, + ) + .await; + match delete_result { + Ok(_) => return Ok(()), + Err(error) => return Err(error), + } + } + async fn delete_replaced_instruction_audit( &self, transaction_id: i64, @@ -248,6 +319,92 @@ impl DexDecodeService { } } + async fn decode_and_persist_upstream_registry_matches( + &self, + transaction: &crate::ChainTransactionDto, + instructions: &[crate::ChainInstructionDto], + already_decoded_instruction_ids: &std::collections::HashSet, + ) -> Result, crate::Error> { + let transaction_id = match transaction.id { + Some(transaction_id) => transaction_id, + None => { + return Err(crate::Error::InvalidState(format!( + "transaction '{}' has no internal id", + transaction.signature + ))); + }, + }; + let decoded_events_result = crate::query_dex_decoded_events_list_by_transaction_id( + self.database.as_ref(), + transaction_id, + ) + .await; + let decoded_events = match decoded_events_result { + Ok(decoded_events) => decoded_events, + Err(error) => return Err(error), + }; + let mut decoded_instruction_ids = already_decoded_instruction_ids.clone(); + for decoded_event in &decoded_events { + let instruction_id = match decoded_event.instruction_id { + Some(instruction_id) => instruction_id, + None => continue, + }; + decoded_instruction_ids.insert(instruction_id); + } + let mut persisted = std::vec::Vec::new(); + for instruction in instructions { + let instruction_id = match instruction.id { + Some(instruction_id) => instruction_id, + None => continue, + }; + if decoded_instruction_ids.contains(&instruction_id) { + continue; + } + let program_id = match instruction.program_id.as_ref() { + Some(program_id) => program_id, + None => continue, + }; + let data_base58 = parse_instruction_data_base58(instruction.data_json.as_deref()); + let registry_match = + crate::upstream_registry_match::upstream_registry_match_instruction_data( + program_id.as_str(), + data_base58.as_deref(), + ); + let registry_match = match registry_match { + Some(registry_match) => registry_match, + None => continue, + }; + let payload = build_upstream_registry_instruction_match_payload( + transaction, + instruction, + ®istry_match, + data_base58.as_deref(), + ); + let persist_result = self + .materialize_named_dex_event( + transaction, + transaction_id, + instruction_id, + crate::UPSTREAM_REGISTRY_PROTOCOL_NAME, + program_id.clone(), + crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND, + None, + None, + None, + None, + None, + payload, + ) + .await; + let persisted_event = match persist_result { + Ok(persisted_event) => persisted_event, + Err(error) => return Err(error), + }; + persisted.push(persisted_event); + } + return Ok(persisted); + } + async fn persist_dexlab_event( &self, transaction: &crate::ChainTransactionDto, @@ -1480,6 +1637,104 @@ impl DexDecodeService { return Ok(persisted); } + async fn persist_openbook_v2_event( + &self, + transaction: &crate::ChainTransactionDto, + decoded_event: &crate::OpenBookV2DecodedEvent, + ) -> Result { + match decoded_event { + crate::OpenBookV2DecodedEvent::Audit(event) => { + return self + .materialize_named_dex_event( + transaction, + event.transaction_id, + event.instruction_id, + "openbook_v2", + event.program_id.clone(), + event.event_kind.as_str(), + None, + event.market_account.clone(), + event.token_a_mint.clone(), + event.token_b_mint.clone(), + None, + event.payload_json.clone(), + ) + .await; + }, + } + } + + async fn decode_and_persist_openbook_v2_audit_events( + &self, + transaction: &crate::ChainTransactionDto, + instructions: &[crate::ChainInstructionDto], + ) -> Result, crate::Error> { + let decoded_result = self.openbook_v2_decoder.decode_transaction(transaction, instructions); + let decoded_events = match decoded_result { + Ok(decoded_events) => decoded_events, + Err(error) => return Err(error), + }; + let mut persisted = std::vec::Vec::new(); + for decoded_event in &decoded_events { + let persist_result = self.persist_openbook_v2_event(transaction, decoded_event).await; + let persisted_event = match persist_result { + Ok(persisted_event) => persisted_event, + Err(error) => return Err(error), + }; + persisted.push(persisted_event); + } + return Ok(persisted); + } + + async fn persist_phoenix_v1_event( + &self, + transaction: &crate::ChainTransactionDto, + decoded_event: &crate::PhoenixV1DecodedEvent, + ) -> Result { + match decoded_event { + crate::PhoenixV1DecodedEvent::Audit(event) => { + return self + .materialize_named_dex_event( + transaction, + event.transaction_id, + event.instruction_id, + "phoenix_v1", + event.program_id.clone(), + event.event_kind.as_str(), + None, + event.market_account.clone(), + event.token_a_mint.clone(), + event.token_b_mint.clone(), + None, + event.payload_json.clone(), + ) + .await; + }, + } + } + + async fn decode_and_persist_phoenix_v1_audit_events( + &self, + transaction: &crate::ChainTransactionDto, + instructions: &[crate::ChainInstructionDto], + ) -> Result, crate::Error> { + let decoded_result = self.phoenix_v1_decoder.decode_transaction(transaction, instructions); + let decoded_events = match decoded_result { + Ok(decoded_events) => decoded_events, + Err(error) => return Err(error), + }; + let mut persisted = std::vec::Vec::new(); + for decoded_event in &decoded_events { + let persist_result = self.persist_phoenix_v1_event(transaction, decoded_event).await; + let persisted_event = match persist_result { + Ok(persisted_event) => persisted_event, + Err(error) => return Err(error), + }; + persisted.push(persisted_event); + } + return Ok(persisted); + } + async fn decode_and_persist_fluxbeam_events( &self, transaction: &crate::ChainTransactionDto, @@ -1964,7 +2219,7 @@ fn build_meteora_instruction_audit_payload( return serde_json::json!({ "decoder": protocol_name, "eventKind": event_kind, - "signature": transaction.signature, + "signature": transaction.signature.clone(), "instructionId": instruction.id, "instructionIndex": instruction.instruction_index, "innerInstructionIndex": instruction.inner_instruction_index, @@ -2023,7 +2278,7 @@ fn build_raydium_instruction_audit_payload( return serde_json::json!({ "decoder": protocol_name, "eventKind": event_kind, - "signature": transaction.signature, + "signature": transaction.signature.clone(), "instructionId": instruction.id, "instructionIndex": instruction.instruction_index, "innerInstructionIndex": instruction.inner_instruction_index, @@ -2073,6 +2328,58 @@ fn candidate_raydium_audit_pool_account( return accounts.get(spec.candidate_pool_account_index).cloned(); } +fn build_upstream_registry_instruction_match_payload( + transaction: &crate::ChainTransactionDto, + instruction: &crate::ChainInstructionDto, + registry_match: &crate::UpstreamRegistryEntryDto, + data_base58: std::option::Option<&str>, +) -> serde_json::Value { + let data_bytes = instruction_data_bytes_from_base58(data_base58); + let data_byte_len = match data_bytes.as_ref() { + Some(data_bytes) => { + let len_result = u64::try_from(data_bytes.len()); + match len_result { + Ok(len) => serde_json::Value::Number(serde_json::Number::from(len)), + Err(_) => serde_json::Value::Null, + } + }, + None => serde_json::Value::Null, + }; + return serde_json::json!({ + "decoder": crate::UPSTREAM_REGISTRY_PROTOCOL_NAME, + "matchKind": "instruction_discriminator", + "signature": transaction.signature.clone(), + "slot": transaction.slot, + "instructionId": instruction.id, + "instructionIndex": instruction.instruction_index, + "innerInstructionIndex": instruction.inner_instruction_index, + "parentInstructionId": instruction.parent_instruction_id, + "stackHeight": instruction.stack_height, + "programId": instruction.program_id.clone(), + "programName": instruction.program_name.clone(), + "accounts": parse_instruction_accounts_value(instruction.accounts_json.as_str()), + "accountCount": parse_instruction_accounts_vec(instruction.accounts_json.as_str()).len(), + "dataBase58": data_base58, + "dataByteLen": data_byte_len, + "upstreamSourceRepo": registry_match.source_repo.clone(), + "upstreamSourcePath": registry_match.source_path.clone(), + "upstreamDecoderCode": registry_match.decoder_code.clone(), + "upstreamProgramFamily": registry_match.program_family.clone(), + "upstreamSurfaceKind": registry_match.surface_kind.clone(), + "upstreamEntryKind": registry_match.entry_kind.clone(), + "upstreamEntryName": registry_match.entry_name.clone(), + "upstreamDiscriminatorHex": registry_match.discriminator_hex.clone(), + "upstreamDiscriminatorLen": registry_match.discriminator_len, + "upstreamProofStatus": registry_match.proof_status.clone(), + "upstreamNotes": registry_match.notes.clone(), + "tradeCandidate": false, + "candleCandidate": false, + "nonTradeUseful": false, + "skipTradeReason": "upstream_git_unverified_registry_match", + "skipCandleReason": "upstream_git_unverified_registry_match" + }); +} + fn parse_instruction_accounts_vec(accounts_json: &str) -> std::vec::Vec { let accounts_result = serde_json::from_str::>(accounts_json); match accounts_result { @@ -2146,6 +2453,20 @@ fn append_persisted_events( } } +fn decoded_instruction_ids_from_persisted_events( + persisted: &[crate::DexDecodedEventDto], +) -> std::collections::HashSet { + let mut decoded_instruction_ids = std::collections::HashSet::::new(); + for decoded_event in persisted { + let instruction_id = match decoded_event.instruction_id { + Some(instruction_id) => instruction_id, + None => continue, + }; + decoded_instruction_ids.insert(instruction_id); + } + return decoded_instruction_ids; +} + fn append_persisted_events_result( target: &mut std::vec::Vec, source_result: Result, crate::Error>, @@ -3223,4 +3544,60 @@ mod tests { ); assert_eq!(super::instruction_audit_event_kind_by_protocol("unknown"), None); } + + #[test] + fn upstream_registry_match_payload_is_never_trade_or_candle_candidate() { + let transaction = crate::ChainTransactionDto::new( + "upstream-registry-test-signature".to_string(), + Some(123), + Some(123456), + Some("test".to_string()), + None, + None, + None, + "{}".to_string(), + ); + let instruction = crate::ChainInstructionDto::new( + 1, + None, + 0, + None, + Some(crate::METEORA_DAMM_V2_PROGRAM_ID.to_string()), + None, + None, + "[]".to_string(), + Some("data".to_string()), + None, + None, + ); + let registry_match = crate::UpstreamRegistryEntryDto { + source_repo: Some("sevenlabs-hq/carbon".to_string()), + source_path: Some("decoders/example.rs".to_string()), + decoder_code: "meteora-damm-v2".to_string(), + program_id: Some(crate::METEORA_DAMM_V2_PROGRAM_ID.to_string()), + program_family: "meteora".to_string(), + surface_kind: "amm".to_string(), + entry_kind: crate::ENTRY_KIND_INSTRUCTION.to_string(), + entry_name: "swap".to_string(), + discriminator_hex: Some("f8c69e91e17587c8".to_string()), + discriminator_len: Some(8), + proof_status: crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED.to_string(), + notes: "test".to_string(), + }; + let payload = super::build_upstream_registry_instruction_match_payload( + &transaction, + &instruction, + ®istry_match, + Some("data"), + ); + assert_eq!(payload.get("tradeCandidate").and_then(serde_json::Value::as_bool), Some(false)); + assert_eq!( + payload.get("candleCandidate").and_then(serde_json::Value::as_bool), + Some(false) + ); + assert_eq!( + payload.get("upstreamProofStatus").and_then(serde_json::Value::as_str), + Some(crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED) + ); + } } diff --git a/kb_lib/src/dex_detect.rs b/kb_lib/src/dex_detect.rs index c6efabf..3ed2feb 100644 --- a/kb_lib/src/dex_detect.rs +++ b/kb_lib/src/dex_detect.rs @@ -84,6 +84,20 @@ impl DexDetectService { Some(route) => route, None => continue, }; + if crate::dex_detection_route::dex_detection_route_requires_full_pool_context(route) + && !crate::dex_detection_route::decoded_event_has_full_pool_context(decoded_event) + { + tracing::trace!( + decoded_event_id = ?decoded_event.id, + protocol_name = %decoded_event.protocol_name, + event_kind = %decoded_event.event_kind, + pool_account = ?decoded_event.pool_account, + token_a_mint = ?decoded_event.token_a_mint, + token_b_mint = ?decoded_event.token_b_mint, + "skipping business-level dex detection for incomplete decoded pool context" + ); + continue; + } let detect_result = match route { crate::dex_detection_route::DexDetectionRoute::RaydiumAmmV4Initialize2Pool => { self.detect_raydium_initialize2_pool(&transaction, decoded_event).await diff --git a/kb_lib/src/dex_detection_route.rs b/kb_lib/src/dex_detection_route.rs index 2fef166..d732fa7 100644 --- a/kb_lib/src/dex_detection_route.rs +++ b/kb_lib/src/dex_detection_route.rs @@ -133,15 +133,122 @@ pub(crate) fn dex_detection_route( } } -fn is_incomplete_pump_swap_decoded_event(decoded_event: &crate::DexDecodedEventDto) -> bool { +/// Returns true when a route materializes a pool and therefore requires +/// pool account plus both token mints before it can run safely. +pub(crate) fn dex_detection_route_requires_full_pool_context( + route: crate::dex_detection_route::DexDetectionRoute, +) -> bool { + match route { + crate::dex_detection_route::DexDetectionRoute::PumpFunCreateV2Token => return false, + crate::dex_detection_route::DexDetectionRoute::SkipIncompletePumpSwapTrade => return false, + _ => return true, + } +} + +/// Returns true when a decoded event has the minimum fields required for +/// deterministic pool, pair and listing materialization. +pub(crate) fn decoded_event_has_full_pool_context( + decoded_event: &crate::DexDecodedEventDto, +) -> bool { if decoded_event.pool_account.is_none() { - return true; + return false; } if decoded_event.token_a_mint.is_none() { - return true; + return false; } if decoded_event.token_b_mint.is_none() { - return true; + return false; + } + return true; +} + +fn is_incomplete_pump_swap_decoded_event(decoded_event: &crate::DexDecodedEventDto) -> bool { + return !crate::dex_detection_route::decoded_event_has_full_pool_context(decoded_event); +} + +#[cfg(test)] +mod tests { + fn make_decoded_event( + protocol_name: &str, + event_kind: &str, + pool_account: std::option::Option<&str>, + token_a_mint: std::option::Option<&str>, + token_b_mint: std::option::Option<&str>, + ) -> crate::DexDecodedEventDto { + return crate::DexDecodedEventDto::new( + 1, + Some(1), + protocol_name.to_string(), + "Program1111111111111111111111111111111111".to_string(), + event_kind.to_string(), + pool_account.map(std::string::ToString::to_string), + None, + token_a_mint.map(std::string::ToString::to_string), + token_b_mint.map(std::string::ToString::to_string), + None, + "{}".to_string(), + ); + } + + #[test] + fn complete_pool_context_requires_pool_and_two_token_mints() { + let complete = make_decoded_event( + "meteora_damm_v2", + "meteora_damm_v2.swap", + Some("Pool111"), + Some("TokenA111"), + Some("TokenB111"), + ); + assert!(crate::dex_detection_route::decoded_event_has_full_pool_context(&complete)); + + let missing_token_a = make_decoded_event( + "meteora_damm_v2", + "meteora_damm_v2.swap", + Some("Pool111"), + None, + Some("TokenB111"), + ); + assert!(!crate::dex_detection_route::decoded_event_has_full_pool_context( + &missing_token_a + )); + } + + #[test] + fn meteora_swap_route_requires_full_pool_context() { + let event = make_decoded_event( + "meteora_damm_v2", + "meteora_damm_v2.swap", + Some("Pool111"), + None, + Some("TokenB111"), + ); + let route_option = crate::dex_detection_route::dex_detection_route(&event); + let route = match route_option { + Some(route) => route, + None => panic!("route must be selected"), + }; + assert!(crate::dex_detection_route::dex_detection_route_requires_full_pool_context( + route + )); + assert!(!crate::dex_detection_route::decoded_event_has_full_pool_context(&event)); + } + + #[test] + fn pump_fun_create_token_route_does_not_require_full_pool_context() { + let event = make_decoded_event( + "pump_fun", + "pump_fun.create_v2_token", + Some("BondingCurve111"), + Some("TokenA111"), + None, + ); + let route_option = crate::dex_detection_route::dex_detection_route(&event); + let route = match route_option { + Some(route) => route, + None => panic!("route must be selected"), + }; + assert!(!crate::dex_detection_route::dex_detection_route_requires_full_pool_context( + route + )); } - return false; } diff --git a/kb_lib/src/dex_event_classification.rs b/kb_lib/src/dex_event_classification.rs index f0469c1..8759667 100644 --- a/kb_lib/src/dex_event_classification.rs +++ b/kb_lib/src/dex_event_classification.rs @@ -266,9 +266,15 @@ pub fn classify_dex_event_actionability_code( /// Returns true for decoded audit-only events retained for corpus analysis. pub fn is_dex_informational_event_kind(event_kind: &str) -> bool { + if event_kind == crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND { + return true; + } if event_kind.contains(".instruction_audit") { return true; } + if event_kind.ends_with("_audit") { + return true; + } if event_kind.contains(".unknown_instruction") { return true; } @@ -1145,4 +1151,38 @@ mod tests { "non_trade_useful" ); } + + #[test] + fn classifies_audit_suffix_events_as_informational() { + assert!(super::is_dex_informational_event_kind("openbook_v2.settle_funds_audit")); + assert_eq!( + super::classify_dex_event_category_code("openbook_v2.settle_funds_audit"), + "informational" + ); + assert_eq!( + super::classify_dex_event_actionability_code( + "openbook_v2.settle_funds_audit", + false, + false, + ), + "informational" + ); + assert!(!super::is_dex_trade_event_kind("openbook_v2.order_place_audit")); + } + + #[test] + fn classifies_upstream_registry_instruction_match_as_informational() { + assert!(super::is_dex_informational_event_kind( + crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND + )); + assert_eq!( + super::classify_dex_event_category_code( + crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND + ), + "informational" + ); + assert!(!super::is_dex_trade_event_kind( + crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND + )); + } } diff --git a/kb_lib/src/dex_support_matrix.rs b/kb_lib/src/dex_support_matrix.rs index 3f519b2..acd743d 100644 --- a/kb_lib/src/dex_support_matrix.rs +++ b/kb_lib/src/dex_support_matrix.rs @@ -249,7 +249,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ }, DexSupportMatrixEntry { code: "raydium_launchlab", - display_name: "Raydium LaunchLab", + display_name: "Raydium LaunchLab / Launchpad", family: "raydium", version: "launchlab", surface_type: "launch", @@ -270,13 +270,13 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ catalog_enabled: false, }, DexSupportMatrixEntry { - code: "raydium_launchpad", - display_name: "Raydium Launchpad", + code: "raydium_liquidity_locking", + display_name: "Raydium Liquidity Locking", family: "raydium", version: "unknown", - surface_type: "launch", - surface_role: "launch_surface", - program_id: None, + surface_type: "liquidity_locking", + surface_role: "to_verify", + program_id: Some(crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -284,11 +284,11 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ materialized: false, trade_candidate: false, candle_candidate: false, - pair_candidate: true, - pool_candidate: true, + pair_candidate: false, + pool_candidate: false, status: "to_verify", confidence: "low", - skip_reason: Some("program_id_to_verify"), + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), catalog_enabled: false, }, DexSupportMatrixEntry { @@ -606,9 +606,9 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "unknown", surface_type: "aggregator", surface_role: "aggregator_router", - program_id: None, + program_id: Some(crate::OKX_DEX_PROGRAM_ID), router_program_id: None, - program_id_status: "unknown", + program_id_status: "to_verify", observed: false, decoded: false, materialized: false, @@ -628,9 +628,9 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "unknown", surface_type: "launch", surface_role: "launch_surface", - program_id: None, + program_id: Some(crate::BOOP_PROGRAM_ID), router_program_id: None, - program_id_status: "unknown", + program_id_status: "to_verify", observed: false, decoded: false, materialized: false, @@ -650,7 +650,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "launch", surface_role: "launch_surface", - program_id: Some("MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG"), + program_id: Some(crate::MOONSHOT_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -892,9 +892,9 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "unknown", surface_type: "launch", surface_role: "launch_surface", - program_id: None, + program_id: Some(crate::HEAVEN_PROGRAM_ID), router_program_id: None, - program_id_status: "unknown", + program_id_status: "to_verify", observed: false, decoded: false, materialized: false, @@ -907,6 +907,493 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ skip_reason: Some("program_id_to_verify"), catalog_enabled: false, }, + // Carbon-backed discovery surfaces added for 0.7.47. These entries expose + // program ids for Demo3 targeting while keeping all business support disabled + // until a dedicated 0.7.47/0.7.48 corpus validates each surface. + DexSupportMatrixEntry { + code: "gavel", + display_name: "Gavel", + family: "gavel", + version: "unknown", + surface_type: "auction", + surface_role: "to_verify", + program_id: Some(crate::GAVEL_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "pump_fees", + display_name: "Pump Fees", + family: "pump", + version: "fee_program", + surface_type: "fee_program", + surface_role: "to_verify", + program_id: Some(crate::PUMP_FEES_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "meteora_pools", + display_name: "Meteora Pools", + family: "meteora", + version: "pools", + surface_type: "AMM", + surface_role: "dex_effective", + program_id: None, + router_program_id: None, + program_id_status: "alias_of_meteora_damm_v1", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: true, + pool_candidate: true, + status: "to_verify", + confidence: "low", + skip_reason: Some("program_id_alias_held_by_meteora_damm_v1"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "dflow_aggregator_v4", + display_name: "DFlow Aggregator v4", + family: "dflow", + version: "v4", + surface_type: "aggregator", + surface_role: "aggregator_router", + program_id: Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "drift_v2", + display_name: "Drift v2", + family: "drift", + version: "v2", + surface_type: "perps", + surface_role: "to_verify", + program_id: Some(crate::DRIFT_V2_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "jupiter_swap", + display_name: "Jupiter Swap", + family: "jupiter", + version: "swap", + surface_type: "aggregator", + surface_role: "aggregator_router", + program_id: Some(crate::JUPITER_SWAP_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "jupiter_dca", + display_name: "Jupiter DCA", + family: "jupiter", + version: "dca", + surface_type: "dca", + surface_role: "aggregator_router", + program_id: Some(crate::JUPITER_DCA_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "jupiter_limit_order", + display_name: "Jupiter Limit Order", + family: "jupiter", + version: "limit_order", + surface_type: "limit_order", + surface_role: "aggregator_router", + program_id: Some(crate::JUPITER_LIMIT_ORDER_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "jupiter_limit_order_2", + display_name: "Jupiter Limit Order 2", + family: "jupiter", + version: "limit_order_2", + surface_type: "limit_order", + surface_role: "aggregator_router", + program_id: Some(crate::JUPITER_LIMIT_ORDER_2_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "jupiter_perpetuals", + display_name: "Jupiter Perpetuals", + family: "jupiter", + version: "perpetuals", + surface_type: "perps", + surface_role: "to_verify", + program_id: Some(crate::JUPITER_PERPETUALS_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "jupiter_lend", + display_name: "Jupiter Lend", + family: "jupiter", + version: "lend", + surface_type: "lending", + surface_role: "to_verify", + program_id: Some(crate::JUPITER_LEND_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "kamino_lending", + display_name: "Kamino Lending", + family: "kamino", + version: "lending", + surface_type: "lending", + surface_role: "to_verify", + program_id: Some(crate::KAMINO_LENDING_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "kamino_vault", + display_name: "Kamino Vault", + family: "kamino", + version: "vault", + surface_type: "vault", + surface_role: "to_verify", + program_id: Some(crate::KAMINO_VAULT_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "kamino_farms", + display_name: "Kamino Farms", + family: "kamino", + version: "farms", + surface_type: "farms", + surface_role: "to_verify", + program_id: Some(crate::KAMINO_FARMS_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "kamino_limit_order", + display_name: "Kamino Limit Order", + family: "kamino", + version: "limit_order", + surface_type: "limit_order", + surface_role: "to_verify", + program_id: Some(crate::KAMINO_LIMIT_ORDER_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "marginfi_v2", + display_name: "Marginfi v2", + family: "marginfi", + version: "v2", + surface_type: "lending", + surface_role: "to_verify", + program_id: Some(crate::MARGINFI_V2_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "onchain_labs_dex_v1", + display_name: "Onchain Labs DEX v1", + family: "onchain_labs", + version: "v1", + surface_type: "AMM", + surface_role: "dex_effective", + program_id: None, + router_program_id: None, + program_id_status: "alias_of_okx_dex", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("program_id_alias_held_by_okx_dex"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "onchain_labs_dex_v2", + display_name: "Onchain Labs DEX v2", + family: "onchain_labs", + version: "v2", + surface_type: "AMM", + surface_role: "dex_effective", + program_id: Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "pancake_swap", + display_name: "Pancake Swap", + family: "pancake", + version: "unknown", + surface_type: "AMM", + surface_role: "dex_effective", + program_id: Some(crate::PANCAKE_SWAP_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "vertigo", + display_name: "Vertigo", + family: "vertigo", + version: "unknown", + surface_type: "AMM", + surface_role: "dex_effective", + program_id: Some(crate::VERTIGO_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "virtuals", + display_name: "Virtuals", + family: "virtuals", + version: "unknown", + surface_type: "launch", + surface_role: "launch_surface", + program_id: Some(crate::VIRTUALS_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "wavebreak", + display_name: "Wavebreak", + family: "wavebreak", + version: "unknown", + surface_type: "AMM", + surface_role: "dex_effective", + program_id: Some(crate::WAVEBREAK_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("upstream_git_program_id_requires_local_corpus_verification"), + catalog_enabled: false, + }, // Historical program ids imported from the legacy Python entities.py list. // These entries are intentionally not treated as verified support: they exist so // Demo3 can target signatures by program id while corpus validation remains strict. @@ -1027,7 +1514,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "unknown", surface_role: "to_verify", - program_id: Some("2wT8Yq49kHgDzXuPxZSaeLaH1qbmGXtEyPy64bL7aD3c"), + program_id: Some(crate::LIFINITY_AMM_V2_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -1115,7 +1602,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "unknown", surface_role: "to_verify", - program_id: Some("PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY"), + program_id: Some(crate::PHOENIX_V1_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -1174,28 +1661,6 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), catalog_enabled: false, }, - DexSupportMatrixEntry { - code: "openbook", - display_name: "OpenBook", - family: "openbook", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, DexSupportMatrixEntry { code: "openbook_v2", display_name: "OpenBook V2", @@ -1203,7 +1668,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "unknown", surface_role: "to_verify", - program_id: Some("opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb"), + program_id: Some(crate::OPENBOOK_V2_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -1291,7 +1756,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "unknown", surface_role: "to_verify", - program_id: Some("swapNyd8XiQwJ6ianp9snpu4brUqFxadzvHebnAXjJZ"), + program_id: Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -1313,29 +1778,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "unknown", surface_role: "to_verify", - program_id: Some("swapFpHZwjELNnjvThjajtiVmkz3yPQEHjLtka2fwHW"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, - DexSupportMatrixEntry { - code: "perps", - display_name: "Perps", - family: "perps", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu"), + program_id: Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -1489,7 +1932,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "unknown", surface_role: "to_verify", - program_id: Some("BSwp6bEBihVLdqJRKGgzjcGLHkcTuzmSo1TQkHepzH8p"), + program_id: Some(crate::BONKSWAP_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -1614,94 +2057,6 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), catalog_enabled: false, }, - DexSupportMatrixEntry { - code: "raydium_legacy_v2", - display_name: "Raydium Legacy V2", - family: "raydium", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("27haf8L6oxUeXrHrgEgsexjSY5hbVUWEmvv9Nyxg8vQv"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, - DexSupportMatrixEntry { - code: "raydium_legacy_v3", - display_name: "Raydium Legacy V3", - family: "raydium", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("7quYqsZdpWSZ3qgDextersDqoKjZy7aCgwHBBfRb7KPt"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, - DexSupportMatrixEntry { - code: "serum_v3", - display_name: "Serum V3", - family: "serum", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, - DexSupportMatrixEntry { - code: "mango_private_pools", - display_name: "Mango Markets Private Pools", - family: "mango", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("AtdP2iyfh6xBGwVZzHvY73E7uKKkZBTH2siHh3ZuEf1P"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, DexSupportMatrixEntry { code: "marinade_liquid_staking", display_name: "Marinade Liquid Staking", @@ -1709,29 +2064,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ version: "historical_entities_py", surface_type: "unknown", surface_role: "to_verify", - program_id: Some("MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, - DexSupportMatrixEntry { - code: "step_finance_pools", - display_name: "Step Finance Pools", - family: "step", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT"), + program_id: Some(crate::MARINADE_FINANCE_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -1768,50 +2101,6 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), catalog_enabled: false, }, - DexSupportMatrixEntry { - code: "cropper_legacy", - display_name: "Cropper Finance Legacy", - family: "cropper", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("CyZuD7RPDcrqCGbNvzrNVs1zpCQehqp7SuXB7rdFKSzo"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, - DexSupportMatrixEntry { - code: "dexlab_beta", - display_name: "Dexlab Beta", - family: "dexlab", - version: "historical_entities_py", - surface_type: "unknown", - surface_role: "to_verify", - program_id: Some("9qvG1zP8ZzY1sTnExx7mkyxhW1063YHVYZxMYz2HkM4m"), - router_program_id: None, - program_id_status: "to_verify", - observed: false, - decoded: false, - materialized: false, - trade_candidate: false, - candle_candidate: false, - pair_candidate: false, - pool_candidate: false, - status: "to_verify", - confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), - catalog_enabled: false, - }, DexSupportMatrixEntry { code: "marinade_governance", display_name: "Marinade Governance", @@ -2011,13 +2300,13 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ catalog_enabled: false, }, DexSupportMatrixEntry { - code: "swab_finance_beta", - display_name: "SWAB Finance Beta", - family: "swab", - version: "historical_entities_py", - surface_type: "unknown", + code: "goosefx_v1", + display_name: "GooseFX V1", + family: "goosefx", + version: "v1", + surface_type: "AMM", surface_role: "to_verify", - program_id: Some("SWABxNGyxEBVoNRGn6RvYBt5UqercSE5PBHuJeYXYHq"), + program_id: Some(crate::GOOSEFX_V1_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -2029,17 +2318,17 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ pool_candidate: false, status: "to_verify", confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), catalog_enabled: false, }, DexSupportMatrixEntry { - code: "craft_early", - display_name: "CRAFT Early", - family: "craft", - version: "historical_entities_py", - surface_type: "unknown", + code: "obric_v2", + display_name: "Obric V2", + family: "obric", + version: "v2", + surface_type: "AMM", surface_role: "to_verify", - program_id: Some("CrAFTUv7zKXBaS5471aBiARBu6x7nP4rDzr8xwBewbr1"), + program_id: Some(crate::OBRIC_V2_PROGRAM_ID), router_program_id: None, program_id_status: "to_verify", observed: false, @@ -2051,7 +2340,315 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[ pool_candidate: false, status: "to_verify", confidence: "low", - skip_reason: Some("historical_entities_py_program_id_requires_corpus_verification"), + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "ondo_global_market", + display_name: "Ondo Global Market", + family: "ondo", + version: "global_market", + surface_type: "unknown", + surface_role: "to_verify", + program_id: Some(crate::ONDO_GLOBAL_MARKET_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "scorch", + display_name: "Scorch", + family: "scorch", + version: "unknown", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::SCORCH_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "zerofi", + display_name: "ZeroFi", + family: "zerofi", + version: "unknown", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::ZEROFI_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "manifest_clob", + display_name: "Manifest CLOB", + family: "manifest", + version: "clob", + surface_type: "orderbook", + surface_role: "to_verify", + program_id: Some(crate::MANIFEST_CLOB_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "alphaq", + display_name: "AlphaQ", + family: "alphaq", + version: "unknown", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::ALPHAQ_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "goonfi", + display_name: "Goonfi", + family: "goonfi", + version: "v1", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::GOONFI_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "goonfi_v2", + display_name: "Goonfi V2", + family: "goonfi", + version: "v2", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::GOONFI_V2_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "byreal", + display_name: "Byreal", + family: "byreal", + version: "unknown", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::BYREAL_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "bisonfi", + display_name: "BisonFi", + family: "bisonfi", + version: "unknown", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::BISONFI_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "fusionamm", + display_name: "FusionAMM", + family: "fusion", + version: "amm", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::FUSIONAMM_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "woofi", + display_name: "Woofi", + family: "woofi", + version: "unknown", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::WOOFI_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "aquifer", + display_name: "Aquifer", + family: "aquifer", + version: "unknown", + surface_type: "unknown", + surface_role: "to_verify", + program_id: Some(crate::AQUIFER_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "humidifi", + display_name: "Humidifi", + family: "humidifi", + version: "unknown", + surface_type: "unknown", + surface_role: "to_verify", + program_id: Some(crate::HUMIDIFI_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), + catalog_enabled: false, + }, + DexSupportMatrixEntry { + code: "solfi_v2", + display_name: "SolFi V2", + family: "solfi", + version: "v2", + surface_type: "AMM", + surface_role: "to_verify", + program_id: Some(crate::SOLFI_V2_PROGRAM_ID), + router_program_id: None, + program_id_status: "to_verify", + observed: false, + decoded: false, + materialized: false, + trade_candidate: false, + candle_candidate: false, + pair_candidate: false, + pool_candidate: false, + status: "to_verify", + confidence: "low", + skip_reason: Some("vybe_supported_dex_amm_requires_local_corpus_and_decoder_source"), catalog_enabled: false, }, ]; @@ -2103,6 +2700,34 @@ pub fn dex_support_matrix_entry_by_program_id( #[cfg(test)] mod tests { + use std::str::FromStr; + + use super::DEX_SUPPORT_MATRIX_ENTRIES; + + #[test] + fn matrix_program_ids_are_valid_solana_pubkeys() { + for entry in DEX_SUPPORT_MATRIX_ENTRIES { + let Some(program_id) = entry.program_id else { + continue; + }; + if let Err(error) = solana_sdk::pubkey::Pubkey::from_str(program_id) { + panic!( + "matrix entry '{}' has invalid Solana program id '{}': {}", + entry.code, program_id, error + ); + } + let Some(router_program_id) = entry.router_program_id else { + continue; + }; + if let Err(error) = solana_sdk::pubkey::Pubkey::from_str(router_program_id) { + panic!( + "matrix entry '{}' has invalid Solana router program id '{}': {}", + entry.code, router_program_id, error + ); + } + } + } + #[test] fn matrix_contains_required_0_7_39_dex_first_entries() { let codes = [ @@ -2112,7 +2737,7 @@ mod tests { "raydium_clmm", "raydium_amm_v4", "raydium_launchlab", - "raydium_launchpad", + "raydium_liquidity_locking", "meteora_dlmm", "meteora_dlc", "meteora_damm_v1", @@ -2141,17 +2766,13 @@ mod tests { #[test] fn matrix_does_not_invent_program_ids_for_unverified_planned_surfaces() { let codes = [ - "raydium_launchpad", "bags", "letsbonk", "bonk", "bonk_fun", - "okx_dex", - "boop_fun", "believe", "moonit", "launchbeam", - "heaven", "metadao", ]; for code in codes { @@ -2216,7 +2837,6 @@ mod tests { let codes = [ "pump_fun", "raydium_launchlab", - "raydium_launchpad", "letsbonk", "bonk_fun", "bags", @@ -2244,7 +2864,6 @@ mod tests { fn matrix_keeps_0_7_39_deferred_surfaces_non_trade_materialized() { let codes = [ "raydium_launchlab", - "raydium_launchpad", "letsbonk", "bonk_fun", "bags", @@ -2313,6 +2932,11 @@ mod tests { let candidates = [ ("printr", crate::PRINTR_PROGRAM_ID), ("zora", crate::ZORA_PROGRAM_ID), + ("raydium_liquidity_locking", crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), + ("okx_dex", crate::OKX_DEX_PROGRAM_ID), + ("boop_fun", crate::BOOP_PROGRAM_ID), + ("heaven", crate::HEAVEN_PROGRAM_ID), + ("bonkswap", crate::BONKSWAP_PROGRAM_ID), ("metadao_launchpad_v0_7_0", crate::METADAO_LAUNCHPAD_V0_7_0_PROGRAM_ID), ("metadao_bid_wall_v0_7_0", crate::METADAO_BID_WALL_V0_7_0_PROGRAM_ID), ("metadao_futarchy_v0_6_0", crate::METADAO_FUTARCHY_V0_6_0_PROGRAM_ID), @@ -2323,7 +2947,14 @@ mod tests { Some(entry) => entry, None => panic!("missing matrix entry for {}", code), }; - assert_eq!(entry.surface_role, "to_verify"); + assert!( + entry.surface_role == "to_verify" + || entry.surface_role == "launch_surface" + || entry.surface_role == "aggregator_router", + "{} has unexpected candidate role {}", + code, + entry.surface_role + ); assert_eq!(entry.program_id, Some(expected_program_id)); assert_eq!(entry.program_id_status, "to_verify"); assert!(!entry.decoded); @@ -2366,6 +2997,86 @@ mod tests { } } + #[test] + fn matrix_exposes_vybe_supported_program_ids_as_unverified_targets() { + let candidates = [ + ("goosefx_v1", crate::GOOSEFX_V1_PROGRAM_ID), + ("obric_v2", crate::OBRIC_V2_PROGRAM_ID), + ("ondo_global_market", crate::ONDO_GLOBAL_MARKET_PROGRAM_ID), + ("scorch", crate::SCORCH_PROGRAM_ID), + ("zerofi", crate::ZEROFI_PROGRAM_ID), + ("manifest_clob", crate::MANIFEST_CLOB_PROGRAM_ID), + ("alphaq", crate::ALPHAQ_PROGRAM_ID), + ("goonfi", crate::GOONFI_PROGRAM_ID), + ("goonfi_v2", crate::GOONFI_V2_PROGRAM_ID), + ("byreal", crate::BYREAL_PROGRAM_ID), + ("bisonfi", crate::BISONFI_PROGRAM_ID), + ("fusionamm", crate::FUSIONAMM_PROGRAM_ID), + ("woofi", crate::WOOFI_PROGRAM_ID), + ("aquifer", crate::AQUIFER_PROGRAM_ID), + ("humidifi", crate::HUMIDIFI_PROGRAM_ID), + ("solfi_v2", crate::SOLFI_V2_PROGRAM_ID), + ]; + for (code, expected_program_id) in candidates { + let entry = match crate::dex_support_matrix_entry_by_code(code) { + Some(entry) => entry, + None => panic!("missing Vybe-backed matrix entry for {}", code), + }; + assert_eq!(entry.program_id, Some(expected_program_id)); + assert_eq!(entry.program_id_status, "to_verify"); + assert_eq!(entry.status, "to_verify"); + assert!(!entry.decoded); + assert!(!entry.materialized); + assert!(!entry.trade_candidate); + assert!(!entry.candle_candidate); + assert!(!entry.catalog_enabled); + } + } + + #[test] + fn matrix_has_no_duplicate_codes_or_program_ids() { + let mut seen_codes = std::collections::BTreeSet::new(); + let mut seen_program_ids = std::collections::BTreeMap::<&str, &str>::new(); + for entry in DEX_SUPPORT_MATRIX_ENTRIES { + assert!(seen_codes.insert(entry.code), "duplicate matrix code {}", entry.code); + if let Some(program_id) = entry.program_id { + match seen_program_ids.insert(program_id, entry.code) { + Some(previous_code) => panic!( + "duplicate matrix program_id {} for {} and {}", + program_id, previous_code, entry.code + ), + None => (), + } + } + } + } + + #[test] + fn matrix_keeps_remaining_alias_surfaces_without_duplicate_program_ids() { + let aliases = [ + ( + "meteora_pools", + "alias_of_meteora_damm_v1", + "program_id_alias_held_by_meteora_damm_v1", + ), + ("onchain_labs_dex_v1", "alias_of_okx_dex", "program_id_alias_held_by_okx_dex"), + ]; + for (code, expected_status, expected_skip_reason) in aliases { + let entry = match crate::dex_support_matrix_entry_by_code(code) { + Some(entry) => entry, + None => panic!("missing alias matrix entry for {}", code), + }; + assert_eq!(entry.program_id, None); + assert_eq!(entry.program_id_status, expected_status); + assert_eq!(entry.skip_reason, Some(expected_skip_reason)); + assert!(!entry.decoded); + assert!(!entry.materialized); + assert!(!entry.trade_candidate); + assert!(!entry.candle_candidate); + assert!(!entry.catalog_enabled); + } + } + #[test] fn matrix_dto_preserves_core_fields() { let entry = match crate::dex_support_matrix_entry_by_code("pump_swap") { diff --git a/kb_lib/src/launch_origin.rs b/kb_lib/src/launch_origin.rs index 6d5b8ed..809ad94 100644 --- a/kb_lib/src/launch_origin.rs +++ b/kb_lib/src/launch_origin.rs @@ -13,13 +13,7 @@ struct BuiltinLaunchSurfaceSpec { const BUILTIN_LAUNCH_SURFACE_SPECS: &[BuiltinLaunchSurfaceSpec] = &[ BuiltinLaunchSurfaceSpec { code: "raydium_launchlab", - name: "Raydium LaunchLab", - protocol_family: "raydium", - enabled: true, - }, - BuiltinLaunchSurfaceSpec { - code: "raydium_launchpad", - name: "Raydium Launchpad", + name: "Raydium LaunchLab / Launchpad", protocol_family: "raydium", enabled: true, }, @@ -988,10 +982,9 @@ mod tests { Ok(surface_ids) => surface_ids, Err(error) => panic!("target launch surfaces must seed: {}", error), }; - assert_eq!(surface_ids.len(), 10); + assert_eq!(surface_ids.len(), 9); let required_codes = [ "raydium_launchlab", - "raydium_launchpad", "letsbonk", "bonk_fun", "bags", diff --git a/kb_lib/src/lib.rs b/kb_lib/src/lib.rs index 05e1a7d..03df383 100644 --- a/kb_lib/src/lib.rs +++ b/kb_lib/src/lib.rs @@ -111,6 +111,14 @@ mod tx_model; mod tx_resolution; /// Shared generic types for `kb_lib`. mod types; +/// Upstream Git registry service facade. +mod upstream_registry; +/// Static upstream Git registry bootstrap data. +mod upstream_registry_generated; +/// Upstream Git registry matching helpers. +mod upstream_registry_match; +/// Upstream Git registry DTOs and static entry types. +mod upstream_registry_types; /// Wallet-holding observation service. mod wallet_holding_observation; /// Wallet-observation service. @@ -147,19 +155,37 @@ pub use config::WsEndpointConfig; /// Address Lookup Table program identifier. ("AddressLookupTab1e1111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::address_lookup_table::ID pub use constants::ADDRESS_LOOKUP_TABLE_PROGRAM_ID; +/// AlphaQ program id from Vybe supported DEX/AMM documentation. +pub use constants::ALPHAQ_PROGRAM_ID; +/// Aquifer program id from Vybe supported DEX/AMM documentation. +pub use constants::AQUIFER_PROGRAM_ID; /// Arbitrage Bot (6MWVT) / Arbitrage or Sandwich Bot. ("6MWVTis8rmmk6Vt9zmAJJbmb3VuLpzoQ1aHH4N6wQEGh"). pub use constants::ARBITRAGE_BOT_6MWVT_PROGRAM_ID; /// Associated Token Account program identifier. ("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"). /// @see solana_sdk::pubkey::Pubkey = spl_associated_token_account_interface::program::ID pub use constants::ASSOCIATED_TOKEN_PROGRAM_ID; +/// BisonFi program id from Vybe supported DEX/AMM documentation. +pub use constants::BISONFI_PROGRAM_ID; /// Canonical Bonk token mint identifier. pub use constants::BONK_MINT_ID; +/// Bonkswap program id extracted from upstream Git decoder source. +pub use constants::BONKSWAP_PROGRAM_ID; +/// Boop program id extracted from upstream Git decoder source. +pub use constants::BOOP_PROGRAM_ID; /// BPF Loader program identifier. ("BPFLoader1111111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::bpf_loader_deprecated::ID pub use constants::BPF_LOADER_DEPRECATED_PROGRAM_ID; /// BPF Loader program identifier. ("BPFLoaderUpgradeab1e11111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::bpf_loader_upgradeable::ID pub use constants::BPF_LOADER_UPGRADEABLE_PROGRAM_ID; +/// Bubblegum program id extracted from upstream Git decoder source. +pub use constants::BUBBLEGUM_PROGRAM_ID; +/// Byreal program id from Vybe supported DEX/AMM documentation. +pub use constants::BYREAL_PROGRAM_ID; +/// Circle Message Transmitter v2 program id extracted from upstream Git decoder source. +pub use constants::CIRCLE_MESSAGE_TRANSMITTER_V2_PROGRAM_ID; +/// Circle Token Messenger v2 program id extracted from upstream Git decoder source. +pub use constants::CIRCLE_TOKEN_MESSENGER_V2_PROGRAM_ID; /// Compute Budget program identifier. ("ComputeBudget111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::compute_budget::ID pub use constants::COMPUTE_BUDGET_PROGRAM_ID; @@ -168,6 +194,10 @@ pub use constants::COMPUTE_BUDGET_PROGRAM_ID; pub use constants::CONFIG_PROGRAM_ID; /// DexLab Swap/Pool program id. ("DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N"). pub use constants::DEXLAB_PROGRAM_ID; +/// DFlow Aggregator v4 program id extracted from upstream Git decoder source. +pub use constants::DFLOW_AGGREGATOR_V4_PROGRAM_ID; +/// Drift v2 program id extracted from upstream Git decoder source. +pub use constants::DRIFT_V2_PROGRAM_ID; /// ED25519 program identifier. ("Ed25519SigVerify111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::ed25519_program::ID pub use constants::ED25519_PROGRAM_ID; @@ -176,14 +206,58 @@ pub use constants::ED25519_PROGRAM_ID; pub use constants::FEATURE_PROGRAM_ID; /// FluxBeam program id. ("FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X"). pub use constants::FLUXBEAM_PROGRAM_ID; +/// FusionAMM program id from Vybe supported DEX/AMM documentation. +pub use constants::FUSIONAMM_PROGRAM_ID; +/// Gavel program id extracted from upstream Git decoder source. +pub use constants::GAVEL_PROGRAM_ID; +/// Goonfi program id from Vybe supported DEX/AMM documentation. +pub use constants::GOONFI_PROGRAM_ID; +/// Goonfi v2 program id from Vybe supported DEX/AMM documentation. +pub use constants::GOONFI_V2_PROGRAM_ID; +/// GooseFX v1 program id from Vybe supported DEX/AMM documentation. +pub use constants::GOOSEFX_V1_PROGRAM_ID; +/// Heaven program id extracted from upstream Git decoder source. +pub use constants::HEAVEN_PROGRAM_ID; +/// Humidifi program id from Vybe supported DEX/AMM documentation. +pub use constants::HUMIDIFI_PROGRAM_ID; /// Incinerator program identifier. ("1nc1nerator11111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::incinerator::ID pub use constants::INCINERATOR_PROGRAM_ID; /// Canonical Jupiter governance token mint identifier. pub use constants::JUP_MINT_ID; +/// Jupiter DCA program id extracted from upstream Git decoder source. +pub use constants::JUPITER_DCA_PROGRAM_ID; +/// Jupiter Lend program id extracted from upstream Git decoder source. +pub use constants::JUPITER_LEND_PROGRAM_ID; +/// Jupiter Limit Order 2 program id extracted from upstream Git decoder source. +pub use constants::JUPITER_LIMIT_ORDER_2_PROGRAM_ID; +/// Jupiter Limit Order program id extracted from upstream Git decoder source. +pub use constants::JUPITER_LIMIT_ORDER_PROGRAM_ID; +/// Jupiter Perpetuals program id extracted from upstream Git decoder source. +pub use constants::JUPITER_PERPETUALS_PROGRAM_ID; +/// Jupiter Swap program id extracted from upstream Git decoder source. +pub use constants::JUPITER_SWAP_PROGRAM_ID; +/// Kamino Farms program id extracted from upstream Git decoder source. +pub use constants::KAMINO_FARMS_PROGRAM_ID; +/// Kamino Lending program id extracted from upstream Git decoder source. +pub use constants::KAMINO_LENDING_PROGRAM_ID; +/// Kamino Limit Order program id extracted from upstream Git decoder source. +pub use constants::KAMINO_LIMIT_ORDER_PROGRAM_ID; +/// Kamino Vault program id extracted from upstream Git decoder source. +pub use constants::KAMINO_VAULT_PROGRAM_ID; +/// Lifinity AMM v2 program id extracted from upstream Git decoder source. +pub use constants::LIFINITY_AMM_V2_PROGRAM_ID; /// Loader V4 program identifier. ("LoaderV411111111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::loader_v4::ID pub use constants::LOADER_V4_PROGRAM_ID; +/// Manifest CLOB program id from Vybe supported DEX/AMM documentation. +pub use constants::MANIFEST_CLOB_PROGRAM_ID; +/// Marginfi v2 program id extracted from upstream Git decoder source. +pub use constants::MARGINFI_V2_PROGRAM_ID; +/// Marinade Finance program id extracted from upstream Git decoder source. +pub use constants::MARINADE_FINANCE_PROGRAM_ID; +/// SPL Memo program id. +pub use constants::MEMO_PROGRAM_ID; /// MetaDAO AMM v0.5.0 program id. pub use constants::METADAO_AMM_V0_5_0_PROGRAM_ID; /// MetaDAO Bid Wall v0.7.0 program id. @@ -192,12 +266,6 @@ pub use constants::METADAO_BID_WALL_V0_7_0_PROGRAM_ID; pub use constants::METADAO_FUTARCHY_V0_6_0_PROGRAM_ID; /// MetaDAO Launchpad v0.7.0 program id. pub use constants::METADAO_LAUNCHPAD_V0_7_0_PROGRAM_ID; -/// MetaDAO META active token mint identifier. -pub use constants::METADAO_META_MINT_ID; -/// MetaDAO METAC legacy token mint identifier. -pub use constants::METADAO_METAC_LEGACY_MINT_ID; -/// MetaDAO-linked P2P token mint candidate. -pub use constants::METADAO_P2P_MINT_ID; /// Meteora DAMM v1 program id. ("Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB"). pub use constants::METEORA_DAMM_V1_PROGRAM_ID; /// Meteora DAMM v2 program id. ("cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"). @@ -206,13 +274,39 @@ pub use constants::METEORA_DAMM_V2_PROGRAM_ID; pub use constants::METEORA_DBC_PROGRAM_ID; /// Meteora DLMM program id. ("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo"). pub use constants::METEORA_DLMM_PROGRAM_ID; +/// Meteora Vault program id extracted from upstream Git decoder source. +pub use constants::METEORA_VAULT_PROGRAM_ID; +/// Moonshot program id extracted from upstream Git decoder source. +pub use constants::MOONSHOT_PROGRAM_ID; +/// MPL Core program id extracted from upstream Git decoder source. +pub use constants::MPL_CORE_PROGRAM_ID; +/// MPL Token Metadata program id extracted from upstream Git decoder source. +pub use constants::MPL_TOKEN_METADATA_PROGRAM_ID; +/// Solana Name Service program id extracted from upstream Git decoder source. +pub use constants::NAME_SERVICE_PROGRAM_ID; /// Native Loader program identifier. ("NativeLoader1111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::native_loader::ID pub use constants::NATIVE_LOADER_PROGRAM_ID; +/// Obric v2 program id from Vybe supported DEX/AMM documentation. +pub use constants::OBRIC_V2_PROGRAM_ID; +/// OKX DEX program id extracted from upstream Git decoder source. +pub use constants::OKX_DEX_PROGRAM_ID; +/// Onchain Labs DEX v2 program id extracted from upstream Git decoder source. +pub use constants::ONCHAIN_LABS_DEX_V2_PROGRAM_ID; +/// Ondo Global Market program id from Vybe supported DEX/AMM documentation. +pub use constants::ONDO_GLOBAL_MARKET_PROGRAM_ID; +/// OpenBook v2 program id extracted from upstream Git decoder source. +pub use constants::OPENBOOK_V2_PROGRAM_ID; /// Orca Whirlpools program id. ("whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"). pub use constants::ORCA_WHIRLPOOLS_PROGRAM_ID; +/// Pancake Swap program id extracted from upstream Git decoder source. +pub use constants::PANCAKE_SWAP_PROGRAM_ID; +/// Phoenix v1 program id extracted from upstream Git decoder source. +pub use constants::PHOENIX_V1_PROGRAM_ID; /// Printr program id candidate observed on Solscan. pub use constants::PRINTR_PROGRAM_ID; +/// Pump Fees program id extracted from upstream Git decoder source. +pub use constants::PUMP_FEES_PROGRAM_ID; /// Pump.fun program id. ("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"). pub use constants::PUMP_FUN_PROGRAM_ID; /// PumpSwap / PumpAMM program id. ("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"). @@ -227,28 +321,44 @@ pub use constants::RAYDIUM_AMM_V4_PROGRAM_ID; pub use constants::RAYDIUM_CLMM_PROGRAM_ID; /// Raydium CPMM mainnet program id. ("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"). pub use constants::RAYDIUM_CPMM_PROGRAM_ID; -/// Raydium LaunchLab program id. ("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj"). +/// Raydium LaunchLab / Launchpad program id. ("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj"). pub use constants::RAYDIUM_LAUNCHLAB_PROGRAM_ID; +/// Raydium Liquidity Locking program id extracted from upstream Git decoder source. +pub use constants::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID; /// Raydium Stable Swap AMM program id, deprecated. ("5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h"). pub use constants::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID; +/// Scorch program id from Vybe supported DEX/AMM documentation. +pub use constants::SCORCH_PROGRAM_ID; /// Secp256k1 program identifier. ("KeccakSecp256k11111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::secp256k1_program::ID pub use constants::SECP256K1_PROGRAM_ID; /// Secp256r1 program identifier. ("Secp256r1SigVerify1111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::secp256r1_program::ID pub use constants::SECP256R1_PROGRAM_ID; +/// Sharky program id extracted from upstream Git decoder source. +pub use constants::SHARKY_PROGRAM_ID; +/// Solayer Restaking program id extracted from upstream Git decoder source. +pub use constants::SOLAYER_RESTAKING_PROGRAM_ID; +/// SolFi v2 program id from Vybe supported DEX/AMM documentation. +pub use constants::SOLFI_V2_PROGRAM_ID; /// SPL Token-2022 program identifier. ("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"). /// @see solana_sdk::pubkey::Pubkey = spl_token_2022_interface::ID pub use constants::SPL_TOKEN_2022_PROGRAM_ID; /// SPL Token program identifier. ("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"). /// @see solana_sdk::pubkey::Pubkey = spl_token_interface::ID pub use constants::SPL_TOKEN_PROGRAM_ID; +/// Stabble stable-swap program id extracted from upstream Git decoder source. +pub use constants::STABBLE_STABLE_SWAP_PROGRAM_ID; +/// Stabble weighted-swap program id extracted from upstream Git decoder source. +pub use constants::STABBLE_WEIGHTED_SWAP_PROGRAM_ID; /// Stake Config program identifier. ("StakeConfig11111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::stake::config::ID pub use constants::STAKE_CONFIG_PROGRAM_ID; /// Stake program identifier. ("Stake11111111111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::stake::ID pub use constants::STAKE_PROGRAM_ID; +/// Swig program id extracted from upstream Git decoder source. +pub use constants::SWIG_PROGRAM_ID; /// System program identifier. ("11111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::system_program::ID pub use constants::SYSTEM_PROGRAM_ID; @@ -295,12 +405,24 @@ pub use constants::SYSVAR_STAKE_HISTORY_PROGRAM_ID; pub use constants::USDC_MINT_ID; /// Canonical Solana USDT mint identifier. pub use constants::USDT_MINT_ID; +/// Vertigo program id extracted from upstream Git decoder source. +pub use constants::VERTIGO_PROGRAM_ID; +/// Virtuals program id extracted from upstream Git decoder source. +pub use constants::VIRTUALS_PROGRAM_ID; /// Vote program identifier. ("Vote111111111111111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::vote::ID pub use constants::VOTE_PROGRAM_ID; +/// Wavebreak program id extracted from upstream Git decoder source. +pub use constants::WAVEBREAK_PROGRAM_ID; +/// Woofi program id from Vybe supported DEX/AMM documentation. +pub use constants::WOOFI_PROGRAM_ID; /// Wrapped SOL mint identifier. ("So11111111111111111111111111111111111111112"). /// @see solana_sdk::pubkey::Pubkey = spl_token_interface::native_mint::ID pub use constants::WSOL_MINT_ID; +/// ZeroFi program id from Vybe supported DEX/AMM documentation. +pub use constants::ZEROFI_PROGRAM_ID; +/// Zeta program id extracted from upstream Git decoder source. +pub use constants::ZETA_PROGRAM_ID; /// Zk El Gamal Proof program identifier. ("ZkE1Gama1Proof11111111111111111111111111111"). /// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::zk_elgamal_proof_program::ID pub use constants::ZK_ELGAMAL_PROOF_PROGRAM_ID; @@ -943,6 +1065,12 @@ pub use dex::MeteoraDlmmPoolLifecycleDecoded; pub use dex::MeteoraDlmmRewardDecoded; /// Decoded Meteora DLMM swap event. pub use dex::MeteoraDlmmSwapDecoded; +/// Decoded OpenBook v2 audit event. +pub use dex::OpenBookV2AuditDecoded; +/// Decoded OpenBook v2 event. +pub use dex::OpenBookV2DecodedEvent; +/// OpenBook v2 audit-only decoder. +pub use dex::OpenBookV2Decoder; /// Decoded Orca Whirlpools create-pool event. pub use dex::OrcaWhirlpoolsCreatePoolDecoded; /// Decoded Orca Whirlpools event. @@ -951,6 +1079,12 @@ pub use dex::OrcaWhirlpoolsDecodedEvent; pub use dex::OrcaWhirlpoolsDecoder; /// Decoded Orca Whirlpools swap event. pub use dex::OrcaWhirlpoolsSwapDecoded; +/// Decoded Phoenix v1 audit event. +pub use dex::PhoenixV1AuditDecoded; +/// Decoded Phoenix v1 event. +pub use dex::PhoenixV1DecodedEvent; +/// Phoenix v1 audit-only decoder. +pub use dex::PhoenixV1Decoder; /// Decoded Pump.fun `create_v2` token event. pub use dex::PumpFunCreateV2TokenDecoded; /// Decoded Pump.fun event. @@ -1164,8 +1298,12 @@ pub use local_pipeline_validation::validate_local_pipeline_diagnostics_summary; pub use non_trade_event_materialization::NonTradeEventMaterializationResult; /// Materializes useful non-trade decoded DEX events. pub use non_trade_event_materialization::NonTradeEventMaterializationService; +/// Backfill signatures grouped by candidate kind. +pub use onchain_dex_pair_discovery::OnchainDexBackfillSignaturesByKindDto; /// Candidate account inferred from generic transaction evidence. pub use onchain_dex_pair_discovery::OnchainDexCandidateAccountDto; +/// Candidate summary grouped by kind and transaction success state. +pub use onchain_dex_pair_discovery::OnchainDexCandidateKindSummaryDto; /// Cursor hint for one on-chain DEX discovery source address. pub use onchain_dex_pair_discovery::OnchainDexPaginationCursorDto; /// Candidate transaction/instruction observed on-chain for one DEX program id. @@ -1266,6 +1404,40 @@ pub use tx_resolution::WsTransactionResolutionRelay; pub use tx_resolution::WsTransactionResolutionRelayStats; /// Generic connection state used by transport clients. pub use types::ConnectionState; +/// Read-only upstream registry service. +pub use upstream_registry::UpstreamRegistryService; +/// Static upstream registry entry kind for account layouts. +pub use upstream_registry_types::ENTRY_KIND_ACCOUNT; +/// Static upstream registry entry kind for events. +pub use upstream_registry_types::ENTRY_KIND_EVENT; +/// Static upstream registry entry kind for instructions. +pub use upstream_registry_types::ENTRY_KIND_INSTRUCTION; +/// Static upstream registry entry kind for programs. +pub use upstream_registry_types::ENTRY_KIND_PROGRAM; +/// Generic upstream Git proof status for layout-only unverified entries. +pub use upstream_registry_types::PROOF_STATUS_UPSTREAM_GIT_LAYOUT_UNVERIFIED; +/// Generic upstream Git proof status for locally materialized entries. +pub use upstream_registry_types::PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_MATERIALIZED; +/// Generic upstream Git proof status for locally observed entries. +pub use upstream_registry_types::PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_OBSERVED; +/// Generic upstream Git proof status for decoder-mapped unverified entries. +pub use upstream_registry_types::PROOF_STATUS_UPSTREAM_GIT_MAPPED_UNVERIFIED; +/// Generic upstream Git proof status for unverified entries. +pub use upstream_registry_types::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED; +/// Generic event kind used for instruction-level upstream registry matches. +pub use upstream_registry_types::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND; +/// Generic protocol name used for upstream registry matches that are not business-materialized. +pub use upstream_registry_types::UPSTREAM_REGISTRY_PROTOCOL_NAME; +/// Static upstream registry entry. +pub use upstream_registry_types::UpstreamRegistryEntry; +/// Owned upstream registry entry DTO. +pub use upstream_registry_types::UpstreamRegistryEntryDto; +/// Upstream registry search request DTO. +pub use upstream_registry_types::UpstreamRegistrySearchRequestDto; +/// Upstream registry search result DTO. +pub use upstream_registry_types::UpstreamRegistrySearchResultDto; +/// Upstream registry summary DTO. +pub use upstream_registry_types::UpstreamRegistrySummaryDto; /// One wallet-holding observation result. pub use wallet_holding_observation::WalletHoldingObservationResult; /// Wallet-holding observation service. diff --git a/kb_lib/src/local_pipeline_replay.rs b/kb_lib/src/local_pipeline_replay.rs index 0c64c16..bdfa875 100644 --- a/kb_lib/src/local_pipeline_replay.rs +++ b/kb_lib/src/local_pipeline_replay.rs @@ -658,7 +658,7 @@ fn build_success_dex_decode_replay_ledger( fn count_effective_decoded_events(decoded_events: &[crate::DexDecodedEventDto]) -> usize { let mut count = 0_usize; for event in decoded_events { - if is_instruction_audit_event(event) { + if is_replay_audit_only_event(event) { continue; } count += 1; @@ -666,8 +666,17 @@ fn count_effective_decoded_events(decoded_events: &[crate::DexDecodedEventDto]) return count; } -fn is_instruction_audit_event(event: &crate::DexDecodedEventDto) -> bool { - return event.event_kind.ends_with(".instruction_audit"); +fn is_replay_audit_only_event(event: &crate::DexDecodedEventDto) -> bool { + if event.event_kind.ends_with(".instruction_audit") { + return true; + } + if event.event_kind.ends_with("_audit") { + return true; + } + if event.event_kind == crate::UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND { + return true; + } + return false; } fn count_distinct_decoded_event_token_mints(decoded_events: &[crate::DexDecodedEventDto]) -> usize { @@ -759,6 +768,20 @@ mod tests { assert!(ledger.can_skip_decode()); } + #[test] + fn ledger_treats_audit_suffix_events_as_audit_only() { + let events = vec![ + make_decoded_event("openbook_v2.settle_funds_audit", Some("mint-a"), Some("mint-b")), + make_decoded_event("openbook_v2.order_place_audit", None, None), + ]; + let ledger = super::build_success_dex_decode_replay_ledger(1, "sig", events.as_slice()) + .expect("ledger must build"); + assert_eq!(ledger.event_count, 2); + assert_eq!(ledger.status_reason.as_deref(), Some("decode completed and certified for skip: event_count=2, effective_event_count=0, instruction_audit_count=2, distinct_token_mint_count=2")); + assert!(!ledger.force_replay_required); + assert!(ledger.can_skip_decode()); + } + #[test] fn ledger_keeps_multiple_effective_events_unsafe() { let events = vec![ diff --git a/kb_lib/src/onchain_dex_pair_discovery.rs b/kb_lib/src/onchain_dex_pair_discovery.rs index 54853a5..6c734e3 100644 --- a/kb_lib/src/onchain_dex_pair_discovery.rs +++ b/kb_lib/src/onchain_dex_pair_discovery.rs @@ -77,6 +77,18 @@ pub struct OnchainDexPairDiscoveryResultDto { pub unique_signature_count: usize, /// Unique signatures returned as backfill-ready hints. pub unique_backfill_signatures: std::vec::Vec, + /// Unique successful transaction signatures returned as preferred backfill hints. + pub successful_backfill_signatures: std::vec::Vec, + /// Unique failed transaction signatures returned as audit-only backfill hints. + pub failed_backfill_signatures: std::vec::Vec, + /// Successful backfill signatures grouped by candidate kind. + pub successful_backfill_signatures_by_kind: + std::vec::Vec, + /// Failed backfill signatures grouped by candidate kind. + pub failed_backfill_signatures_by_kind: + std::vec::Vec, + /// Candidate summary grouped by kind and transaction success state. + pub candidate_kind_summary: std::vec::Vec, /// Rejected candidate summary grouped by kind/prefix/name/reason. pub rejected_candidate_summary: std::vec::Vec, /// Number of signatures returned by the RPC endpoint. @@ -91,6 +103,18 @@ pub struct OnchainDexPairDiscoveryResultDto { pub skipped_failed_transaction_count: usize, /// Number of swap-log transactions skipped by the transaction-level swap guard. pub skipped_swap_log_transaction_count: usize, + /// Number of top-level and inner instructions scanned after RPC transaction decoding. + pub scanned_instruction_count: usize, + /// Number of scanned instructions whose resolved program id matches the requested program. + pub target_program_instruction_count: usize, + /// Number of fetched transactions whose account keys mention the requested program id. + pub target_program_account_mention_transaction_count: usize, + /// Number of fetched transactions whose logs mention the requested program id. + pub target_program_log_mention_transaction_count: usize, + /// Number of fetched transactions mentioning the requested program without a resolved matching instruction. + pub target_program_mention_without_instruction_count: usize, + /// Number of failed transactions mentioning the requested program without a resolved matching instruction. + pub failed_target_program_mention_without_instruction_count: usize, /// Number of candidate rows extracted before target-event filtering. pub extracted_candidate_count: usize, /// Number of candidate rows rejected by target-event filtering. @@ -115,6 +139,32 @@ pub struct OnchainDexPaginationCursorDto { pub fetched_page_count: usize, } +/// Backfill signatures grouped by candidate kind. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct OnchainDexBackfillSignaturesByKindDto { + /// Candidate kind. + pub candidate_kind: std::string::String, + /// Unique transaction signatures for this candidate kind. + pub signatures: std::vec::Vec, +} + +/// Candidate summary grouped by kind and transaction success state. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct OnchainDexCandidateKindSummaryDto { + /// Candidate kind. + pub candidate_kind: std::string::String, + /// Number of returned candidate rows of this kind. + pub count: usize, + /// Number of returned successful candidate rows of this kind. + pub success_count: usize, + /// Number of returned failed candidate rows of this kind. + pub failed_count: usize, + /// Number of unique transaction signatures for this kind. + pub unique_signature_count: usize, +} + /// Rejected candidate summary for one discovery run. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "camelCase")] @@ -273,6 +323,11 @@ impl OnchainDexPairDiscoveryService { unique_fetched_signature_count: signature_fetch.unique_signature_count, unique_signature_count: 0, unique_backfill_signatures: std::vec::Vec::new(), + successful_backfill_signatures: std::vec::Vec::new(), + failed_backfill_signatures: std::vec::Vec::new(), + successful_backfill_signatures_by_kind: std::vec::Vec::new(), + failed_backfill_signatures_by_kind: std::vec::Vec::new(), + candidate_kind_summary: std::vec::Vec::new(), rejected_candidate_summary: std::vec::Vec::new(), fetched_signature_count: signature_fetch.raw_signature_count, fetched_transaction_count: 0, @@ -280,6 +335,12 @@ impl OnchainDexPairDiscoveryService { failed_transaction_count: 0, skipped_failed_transaction_count: 0, skipped_swap_log_transaction_count: 0, + scanned_instruction_count: 0, + target_program_instruction_count: 0, + target_program_account_mention_transaction_count: 0, + target_program_log_mention_transaction_count: 0, + target_program_mention_without_instruction_count: 0, + failed_target_program_mention_without_instruction_count: 0, extracted_candidate_count: 0, target_rejected_candidate_count: 0, candidate_count: 0, @@ -336,6 +397,23 @@ impl OnchainDexPairDiscoveryService { resolved.dex_code.clone(), normalized_request.target_event.as_deref(), ); + result.scanned_instruction_count += extraction.scanned_instruction_count; + result.target_program_instruction_count += extraction.target_program_instruction_count; + if extraction.target_program_account_mentioned { + result.target_program_account_mention_transaction_count += 1; + } + if extraction.target_program_log_mentioned { + result.target_program_log_mention_transaction_count += 1; + } + if extraction.target_program_instruction_count == 0 + && (extraction.target_program_account_mentioned + || extraction.target_program_log_mentioned) + { + result.target_program_mention_without_instruction_count += 1; + if failed { + result.failed_target_program_mention_without_instruction_count += 1; + } + } result.extracted_candidate_count += extraction.extracted_candidate_count; result.target_rejected_candidate_count += extraction.target_rejected_candidate_count; merge_rejected_candidate_summaries( @@ -359,8 +437,7 @@ impl OnchainDexPairDiscoveryService { result.candidates.push(candidate); } } - result.candidate_count = result.candidates.len(); - result.unique_signature_count = result.unique_backfill_signatures.len(); + rebuild_candidate_backfill_indexes(&mut result); return Ok(result); } @@ -582,6 +659,10 @@ const DEMO3_DAMM_V1_LOCK: [u8; 8] = [0x15, 0x13, 0xd0, 0x2b, 0xed, 0x3e, 0xff, 0 #[derive(Debug, Clone)] struct OnchainCandidateExtraction { candidates: std::vec::Vec, + scanned_instruction_count: usize, + target_program_instruction_count: usize, + target_program_account_mentioned: bool, + target_program_log_mentioned: bool, extracted_candidate_count: usize, target_rejected_candidate_count: usize, rejected_candidate_summary: std::vec::Vec, @@ -839,7 +920,7 @@ fn looks_like_solana_address(value: &str) -> bool { return false; } } - return true; + return value.parse::().is_ok(); } fn looks_like_solana_signature(value: &str) -> bool { @@ -903,8 +984,13 @@ fn extract_candidates_from_transaction( let failed = transaction_failed(transaction); let logs = extract_log_messages(transaction); let evidence = extract_transaction_generic_evidence(transaction); + let target_program_account_mentioned = + account_keys_contain_address(evidence.account_keys.as_slice(), target_program_id); + let target_program_log_mentioned = logs_contain_text(logs.as_slice(), target_program_id); let prefer_non_swap_audit = target_event_prefers_instruction_local_classification(target_event); - let instructions = extract_onchain_instructions(transaction); + let instructions = extract_onchain_instructions(transaction, evidence.account_keys.as_slice()); + let scanned_instruction_count = instructions.len(); + let mut target_program_instruction_count = 0usize; for instruction in instructions { let program_id = match &instruction.program_id { Some(program_id) => program_id.clone(), @@ -913,6 +999,7 @@ fn extract_candidates_from_transaction( if program_id.as_str() != target_program_id { continue; } + target_program_instruction_count += 1; let decoded_candidate = decode_known_candidate( signature, slot, @@ -958,6 +1045,10 @@ fn extract_candidates_from_transaction( } return OnchainCandidateExtraction { candidates, + scanned_instruction_count, + target_program_instruction_count, + target_program_account_mentioned, + target_program_log_mentioned, extracted_candidate_count, target_rejected_candidate_count, rejected_candidate_summary, @@ -1461,10 +1552,19 @@ fn build_heuristic_candidate( logs: &[std::string::String], prefer_instruction_local_classification: bool, ) -> crate::OnchainDexPairCandidateDto { - let instruction_name = if prefer_instruction_local_classification { - infer_instruction_name_from_parsed(instruction.parsed.as_ref()) - } else { - infer_instruction_name(instruction.parsed.as_ref(), logs) + let registry_match = crate::upstream_registry_match::upstream_registry_match_instruction_data( + program_id, + instruction.data.as_deref(), + ); + let instruction_name = match registry_match.as_ref() { + Some(registry_match) => Some(registry_match.entry_name.clone()), + None => { + if prefer_instruction_local_classification { + infer_instruction_name_from_parsed(instruction.parsed.as_ref()) + } else { + infer_instruction_name(instruction.parsed.as_ref(), logs) + } + }, }; let pool_address = extract_string_by_candidate_keys_from_instruction( instruction, @@ -1478,13 +1578,20 @@ fn build_heuristic_candidate( instruction, &["tokenB", "tokenBMint", "mintB", "quoteMint", "token1Mint", "mint1", "pcMint"], ); - let candidate_kind = infer_candidate_kind( - instruction_name.as_ref(), - logs, - instruction.data.is_some(), - prefer_instruction_local_classification, - ); - let confidence = if pool_address.is_some() || token_a_mint.is_some() || token_b_mint.is_some() { + let candidate_kind = match registry_match.as_ref() { + Some(registry_match) => { + upstream_registry_entry_name_to_candidate_kind(registry_match.entry_name.as_str()) + }, + None => infer_candidate_kind( + instruction_name.as_ref(), + logs, + instruction.data.is_some(), + prefer_instruction_local_classification, + ), + }; + let confidence = if registry_match.is_some() { + "high".to_string() + } else if pool_address.is_some() || token_a_mint.is_some() || token_b_mint.is_some() { "medium".to_string() } else { "low".to_string() @@ -1585,6 +1692,24 @@ fn enrich_candidate_with_generic_evidence( } } +fn account_keys_contain_address(account_keys: &[AccountKeyInfo], address: &str) -> bool { + for account_key in account_keys { + if account_key.address == address { + return true; + } + } + return false; +} + +fn logs_contain_text(logs: &[std::string::String], text: &str) -> bool { + for log in logs { + if log.contains(text) { + return true; + } + } + return false; +} + fn extract_transaction_generic_evidence( transaction: &serde_json::Value, ) -> TransactionGenericEvidence { @@ -1617,9 +1742,54 @@ fn extract_transaction_account_keys( index += 1; } } + append_loaded_address_account_keys(transaction, &mut account_keys); return account_keys; } +fn append_loaded_address_account_keys( + transaction: &serde_json::Value, + account_keys: &mut std::vec::Vec, +) { + let loaded_addresses = + transaction.get("meta").and_then(|value| return value.get("loadedAddresses")); + let loaded_addresses = match loaded_addresses { + Some(loaded_addresses) => loaded_addresses, + None => return, + }; + append_loaded_address_side(loaded_addresses, "writable", account_keys, Some(true)); + append_loaded_address_side(loaded_addresses, "readonly", account_keys, Some(false)); +} + +fn append_loaded_address_side( + loaded_addresses: &serde_json::Value, + key: &str, + account_keys: &mut std::vec::Vec, + writable: std::option::Option, +) { + let values = loaded_addresses.get(key).and_then(serde_json::Value::as_array); + let values = match values { + Some(values) => values, + None => return, + }; + for value in values { + let address = match value.as_str() { + Some(address) => address, + None => continue, + }; + let index_result = i64::try_from(account_keys.len()); + let index = match index_result { + Ok(index) => index, + Err(_) => return, + }; + account_keys.push(AccountKeyInfo { + index, + address: address.to_string(), + signer: Some(false), + writable, + }); + } +} + fn parse_account_key_info( value: &serde_json::Value, index: i64, @@ -2011,6 +2181,122 @@ fn push_unique_string(values: &mut std::vec::Vec, value: st values.push(value); } +fn rebuild_candidate_backfill_indexes(result: &mut crate::OnchainDexPairDiscoveryResultDto) { + result.unique_backfill_signatures.clear(); + result.successful_backfill_signatures.clear(); + result.failed_backfill_signatures.clear(); + result.successful_backfill_signatures_by_kind.clear(); + result.failed_backfill_signatures_by_kind.clear(); + result.candidate_kind_summary.clear(); + + for candidate in &result.candidates { + push_unique_string(&mut result.unique_backfill_signatures, candidate.signature.clone()); + if candidate.failed { + push_unique_string(&mut result.failed_backfill_signatures, candidate.signature.clone()); + push_backfill_signature_by_kind( + &mut result.failed_backfill_signatures_by_kind, + candidate.candidate_kind.as_str(), + candidate.signature.as_str(), + ); + } else { + push_unique_string( + &mut result.successful_backfill_signatures, + candidate.signature.clone(), + ); + push_backfill_signature_by_kind( + &mut result.successful_backfill_signatures_by_kind, + candidate.candidate_kind.as_str(), + candidate.signature.as_str(), + ); + } + push_candidate_kind_summary( + &mut result.candidate_kind_summary, + candidate.candidate_kind.as_str(), + candidate.failed, + ); + } + + refresh_candidate_kind_unique_signature_counts( + &mut result.candidate_kind_summary, + result.successful_backfill_signatures_by_kind.as_slice(), + result.failed_backfill_signatures_by_kind.as_slice(), + ); + result.candidate_count = result.candidates.len(); + result.unique_signature_count = result.unique_backfill_signatures.len(); +} + +fn push_backfill_signature_by_kind( + values: &mut std::vec::Vec, + candidate_kind: &str, + signature: &str, +) { + for value in values.iter_mut() { + if value.candidate_kind == candidate_kind { + push_unique_string(&mut value.signatures, signature.to_string()); + return; + } + } + values.push(crate::OnchainDexBackfillSignaturesByKindDto { + candidate_kind: candidate_kind.to_string(), + signatures: vec![signature.to_string()], + }); +} + +fn push_candidate_kind_summary( + values: &mut std::vec::Vec, + candidate_kind: &str, + failed: bool, +) { + for value in values.iter_mut() { + if value.candidate_kind == candidate_kind { + value.count += 1; + if failed { + value.failed_count += 1; + } else { + value.success_count += 1; + } + return; + } + } + let success_count = if failed { 0 } else { 1 }; + let failed_count = if failed { 1 } else { 0 }; + values.push(crate::OnchainDexCandidateKindSummaryDto { + candidate_kind: candidate_kind.to_string(), + count: 1, + success_count, + failed_count, + unique_signature_count: 0, + }); +} + +fn refresh_candidate_kind_unique_signature_counts( + summaries: &mut [crate::OnchainDexCandidateKindSummaryDto], + successful: &[crate::OnchainDexBackfillSignaturesByKindDto], + failed: &[crate::OnchainDexBackfillSignaturesByKindDto], +) { + for summary in summaries { + let mut signatures: std::vec::Vec = std::vec::Vec::new(); + collect_kind_signatures(&mut signatures, successful, summary.candidate_kind.as_str()); + collect_kind_signatures(&mut signatures, failed, summary.candidate_kind.as_str()); + summary.unique_signature_count = signatures.len(); + } +} + +fn collect_kind_signatures( + destination: &mut std::vec::Vec, + source: &[crate::OnchainDexBackfillSignaturesByKindDto], + candidate_kind: &str, +) { + for value in source { + if value.candidate_kind != candidate_kind { + continue; + } + for signature in &value.signatures { + push_unique_string(destination, signature.clone()); + } + } +} + fn push_unique_candidate_account( values: &mut std::vec::Vec, value: crate::OnchainDexCandidateAccountDto, @@ -2072,6 +2358,7 @@ fn is_known_program_or_sysvar(address: &str) -> bool { fn extract_onchain_instructions( transaction: &serde_json::Value, + account_keys: &[AccountKeyInfo], ) -> std::vec::Vec { let mut instructions = std::vec::Vec::new(); let top_level = transaction @@ -2082,7 +2369,12 @@ fn extract_onchain_instructions( if let Some(top_level) = top_level { let mut index = 0usize; for instruction in top_level { - instructions.push(parse_instruction_candidate(instruction, Some(index as i64), None)); + instructions.push(parse_instruction_candidate( + instruction, + Some(index as i64), + None, + account_keys, + )); index += 1; } } @@ -2101,6 +2393,7 @@ fn extract_onchain_instructions( instruction, parent_index, Some(inner_index as i64), + account_keys, )); inner_index += 1; } @@ -2114,18 +2407,37 @@ fn parse_instruction_candidate( instruction: &serde_json::Value, instruction_index: std::option::Option, inner_instruction_index: std::option::Option, + account_keys: &[AccountKeyInfo], ) -> OnchainInstructionCandidate { return OnchainInstructionCandidate { instruction_index, inner_instruction_index, - program_id: extract_string_field(instruction, "programId"), - accounts: extract_accounts(instruction), + program_id: extract_instruction_program_id(instruction, account_keys), + accounts: extract_accounts(instruction, account_keys), data: extract_instruction_data(instruction), parsed: instruction.get("parsed").cloned(), }; } -fn extract_accounts(instruction: &serde_json::Value) -> std::vec::Vec { +fn extract_instruction_program_id( + instruction: &serde_json::Value, + account_keys: &[AccountKeyInfo], +) -> std::option::Option { + if let Some(program_id) = extract_string_field(instruction, "programId") { + return Some(program_id); + } + let program_id_index = instruction.get("programIdIndex").and_then(serde_json::Value::as_i64); + let program_id_index = match program_id_index { + Some(program_id_index) => program_id_index, + None => return None, + }; + return account_address_by_index(account_keys, program_id_index); +} + +fn extract_accounts( + instruction: &serde_json::Value, + account_keys: &[AccountKeyInfo], +) -> std::vec::Vec { let mut accounts = std::vec::Vec::new(); let account_values = instruction.get("accounts").and_then(serde_json::Value::as_array); if let Some(account_values) = account_values { @@ -2134,6 +2446,12 @@ fn extract_accounts(instruction: &serde_json::Value) -> std::vec::Vec std::string::String { + let lower = entry_name.to_ascii_lowercase(); + if lower.contains("swap") || lower == "buy" || lower == "sell" { + return "swap".to_string(); + } + if lower.contains("add_liquidity") + || lower.contains("increase_liquidity") + || lower == "deposit" + || lower.ends_with("_deposit") + { + return "add_liquidity".to_string(); + } + if lower.contains("remove_liquidity") + || lower.contains("decrease_liquidity") + || lower == "withdraw" + || lower.ends_with("_withdraw") + { + return "remove_liquidity".to_string(); + } + if lower.contains("claim") && lower.contains("reward") { + return "claim_reward".to_string(); + } + if lower.contains("claim") && lower.contains("fee") { + return "claim_fee".to_string(); + } + if lower.contains("open_position") || lower.contains("initialize_position") { + return "position_open".to_string(); + } + if lower.contains("close_position") { + return "position_close".to_string(); + } + if text_matches_burn(lower.as_str()) { + return "burn".to_string(); + } + if text_matches_mint(lower.as_str()) { + return "mint".to_string(); + } + if text_matches_transfer(lower.as_str()) { + return "transfer".to_string(); + } + if text_matches_close_account(lower.as_str()) { + return "close_account".to_string(); + } + if text_matches_token_account_create(lower.as_str()) { + return "token_account_create".to_string(); + } + if text_matches_wrap_sol(lower.as_str()) { + return "wrap_sol".to_string(); + } + if text_matches_unwrap_sol(lower.as_str()) { + return "unwrap_sol".to_string(); + } + if text_matches_unstake(lower.as_str()) { + return "unstake".to_string(); + } + if text_matches_stake(lower.as_str()) { + return "stake".to_string(); + } + if lower.contains("create_lock_escrow") { + return "create_lock_escrow".to_string(); + } + if lower.contains("lock_liquidity") { + return "lock_liquidity".to_string(); + } + if lower.contains("create") && lower.contains("pool") { + return "create_pool".to_string(); + } + if lower.contains("initialize") && lower.contains("pool") { + return "initialize_pool".to_string(); + } + if text_matches_orderbook_fill(lower.as_str()) { + return "order_fill".to_string(); + } + if text_matches_orderbook_place(lower.as_str()) { + return "order_place".to_string(); + } + if text_matches_orderbook_cancel(lower.as_str()) { + return "order_cancel".to_string(); + } + if text_matches_settle_funds(lower.as_str()) { + return "settle_funds".to_string(); + } + if text_matches_consume_events(lower.as_str()) { + return "consume_events".to_string(); + } + if text_matches_market_create(lower.as_str()) { + return "market_create".to_string(); + } + if text_matches_open_orders_create(lower.as_str()) { + return "open_orders_create".to_string(); + } + if text_matches_open_orders_close(lower.as_str()) { + return "open_orders_close".to_string(); + } + if text_matches_close_market(lower.as_str()) { + return "close_market".to_string(); + } + if lower.contains("set_") || lower.contains("update_") || lower.contains("admin") { + return "pool_admin".to_string(); + } + return "upstream_git_instruction".to_string(); +} + fn infer_candidate_kind( instruction_name: std::option::Option<&std::string::String>, logs: &[std::string::String], @@ -2302,6 +2723,33 @@ fn infer_candidate_kind( if lower.contains("swap") || lower.contains("buy") || lower.contains("sell") { return "swap".to_string(); } + if text_matches_orderbook_fill(lower.as_str()) { + return "order_fill".to_string(); + } + if text_matches_orderbook_place(lower.as_str()) { + return "order_place".to_string(); + } + if text_matches_orderbook_cancel(lower.as_str()) { + return "order_cancel".to_string(); + } + if text_matches_settle_funds(lower.as_str()) { + return "settle_funds".to_string(); + } + if text_matches_consume_events(lower.as_str()) { + return "consume_events".to_string(); + } + if text_matches_market_create(lower.as_str()) { + return "market_create".to_string(); + } + if text_matches_open_orders_create(lower.as_str()) { + return "open_orders_create".to_string(); + } + if text_matches_open_orders_close(lower.as_str()) { + return "open_orders_close".to_string(); + } + if text_matches_close_market(lower.as_str()) { + return "close_market".to_string(); + } if lower.contains("liquidity") || lower.contains("position") { return "liquidity_or_position".to_string(); } @@ -2316,6 +2764,24 @@ fn target_event_prefers_instruction_local_classification( || target == "audit_non_swap_like" || target == "unclassified_instruction" || target == "non_swap" + || target == "burn" + || target == "mint" + || target == "transfer" + || target == "close_account" + || target == "token_account_create" + || target == "wrap_sol" + || target == "unwrap_sol" + || target == "stake" + || target == "unstake" + || target == "order_place" + || target == "order_cancel" + || target == "order_fill" + || target == "settle_funds" + || target == "consume_events" + || target == "market_create" + || target == "open_orders_create" + || target == "open_orders_close" + || target == "close_market" { return true; } @@ -2355,6 +2821,24 @@ fn text_matches_non_swap_target(lower: &str) -> bool { || text_matches_position_open(lower) || text_matches_add_liquidity(lower) || text_matches_remove_liquidity(lower) + || text_matches_burn(lower) + || text_matches_mint(lower) + || text_matches_transfer(lower) + || text_matches_close_account(lower) + || text_matches_token_account_create(lower) + || text_matches_wrap_sol(lower) + || text_matches_unwrap_sol(lower) + || text_matches_stake(lower) + || text_matches_unstake(lower) + || text_matches_orderbook_place(lower) + || text_matches_orderbook_cancel(lower) + || text_matches_orderbook_fill(lower) + || text_matches_settle_funds(lower) + || text_matches_consume_events(lower) + || text_matches_market_create(lower) + || text_matches_open_orders_create(lower) + || text_matches_open_orders_close(lower) + || text_matches_close_market(lower) || ((lower.contains("create") || lower.contains("initialize")) && lower.contains("pool")); } @@ -2380,12 +2864,66 @@ fn infer_non_swap_candidate_kind(lower: &str) -> std::string::String { if text_matches_remove_liquidity(lower) { return "remove_liquidity".to_string(); } + if text_matches_burn(lower) { + return "burn".to_string(); + } + if text_matches_mint(lower) { + return "mint".to_string(); + } + if text_matches_transfer(lower) { + return "transfer".to_string(); + } + if text_matches_close_account(lower) { + return "close_account".to_string(); + } + if text_matches_token_account_create(lower) { + return "token_account_create".to_string(); + } + if text_matches_wrap_sol(lower) { + return "wrap_sol".to_string(); + } + if text_matches_unwrap_sol(lower) { + return "unwrap_sol".to_string(); + } + if text_matches_unstake(lower) { + return "unstake".to_string(); + } + if text_matches_stake(lower) { + return "stake".to_string(); + } if lower.contains("create") && lower.contains("pool") { return "create_pool".to_string(); } if lower.contains("initialize") && lower.contains("pool") { return "initialize_pool".to_string(); } + if text_matches_orderbook_fill(lower) { + return "order_fill".to_string(); + } + if text_matches_orderbook_place(lower) { + return "order_place".to_string(); + } + if text_matches_orderbook_cancel(lower) { + return "order_cancel".to_string(); + } + if text_matches_settle_funds(lower) { + return "settle_funds".to_string(); + } + if text_matches_consume_events(lower) { + return "consume_events".to_string(); + } + if text_matches_market_create(lower) { + return "market_create".to_string(); + } + if text_matches_open_orders_create(lower) { + return "open_orders_create".to_string(); + } + if text_matches_open_orders_close(lower) { + return "open_orders_close".to_string(); + } + if text_matches_close_market(lower) { + return "close_market".to_string(); + } return "non_swap_activity".to_string(); } @@ -2400,7 +2938,7 @@ fn split_target_event_filter( for token in value.split(|character: char| { return character == ',' || character == ';' || character.is_whitespace(); }) { - let normalized = token.trim().to_ascii_lowercase().replace(['-', ' '], "_"); + let normalized = normalize_target_event_token(token.trim()); if normalized.is_empty() || normalized == "any" || normalized == "all" { continue; } @@ -2409,6 +2947,30 @@ fn split_target_event_filter( return targets; } +fn normalize_target_event_token(value: &str) -> std::string::String { + let normalized = value.trim().to_ascii_lowercase().replace(['-', ' '], "_"); + match normalized.as_str() { + "token_burn" | "burn_token" | "burn_tokens" => return "burn".to_string(), + "token_mint" | "mint_token" | "mint_tokens" | "mint_to" => return "mint".to_string(), + "token_transfer" | "transfer_token" | "transfer_tokens" | "transfer_checked" => { + return "transfer".to_string(); + }, + "close_token_account" | "token_account_close" | "close_account" => { + return "close_account".to_string(); + }, + "create_token_account" | "associated_token_account" | "ata_create" => { + return "token_account_create".to_string(); + }, + "wrap" | "wrap_native" | "wrap_sol" => return "wrap_sol".to_string(), + "unwrap" | "unwrap_native" | "unwrap_sol" | "sync_native_close" => { + return "unwrap_sol".to_string(); + }, + "staking" | "delegate_stake" => return "stake".to_string(), + "unstaking" | "withdraw_stake" | "deactivate_stake" => return "unstake".to_string(), + _ => return normalized, + } +} + fn refine_candidate_for_target( candidate: &mut crate::OnchainDexPairCandidateDto, target_event: std::option::Option<&str>, @@ -2523,6 +3085,24 @@ fn candidate_matches_single_target_event( || lower.contains("lock liquidity") || lower.contains("meteora_damm_v1.lock"); }, + "burn" => return text_matches_burn(lower.as_str()), + "mint" => return text_matches_mint(lower.as_str()), + "transfer" => return text_matches_transfer(lower.as_str()), + "close_account" => return text_matches_close_account(lower.as_str()), + "token_account_create" => return text_matches_token_account_create(lower.as_str()), + "wrap_sol" => return text_matches_wrap_sol(lower.as_str()), + "unwrap_sol" => return text_matches_unwrap_sol(lower.as_str()), + "stake" => return text_matches_stake(lower.as_str()), + "unstake" => return text_matches_unstake(lower.as_str()), + "order_place" => return text_matches_orderbook_place(lower.as_str()), + "order_cancel" => return text_matches_orderbook_cancel(lower.as_str()), + "order_fill" => return text_matches_orderbook_fill(lower.as_str()), + "settle_funds" => return text_matches_settle_funds(lower.as_str()), + "consume_events" => return text_matches_consume_events(lower.as_str()), + "market_create" => return text_matches_market_create(lower.as_str()), + "open_orders_create" => return text_matches_open_orders_create(lower.as_str()), + "open_orders_close" => return text_matches_open_orders_close(lower.as_str()), + "close_market" => return text_matches_close_market(lower.as_str()), _ => return true, } } @@ -2544,6 +3124,24 @@ fn exact_candidate_kind_matches_target(candidate_kind: &str, target_event: &str) }, "create_lock_escrow" => return candidate_kind == "create_lock_escrow", "lock_liquidity" | "lock" => return candidate_kind == "lock_liquidity", + "burn" => return candidate_kind == "burn", + "mint" => return candidate_kind == "mint", + "transfer" => return candidate_kind == "transfer", + "close_account" => return candidate_kind == "close_account", + "token_account_create" => return candidate_kind == "token_account_create", + "wrap_sol" => return candidate_kind == "wrap_sol", + "unwrap_sol" => return candidate_kind == "unwrap_sol", + "stake" => return candidate_kind == "stake", + "unstake" => return candidate_kind == "unstake", + "order_place" => return candidate_kind == "order_place", + "order_cancel" => return candidate_kind == "order_cancel", + "order_fill" => return candidate_kind == "order_fill", + "settle_funds" => return candidate_kind == "settle_funds", + "consume_events" => return candidate_kind == "consume_events", + "market_create" => return candidate_kind == "market_create", + "open_orders_create" => return candidate_kind == "open_orders_create", + "open_orders_close" => return candidate_kind == "open_orders_close", + "close_market" => return candidate_kind == "close_market", _ => return false, } } @@ -2561,7 +3159,25 @@ fn candidate_kind_is_explicit_surface(candidate_kind: &str) -> bool { || candidate_kind == "create_pool" || candidate_kind == "initialize_pool" || candidate_kind == "create_lock_escrow" - || candidate_kind == "lock_liquidity"; + || candidate_kind == "lock_liquidity" + || candidate_kind == "burn" + || candidate_kind == "mint" + || candidate_kind == "transfer" + || candidate_kind == "close_account" + || candidate_kind == "token_account_create" + || candidate_kind == "wrap_sol" + || candidate_kind == "unwrap_sol" + || candidate_kind == "stake" + || candidate_kind == "unstake" + || candidate_kind == "order_place" + || candidate_kind == "order_cancel" + || candidate_kind == "order_fill" + || candidate_kind == "settle_funds" + || candidate_kind == "consume_events" + || candidate_kind == "market_create" + || candidate_kind == "open_orders_create" + || candidate_kind == "open_orders_close" + || candidate_kind == "close_market"; } fn candidate_is_non_swap_audit_candidate(candidate: &crate::OnchainDexPairCandidateDto) -> bool { @@ -2583,6 +3199,25 @@ fn candidate_is_non_swap_audit_candidate(candidate: &crate::OnchainDexPairCandid || candidate.candidate_kind == "initialize_pool" || candidate.candidate_kind == "create_lock_escrow" || candidate.candidate_kind == "lock_liquidity" + || candidate.candidate_kind == "burn" + || candidate.candidate_kind == "mint" + || candidate.candidate_kind == "transfer" + || candidate.candidate_kind == "close_account" + || candidate.candidate_kind == "token_account_create" + || candidate.candidate_kind == "wrap_sol" + || candidate.candidate_kind == "unwrap_sol" + || candidate.candidate_kind == "stake" + || candidate.candidate_kind == "unstake" + || candidate.candidate_kind == "order_place" + || candidate.candidate_kind == "order_cancel" + || candidate.candidate_kind == "order_fill" + || candidate.candidate_kind == "settle_funds" + || candidate.candidate_kind == "consume_events" + || candidate.candidate_kind == "market_create" + || candidate.candidate_kind == "open_orders_create" + || candidate.candidate_kind == "open_orders_close" + || candidate.candidate_kind == "close_market" + || candidate.candidate_kind == "upstream_git_instruction" { return true; } @@ -2758,6 +3393,167 @@ fn text_matches_pool_admin(lower: &str) -> bool { || lower.contains("admin"); } +fn text_matches_orderbook_place(lower: &str) -> bool { + return lower.contains("place_order") + || lower.contains("place order") + || lower.contains("placeorder") + || lower.contains("new_order") + || lower.contains("new order") + || lower.contains("placelimitorder") + || lower.contains("place_limit_order") + || lower.contains("place_take_order") + || lower.contains("post_only"); +} + +fn text_matches_orderbook_cancel(lower: &str) -> bool { + return lower.contains("cancel_order") + || lower.contains("cancel order") + || lower.contains("cancelorder") + || lower.contains("cancel_all_orders") + || lower.contains("cancel all orders") + || lower.contains("cancelallorders"); +} + +fn text_matches_orderbook_fill(lower: &str) -> bool { + return lower.contains("fill_log_event") + || lower.contains("fill log event") + || lower.contains("filllogevent") + || lower.contains("total_order_fill_event") + || lower.contains("total order fill event") + || lower.contains("order_fill") + || lower.contains("fill_order") + || lower.contains("order fill"); +} + +fn text_matches_settle_funds(lower: &str) -> bool { + return lower.contains("settle_funds") + || lower.contains("settle funds") + || lower.contains("settlefunds") + || lower.contains("settle_funds_expired"); +} + +fn text_matches_consume_events(lower: &str) -> bool { + return lower.contains("consume_events") + || lower.contains("consume events") + || lower.contains("consumeevents") + || lower.contains("consume_given_events"); +} + +fn text_matches_market_create(lower: &str) -> bool { + return lower.contains("create_market") + || lower.contains("create market") + || lower.contains("createmarket") + || lower.contains("initialize_market") + || lower.contains("initialize market") + || lower.contains("initializemarket"); +} + +fn text_matches_open_orders_create(lower: &str) -> bool { + return lower.contains("create_open_orders") + || lower.contains("create open orders") + || lower.contains("create_open_orders_account") + || lower.contains("create_open_orders_indexer") + || lower.contains("open_orders_create"); +} + +fn text_matches_open_orders_close(lower: &str) -> bool { + return lower.contains("close_open_orders") + || lower.contains("close open orders") + || lower.contains("close_open_orders_account") + || lower.contains("close_open_orders_indexer") + || lower.contains("open_orders_close"); +} + +fn text_matches_close_market(lower: &str) -> bool { + return lower.contains("close_market") + || lower.contains("close market") + || lower.contains("closemarket"); +} + +fn text_matches_burn(lower: &str) -> bool { + return lower.contains("burn") + || lower.contains("burnchecked") + || lower.contains("burn_checked") + || lower.contains("burn token") + || lower.contains("token burn"); +} + +fn text_matches_mint(lower: &str) -> bool { + return lower.contains("mintto") + || lower.contains("mint_to") + || lower.contains("mint to") + || lower.contains("mint token") + || lower.contains("token mint") + || lower == "mint" + || lower.contains("instruction: mint"); +} + +fn text_matches_transfer(lower: &str) -> bool { + return lower.contains("transferchecked") + || lower.contains("transfer_checked") + || lower.contains("transfer checked") + || lower.contains("token transfer") + || lower.contains("transfer token") + || lower.contains("instruction: transfer"); +} + +fn text_matches_close_account(lower: &str) -> bool { + return lower.contains("closeaccount") + || lower.contains("close_account") + || lower.contains("close account") + || lower.contains("close token account") + || lower.contains("token account close"); +} + +fn text_matches_token_account_create(lower: &str) -> bool { + return lower.contains("createtokenaccount") + || lower.contains("create_token_account") + || lower.contains("create token account") + || lower.contains("createassociatedtokenaccount") + || lower.contains("create_associated_token_account") + || lower.contains("associated token account") + || lower.contains("initializeaccount") + || lower.contains("initialize_account") + || lower.contains("initialize account"); +} + +fn text_matches_wrap_sol(lower: &str) -> bool { + return lower.contains("wrapsol") + || lower.contains("wrap_sol") + || lower.contains("wrap sol") + || lower.contains("wrap native") + || lower.contains("syncnative") + || lower.contains("sync_native"); +} + +fn text_matches_unwrap_sol(lower: &str) -> bool { + return lower.contains("unwrapsol") + || lower.contains("unwrap_sol") + || lower.contains("unwrap sol") + || lower.contains("unwrap native") + || lower.contains("close wsol") + || lower.contains("close wrapped sol"); +} + +fn text_matches_stake(lower: &str) -> bool { + if text_matches_unstake(lower) { + return false; + } + return lower.contains("stake") + || lower.contains("delegate") + || lower.contains("delegate_stake") + || lower.contains("depositstake") + || lower.contains("deposit_stake"); +} + +fn text_matches_unstake(lower: &str) -> bool { + return lower.contains("unstake") + || lower.contains("deactivate") + || lower.contains("deactivate_stake") + || lower.contains("withdrawstake") + || lower.contains("withdraw_stake"); +} + fn transaction_failed(transaction: &serde_json::Value) -> bool { let err = transaction.get("meta").and_then(|value| return value.get("err")); match err { @@ -2904,6 +3700,124 @@ mod tests { assert!(resolved.is_err()); } + #[test] + fn reject_wrong_size_base58_program_id_before_rpc_call() { + let request = crate::OnchainDexPairDiscoveryRequestDto { + dex_code: Some("goonfi_v2".to_string()), + program_id: Some("goonuddtQRrWqqn5FyczVKaie28f3kDkHWkHtURSLE".to_string()), + signature_source: None, + source_address: None, + source_addresses: std::vec::Vec::new(), + before_signature: None, + until_signature: None, + max_pages: 1, + scan_order: None, + target_event: None, + exclude_swaps: false, + include_failed: true, + http_role: "history_backfill".to_string(), + signature_limit: 10, + transaction_limit: 5, + candidate_limit: 3, + }; + let normalized_request = super::normalize_request(request); + let resolved = match super::resolve_program_id(&normalized_request) { + Ok(resolved) => resolved, + Err(error) => { + panic!("explicit program id resolution should not fail before validation: {error}") + }, + }; + let signature_sources = super::resolve_signature_sources(&normalized_request, &resolved); + assert!(signature_sources.is_err()); + } + + #[test] + fn raw_compiled_openbook_v2_instruction_is_resolved_from_program_id_index() { + let mut data = vec![3_u8, 44_u8, 71_u8, 3_u8, 26_u8, 199_u8, 203_u8, 85_u8]; + data.extend_from_slice(&[0_u8, 1_u8, 2_u8, 3_u8]); + let data_base58 = bs58::encode(data.as_slice()).into_string(); + let transaction = serde_json::json!({ + "slot": 777, + "blockTime": 1770000000, + "transaction": { + "message": { + "accountKeys": [ + "Payer111111111111111111111111111111111111", + crate::OPENBOOK_V2_PROGRAM_ID, + "Market11111111111111111111111111111111111", + "OpenOrders1111111111111111111111111111111" + ], + "instructions": [ + { + "programIdIndex": 1, + "accounts": [2, 3], + "data": data_base58 + } + ] + } + }, + "meta": { + "err": null, + "logMessages": [] + } + }); + let extraction = super::extract_candidates_from_transaction( + "sig-openbook-v2-raw", + &transaction, + crate::OPENBOOK_V2_PROGRAM_ID, + Some("openbook_v2".to_string()), + Some("order_place"), + ); + assert_eq!(extraction.extracted_candidate_count, 1); + assert_eq!(extraction.target_rejected_candidate_count, 0); + assert_eq!(extraction.candidates.len(), 1); + assert_eq!(extraction.candidates[0].candidate_kind, "order_place".to_string()); + assert_eq!(extraction.candidates[0].instruction_name, Some("place_take_order".to_string())); + assert_eq!(extraction.candidates[0].confidence, "high".to_string()); + assert_eq!( + extraction.candidates[0].account_samples, + vec![ + "Market11111111111111111111111111111111111".to_string(), + "OpenOrders1111111111111111111111111111111".to_string(), + ] + ); + } + + #[test] + fn loaded_address_indices_are_available_to_demo3_raw_instruction_resolution() { + let transaction = serde_json::json!({ + "transaction": { + "message": { + "accountKeys": [ + "Payer111111111111111111111111111111111111" + ], + "instructions": [ + { + "programIdIndex": 1, + "accounts": [2], + "data": "11111111111" + } + ] + } + }, + "meta": { + "loadedAddresses": { + "writable": [crate::OPENBOOK_V2_PROGRAM_ID], + "readonly": ["Readonly1111111111111111111111111111111111"] + } + } + }); + let account_keys = super::extract_transaction_account_keys(&transaction); + let instructions = + super::extract_onchain_instructions(&transaction, account_keys.as_slice()); + assert_eq!(instructions.len(), 1); + assert_eq!(instructions[0].program_id, Some(crate::OPENBOOK_V2_PROGRAM_ID.to_string())); + assert_eq!( + instructions[0].accounts, + vec!["Readonly1111111111111111111111111111111111".to_string()] + ); + } + #[test] fn known_meteora_damm_v2_trade_like_prefix_is_not_returned_as_non_swap_audit() { let candidate = crate::OnchainDexPairCandidateDto { @@ -3037,6 +3951,27 @@ mod tests { ); } + #[test] + fn split_target_event_filter_normalizes_extended_non_swap_aliases() { + let targets = super::split_target_event_filter(Some( + "token-burn mint_to transfer_checked close-token-account create-token-account wrap unwrap delegate-stake withdraw-stake", + )); + assert_eq!( + targets, + vec![ + "burn".to_string(), + "mint".to_string(), + "transfer".to_string(), + "close_account".to_string(), + "token_account_create".to_string(), + "wrap_sol".to_string(), + "unwrap_sol".to_string(), + "stake".to_string(), + "unstake".to_string(), + ] + ); + } + #[test] fn resolve_multiple_source_addresses_from_single_field() { let request = crate::OnchainDexPairDiscoveryRequestDto { @@ -3115,4 +4050,33 @@ mod tests { backfill_hint: "hint".to_string(), }; } + + #[test] + fn maps_upstream_registry_entry_names_to_candidate_kinds() { + assert_eq!( + super::upstream_registry_entry_name_to_candidate_kind("add_liquidity"), + "add_liquidity" + ); + assert_eq!(super::upstream_registry_entry_name_to_candidate_kind("swap_base_in"), "swap"); + assert_eq!( + super::upstream_registry_entry_name_to_candidate_kind("claim_protocol_fee"), + "claim_fee" + ); + assert_eq!( + super::upstream_registry_entry_name_to_candidate_kind("close_open_orders_account"), + "open_orders_close" + ); + assert_eq!( + super::upstream_registry_entry_name_to_candidate_kind("unknown_surface"), + "upstream_git_instruction" + ); + } + + #[test] + fn target_filter_accepts_open_orders_close_candidates() { + let candidate = make_candidate("open_orders_close", "CloseOpenOrdersAccount"); + assert!(super::candidate_matches_target_event(&candidate, Some("open_orders_close"))); + assert!(super::candidate_matches_target_event(&candidate, Some("unknown_non_swap"))); + assert!(!super::candidate_matches_target_event(&candidate, Some("close_market"))); + } } diff --git a/kb_lib/src/upstream_registry.rs b/kb_lib/src/upstream_registry.rs new file mode 100644 index 0000000..be2e19f --- /dev/null +++ b/kb_lib/src/upstream_registry.rs @@ -0,0 +1,58 @@ +// file: kb_lib/src/upstream_registry.rs + +//! Public service facade for the upstream Git registry. +//! +//! The registry is intentionally read-only in this tranche and does not touch +//! SQLite. It only exposes discovery seeds and static upstream-derived metadata +//! for UI inspection and later corpus validation. + +/// Read-only upstream registry service. +#[derive(Clone, Debug, Default)] +pub struct UpstreamRegistryService; + +impl UpstreamRegistryService { + /// Creates a new read-only upstream registry service. + pub fn new() -> crate::UpstreamRegistryService { + return crate::UpstreamRegistryService; + } + + /// Returns every static registry entry. + pub fn all_entries(&self) -> std::vec::Vec { + return crate::upstream_registry_match::upstream_registry_all_entries(); + } + + /// Searches the static registry with optional filters. + pub fn search( + &self, + request: &crate::UpstreamRegistrySearchRequestDto, + ) -> crate::UpstreamRegistrySearchResultDto { + return crate::upstream_registry_match::upstream_registry_search(request); + } +} + +#[cfg(test)] +mod tests { + #[test] + fn service_returns_static_registry_entries() { + let service = crate::UpstreamRegistryService::new(); + let entries = service.all_entries(); + assert!(!entries.is_empty()); + } + + #[test] + fn service_search_preserves_normalized_request() { + let service = crate::UpstreamRegistryService::new(); + let request = crate::UpstreamRegistrySearchRequestDto { + decoder_code: Some("raydium-cpmm".to_string()), + program_id: None, + program_family: None, + surface_kind: None, + entry_kind: None, + proof_status: None, + limit: Some(10), + }; + let result = service.search(&request); + assert_eq!(result.request, request); + assert!(!result.entries.is_empty()); + } +} diff --git a/kb_lib/src/upstream_registry_generated.rs b/kb_lib/src/upstream_registry_generated.rs new file mode 100644 index 0000000..2304cdc --- /dev/null +++ b/kb_lib/src/upstream_registry_generated.rs @@ -0,0 +1,15595 @@ +// file: kb_lib/src/upstream_registry_generated.rs +//! Static entries for the upstream Git registry. +//! +//! These rows are intentionally conservative. Bootstrap rows keep the 0.7.47 +//! discovery plan visible, while upstream Git rows carry only source-level facts +//! extracted from decoder files or from the discriminator convention used by those +//! generated decoders. None of these rows are local corpus proof. + +const UPSTREAM_GIT_SOURCE_REPO: &str = "sevenlabs-hq/carbon"; + +const UPSTREAM_GIT_PROGRAM_NOTES: &str = "program id extracted from upstream Git decoder source; not corpus-verified; no trade/candle/materialization proof"; +const UPSTREAM_GIT_DISCRIMINATOR_NOTES: &str = "entry name and discriminator extracted from upstream Git decoder source or from the discriminator convention used by that upstream decoder; not corpus-verified; no trade/candle/materialization proof"; +const UPSTREAM_GIT_ALIAS_PROGRAM_NOTES: &str = "upstream Git decoder name kept as a discovery alias; program id and discriminator rows are represented by the canonical decoder entry to avoid duplicate registry keys"; + +const fn upstream_git_program_entry( + decoder_code: &'static str, + program_id: std::option::Option<&'static str>, + program_family: &'static str, + surface_kind: &'static str, + source_path: &'static str, +) -> crate::UpstreamRegistryEntry { + return crate::UpstreamRegistryEntry { + source_repo: Some(UPSTREAM_GIT_SOURCE_REPO), + source_path: Some(source_path), + decoder_code, + program_id, + program_family, + surface_kind, + entry_kind: crate::ENTRY_KIND_PROGRAM, + entry_name: "program", + discriminator_hex: None, + discriminator_len: None, + proof_status: crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED, + notes: UPSTREAM_GIT_PROGRAM_NOTES, + }; +} + +const fn upstream_git_alias_program_entry( + decoder_code: &'static str, + program_family: &'static str, + surface_kind: &'static str, + source_path: &'static str, +) -> crate::UpstreamRegistryEntry { + return crate::UpstreamRegistryEntry { + source_repo: Some(UPSTREAM_GIT_SOURCE_REPO), + source_path: Some(source_path), + decoder_code, + program_id: None, + program_family, + surface_kind, + entry_kind: crate::ENTRY_KIND_PROGRAM, + entry_name: "program_alias", + discriminator_hex: None, + discriminator_len: None, + proof_status: crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED, + notes: UPSTREAM_GIT_ALIAS_PROGRAM_NOTES, + }; +} + +const fn upstream_git_discriminator_entry( + decoder_code: &'static str, + program_id: std::option::Option<&'static str>, + program_family: &'static str, + surface_kind: &'static str, + entry_kind: &'static str, + entry_name: &'static str, + discriminator_hex: &'static str, + discriminator_len: u16, + source_path: &'static str, +) -> crate::UpstreamRegistryEntry { + return crate::UpstreamRegistryEntry { + source_repo: Some(UPSTREAM_GIT_SOURCE_REPO), + source_path: Some(source_path), + decoder_code, + program_id, + program_family, + surface_kind, + entry_kind, + entry_name, + discriminator_hex: Some(discriminator_hex), + discriminator_len: Some(discriminator_len), + proof_status: crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED, + notes: UPSTREAM_GIT_DISCRIMINATOR_NOTES, + }; +} + +/// Static registry snapshot for 0.7.47 upstream Git discovery preparation. +pub(crate) const UPSTREAM_REGISTRY_ENTRIES: &[crate::UpstreamRegistryEntry] = &[ + upstream_git_program_entry( + "address-lookup-table", + Some(crate::ADDRESS_LOOKUP_TABLE_PROGRAM_ID), + "solana_core", + "lookup_table", + "decoders/address-lookup-table-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "associated-token-account", + Some(crate::ASSOCIATED_TOKEN_PROGRAM_ID), + "spl_associated_token_account", + "token_account", + "decoders/associated-token-account-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + "decoders/bonkswap-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + "decoders/boop-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "bubblegum", + Some(crate::BUBBLEGUM_PROGRAM_ID), + "metaplex", + "nft_compression", + "decoders/bubblegum_decoder/src/lib.rs", + ), + upstream_git_program_entry( + "circle-message-transmitter-v2", + Some(crate::CIRCLE_MESSAGE_TRANSMITTER_V2_PROGRAM_ID), + "circle", + "bridge_messaging", + "decoders/circle-message-transmitter-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "circle-token-messenger-v2", + Some(crate::CIRCLE_TOKEN_MESSENGER_V2_PROGRAM_ID), + "circle", + "bridge_token", + "decoders/circle-token-messenger-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + "decoders/dflow-aggregator-v4-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + "decoders/drift-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "fluxbeam", + Some(crate::FLUXBEAM_PROGRAM_ID), + "fluxbeam", + "amm", + "decoders/fluxbeam-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "gavel", + Some(crate::GAVEL_PROGRAM_ID), + "gavel", + "auction", + "decoders/gavel-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + "decoders/heaven-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "jupiter-dca", + Some(crate::JUPITER_DCA_PROGRAM_ID), + "jupiter", + "dca", + "decoders/jupiter-dca-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + "decoders/jupiter-lend-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "jupiter-limit-order-2", + Some(crate::JUPITER_LIMIT_ORDER_2_PROGRAM_ID), + "jupiter", + "limit_order", + "decoders/jupiter-limit-order-2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "jupiter-limit-order", + Some(crate::JUPITER_LIMIT_ORDER_PROGRAM_ID), + "jupiter", + "limit_order", + "decoders/jupiter-limit-order-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "jupiter-perpetuals", + Some(crate::JUPITER_PERPETUALS_PROGRAM_ID), + "jupiter", + "perps", + "decoders/jupiter-perpetuals-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + "decoders/jupiter-swap-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "kamino-farms", + Some(crate::KAMINO_FARMS_PROGRAM_ID), + "kamino", + "farms", + "decoders/kamino-farms-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "kamino-lending", + Some(crate::KAMINO_LENDING_PROGRAM_ID), + "kamino", + "lending", + "decoders/kamino-lending-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "kamino-limit-order", + Some(crate::KAMINO_LIMIT_ORDER_PROGRAM_ID), + "kamino", + "limit_order", + "decoders/kamino-limit-order-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "kamino-vault", + Some(crate::KAMINO_VAULT_PROGRAM_ID), + "kamino", + "vault", + "decoders/kamino-vault-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "lifinity-amm-v2", + Some(crate::LIFINITY_AMM_V2_PROGRAM_ID), + "lifinity", + "amm", + "decoders/lifinity-amm-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + "decoders/marginfi-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "marinade-finance", + Some(crate::MARINADE_FINANCE_PROGRAM_ID), + "marinade", + "staking", + "decoders/marinade-finance-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "memo-program", + Some(crate::MEMO_PROGRAM_ID), + "solana_core", + "memo", + "decoders/memo-program-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + "decoders/meteora-damm-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + "decoders/meteora-dbc-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + "decoders/meteora-dlmm-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "meteora-pools", + Some(crate::METEORA_DAMM_V1_PROGRAM_ID), + "meteora", + "amm", + "decoders/meteora-pools-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + "decoders/meteora-vault-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + "decoders/moonshot-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "mpl-core", + Some(crate::MPL_CORE_PROGRAM_ID), + "metaplex", + "metadata", + "decoders/mpl-core-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "mpl-token-metadata", + Some(crate::MPL_TOKEN_METADATA_PROGRAM_ID), + "metaplex", + "metadata", + "decoders/mpl-token-metadata-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "name-service", + Some(crate::NAME_SERVICE_PROGRAM_ID), + "solana_name_service", + "name_service", + "decoders/name-service-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + "decoders/okx-dex-decoder/src/lib.rs", + ), + upstream_git_alias_program_entry( + "onchain-labs-dex-v1", + "onchain_labs", + "amm", + "decoders/onchain-labs-dex-v1-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + "decoders/onchain-labs-dex-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + "decoders/openbook-v2-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + "decoders/orca-whirlpool-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + "decoders/pancake-swap-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + "decoders/phoenix-v1-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + "decoders/pump-fees-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + "decoders/pump-swap-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + "decoders/pumpfun-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + "decoders/raydium-amm-v4-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + "decoders/raydium-clmm-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + "decoders/raydium-cpmm-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + "decoders/raydium-launchpad-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "raydium-liquidity-locking", + Some(crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), + "raydium", + "liquidity_locking", + "decoders/raydium-liquidity-locking-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "raydium-stable-swap", + Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID), + "raydium", + "stable_swap", + "decoders/raydium-stable-swap-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "sharky", + Some(crate::SHARKY_PROGRAM_ID), + "sharky", + "lending", + "decoders/sharky-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "solayer-restaking-program", + Some(crate::SOLAYER_RESTAKING_PROGRAM_ID), + "solayer", + "restaking", + "decoders/solayer-restaking-program-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + "decoders/stabble-stable-swap-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + "decoders/stabble-weighted-swap-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "stake-program", + Some(crate::STAKE_PROGRAM_ID), + "solana_core", + "stake", + "decoders/stake-program-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "swig", + Some(crate::SWIG_PROGRAM_ID), + "swig", + "wallet_auth", + "decoders/swig-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "system-program", + Some(crate::SYSTEM_PROGRAM_ID), + "solana_core", + "core", + "decoders/system-program-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "token-2022", + Some(crate::SPL_TOKEN_2022_PROGRAM_ID), + "spl_token", + "token", + "decoders/token-2022-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "token-program", + Some(crate::SPL_TOKEN_PROGRAM_ID), + "spl_token", + "token", + "decoders/token-program-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + "decoders/vertigo-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + "decoders/virtuals-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + "decoders/wavebreak-decoder/src/lib.rs", + ), + upstream_git_program_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + "decoders/zeta-decoder/src/lib.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity", + "b59d59438fb63448", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/add_liquidity.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_partner_fee", + "61ce27695e5e7e94", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/claim_partner_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_position_fee", + "b4269a118521a2d3", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/claim_position_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_protocol_fee", + "a5e4853063f9ff21", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/claim_protocol_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_reward", + "955fb5f25e5a9ea2", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/claim_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_config", + "9109489d5f7d3d55", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/close_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_operator_account", + "ab09d54a7817031d", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/close_operator_account.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position", + "7b86510031446262", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/close_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_token_badge", + "6c92566eb3fe0a68", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/close_token_badge.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "bcd8a66c1aa68eb6", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_config", + "c9cff3724b6f2fbd", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/create_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_dynamic_config", + "51fb7a4e4239d052", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/create_dynamic_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_operator_account", + "dd40f695f099e5a3", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/create_operator_account.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_position", + "30d7c59960cbb485", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/create_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_token_badge", + "58ce005b3caf9776", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/create_token_badge.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "dummy_ix", + "ea5fb0b9072a239f", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/dummy_ix.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "fund_reward", + "bc32f9a55d97263f", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/fund_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_customizable_pool", + "14a1f118bdddb402", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/initialize_customizable_pool.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_pool", + "5fb40aac54aee828", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/initialize_pool.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_pool_with_dynamic_config", + "955248c5fdfc440f", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/initialize_pool_with_dynamic_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_reward", + "5f87c0c4f281e644", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/initialize_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "lock_position", + "e33e02fcf70aabb9", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/lock_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permanent_lock_position", + "a5b07d06e7abbad5", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/permanent_lock_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "refresh_vesting", + "095ed80e74ccf700", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/refresh_vesting.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "remove_all_liquidity", + "0a333d2370691855", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/remove_all_liquidity.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "remove_liquidity", + "5055d14818ceb16c", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/remove_liquidity.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "set_pool_status", + "705787df53cc8435", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/set_pool_status.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "split_position", + "acf1dd8aa11dfd2a", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/split_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "split_position2", + "dd93e4cf8cd41177", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/split_position2.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap2", + "414b3f4ceb5b5b88", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/swap2.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_pool_fees", + "76d9cbb33c084659", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/update_pool_fees.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_reward_duration", + "8aaec4a9d5ebfe6b", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/update_reward_duration.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_reward_funder", + "d31c3020d7a02317", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/update_reward_funder.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_ineligible_reward", + "94ce2ac3f7316708", + 8, + "decoders/meteora-damm-v2-decoder/src/instructions/withdraw_ineligible_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_claim_partner_fee", + "76634d0ae2010157", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_claim_partner_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_claim_position_fee", + "c6b6b734610c3138", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_claim_position_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_claim_protocol_fee", + "baf44bfbbc0d1921", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_claim_protocol_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_claim_reward", + "da5693c8ebbcd7e7", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_claim_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_close_config", + "241eef2d3a840e05", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_close_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_close_position", + "149190448f8ed6b2", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_close_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_create_config", + "83cfb4aeb449a536", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_create_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_create_dynamic_config", + "e7c50da4f8d58598", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_create_dynamic_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_create_position", + "9c0f77c61db5dd37", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_create_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_create_token_badge", + "8d788674221c72a0", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_create_token_badge.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_fund_reward", + "68e9ed7ac7bf7955", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_fund_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_initialize_pool", + "e432f655cb428625", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_initialize_pool.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_initialize_reward", + "815bbc03f634b9f9", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_initialize_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_liquidity_change", + "c5ab4e7fe0d3570d", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_liquidity_change.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_lock_position", + "a83f6c53db5202c8", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_lock_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_permanent_lock_position", + "918fa2dada50430b", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_permanent_lock_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_set_pool_status", + "64d54a035f5be492", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_set_pool_status.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_split_position2", + "a520cbae4864e967", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_split_position2.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_swap2", + "bd4233a826507599", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_swap2.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_update_pool_fees", + "4ca5f66666d99c2c", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_update_pool_fees.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_update_reward_duration", + "958741e781994139", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_update_reward_duration.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_update_reward_funder", + "4c9ad00d2873f692", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_update_reward_funder.rs", + ), + upstream_git_discriminator_entry( + "meteora-damm-v2", + Some(crate::METEORA_DAMM_V2_PROGRAM_ID), + "meteora", + "amm", + crate::ENTRY_KIND_EVENT, + "evt_withdraw_ineligible_reward", + "f8d7b84e1fb4b3a8", + 8, + "decoders/meteora-damm-v2-decoder/src/events/evt_withdraw_ineligible_reward.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "add_supply", + "50664639eb58ef08", + 8, + "decoders/bonkswap-decoder/src/instructions/add_supply.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "add_tokens", + "1cda1ed1af9b99f0", + 8, + "decoders/bonkswap-decoder/src/instructions/add_tokens.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_pool", + "8cbdd117ef3eef0b", + 8, + "decoders/bonkswap-decoder/src/instructions/close_pool.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_dual_farm", + "2ab4678ace2bd062", + 8, + "decoders/bonkswap-decoder/src/instructions/create_dual_farm.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_farm", + "4a3b80a057ae99c2", + 8, + "decoders/bonkswap-decoder/src/instructions/create_farm.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_pool", + "e992d18ecf6840bc", + 8, + "decoders/bonkswap-decoder/src/instructions/create_pool.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_provider", + "4a35d3ae26a8e3b1", + 8, + "decoders/bonkswap-decoder/src/instructions/create_provider.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_state", + "d6d3d14f6b69f7de", + 8, + "decoders/bonkswap-decoder/src/instructions/create_state.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_triple_farm", + "9a1ab49112c987ab", + 8, + "decoders/bonkswap-decoder/src/instructions/create_triple_farm.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reset_farm", + "2f4de97576373d71", + 8, + "decoders/bonkswap-decoder/src/instructions/reset_farm.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/bonkswap-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_fees", + "e11b0d064554acbf", + 8, + "decoders/bonkswap-decoder/src/instructions/update_fees.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_reward_tokens", + "f9ec474a683ae11c", + 8, + "decoders/bonkswap-decoder/src/instructions/update_reward_tokens.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_buyback", + "bc4b1ec6632b0c36", + 8, + "decoders/bonkswap-decoder/src/instructions/withdraw_buyback.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_lp_fee", + "95a102d5c3932a41", + 8, + "decoders/bonkswap-decoder/src/instructions/withdraw_lp_fee.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_mercanti_fee", + "fde581252f480bf0", + 8, + "decoders/bonkswap-decoder/src/instructions/withdraw_mercanti_fee.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_project_fee", + "82c98e9c9fcfa816", + 8, + "decoders/bonkswap-decoder/src/instructions/withdraw_project_fee.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_rewards", + "0ad6db8bcd16fb15", + 8, + "decoders/bonkswap-decoder/src/instructions/withdraw_rewards.rs", + ), + upstream_git_discriminator_entry( + "bonkswap", + Some(crate::BONKSWAP_PROGRAM_ID), + "bonkswap", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_shares", + "b0689a69fa5044f4", + 8, + "decoders/bonkswap-decoder/src/instructions/withdraw_shares.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "add_operators", + "a5c73ed651360496", + 8, + "decoders/boop-decoder/src/instructions/add_operators.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "authority_transfer_cancelled_event", + "c0798ce0e5600d8f", + 8, + "decoders/boop-decoder/src/instructions/authority_transfer_cancelled_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "authority_transfer_completed_event", + "a384d980f35c5af9", + 8, + "decoders/boop-decoder/src/instructions/authority_transfer_completed_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "authority_transfer_initiated_event", + "79f65f9be56d94cd", + 8, + "decoders/boop-decoder/src/instructions/authority_transfer_initiated_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "bonding_curve_deployed_event", + "e150b222d927b894", + 8, + "decoders/boop-decoder/src/instructions/bonding_curve_deployed_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "bonding_curve_deployed_fallback_event", + "6afcf373c79ff71f", + 8, + "decoders/boop-decoder/src/instructions/bonding_curve_deployed_fallback_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "bonding_curve_vault_closed_event", + "b9249c52bda4cf4f", + 8, + "decoders/boop-decoder/src/instructions/bonding_curve_vault_closed_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy_token", + "8a7f0e5b26577369", + 8, + "decoders/boop-decoder/src/instructions/buy_token.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_authority_transfer", + "5e837db8b7187de5", + 8, + "decoders/boop-decoder/src/instructions/cancel_authority_transfer.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "close_bonding_curve_vault", + "bd47bdef71423bbd", + 8, + "decoders/boop-decoder/src/instructions/close_bonding_curve_vault.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "collect_meteora_trading_fees", + "f95f7e5b51a253fa", + 8, + "decoders/boop-decoder/src/instructions/collect_meteora_trading_fees.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "collect_trading_fees", + "bd26cdea514d1901", + 8, + "decoders/boop-decoder/src/instructions/collect_trading_fees.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "complete_authority_transfer", + "51e95b84af1f978d", + 8, + "decoders/boop-decoder/src/instructions/complete_authority_transfer.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "config_updated_event", + "f59e81633c64d6dc", + 8, + "decoders/boop-decoder/src/instructions/config_updated_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_meteora_pool", + "f6fe2125e1b029e8", + 8, + "decoders/boop-decoder/src/instructions/create_meteora_pool.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_raydium_pool", + "412d774dccb25402", + 8, + "decoders/boop-decoder/src/instructions/create_raydium_pool.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_raydium_random_pool", + "4e2cad1d84b404ac", + 8, + "decoders/boop-decoder/src/instructions/create_raydium_random_pool.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_token", + "5434cce4188cea4b", + 8, + "decoders/boop-decoder/src/instructions/create_token.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_token_fallback", + "fdb87ec7ebe8aca2", + 8, + "decoders/boop-decoder/src/instructions/create_token_fallback.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "deploy_bonding_curve", + "b459c74ca8ecd98a", + 8, + "decoders/boop-decoder/src/instructions/deploy_bonding_curve.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "deploy_bonding_curve_fallback", + "35e6ac544dae163d", + 8, + "decoders/boop-decoder/src/instructions/deploy_bonding_curve_fallback.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_into_raydium", + "a859631e753158e0", + 8, + "decoders/boop-decoder/src/instructions/deposit_into_raydium.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "graduate", + "2debe1b511da4082", + 8, + "decoders/boop-decoder/src/instructions/graduate.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/boop-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initiate_authority_transfer", + "d22b65d7778c6ada", + 8, + "decoders/boop-decoder/src/instructions/initiate_authority_transfer.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "liquidity_deposited_into_raydium_event", + "ec32611bc665f814", + 8, + "decoders/boop-decoder/src/instructions/liquidity_deposited_into_raydium_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "lock_raydium_liquidity", + "adff94067a638c16", + 8, + "decoders/boop-decoder/src/instructions/lock_raydium_liquidity.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "operators_added_event", + "f73a7038cbba7098", + 8, + "decoders/boop-decoder/src/instructions/operators_added_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "operators_removed_event", + "2c484b46972a3559", + 8, + "decoders/boop-decoder/src/instructions/operators_removed_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "paused_toggled_event", + "8fdee4e006e640b0", + 8, + "decoders/boop-decoder/src/instructions/paused_toggled_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "raydium_liquidity_locked_event", + "acbd08f189af3b64", + 8, + "decoders/boop-decoder/src/instructions/raydium_liquidity_locked_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "raydium_pool_created_event", + "aab215d754de2265", + 8, + "decoders/boop-decoder/src/instructions/raydium_pool_created_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "raydium_random_pool_created_event", + "98fb80989eeb5335", + 8, + "decoders/boop-decoder/src/instructions/raydium_random_pool_created_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "remove_operators", + "2a145953de25046d", + 8, + "decoders/boop-decoder/src/instructions/remove_operators.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sell_token", + "6d3d28bbe6b087ae", + 8, + "decoders/boop-decoder/src/instructions/sell_token.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "split_trading_fees", + "607ee12fb9d5323a", + 8, + "decoders/boop-decoder/src/instructions/split_trading_fees.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "swap_sol_for_tokens_on_raydium", + "6bf883ef98ea3623", + 8, + "decoders/boop-decoder/src/instructions/swap_sol_for_tokens_on_raydium.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "swap_sol_for_tokens_on_raydium_event", + "f70108a6dd747162", + 8, + "decoders/boop-decoder/src/instructions/swap_sol_for_tokens_on_raydium_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "swap_tokens_for_sol_on_raydium", + "d8ac82942262d7a3", + 8, + "decoders/boop-decoder/src/instructions/swap_tokens_for_sol_on_raydium.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "swap_tokens_for_sol_on_raydium_event", + "4cf9dda241467620", + 8, + "decoders/boop-decoder/src/instructions/swap_tokens_for_sol_on_raydium_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_paused", + "365393c67b61da48", + 8, + "decoders/boop-decoder/src/instructions/toggle_paused.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "token_bought_event", + "4759de7cd7c0e68a", + 8, + "decoders/boop-decoder/src/instructions/token_bought_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "token_created_event", + "607a718a32e39539", + 8, + "decoders/boop-decoder/src/instructions/token_created_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "token_created_fallback_event", + "9dca235ca5a32738", + 8, + "decoders/boop-decoder/src/instructions/token_created_fallback_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "token_graduated_event", + "49746f1a5cd9928d", + 8, + "decoders/boop-decoder/src/instructions/token_graduated_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "token_sold_event", + "ccefb64df1334d42", + 8, + "decoders/boop-decoder/src/instructions/token_sold_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "trading_fees_collected_event", + "e13f1a3786f3d2cb", + 8, + "decoders/boop-decoder/src/instructions/trading_fees_collected_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_EVENT, + "trading_fees_split_event", + "713c9f11fdae877a", + 8, + "decoders/boop-decoder/src/instructions/trading_fees_split_event.rs", + ), + upstream_git_discriminator_entry( + "boop", + Some(crate::BOOP_PROGRAM_ID), + "boop", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_config", + "1d9efcbf0a53db63", + 8, + "decoders/boop-decoder/src/instructions/update_config.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "close_order", + "5a67d11c073fa804", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/close_order.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "e445a52e51cb9a1d", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "create_referral_token_account_idempotent", + "2ee829905525aaaf", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/create_referral_token_account_idempotent.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "fill_order", + "e87a7319c78f88a2", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/fill_order.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "open_order", + "ce58588f268832e0", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/open_order.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap2", + "414b3f4ceb5b5b88", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/swap2.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap2_with_destination", + "5f7bd5f67a0156e7", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/swap2_with_destination.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap2_with_destination_native", + "de64b892bac469a5", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/swap2_with_destination_native.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap_with_destination", + "a8ac184dc59c8765", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/swap_with_destination.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap_with_destination_native", + "cd4d7f6cf120c4c3", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/swap_with_destination_native.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_fee", + "81a4c415b130b4a2", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/transfer_fee.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_sol", + "4e0aecf76d75154c", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/transfer_sol.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_to_sponsor", + "9bb38297c48bfda3", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/transfer_to_sponsor.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "unwrap_sol", + "63280e692d6bacc9", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/unwrap_sol.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "wrap_sol", + "2f3e9bac83cd25c9", + 8, + "decoders/dflow-aggregator-v4-decoder/src/instructions/wrap_sol.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_EVENT, + "fee_event", + "494f4e7fb8d50ddc", + 8, + "decoders/dflow-aggregator-v4-decoder/src/events/fee_event.rs", + ), + upstream_git_discriminator_entry( + "dflow-aggregator-v4", + Some(crate::DFLOW_AGGREGATOR_V4_PROGRAM_ID), + "dflow", + "aggregator", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/dflow-aggregator-v4-decoder/src/events/swap_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "add_insurance_fund_stake", + "fb90730bde2f3eec", + 8, + "decoders/drift-v2-decoder/src/instructions/add_insurance_fund_stake.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "add_perp_lp_shares", + "38d138c577febc75", + 8, + "decoders/drift-v2-decoder/src/instructions/add_perp_lp_shares.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "admin_disable_update_perp_bid_ask_twap", + "11a4522db756bfc7", + 8, + "decoders/drift-v2-decoder/src/instructions/admin_disable_update_perp_bid_ask_twap.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "begin_swap", + "ae6de401f269e869", + 8, + "decoders/drift-v2-decoder/src/instructions/begin_swap.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order", + "5f81edf00831df84", + 8, + "decoders/drift-v2-decoder/src/instructions/cancel_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order_by_user_id", + "6bd3fa8512253964", + 8, + "decoders/drift-v2-decoder/src/instructions/cancel_order_by_user_id.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_orders", + "eee15f9ee36708c2", + 8, + "decoders/drift-v2-decoder/src/instructions/cancel_orders.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_orders_by_ids", + "861390a55ef0d25e", + 8, + "decoders/drift-v2-decoder/src/instructions/cancel_orders_by_ids.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_request_remove_insurance_fund_stake", + "61eb4e3ed42af17f", + 8, + "decoders/drift-v2-decoder/src/instructions/cancel_request_remove_insurance_fund_stake.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "curve_record_event", + "7ff35439bb0e9896", + 8, + "decoders/drift-v2-decoder/src/instructions/curve_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "delete_initialized_perp_market", + "5b9a18576a3bbe42", + 8, + "decoders/drift-v2-decoder/src/instructions/delete_initialized_perp_market.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "delete_initialized_spot_market", + "1f8c43bfbd1465dd", + 8, + "decoders/drift-v2-decoder/src/instructions/delete_initialized_spot_market.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "delete_prelaunch_oracle", + "3ba964314511adfd", + 8, + "decoders/drift-v2-decoder/src/instructions/delete_prelaunch_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "delete_signed_msg_user_orders", + "ddf780fdd4fe2e99", + 8, + "decoders/drift-v2-decoder/src/instructions/delete_signed_msg_user_orders.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "delete_user", + "ba5511f9dbe762fb", + 8, + "decoders/drift-v2-decoder/src/instructions/delete_user.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "delete_user_record_event", + "1f69f046cf9975fe", + 8, + "decoders/drift-v2-decoder/src/instructions/delete_user_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/drift-v2-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_into_perp_market_fee_pool", + "223a39446150f406", + 8, + "decoders/drift-v2-decoder/src/instructions/deposit_into_perp_market_fee_pool.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_into_spot_market_revenue_pool", + "5c28972a7afe8bf6", + 8, + "decoders/drift-v2-decoder/src/instructions/deposit_into_spot_market_revenue_pool.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_into_spot_market_vault", + "30fc7749ffcdaef7", + 8, + "decoders/drift-v2-decoder/src/instructions/deposit_into_spot_market_vault.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "deposit_record_event", + "eee290ba20182aeb", + 8, + "decoders/drift-v2-decoder/src/instructions/deposit_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "disable_user_high_leverage_mode", + "b79b2d00e255d545", + 8, + "decoders/drift-v2-decoder/src/instructions/disable_user_high_leverage_mode.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "enable_user_high_leverage_mode", + "e718e670c9ad49b8", + 8, + "decoders/drift-v2-decoder/src/instructions/enable_user_high_leverage_mode.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "end_swap", + "b1b81bc1220dd291", + 8, + "decoders/drift-v2-decoder/src/instructions/end_swap.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "fill_perp_order", + "0dbcf86786d96af0", + 8, + "decoders/drift-v2-decoder/src/instructions/fill_perp_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "fill_spot_order", + "d4ce82ad1522c728", + 8, + "decoders/drift-v2-decoder/src/instructions/fill_spot_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "force_cancel_orders", + "40b5c43fde4840e8", + 8, + "decoders/drift-v2-decoder/src/instructions/force_cancel_orders.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "force_delete_user", + "02f1c3ace318fe9e", + 8, + "decoders/drift-v2-decoder/src/instructions/force_delete_user.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "fuel_season_record_event", + "9fbe39bcebdc343c", + 8, + "decoders/drift-v2-decoder/src/instructions/fuel_season_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "fuel_sweep_record_event", + "03fe68f218e8e167", + 8, + "decoders/drift-v2-decoder/src/instructions/fuel_sweep_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "funding_payment_record_event", + "e4d53a385ef9b1ec", + 8, + "decoders/drift-v2-decoder/src/instructions/funding_payment_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "funding_rate_record_event", + "d0653a9ea9cdeadd", + 8, + "decoders/drift-v2-decoder/src/instructions/funding_rate_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "init_user_fuel", + "84bfe48dc98a3c30", + 8, + "decoders/drift-v2-decoder/src/instructions/init_user_fuel.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_fuel_overflow", + "58df84a1d0588e2a", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_fuel_overflow.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_high_leverage_mode_config", + "d5a75df6d0825af8", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_high_leverage_mode_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_insurance_fund_stake", + "bbb3f346f85a5c93", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_insurance_fund_stake.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_openbook_v2_fulfillment_config", + "07dd67996b391bc5", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_openbook_v2_fulfillment_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_perp_market", + "8409e5767576753e", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_perp_market.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_phoenix_fulfillment_config", + "87846e6bb9a0a99a", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_phoenix_fulfillment_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_prediction_market", + "f846c6e0e0697dc3", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_prediction_market.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_prelaunch_oracle", + "a9b25419af3e1df7", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_prelaunch_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_protected_maker_mode_config", + "4367dc435820fc08", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_protected_maker_mode_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_protocol_if_shares_transfer_config", + "5983efc8b28d6ac2", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_protocol_if_shares_transfer_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_pyth_lazer_oracle", + "8c6b21d6ebdb6714", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_pyth_lazer_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_pyth_pull_oracle", + "f98cfdf3f84af0ee", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_pyth_pull_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_referrer_name", + "eb7ee70a2aa41a3d", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_referrer_name.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_serum_fulfillment_config", + "c1d384ac46ab075e", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_serum_fulfillment_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_signed_msg_user_orders", + "a4639c7e9c3963b4", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_signed_msg_user_orders.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_spot_market", + "eac4802c5e0f30c9", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_spot_market.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_user", + "6f11b9fa3c7a26fe", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_user.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_user_stats", + "fef34862fb82a8d5", + 8, + "decoders/drift-v2-decoder/src/instructions/initialize_user_stats.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "insurance_fund_record_event", + "34491bdc4ec95625", + 8, + "decoders/drift-v2-decoder/src/instructions/insurance_fund_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "insurance_fund_stake_record_event", + "fc83c1cbd8739d60", + 8, + "decoders/drift-v2-decoder/src/instructions/insurance_fund_stake_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_borrow_for_perp_pnl", + "a911205acf94d11b", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidate_borrow_for_perp_pnl.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_perp", + "4b2377f7bf128b02", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidate_perp.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_perp_pnl_for_deposit", + "ed4bc6ebe9ba4b23", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidate_perp_pnl_for_deposit.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_perp_with_fill", + "5f6f7c6956a9bb22", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidate_perp_with_fill.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_spot", + "6b00802923e5fb12", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidate_spot.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_spot_with_swap_begin", + "0c2bb0539cfb750d", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidate_spot_with_swap_begin.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_spot_with_swap_end", + "8e58a3a0df4b37e1", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidate_spot_with_swap_end.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "liquidation_record_event", + "579a897eecc80ea1", + 8, + "decoders/drift-v2-decoder/src/instructions/liquidation_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "log_user_balances", + "a21523fb2039a1d2", + 8, + "decoders/drift-v2-decoder/src/instructions/log_user_balances.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "lp_record_event", + "1acbd721c6b60a4e", + 8, + "decoders/drift-v2-decoder/src/instructions/lp_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "modify_order", + "2f7c75ffc9c5825e", + 8, + "decoders/drift-v2-decoder/src/instructions/modify_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "modify_order_by_user_id", + "9e4d04fdfcc2a1b3", + 8, + "decoders/drift-v2-decoder/src/instructions/modify_order_by_user_id.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "move_amm_price", + "eb6d0252db76069f", + 8, + "decoders/drift-v2-decoder/src/instructions/move_amm_price.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "new_user_record_event", + "960f8b20cec5e0ac", + 8, + "decoders/drift-v2-decoder/src/instructions/new_user_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "openbook_v2_fulfillment_config_status", + "19ad13bd04d340ee", + 8, + "decoders/drift-v2-decoder/src/instructions/openbook_v2_fulfillment_config_status.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "order_action_record_event", + "e6596f7a478aa493", + 8, + "decoders/drift-v2-decoder/src/instructions/order_action_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "order_record_event", + "29a742f4326ff4ca", + 8, + "decoders/drift-v2-decoder/src/instructions/order_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "pause_spot_market_deposit_withdraw", + "b7773baa8923f256", + 8, + "decoders/drift-v2-decoder/src/instructions/pause_spot_market_deposit_withdraw.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "phoenix_fulfillment_config_status", + "601f71200ccb079a", + 8, + "decoders/drift-v2-decoder/src/instructions/phoenix_fulfillment_config_status.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_and_make_perp_order", + "95750bed2f5f59ed", + 8, + "decoders/drift-v2-decoder/src/instructions/place_and_make_perp_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_and_make_signed_msg_perp_order", + "101a7b835e1daf62", + 8, + "decoders/drift-v2-decoder/src/instructions/place_and_make_signed_msg_perp_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_and_make_spot_order", + "959e5542ef09f362", + 8, + "decoders/drift-v2-decoder/src/instructions/place_and_make_spot_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_and_take_perp_order", + "d53301bb6cdce6e0", + 8, + "decoders/drift-v2-decoder/src/instructions/place_and_take_perp_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_and_take_spot_order", + "bf038a4772c6ca64", + 8, + "decoders/drift-v2-decoder/src/instructions/place_and_take_spot_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_orders", + "3c3f327b0cc53cbe", + 8, + "decoders/drift-v2-decoder/src/instructions/place_orders.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_perp_order", + "45a15dca787e4cb9", + 8, + "decoders/drift-v2-decoder/src/instructions/place_perp_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_signed_msg_taker_order", + "204f658b1906620f", + 8, + "decoders/drift-v2-decoder/src/instructions/place_signed_msg_taker_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_spot_order", + "2d4f51a0f85a5bdc", + 8, + "decoders/drift-v2-decoder/src/instructions/place_spot_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "post_multi_pyth_pull_oracle_updates_atomic", + "f34fcce4e3d064f4", + 8, + "decoders/drift-v2-decoder/src/instructions/post_multi_pyth_pull_oracle_updates_atomic.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "post_pyth_lazer_oracle_update", + "daedaaf5278fa621", + 8, + "decoders/drift-v2-decoder/src/instructions/post_pyth_lazer_oracle_update.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "post_pyth_pull_oracle_update_atomic", + "747a899ee0c3ad77", + 8, + "decoders/drift-v2-decoder/src/instructions/post_pyth_pull_oracle_update_atomic.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "recenter_perp_market_amm", + "18570a73a5be508b", + 8, + "decoders/drift-v2-decoder/src/instructions/recenter_perp_market_amm.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "reclaim_rent", + "dac813c5e359c016", + 8, + "decoders/drift-v2-decoder/src/instructions/reclaim_rent.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "remove_insurance_fund_stake", + "80a68e09febb8fae", + 8, + "decoders/drift-v2-decoder/src/instructions/remove_insurance_fund_stake.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "remove_perp_lp_shares", + "d559d912a037358d", + 8, + "decoders/drift-v2-decoder/src/instructions/remove_perp_lp_shares.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "remove_perp_lp_shares_in_expiring_market", + "53fefd893b7a449c", + 8, + "decoders/drift-v2-decoder/src/instructions/remove_perp_lp_shares_in_expiring_market.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "repeg_amm_curve", + "03246659b48078d5", + 8, + "decoders/drift-v2-decoder/src/instructions/repeg_amm_curve.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "request_remove_insurance_fund_stake", + "8e46cc5c496ab434", + 8, + "decoders/drift-v2-decoder/src/instructions/request_remove_insurance_fund_stake.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "reset_fuel_season", + "c77ac0ff20633fc8", + 8, + "decoders/drift-v2-decoder/src/instructions/reset_fuel_season.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "reset_perp_market_amm_oracle_twap", + "7f0a37a47be22f18", + 8, + "decoders/drift-v2-decoder/src/instructions/reset_perp_market_amm_oracle_twap.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "resize_signed_msg_user_orders", + "890a579612734fa8", + 8, + "decoders/drift-v2-decoder/src/instructions/resize_signed_msg_user_orders.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "resolve_perp_bankruptcy", + "e010b0d6a2d5b7de", + 8, + "decoders/drift-v2-decoder/src/instructions/resolve_perp_bankruptcy.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "resolve_perp_pnl_deficit", + "a8cc44969f7e5f94", + 8, + "decoders/drift-v2-decoder/src/instructions/resolve_perp_pnl_deficit.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "resolve_spot_bankruptcy", + "7cc2f0fec6d5347a", + 8, + "decoders/drift-v2-decoder/src/instructions/resolve_spot_bankruptcy.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "revert_fill", + "eceeb045ef0ab5c1", + 8, + "decoders/drift-v2-decoder/src/instructions/revert_fill.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "set_user_status_to_being_liquidated", + "6a85a0cec1abc0c2", + 8, + "decoders/drift-v2-decoder/src/instructions/set_user_status_to_being_liquidated.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_expired_market", + "78590b197a4d48c1", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_expired_market.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_expired_market_pools_to_revenue_pool", + "3713eea9e35ac8b8", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_expired_market_pools_to_revenue_pool.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_funding_payment", + "de5aca5e1c2d73b7", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_funding_payment.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_lp", + "9be7747161e58b8d", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_lp.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_multiple_pnls", + "7f4275392832987f", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_multiple_pnls.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_pnl", + "2b3dea2d0f5f9899", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_pnl.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "settle_pnl_record_event", + "ae227d58658b6900", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_pnl_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_revenue_to_insurance_fund", + "c8785d884526c79f", + 8, + "decoders/drift-v2-decoder/src/instructions/settle_revenue_to_insurance_fund.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "signed_msg_order_record_event", + "5fe6cd9a7cd31c86", + 8, + "decoders/drift-v2-decoder/src/instructions/signed_msg_order_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "spot_interest_record_event", + "99729af803e7332c", + 8, + "decoders/drift-v2-decoder/src/instructions/spot_interest_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "spot_market_vault_deposit_record_event", + "0a2ba8fbacb0764f", + 8, + "decoders/drift-v2-decoder/src/instructions/spot_market_vault_deposit_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_EVENT, + "swap_record_event", + "4ab80ac1dc9556b2", + 8, + "decoders/drift-v2-decoder/src/instructions/swap_record_event.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "sweep_fuel", + "af6b1338a5f12b45", + 8, + "decoders/drift-v2-decoder/src/instructions/sweep_fuel.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_deposit", + "141493df293fcc6f", + 8, + "decoders/drift-v2-decoder/src/instructions/transfer_deposit.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_pools", + "c5679a196b5a3c5e", + 8, + "decoders/drift-v2-decoder/src/instructions/transfer_pools.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_protocol_if_shares", + "5e5de2f0c3c9b86d", + 8, + "decoders/drift-v2-decoder/src/instructions/transfer_protocol_if_shares.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "trigger_order", + "3f7033e9e82ff0c7", + 8, + "decoders/drift-v2-decoder/src/instructions/trigger_order.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_admin", + "a1b028d53cb8b3e4", + 8, + "decoders/drift-v2-decoder/src/instructions/update_admin.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_amm_jit_intensity", + "b5bf356da6f9378e", + 8, + "decoders/drift-v2-decoder/src/instructions/update_amm_jit_intensity.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_amms", + "c96ad9fd04afe461", + 8, + "decoders/drift-v2-decoder/src/instructions/update_amms.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_discount_mint", + "20fc7ad3421f2ff1", + 8, + "decoders/drift-v2-decoder/src/instructions/update_discount_mint.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_exchange_status", + "53a0fcfa817431df", + 8, + "decoders/drift-v2-decoder/src/instructions/update_exchange_status.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_funding_rate", + "c9b274d4a69048ee", + 8, + "decoders/drift-v2-decoder/src/instructions/update_funding_rate.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_high_leverage_mode_config", + "407ad45d8dd9ca37", + 8, + "decoders/drift-v2-decoder/src/instructions/update_high_leverage_mode_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_initial_pct_to_liquidate", + "d285e180c2320d6d", + 8, + "decoders/drift-v2-decoder/src/instructions/update_initial_pct_to_liquidate.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_insurance_fund_unstaking_period", + "2c452be2ccdfca34", + 8, + "decoders/drift-v2-decoder/src/instructions/update_insurance_fund_unstaking_period.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_k", + "4862098b81e5ac38", + 8, + "decoders/drift-v2-decoder/src/instructions/update_k.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_liquidation_duration", + "1c9a14f966c04947", + 8, + "decoders/drift-v2-decoder/src/instructions/update_liquidation_duration.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_liquidation_margin_buffer_ratio", + "84e0f3a09a5261d7", + 8, + "decoders/drift-v2-decoder/src/instructions/update_liquidation_margin_buffer_ratio.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_lp_cooldown_time", + "c6855829f1773d0e", + 8, + "decoders/drift-v2-decoder/src/instructions/update_lp_cooldown_time.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_oracle_guard_rails", + "83700a3b203628a4", + 8, + "decoders/drift-v2-decoder/src/instructions/update_oracle_guard_rails.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_auction_duration", + "7e6e34ae1eced75a", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_auction_duration.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_bid_ask_twap", + "f717ff41d45addc2", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_bid_ask_twap.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_fee_structure", + "17b26fcb49168c4b", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_fee_structure.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_amm_oracle_twap", + "f14a727bce9918ca", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_amm_oracle_twap.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_amm_summary_stats", + "7a65f9eed109f1f5", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_amm_summary_stats.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_base_spread", + "475f54a8099dc641", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_base_spread.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_concentration_coef", + "184ee87ea9b0e610", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_concentration_coef.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_contract_tier", + "ec800f5fcbd64475", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_contract_tier.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_curve_update_intensity", + "3283069ce2e7bd48", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_curve_update_intensity.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_expiry", + "2cdde397838c166e", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_expiry.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_fee_adjustment", + "c2ae57662b942070", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_fee_adjustment.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_fuel", + "fc8d6e651b63b615", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_fuel.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_funding_period", + "aba1455b818ba11c", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_funding_period.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_high_leverage_margin_ratio", + "5870563118744a9d", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_high_leverage_margin_ratio.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_imf_factor", + "cfc23884234347f4", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_imf_factor.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_liquidation_fee", + "5a89099129089475", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_liquidation_fee.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_margin_ratio", + "82ad6b2d77691a71", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_margin_ratio.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_max_fill_reserve_fraction", + "13ac729a2a87a185", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_max_fill_reserve_fraction.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_max_imbalances", + "0fce49853c085659", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_max_imbalances.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_max_open_interest", + "c24f95e0f666ba8c", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_max_open_interest.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_max_slippage_ratio", + "eb2528c4469236c9", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_max_slippage_ratio.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_max_spread", + "50fc7a3e28da5b64", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_max_spread.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_min_order_size", + "e24a05596cdf2e8d", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_min_order_size.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_name", + "d31f15d2406c42c9", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_name.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_number_of_users", + "233e90b1b43ed7c4", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_number_of_users.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_oracle", + "b6716fa043ae59bf", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_paused_operations", + "351088841edc7955", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_paused_operations.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_per_lp_base", + "679867665990c147", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_per_lp_base.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_status", + "47c9af7affcfc4cf", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_status.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_step_size_and_tick_size", + "e7ff6119928bae04", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_step_size_and_tick_size.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_target_base_asset_amount_per_lp", + "3e5744731d9696a5", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_target_base_asset_amount_per_lp.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_market_unrealized_asset_weight", + "8784cda56d96a66a", + 8, + "decoders/drift-v2-decoder/src/instructions/update_perp_market_unrealized_asset_weight.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_prelaunch_oracle", + "dc841b1be9dc3ddb", + 8, + "decoders/drift-v2-decoder/src/instructions/update_prelaunch_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_prelaunch_oracle_params", + "62cd93f3124b53cf", + 8, + "decoders/drift-v2-decoder/src/instructions/update_prelaunch_oracle_params.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_protected_maker_mode_config", + "56a6ebfd43cadf11", + 8, + "decoders/drift-v2-decoder/src/instructions/update_protected_maker_mode_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_protocol_if_shares_transfer_config", + "22872f5bdc18d435", + 8, + "decoders/drift-v2-decoder/src/instructions/update_protocol_if_shares_transfer_config.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_pyth_pull_oracle", + "e6bfbd5e6c3b4ac5", + 8, + "decoders/drift-v2-decoder/src/instructions/update_pyth_pull_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_serum_fulfillment_config_status", + "ab6df0fb5f019559", + 8, + "decoders/drift-v2-decoder/src/instructions/update_serum_fulfillment_config_status.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_serum_vault", + "db08f660a9795b6e", + 8, + "decoders/drift-v2-decoder/src/instructions/update_serum_vault.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_auction_duration", + "b6b2cb48bb8f9d6b", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_auction_duration.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_fee_structure", + "61d8698371f68e8d", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_fee_structure.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_asset_tier", + "fdd1e70ef2d0f382", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_asset_tier.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_borrow_rate", + "47efec99d23efe4c", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_borrow_rate.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_cumulative_interest", + "27a68bf39ea59be1", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_cumulative_interest.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_expiry", + "d00bd39fe2180bf7", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_expiry.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_fee_adjustment", + "94b6037e9d72dc63", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_fee_adjustment.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_fuel", + "e2fd4c471102aba9", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_fuel.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_if_factor", + "931ee02212e66904", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_if_factor.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_if_paused_operations", + "65d74f4a3b294f0c", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_if_paused_operations.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_liquidation_fee", + "0b0dff35388868b1", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_liquidation_fee.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_margin_weights", + "6d2157c3ff240651", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_margin_weights.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_max_token_borrows", + "3966ccd4fd5f0dc7", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_max_token_borrows.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_max_token_deposits", + "38bf4f121a7950d0", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_max_token_deposits.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_min_order_size", + "5d800b771a14b532", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_min_order_size.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_name", + "11d00101a2d3bce0", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_name.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_oracle", + "72b86625f6bab463", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_oracle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_orders_enabled", + "be4fce0f1ae5e52b", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_orders_enabled.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_paused_operations", + "643d9951b40c06f8", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_paused_operations.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_pool_id", + "16d5c5a08bc15195", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_pool_id.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_revenue_settle_period", + "515c7e29fae19cdb", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_revenue_settle_period.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_scale_initial_asset_weight_start", + "d9cccc76cc82e193", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_scale_initial_asset_weight_start.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_status", + "4e5e10bcc16ee71f", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_status.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_spot_market_step_size_and_tick_size", + "ee998950ce3bfa3d", + 8, + "decoders/drift-v2-decoder/src/instructions/update_spot_market_step_size_and_tick_size.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_state_max_initialize_user_fee", + "ede119edc12d4d61", + 8, + "decoders/drift-v2-decoder/src/instructions/update_state_max_initialize_user_fee.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_state_max_number_of_sub_accounts", + "9b7bd602dda6cc55", + 8, + "decoders/drift-v2-decoder/src/instructions/update_state_max_number_of_sub_accounts.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_state_settlement_duration", + "6144c7eb83503dad", + 8, + "decoders/drift-v2-decoder/src/instructions/update_state_settlement_duration.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_advanced_lp", + "42506bba1bf2425f", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_advanced_lp.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_custom_margin_ratio", + "15dd8cbb20810b7b", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_custom_margin_ratio.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_delegate", + "8bcd8d8d71245ebb", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_delegate.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_fuel_bonus", + "58afc9bede648f39", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_fuel_bonus.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_gov_token_insurance_stake", + "8f63ebbb149fb854", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_gov_token_insurance_stake.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_gov_token_insurance_stake_devnet", + "81b9f3b7e46f40af", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_gov_token_insurance_stake_devnet.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_idle", + "fd85431667a11464", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_idle.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_margin_trading_enabled", + "c25cccdff6bc1fcb", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_margin_trading_enabled.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_name", + "8719b938a5352288", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_name.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_open_orders_count", + "682741d2faa36486", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_open_orders_count.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_pool_id", + "db56496a38da806d", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_pool_id.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_protected_maker_orders", + "72277bc6bb195adb", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_protected_maker_orders.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_quote_asset_insurance_stake", + "fb659c07023f1e17", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_quote_asset_insurance_stake.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_reduce_only", + "c7472a439013566d", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_reduce_only.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_stats_referrer_status", + "ae9a482abf9491cd", + 8, + "decoders/drift-v2-decoder/src/instructions/update_user_stats_referrer_status.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_whitelist_mint", + "a10fa21394789097", + 8, + "decoders/drift-v2-decoder/src/instructions/update_whitelist_mint.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_withdraw_guard_threshold", + "3812273d9bd32c85", + 8, + "decoders/drift-v2-decoder/src/instructions/update_withdraw_guard_threshold.rs", + ), + upstream_git_discriminator_entry( + "drift-v2", + Some(crate::DRIFT_V2_PROGRAM_ID), + "drift", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "b712469c946da122", + 8, + "decoders/drift-v2-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "fluxbeam", + Some(crate::FLUXBEAM_PROGRAM_ID), + "fluxbeam", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_all_token_types", + "205f453c4b4fcdee", + 8, + "decoders/fluxbeam-decoder/src/instructions/deposit_all_token_types.rs", + ), + upstream_git_discriminator_entry( + "fluxbeam", + Some(crate::FLUXBEAM_PROGRAM_ID), + "fluxbeam", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_single_token_type_exact_amount_in", + "63cf042a589d2d37", + 8, + "decoders/fluxbeam-decoder/src/instructions/deposit_single_token_type_exact_amount_in.rs", + ), + upstream_git_discriminator_entry( + "fluxbeam", + Some(crate::FLUXBEAM_PROGRAM_ID), + "fluxbeam", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/fluxbeam-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "fluxbeam", + Some(crate::FLUXBEAM_PROGRAM_ID), + "fluxbeam", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/fluxbeam-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "fluxbeam", + Some(crate::FLUXBEAM_PROGRAM_ID), + "fluxbeam", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_all_token_types", + "bdfe9caed209a4d8", + 8, + "decoders/fluxbeam-decoder/src/instructions/withdraw_all_token_types.rs", + ), + upstream_git_discriminator_entry( + "fluxbeam", + Some(crate::FLUXBEAM_PROGRAM_ID), + "fluxbeam", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_single_token_type_exact_amount_out", + "f3c0468bd19c088b", + 8, + "decoders/fluxbeam-decoder/src/instructions/withdraw_single_token_type_exact_amount_out.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_borrow_sol", + "cc485fd7acc089fc", + 8, + "decoders/heaven-decoder/src/instructions/admin_borrow_sol.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_claim_msol", + "7c303cc7cb312429", + 8, + "decoders/heaven-decoder/src/instructions/admin_claim_msol.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_claim_staking_rewards", + "18a3dcabe1dea6f8", + 8, + "decoders/heaven-decoder/src/instructions/admin_claim_staking_rewards.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_claim_standard_creator_trading_fees", + "b627a819603f4c11", + 8, + "decoders/heaven-decoder/src/instructions/admin_claim_standard_creator_trading_fees.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_deposit_msol", + "cebdd0a61351ca30", + 8, + "decoders/heaven-decoder/src/instructions/admin_deposit_msol.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_mint_msol", + "8cca39c361d5a813", + 8, + "decoders/heaven-decoder/src/instructions/admin_mint_msol.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_repay_sol", + "883d30e8a61acf2e", + 8, + "decoders/heaven-decoder/src/instructions/admin_repay_sol.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_unstake_msol", + "fdda8dfc2809079a", + 8, + "decoders/heaven-decoder/src/instructions/admin_unstake_msol.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_update_standard_liquidity_pool_state", + "63e4293fddf4c8c7", + 8, + "decoders/heaven-decoder/src/instructions/admin_update_standard_liquidity_pool_state.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_withdraw_msol", + "f9db8d48d26ed863", + 8, + "decoders/heaven-decoder/src/instructions/admin_withdraw_msol.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_withdraw_transfer_fee", + "754fa4cb7e4816f6", + 8, + "decoders/heaven-decoder/src/instructions/admin_withdraw_transfer_fee.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy", + "66063d1201daebea", + 8, + "decoders/heaven-decoder/src/instructions/buy.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_standard_creator_trading_fee_protocol_fees", + "00c9e2e47f2d456e", + 8, + "decoders/heaven-decoder/src/instructions/claim_standard_creator_trading_fee_protocol_fees.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_standard_creator_trading_fees", + "a559dd34aaf9226f", + 8, + "decoders/heaven-decoder/src/instructions/claim_standard_creator_trading_fees.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_standard_protocol_trading_fees", + "54ce8cf53fd440ed", + 8, + "decoders/heaven-decoder/src/instructions/claim_standard_protocol_trading_fees.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_standard_reflection_trading_fees", + "4694259366141e17", + 8, + "decoders/heaven-decoder/src/instructions/claim_standard_reflection_trading_fees.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "close_protocol_lookup_table", + "4f48302777032a74", + 8, + "decoders/heaven-decoder/src/instructions/close_protocol_lookup_table.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_EVENT, + "create_liquidity_pool_event", + "74d8ef8dcfd3b27f", + 8, + "decoders/heaven-decoder/src/instructions/create_liquidity_pool_event.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_or_update_protocol_fee_admin", + "157eb014556f351f", + 8, + "decoders/heaven-decoder/src/instructions/create_or_update_protocol_fee_admin.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_or_update_protocol_owner", + "aa7c802830698b94", + 8, + "decoders/heaven-decoder/src/instructions/create_or_update_protocol_owner.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_or_update_protocol_staking_admin", + "04acc4d578321e89", + 8, + "decoders/heaven-decoder/src/instructions/create_or_update_protocol_staking_admin.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_protocol_config", + "7372186f0e3571fe", + 8, + "decoders/heaven-decoder/src/instructions/create_protocol_config.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_protocol_lookup_table", + "f9036399a8f1f3e4", + 8, + "decoders/heaven-decoder/src/instructions/create_protocol_lookup_table.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_standard_liquidity_pool", + "2a2b7e38e70ad035", + 8, + "decoders/heaven-decoder/src/instructions/create_standard_liquidity_pool.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_EVENT, + "create_standard_liquidity_pool_event", + "bd3883904b3ff994", + 8, + "decoders/heaven-decoder/src/instructions/create_standard_liquidity_pool_event.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_EVENT, + "creating_liquidity_pool_event", + "348004a67ab054cf", + 8, + "decoders/heaven-decoder/src/instructions/creating_liquidity_pool_event.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "deactivate_protocol_lookup_table", + "da0c583a962c9848", + 8, + "decoders/heaven-decoder/src/instructions/deactivate_protocol_lookup_table.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "extend_protocol_lookup_table", + "07e3c6016b711f58", + 8, + "decoders/heaven-decoder/src/instructions/extend_protocol_lookup_table.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_protocol_lending", + "00cdedf01b4f1b3b", + 8, + "decoders/heaven-decoder/src/instructions/initialize_protocol_lending.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "remaining_accounts_stub", + "208f535e17223bef", + 8, + "decoders/heaven-decoder/src/instructions/remaining_accounts_stub.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sell", + "33e685a4017f83ad", + 8, + "decoders/heaven-decoder/src/instructions/sell.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "set_protocol_slot_fees", + "b552130f7ecd98f2", + 8, + "decoders/heaven-decoder/src/instructions/set_protocol_slot_fees.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_EVENT, + "trade_event", + "bddb7fd34ee661ee", + 8, + "decoders/heaven-decoder/src/instructions/trade_event.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_allow_create_pool", + "dffce73e60dbf1d6", + 8, + "decoders/heaven-decoder/src/instructions/update_allow_create_pool.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_creator_trading_fee_receiver", + "f6e5c84f1f157819", + 8, + "decoders/heaven-decoder/src/instructions/update_creator_trading_fee_receiver.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_protocol_config", + "c5617b36dda80b87", + 8, + "decoders/heaven-decoder/src/instructions/update_protocol_config.rs", + ), + upstream_git_discriminator_entry( + "heaven", + Some(crate::HEAVEN_PROGRAM_ID), + "heaven", + "launch", + crate::ENTRY_KIND_EVENT, + "user_defined_event", + "21156c14f1f4a783", + 8, + "decoders/heaven-decoder/src/instructions/user_defined_event.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "change_status", + "ec9183e4e311c0ff", + 8, + "decoders/jupiter-lend-decoder/src/instructions/change_status.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "claim", + "3ec6d6c1d59f6cd2", + 8, + "decoders/jupiter-lend-decoder/src/instructions/claim.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "close_claim_account", + "f192cbd83ade5b76", + 8, + "decoders/jupiter-lend-decoder/src/instructions/close_claim_account.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "collect_revenue", + "5760d324f02bf657", + 8, + "decoders/jupiter-lend-decoder/src/instructions/collect_revenue.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "e445a52e51cb9a1d", + 8, + "decoders/jupiter-lend-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "init_claim_account", + "708d2faa2a639091", + 8, + "decoders/jupiter-lend-decoder/src/instructions/init_claim_account.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "init_liquidity", + "5fbdd8b7bc3ef46c", + 8, + "decoders/jupiter-lend-decoder/src/instructions/init_liquidity.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "init_new_protocol", + "c19305208a87d59e", + 8, + "decoders/jupiter-lend-decoder/src/instructions/init_new_protocol.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "init_token_reserve", + "e4eb41819f0f0654", + 8, + "decoders/jupiter-lend-decoder/src/instructions/init_token_reserve.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "operate", + "d96ad06374972a87", + 8, + "decoders/jupiter-lend-decoder/src/instructions/operate.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "pause_user", + "123f2b5eef35650e", + 8, + "decoders/jupiter-lend-decoder/src/instructions/pause_user.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "pre_operate", + "81cd9e9bc69b4885", + 8, + "decoders/jupiter-lend-decoder/src/instructions/pre_operate.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "unpause_user", + "477380fcb67eea3e", + 8, + "decoders/jupiter-lend-decoder/src/instructions/unpause_user.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_authority", + "202e401c954bf358", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_authority.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_auths", + "5d60b29c3975fdd1", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_auths.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_exchange_price", + "eff40af874193596", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_exchange_price.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_guardians", + "2b3efa8a8d758461", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_guardians.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_rate_data_v1", + "0614227a1696b416", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_rate_data_v1.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_rate_data_v2", + "74493592d82de47c", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_rate_data_v2.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_revenue_collector", + "a78e7cf0dc718d3b", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_revenue_collector.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_token_config", + "e77ab54fff4f90a7", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_token_config.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_borrow_config", + "64b0c9aef70236a8", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_user_borrow_config.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_class", + "0cce44873fd43077", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_user_class.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_supply_config", + "d9efe1da2131eab7", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_user_supply_config.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "update_user_withdrawal_limit", + "a209ba09d51ead4e", + 8, + "decoders/jupiter-lend-decoder/src/instructions/update_user_withdrawal_limit.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_borrow_rate_cap", + "9c83e85efe9c0e75", + 8, + "decoders/jupiter-lend-decoder/src/events/log_borrow_rate_cap.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_change_status", + "594d25ac8d1f4a2a", + 8, + "decoders/jupiter-lend-decoder/src/events/log_change_status.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_claim", + "ee329d55973ae72d", + 8, + "decoders/jupiter-lend-decoder/src/events/log_claim.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_collect_revenue", + "40c616c27b57a652", + 8, + "decoders/jupiter-lend-decoder/src/events/log_collect_revenue.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_operate", + "b40851471384ad08", + 8, + "decoders/jupiter-lend-decoder/src/events/log_operate.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_pause_user", + "641172e0b41e34aa", + 8, + "decoders/jupiter-lend-decoder/src/events/log_pause_user.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_unpause_user", + "aa5b8460b34da81a", + 8, + "decoders/jupiter-lend-decoder/src/events/log_unpause_user.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_authority", + "96989d8f0687c165", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_authority.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_auths", + "58506d306fcb4cfb", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_auths.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_exchange_prices", + "bec245cc1e56b5a3", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_exchange_prices.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_guardians", + "e71cbf33358c4f8e", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_guardians.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_rate_data_v1", + "1e6683c0001e55df", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_rate_data_v1.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_rate_data_v2", + "ce35c34671d35c81", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_rate_data_v2.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_revenue_collector", + "2c8f50fad393b49f", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_revenue_collector.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_token_configs", + "18cdbf822f28e9da", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_token_configs.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_user_borrow_configs", + "d2fbf29fcd219a4a", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_user_borrow_configs.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_user_class", + "b9c16af80b350088", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_user_class.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_user_supply_configs", + "8ea0155a57581233", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_user_supply_configs.rs", + ), + upstream_git_discriminator_entry( + "jupiter-lend", + Some(crate::JUPITER_LEND_PROGRAM_ID), + "jupiter", + "lending", + crate::ENTRY_KIND_EVENT, + "log_update_user_withdrawal_limit", + "728398bd78fd5869", + 8, + "decoders/jupiter-lend-decoder/src/events/log_update_user_withdrawal_limit.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "claim", + "3ec6d6c1d59f6cd2", + 8, + "decoders/jupiter-swap-decoder/src/instructions/claim.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "claim_token", + "74ce1bbfa6130049", + 8, + "decoders/jupiter-swap-decoder/src/instructions/claim_token.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "close_token", + "1a4aec976840b7f9", + 8, + "decoders/jupiter-swap-decoder/src/instructions/close_token.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "e445a52e51cb9a1d", + 8, + "decoders/jupiter-swap-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "create_token_account", + "93f17b64f484ae76", + 8, + "decoders/jupiter-swap-decoder/src/instructions/create_token_account.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "create_token_ledger", + "e8f2c5fdf08f8134", + 8, + "decoders/jupiter-swap-decoder/src/instructions/create_token_ledger.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "exact_out_route", + "d033ef977b2bed5c", + 8, + "decoders/jupiter-swap-decoder/src/instructions/exact_out_route.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "exact_out_route_v2", + "9d8ab85215f4f324", + 8, + "decoders/jupiter-swap-decoder/src/instructions/exact_out_route_v2.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "route", + "e517cb977ae3ad2a", + 8, + "decoders/jupiter-swap-decoder/src/instructions/route.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "route_v2", + "bb64facc31c4af14", + 8, + "decoders/jupiter-swap-decoder/src/instructions/route_v2.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "route_with_token_ledger", + "96564774a75d0e68", + 8, + "decoders/jupiter-swap-decoder/src/instructions/route_with_token_ledger.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "set_token_ledger", + "e455b9704e4f4d02", + 8, + "decoders/jupiter-swap-decoder/src/instructions/set_token_ledger.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "shared_accounts_exact_out_route", + "b0d169a89a7d453e", + 8, + "decoders/jupiter-swap-decoder/src/instructions/shared_accounts_exact_out_route.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "shared_accounts_exact_out_route_v2", + "3560e5cad8bbfa18", + 8, + "decoders/jupiter-swap-decoder/src/instructions/shared_accounts_exact_out_route_v2.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "shared_accounts_route", + "c1209b3341d69c81", + 8, + "decoders/jupiter-swap-decoder/src/instructions/shared_accounts_route.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "shared_accounts_route_v2", + "d19853937cfed8e9", + 8, + "decoders/jupiter-swap-decoder/src/instructions/shared_accounts_route_v2.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "shared_accounts_route_with_token_ledger", + "e6798f50779f6aaa", + 8, + "decoders/jupiter-swap-decoder/src/instructions/shared_accounts_route_with_token_ledger.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_EVENT, + "best_swap_out_amount_violation", + "7c42c433daad2e5d", + 8, + "decoders/jupiter-swap-decoder/src/events/best_swap_out_amount_violation.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_EVENT, + "candidate_swap_results", + "2d09f41ee534a87b", + 8, + "decoders/jupiter-swap-decoder/src/events/candidate_swap_results.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_EVENT, + "fee_event", + "494f4e7fb8d50ddc", + 8, + "decoders/jupiter-swap-decoder/src/events/fee_event.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/jupiter-swap-decoder/src/events/swap_event.rs", + ), + upstream_git_discriminator_entry( + "jupiter-swap", + Some(crate::JUPITER_SWAP_PROGRAM_ID), + "jupiter", + "aggregator", + crate::ENTRY_KIND_EVENT, + "swaps_event", + "982f4eebc0606e6a", + 8, + "decoders/jupiter-swap-decoder/src/events/swaps_event.rs", + ), + upstream_git_discriminator_entry( + "lifinity-amm-v2", + Some(crate::LIFINITY_AMM_V2_PROGRAM_ID), + "lifinity", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_all_token_types", + "205f453c4b4fcdee", + 8, + "decoders/lifinity-amm-v2-decoder/src/instructions/deposit_all_token_types.rs", + ), + upstream_git_discriminator_entry( + "lifinity-amm-v2", + Some(crate::LIFINITY_AMM_V2_PROGRAM_ID), + "lifinity", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/lifinity-amm-v2-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "lifinity-amm-v2", + Some(crate::LIFINITY_AMM_V2_PROGRAM_ID), + "lifinity", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_all_token_types", + "bdfe9caed209a4d8", + 8, + "decoders/lifinity-amm-v2-decoder/src/instructions/withdraw_all_token_types.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_borrow", + "047e74353005d41f", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_borrow.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_account_borrow_event", + "df60510a9c631a3b", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_borrow_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_close_balance", + "f5362904f3ca1f11", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_close_balance.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_deposit", + "ab5eeb675240d48c", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_deposit.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_account_deposit_event", + "a136edd969f87a97", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_deposit_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_end_flashloan", + "697cc96a9902089c", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_end_flashloan.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_liquidate", + "d6a997d5fba756db", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_liquidate.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_account_liquidate_event", + "a6a0f99ab72717f2", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_liquidate_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_repay", + "4fd1acb1de33ad97", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_repay.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_account_repay_event", + "10dc376f07501019", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_repay_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_settle_emissions", + "a13a88aef2df9cb0", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_settle_emissions.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_start_flashloan", + "0e8321dc51bab46b", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_start_flashloan.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_withdraw", + "24484a13d2d2c0c0", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_withdraw.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_account_withdraw_emissions", + "ea1654d676b08caa", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_withdraw_emissions.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_account_withdraw_event", + "03dc94f321f93658", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_account_withdraw_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_accrue_bank_interest", + "6cc91e572f4161bc", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_accrue_bank_interest.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_add_bank", + "d744484ed0da67b6", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_add_bank.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_add_bank_with_seed", + "4cd3d5ab754e9e4c", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_add_bank_with_seed.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_pool_bank_accrue_interest_event", + "6875bb9c6f9a6aba", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_bank_accrue_interest_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_pool_bank_collect_fees_event", + "657761faa9af9cfd", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_bank_collect_fees_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_pool_bank_configure_event", + "f623e96e5d98eb28", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_bank_configure_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_pool_bank_create_event", + "ecdcc93fef7e88f9", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_bank_create_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "lending_pool_bank_handle_bankruptcy_event", + "a64d298c245e0a39", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_bank_handle_bankruptcy_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_collect_bank_fees", + "c905d774e65c4b96", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_collect_bank_fees.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_configure_bank", + "79ad9c285d9438ed", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_configure_bank.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_handle_bankruptcy", + "a20b388b5a8046ad", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_handle_bankruptcy.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_setup_emissions", + "ce6178ac71cca946", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_setup_emissions.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "lending_pool_update_emissions_parameters", + "37d5e0a89935c528", + 8, + "decoders/marginfi-v2-decoder/src/instructions/lending_pool_update_emissions_parameters.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "marginfi_account_create_event", + "b70575687ac74433", + 8, + "decoders/marginfi-v2-decoder/src/instructions/marginfi_account_create_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "marginfi_account_initialize", + "2b4e3dff9434f99a", + 8, + "decoders/marginfi-v2-decoder/src/instructions/marginfi_account_initialize.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "marginfi_account_transfer_account_authority_event", + "703d8c84fb5c5aca", + 8, + "decoders/marginfi-v2-decoder/src/instructions/marginfi_account_transfer_account_authority_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "marginfi_group_configure", + "3ec7514e210dec3d", + 8, + "decoders/marginfi-v2-decoder/src/instructions/marginfi_group_configure.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "marginfi_group_configure_event", + "f168aca729c3c7aa", + 8, + "decoders/marginfi-v2-decoder/src/instructions/marginfi_group_configure_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_EVENT, + "marginfi_group_create_event", + "e97d3d0e62f088fd", + 8, + "decoders/marginfi-v2-decoder/src/instructions/marginfi_group_create_event.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "marginfi_group_initialize", + "ff43431a5e1f2214", + 8, + "decoders/marginfi-v2-decoder/src/instructions/marginfi_group_initialize.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "set_account_flag", + "38ee12cfc1528aae", + 8, + "decoders/marginfi-v2-decoder/src/instructions/set_account_flag.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "set_new_account_authority", + "99a23254b6c94ab3", + 8, + "decoders/marginfi-v2-decoder/src/instructions/set_new_account_authority.rs", + ), + upstream_git_discriminator_entry( + "marginfi-v2", + Some(crate::MARGINFI_V2_PROGRAM_ID), + "marginfi", + "lending", + crate::ENTRY_KIND_INSTRUCTION, + "unset_account_flag", + "385138555c31ff46", + 8, + "decoders/marginfi-v2-decoder/src/instructions/unset_account_flag.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "claim_creator_trading_fee", + "52dcfabd03556b2d", + 8, + "decoders/meteora-dbc-decoder/src/instructions/claim_creator_trading_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "claim_protocol_fee", + "a5e4853063f9ff21", + 8, + "decoders/meteora-dbc-decoder/src/instructions/claim_protocol_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "claim_trading_fee", + "08ec5931987db151", + 8, + "decoders/meteora-dbc-decoder/src/instructions/claim_trading_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "close_claim_fee_operator", + "268652d85f7c1163", + 8, + "decoders/meteora-dbc-decoder/src/instructions/close_claim_fee_operator.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "create_claim_fee_operator", + "a93ecf6b3abba26d", + 8, + "decoders/meteora-dbc-decoder/src/instructions/create_claim_fee_operator.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "create_config", + "c9cff3724b6f2fbd", + 8, + "decoders/meteora-dbc-decoder/src/instructions/create_config.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "create_locker", + "a75a899a4b2f1154", + 8, + "decoders/meteora-dbc-decoder/src/instructions/create_locker.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "create_partner_metadata", + "c0a8eabfbce2e3ff", + 8, + "decoders/meteora-dbc-decoder/src/instructions/create_partner_metadata.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "create_virtual_pool_metadata", + "2d61bb67fe6d7c86", + 8, + "decoders/meteora-dbc-decoder/src/instructions/create_virtual_pool_metadata.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "creator_withdraw_surplus", + "a50389071c864c50", + 8, + "decoders/meteora-dbc-decoder/src/instructions/creator_withdraw_surplus.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_claim_creator_trading_fee_event", + "821d783023b63034", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_claim_creator_trading_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_claim_protocol_fee_event", + "8cd848aed8ea5eb8", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_claim_protocol_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_claim_trading_fee_event", + "1355953c26eaf904", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_claim_trading_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_close_claim_fee_operator_event", + "e09bd35f2938a922", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_close_claim_fee_operator_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_create_claim_fee_operator_event", + "4e1c7bef11ee4ec4", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_create_claim_fee_operator_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_create_config_event", + "1fe3bff0d2b5fea5", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_create_config_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_create_config_v2_event", + "2c22ec1acb0d21cb", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_create_config_v2_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_create_damm_v2_migration_metadata_event", + "c97cbeb7c6cc7e03", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_create_damm_v2_migration_metadata_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_create_meteora_migration_metadata_event", + "465597deba6c23dd", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_create_meteora_migration_metadata_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_creator_withdraw_surplus_event", + "310164615c8cb653", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_creator_withdraw_surplus_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_curve_complete_event", + "9f20ae94fd3f2007", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_curve_complete_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_initialize_pool_event", + "2d736b8ce2ed17db", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_initialize_pool_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_partner_metadata_event", + "3e4811500e7659f8", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_partner_metadata_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_partner_withdraw_migration_fee_event", + "f05f977f7a4cf2a2", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_partner_withdraw_migration_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_partner_withdraw_surplus_event", + "75b83ffdcde95dfa", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_partner_withdraw_surplus_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_protocol_withdraw_surplus_event", + "89113d22b7254e0f", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_protocol_withdraw_surplus_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_swap2_event", + "17a2d450166ea0b8", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_swap2_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_swap_event", + "a441bd21c9ca28ef", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_swap_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_update_pool_creator_event", + "74804fde5e40643c", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_update_pool_creator_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_virtual_pool_metadata_event", + "72e133886d46fe9d", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_virtual_pool_metadata_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_withdraw_leftover_event", + "57e9960dec09dea9", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_withdraw_leftover_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_EVENT, + "evt_withdraw_migration_fee_event", + "1a375dae2244a10b", + 8, + "decoders/meteora-dbc-decoder/src/instructions/evt_withdraw_migration_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_virtual_pool_with_spl_token", + "8c55d7b06636684f", + 8, + "decoders/meteora-dbc-decoder/src/instructions/initialize_virtual_pool_with_spl_token.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_virtual_pool_with_token2022", + "a976334e916edc9b", + 8, + "decoders/meteora-dbc-decoder/src/instructions/initialize_virtual_pool_with_token2022.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_meteora_damm", + "1b013016b43f76d9", + 8, + "decoders/meteora-dbc-decoder/src/instructions/migrate_meteora_damm.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_meteora_damm_claim_lp_token", + "8b85021e5b917f9a", + 8, + "decoders/meteora-dbc-decoder/src/instructions/migrate_meteora_damm_claim_lp_token.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_meteora_damm_lock_lp_token", + "b137ee9dfb58a52a", + 8, + "decoders/meteora-dbc-decoder/src/instructions/migrate_meteora_damm_lock_lp_token.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "migration_damm_v2", + "9ca9e66735e45040", + 8, + "decoders/meteora-dbc-decoder/src/instructions/migration_damm_v2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "migration_damm_v2_create_metadata", + "6dbd1324c3b7de52", + 8, + "decoders/meteora-dbc-decoder/src/instructions/migration_damm_v2_create_metadata.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "migration_meteora_damm_create_metadata", + "2f5e7e73dde2c285", + 8, + "decoders/meteora-dbc-decoder/src/instructions/migration_meteora_damm_create_metadata.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "partner_withdraw_surplus", + "a8ad4864c962265c", + 8, + "decoders/meteora-dbc-decoder/src/instructions/partner_withdraw_surplus.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "protocol_withdraw_surplus", + "3688e18aacb6d6a7", + 8, + "decoders/meteora-dbc-decoder/src/instructions/protocol_withdraw_surplus.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/meteora-dbc-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "swap2", + "414b3f4ceb5b5b88", + 8, + "decoders/meteora-dbc-decoder/src/instructions/swap2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_pool_creator", + "1407a9213a93a621", + 8, + "decoders/meteora-dbc-decoder/src/instructions/transfer_pool_creator.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_leftover", + "14c6caedebf3b742", + 8, + "decoders/meteora-dbc-decoder/src/instructions/withdraw_leftover.rs", + ), + upstream_git_discriminator_entry( + "meteora-dbc", + Some(crate::METEORA_DBC_PROGRAM_ID), + "meteora", + "bonding_curve", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_migration_fee", + "ed8e2d178106dea2", + 8, + "decoders/meteora-dbc-decoder/src/instructions/withdraw_migration_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity", + "b59d59438fb63448", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity2", + "e4a24e1c46db7473", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity_by_strategy", + "0703967f94283dc8", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_by_strategy.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity_by_strategy2", + "03dd95da6f8d76d5", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_by_strategy2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity_by_strategy_one_side", + "2905eeaf64e106cd", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_by_strategy_one_side.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity_by_weight", + "1c8cee63e7a21595", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_by_weight.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "add_liquidity_event", + "1bb299ba2fc48c2d", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity_one_side", + "5e9b6797465fdca5", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_one_side.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity_one_side_precise", + "a1c26754ab47fa9a", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_one_side_precise.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "add_liquidity_one_side_precise2", + "2133a3c975627de7", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/add_liquidity_one_side_precise2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_fee", + "a9204f8988e84689", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/claim_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_fee2", + "70bf65ab1c907fbb", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/claim_fee2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "claim_fee_event", + "ad50eb0f74139021", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/claim_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_reward", + "955fb5f25e5a9ea2", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/claim_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_reward2", + "be037f77b2579db7", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/claim_reward2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "claim_reward_event", + "cf100eaab0472835", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/claim_reward_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_claim_protocol_fee_operator", + "082957235030791a", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/close_claim_protocol_fee_operator.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position", + "7b86510031446262", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/close_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position2", + "ae5a2373ba2893e2", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/close_position2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position_if_empty", + "3b7cd4765b986e9d", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/close_position_if_empty.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_preset_parameter", + "04949164861ab53d", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/close_preset_parameter.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_preset_parameter2", + "27195f6b7411731c", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/close_preset_parameter2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "composition_fee_event", + "5a755d5218f439be", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/composition_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "create_claim_protocol_fee_operator", + "331396fc699d305b", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/create_claim_protocol_fee_operator.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "decrease_position_length_event", + "8c355347761f9a7e", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/decrease_position_length_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "dynamic_fee_parameter_update_event", + "27ba95923e405097", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/dynamic_fee_parameter_update_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "fee_parameter_update_event", + "c1f11d79f5c27c6f", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/fee_parameter_update_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "fund_reward", + "bc32f9a55d97263f", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/fund_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "fund_reward_event", + "83f1cdf265fcd8bf", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/fund_reward_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "go_to_a_bin", + "9248aee028fd54ae", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/go_to_a_bin.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "go_to_a_bin_event", + "3b7acadcb7d77c02", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/go_to_a_bin_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "increase_observation_event", + "fafec85f924f8ef6", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/increase_observation_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "increase_oracle_length", + "be3d7d57674f9ead", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/increase_oracle_length.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "increase_position_length_event", + "d5794cf316fe6687", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/increase_position_length_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_bin_array", + "235613b94ed44bd3", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_bin_array.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_bin_array_bitmap_extension", + "2f9de2b40cf02147", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_bin_array_bitmap_extension.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_customizable_permissionless_lb_pair", + "2e2729876fb7c840", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_customizable_permissionless_lb_pair.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_customizable_permissionless_lb_pair2", + "f349817e3313f16b", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_customizable_permissionless_lb_pair2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_lb_pair", + "2d9aedd2dd0fa65c", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_lb_pair.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_lb_pair2", + "493b2478ed536cc6", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_lb_pair2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_permission_lb_pair", + "6c66d555fb033515", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_permission_lb_pair.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_position", + "dbc0ea47bebf6650", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_position_by_operator", + "fbbdbef475fe2394", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_position_by_operator.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_position_pda", + "2e527d92558de499", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_position_pda.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_preset_parameter", + "42bc47d3626d0eba", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_preset_parameter.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_preset_parameter2", + "b807f0ab672fb779", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_preset_parameter2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_reward", + "5f87c0c4f281e644", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "initialize_reward_event", + "32e2cc12c8200e2d", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_reward_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_token_badge", + "fd4dcd5f1be059df", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/initialize_token_badge.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "lb_pair_create_event", + "b67d6b454f2e369f", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/lb_pair_create_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_bin_array", + "11179fd365b829f1", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/migrate_bin_array.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_position", + "0f843b32c706fb2e", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/migrate_position.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "position_close_event", + "5505a664da57e681", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/position_close_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "position_create_event", + "652590f4d9bb6025", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/position_create_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "remove_all_liquidity", + "0a333d2370691855", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/remove_all_liquidity.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "remove_liquidity", + "5055d14818ceb16c", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/remove_liquidity.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "remove_liquidity2", + "e6d7527ff165e392", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/remove_liquidity2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "remove_liquidity_by_range", + "1a526698f04a691a", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/remove_liquidity_by_range.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "remove_liquidity_by_range2", + "cc02c391359191cd", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/remove_liquidity_by_range2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "remove_liquidity_event", + "8dc7b67b9f5ed766", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/remove_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_activation_point", + "5bf90fa51a81fe7d", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/set_activation_point.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_pair_status", + "43f8e7899a95d9ae", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/set_pair_status.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_pair_status_permissionless", + "4e3b98d346b72ed0", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/set_pair_status_permissionless.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_pre_activation_duration", + "a53dc9f4829f1664", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/set_pre_activation_duration.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_pre_activation_swap_address", + "398b2f7bd850df0a", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/set_pre_activation_swap_address.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap2", + "414b3f4ceb5b5b88", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/swap2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/swap_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_exact_out", + "fa49652126cf4bb8", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/swap_exact_out.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_exact_out2", + "2bd7f784893cf351", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/swap_exact_out2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_with_price_impact", + "38ade6d0ade49ccd", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/swap_with_price_impact.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_with_price_impact2", + "4a62c0d6b1334b33", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/swap_with_price_impact2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_base_fee_parameters", + "4ba8dfa110c3032f", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_base_fee_parameters.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_dynamic_fee_parameters", + "5ca12ef6ffbd1616", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_dynamic_fee_parameters.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_fees_and_reward2", + "208eb89a6741b858", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_fees_and_reward2.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_fees_and_rewards", + "9ae6fa0decd14bdf", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_fees_and_rewards.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "update_position_lock_release_point_event", + "81107e4c9c5c6ad1", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_position_lock_release_point_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_position_operator", + "cab8678fb4bf74d9", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_position_operator.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "update_position_operator_event", + "f7bb4cd73f1e4cc2", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_position_operator_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_reward_duration", + "8aaec4a9d5ebfe6b", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_reward_duration.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "update_reward_duration_event", + "6f2cf13dac36a92b", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_reward_duration_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_reward_funder", + "d31c3020d7a02317", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_reward_funder.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "update_reward_funder_event", + "e6474ce314ef3a72", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/update_reward_funder_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_ineligible_reward", + "94ce2ac3f7316708", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/withdraw_ineligible_reward.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_EVENT, + "withdraw_ineligible_reward_event", + "d21b0d95c8e38b4e", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/withdraw_ineligible_reward_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-dlmm", + Some(crate::METEORA_DLMM_PROGRAM_ID), + "meteora", + "dlmm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_protocol_fee", + "9ec99ebd215da267", + 8, + "decoders/meteora-dlmm-decoder/src/instructions/withdraw_protocol_fee.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "add_liquidity_event", + "1bb299ba2fc48c2d", + 8, + "decoders/meteora-vault-decoder/src/instructions/add_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "add_strategy", + "407b7fe3c0eac614", + 8, + "decoders/meteora-vault-decoder/src/instructions/add_strategy.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "claim_reward_event", + "cf100eaab0472835", + 8, + "decoders/meteora-vault-decoder/src/instructions/claim_reward_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "collect_dust", + "f6951552a04afef0", + 8, + "decoders/meteora-vault-decoder/src/instructions/collect_dust.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/meteora-vault-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_strategy", + "f65239e283defdf9", + 8, + "decoders/meteora-vault-decoder/src/instructions/deposit_strategy.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "enable_vault", + "9152f19c1a9ae9d3", + 8, + "decoders/meteora-vault-decoder/src/instructions/enable_vault.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/meteora-vault-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_strategy", + "d0779091b23969fc", + 8, + "decoders/meteora-vault-decoder/src/instructions/initialize_strategy.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "performance_fee_event", + "25aecdd0b95ec642", + 8, + "decoders/meteora-vault-decoder/src/instructions/performance_fee_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "remove_liquidity_event", + "8dc7b67b9f5ed766", + 8, + "decoders/meteora-vault-decoder/src/instructions/remove_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "remove_strategy", + "b9ee215b86d2611a", + 8, + "decoders/meteora-vault-decoder/src/instructions/remove_strategy.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "remove_strategy2", + "8a68d0947e23c30e", + 8, + "decoders/meteora-vault-decoder/src/instructions/remove_strategy2.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "report_loss_event", + "13181c1baf815a95", + 8, + "decoders/meteora-vault-decoder/src/instructions/report_loss_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "set_operator", + "ee9965a9f3832401", + 8, + "decoders/meteora-vault-decoder/src/instructions/set_operator.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "strategy_deposit_event", + "2c96614dbe6a4ced", + 8, + "decoders/meteora-vault-decoder/src/instructions/strategy_deposit_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "strategy_withdraw_event", + "78bc842dd7a07351", + 8, + "decoders/meteora-vault-decoder/src/instructions/strategy_withdraw_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_EVENT, + "total_amount_event", + "19f1aa47eac398df", + 8, + "decoders/meteora-vault-decoder/src/instructions/total_amount_event.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "b712469c946da122", + 8, + "decoders/meteora-vault-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw2", + "50066f49aed34284", + 8, + "decoders/meteora-vault-decoder/src/instructions/withdraw2.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_directly_from_strategy", + "c98d922ead74c616", + 8, + "decoders/meteora-vault-decoder/src/instructions/withdraw_directly_from_strategy.rs", + ), + upstream_git_discriminator_entry( + "meteora-vault", + Some(crate::METEORA_VAULT_PROGRAM_ID), + "meteora", + "vault", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_strategy", + "1f2da205c1d986bc", + 8, + "decoders/meteora-vault-decoder/src/instructions/withdraw_strategy.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy", + "66063d1201daebea", + 8, + "decoders/moonshot-decoder/src/instructions/buy.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "config_init", + "0deca4ad6afda4b9", + 8, + "decoders/moonshot-decoder/src/instructions/config_init.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "config_update", + "50256d88528759f1", + 8, + "decoders/moonshot-decoder/src/instructions/config_update.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_funds", + "2ae50ae7bd3ec1ae", + 8, + "decoders/moonshot-decoder/src/instructions/migrate_funds.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_EVENT, + "migration_event", + "ffca4c935be74916", + 8, + "decoders/moonshot-decoder/src/instructions/migration_event.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sell", + "33e685a4017f83ad", + 8, + "decoders/moonshot-decoder/src/instructions/sell.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "token_mint", + "032ca4b87b0df5b3", + 8, + "decoders/moonshot-decoder/src/instructions/token_mint.rs", + ), + upstream_git_discriminator_entry( + "moonshot", + Some(crate::MOONSHOT_PROGRAM_ID), + "moonshot", + "launch", + crate::ENTRY_KIND_EVENT, + "trade_event", + "bddb7fd34ee661ee", + 8, + "decoders/moonshot-decoder/src/instructions/trade_event.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_sol_from_swap", + "813b450a844c2314", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_sol_from_swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_sol_proxy_swap", + "1e21d05b1f9d2512", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_sol_proxy_swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_sol_swap", + "5180864972492d5e", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_sol_swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_sol_swap2", + "71841f4a63a93992", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_sol_swap2.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_spl_from_swap", + "054d9032dee4e9ab", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_spl_from_swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_spl_proxy_swap", + "60430c9781a41247", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_spl_proxy_swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_spl_swap", + "eb47d3c472c78f5c", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_spl_swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "commission_spl_swap2", + "ad834e2696a57b0f", + 8, + "decoders/okx-dex-decoder/src/instructions/commission_spl_swap2.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "from_swap_log", + "85ba0f691f4c1f70", + 8, + "decoders/okx-dex-decoder/src/instructions/from_swap_log.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "proxy_swap", + "132c829448382cee", + 8, + "decoders/okx-dex-decoder/src/instructions/proxy_swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/okx-dex-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_INSTRUCTION, + "swap2", + "414b3f4ceb5b5b88", + 8, + "decoders/okx-dex-decoder/src/instructions/swap2.rs", + ), + upstream_git_discriminator_entry( + "okx-dex", + Some(crate::OKX_DEX_PROGRAM_ID), + "okx", + "aggregator", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/okx-dex-decoder/src/instructions/swap_event.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim", + "3ec6d6c1d59f6cd2", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/claim.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "e445a52e51cb9a1d", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_token_account", + "93f17b64f484ae76", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/create_token_account.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_token_account_with_seed", + "7dbfef8c420809e4", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/create_token_account_with_seed.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "proxy_swap", + "132c829448382cee", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/proxy_swap.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_tob", + "aa2955b184501f35", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/swap_tob.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_tob_enhanced", + "be9ca9b0959aa16c", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/swap_tob_enhanced.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_tob_with_receiver", + "dfaad8eacc06f119", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/swap_tob_with_receiver.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_toc", + "bbc9d433109bec3c", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/swap_toc.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_toc_v2", + "7fd66bbd175a2f68", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/swap_toc_v2.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "wrap_unwrap", + "dc658bf929be76c7", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/wrap_unwrap.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "wrap_unwrap_with_receiver", + "7b192f86e9a7abaa", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/instructions/wrap_unwrap_with_receiver.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_EVENT, + "swap_cpi_event", + "555195efa34a9e6f", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/events/swap_cpi_event.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/events/swap_event.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_EVENT, + "swap_to_c_with_fees_cpi_event_v2", + "47894a3cbd75b641", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/events/swap_to_c_with_fees_cpi_event_v2.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_EVENT, + "swap_with_fees_cpi_event", + "bd61430c25d1f71d", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/events/swap_with_fees_cpi_event.rs", + ), + upstream_git_discriminator_entry( + "onchain-labs-dex-v2", + Some(crate::ONCHAIN_LABS_DEX_V2_PROGRAM_ID), + "onchain_labs", + "amm", + crate::ENTRY_KIND_EVENT, + "swap_with_fees_cpi_event_enhanced", + "2548db4332f401d5", + 8, + "decoders/onchain-labs-dex-v2-decoder/src/events/swap_with_fees_cpi_event_enhanced.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_all_and_place_orders", + "809bde3cba28e132", + 8, + "decoders/openbook-v2-decoder/src/instructions/cancel_all_and_place_orders.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_all_orders", + "c453f3ab1164a08f", + 8, + "decoders/openbook-v2-decoder/src/instructions/cancel_all_orders.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order", + "5f81edf00831df84", + 8, + "decoders/openbook-v2-decoder/src/instructions/cancel_order.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order_by_client_order_id", + "73b2c908afb77b77", + 8, + "decoders/openbook-v2-decoder/src/instructions/cancel_order_by_client_order_id.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "close_market", + "589af8ba300e7bf4", + 8, + "decoders/openbook-v2-decoder/src/instructions/close_market.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "close_open_orders_account", + "b04a73d236b35b67", + 8, + "decoders/openbook-v2-decoder/src/instructions/close_open_orders_account.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "close_open_orders_indexer", + "67f9e5e7f7fdc588", + 8, + "decoders/openbook-v2-decoder/src/instructions/close_open_orders_indexer.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "consume_events", + "dd91b1341f2f3fc9", + 8, + "decoders/openbook-v2-decoder/src/instructions/consume_events.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "consume_given_events", + "d1e336046dac2947", + 8, + "decoders/openbook-v2-decoder/src/instructions/consume_given_events.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "create_market", + "67e261ebc8bcfbfe", + 8, + "decoders/openbook-v2-decoder/src/instructions/create_market.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "create_open_orders_account", + "ccb5afde287dbc47", + 8, + "decoders/openbook-v2-decoder/src/instructions/create_open_orders_account.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "create_open_orders_indexer", + "404099ffd947f985", + 8, + "decoders/openbook-v2-decoder/src/instructions/create_open_orders_indexer.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/openbook-v2-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "deposit_log_event", + "12a0579fb4d263af", + 8, + "decoders/openbook-v2-decoder/src/instructions/deposit_log_event.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "edit_order", + "fed0761dadf8c846", + 8, + "decoders/openbook-v2-decoder/src/instructions/edit_order.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "edit_order_pegged", + "3ebb7d451add9d85", + 8, + "decoders/openbook-v2-decoder/src/instructions/edit_order_pegged.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "fill_log_event", + "4af292b9d7ae982a", + 8, + "decoders/openbook-v2-decoder/src/instructions/fill_log_event.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "market_meta_data_log_event", + "6fded69ee50f54c9", + 8, + "decoders/openbook-v2-decoder/src/instructions/market_meta_data_log_event.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "open_orders_position_log_event", + "94c01fc59f76a8bd", + 8, + "decoders/openbook-v2-decoder/src/instructions/open_orders_position_log_event.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_order", + "33c29baf6d82606a", + 8, + "decoders/openbook-v2-decoder/src/instructions/place_order.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_order_pegged", + "8db9fb3f4a55d291", + 8, + "decoders/openbook-v2-decoder/src/instructions/place_order_pegged.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_orders", + "3c3f327b0cc53cbe", + 8, + "decoders/openbook-v2-decoder/src/instructions/place_orders.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_take_order", + "032c47031ac7cb55", + 8, + "decoders/openbook-v2-decoder/src/instructions/place_take_order.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "prune_orders", + "1bd59fbf0c747079", + 8, + "decoders/openbook-v2-decoder/src/instructions/prune_orders.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "refill", + "80cf8e0b36e826c9", + 8, + "decoders/openbook-v2-decoder/src/instructions/refill.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "set_delegate", + "f21e2e4c6ceb80b5", + 8, + "decoders/openbook-v2-decoder/src/instructions/set_delegate.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "set_delegate_log_event", + "1ffa74c1f0d83341", + 8, + "decoders/openbook-v2-decoder/src/instructions/set_delegate_log_event.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "set_market_expired", + "db52dbec3c73c540", + 8, + "decoders/openbook-v2-decoder/src/instructions/set_market_expired.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "settle_funds", + "ee40a3604bab1021", + 8, + "decoders/openbook-v2-decoder/src/instructions/settle_funds.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "settle_funds_expired", + "6b123845e43837a4", + 8, + "decoders/openbook-v2-decoder/src/instructions/settle_funds_expired.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "settle_funds_log_event", + "911107442c29bc0a", + 8, + "decoders/openbook-v2-decoder/src/instructions/settle_funds_log_event.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "stub_oracle_close", + "5c892d032d3c75e0", + 8, + "decoders/openbook-v2-decoder/src/instructions/stub_oracle_close.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "stub_oracle_create", + "ac3f65538d4cc7d8", + 8, + "decoders/openbook-v2-decoder/src/instructions/stub_oracle_create.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "stub_oracle_set", + "6dc64f7941caa18e", + 8, + "decoders/openbook-v2-decoder/src/instructions/stub_oracle_set.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "sweep_fees", + "afe1624776422294", + 8, + "decoders/openbook-v2-decoder/src/instructions/sweep_fees.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "sweep_fees_log_event", + "dd0651e3fcb32931", + 8, + "decoders/openbook-v2-decoder/src/instructions/sweep_fees_log_event.rs", + ), + upstream_git_discriminator_entry( + "openbook-v2", + Some(crate::OPENBOOK_V2_PROGRAM_ID), + "openbook", + "orderbook", + crate::ENTRY_KIND_EVENT, + "total_order_fill_event", + "08eb303aae4c9c69", + 8, + "decoders/openbook-v2-decoder/src/instructions/total_order_fill_event.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_bundled_position", + "2924d8f51b556743", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/close_bundled_position.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position", + "7b86510031446262", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/close_position.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position_with_token_extensions", + "01b6873b9b1963df", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/close_position_with_token_extensions.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_fees", + "a498cf631eba13b6", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/collect_fees.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_fees_v2", + "cf755fbfe5b4e20f", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/collect_fees_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_protocol_fees", + "1643176296b246dc", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/collect_protocol_fees.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_protocol_fees_v2", + "6780de8672c816c8", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/collect_protocol_fees_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_reward", + "4605845756ebb122", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/collect_reward.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_reward_v2", + "b16b25b4a01331d1", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/collect_reward_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "decrease_liquidity", + "a026d06f685b2c01", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/decrease_liquidity.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "decrease_liquidity_v2", + "3a7fbc3e4f52c460", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/decrease_liquidity_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "delete_position_bundle", + "64196302d9ef7cad", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/delete_position_bundle.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "delete_token_badge", + "35924408127511b9", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/delete_token_badge.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "increase_liquidity", + "2e9cf3760dcdfbb2", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/increase_liquidity.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "increase_liquidity_v2", + "851d59df45eeb00a", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/increase_liquidity_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_adaptive_fee_tier", + "4d63d0c88d7b7530", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_adaptive_fee_tier.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_config", + "d07f1501c2bec446", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_config.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_config_extension", + "370935097239d134", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_config_extension.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_fee_tier", + "b74a9ca070022a1e", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_fee_tier.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_pool", + "5fb40aac54aee828", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_pool.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_pool_v2", + "cf2d57f21b3fcc43", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_pool_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_pool_with_adaptive_fee", + "8f5e604cac7c77c7", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_pool_with_adaptive_fee.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_position_bundle", + "752df1951812c241", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_position_bundle.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_position_bundle_with_metadata", + "5d7c10b3f98373f5", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_position_bundle_with_metadata.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_reward", + "5f87c0c4f281e644", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_reward.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_reward_v2", + "5b014d32ebe58531", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_reward_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_tick_array", + "0bbcc1d68d5b95b8", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_tick_array.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_token_badge", + "fd4dcd5f1be059df", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/initialize_token_badge.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_EVENT, + "liquidity_decreased_event", + "da952ac97e982f06", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/liquidity_decreased_event.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_EVENT, + "liquidity_increased_event", + "72dfe50f793cd066", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/liquidity_increased_event.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "lock_position", + "e33e02fcf70aabb9", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/lock_position.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "open_bundled_position", + "a9717eabd5acd431", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/open_bundled_position.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position", + "87802f4d0f98f031", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/open_position.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position_with_metadata", + "f21d86303a6e0e3c", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/open_position_with_metadata.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position_with_token_extensions", + "d42f5f5c726683fa", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/open_position_with_token_extensions.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_EVENT, + "pool_initialized_event", + "f967814dd6a95818", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/pool_initialized_event.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "reset_position_range", + "a47bb48dc264a0af", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/reset_position_range.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_collect_protocol_fees_authority", + "22965df48be1e943", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_collect_protocol_fees_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_config_extension_authority", + "2c5ef17418bc3c8f", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_config_extension_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_default_base_fee_rate", + "e54254fba486b707", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_default_base_fee_rate.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_default_fee_rate", + "76d7d69db6e5d0e4", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_default_fee_rate.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_default_protocol_fee_rate", + "6bcdf9e297235600", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_default_protocol_fee_rate.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_delegated_fee_authority", + "c1eae7938a39037a", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_delegated_fee_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_fee_authority", + "1f013257ed656184", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_fee_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_fee_rate", + "35f38941088c9e06", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_fee_rate.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_fee_rate_by_delegated_fee_authority", + "7979367283e6a268", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_fee_rate_by_delegated_fee_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_initialize_pool_authority", + "7d2b7feb951a6aec", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_initialize_pool_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_preset_adaptive_fee_constants", + "84b94294535886c6", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_preset_adaptive_fee_constants.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_protocol_fee_rate", + "5f0704329a4f9c83", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_protocol_fee_rate.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reward_authority", + "2227b7fc531c557f", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_reward_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reward_authority_by_super_authority", + "f09ac9c6945d3819", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_reward_authority_by_super_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reward_emissions", + "0dc556a86db01bf4", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_reward_emissions.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reward_emissions_super_authority", + "cf05c8d17a3852b7", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_reward_emissions_super_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reward_emissions_v2", + "72e44820c130a066", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_reward_emissions_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_token_badge_authority", + "cfca0420cd4f0db2", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/set_token_badge_authority.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_v2", + "2b04ed0b1ac91e62", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/swap_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_EVENT, + "traded_event", + "38593adef0981085", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/traded_event.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_locked_position", + "b379e52e438ac28a", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/transfer_locked_position.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "two_hop_swap", + "c360ed6c44a2dbe6", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/two_hop_swap.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "two_hop_swap_v2", + "ba8fd11dfe02c275", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/two_hop_swap_v2.rs", + ), + upstream_git_discriminator_entry( + "orca-whirlpool", + Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID), + "orca", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_fees_and_rewards", + "9ae6fa0decd14bdf", + 8, + "decoders/orca-whirlpool-decoder/src/instructions/update_fees_and_rewards.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position", + "7b86510031446262", + 8, + "decoders/pancake-swap-decoder/src/instructions/close_position.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_fund_fee", + "a78a4e95dfc2067e", + 8, + "decoders/pancake-swap-decoder/src/instructions/collect_fund_fee.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "collect_personal_fee_event", + "a6ae69c051a15369", + 8, + "decoders/pancake-swap-decoder/src/instructions/collect_personal_fee_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_protocol_fee", + "8888fcddc2427e59", + 8, + "decoders/pancake-swap-decoder/src/instructions/collect_protocol_fee.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "collect_protocol_fee_event", + "ce57114f2d29d53d", + 8, + "decoders/pancake-swap-decoder/src/instructions/collect_protocol_fee_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_remaining_rewards", + "12eda6c52210d590", + 8, + "decoders/pancake-swap-decoder/src/instructions/collect_remaining_rewards.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "config_change_event", + "f7bd07776a705f97", + 8, + "decoders/pancake-swap-decoder/src/instructions/config_change_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_amm_config", + "8934edd4d7756c68", + 8, + "decoders/pancake-swap-decoder/src/instructions/create_amm_config.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_operation_account", + "3f5794216d230868", + 8, + "decoders/pancake-swap-decoder/src/instructions/create_operation_account.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_permissionless_farm_switch", + "58f2c646f106c4fb", + 8, + "decoders/pancake-swap-decoder/src/instructions/create_permissionless_farm_switch.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "create_personal_position_event", + "641e57f9c4df9ace", + 8, + "decoders/pancake-swap-decoder/src/instructions/create_personal_position_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_pool", + "e992d18ecf6840bc", + 8, + "decoders/pancake-swap-decoder/src/instructions/create_pool.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_support_mint_associated", + "11fb415c88f20ea9", + 8, + "decoders/pancake-swap-decoder/src/instructions/create_support_mint_associated.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "decrease_liquidity", + "a026d06f685b2c01", + 8, + "decoders/pancake-swap-decoder/src/instructions/decrease_liquidity.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "decrease_liquidity_event", + "3ade563a44325538", + 8, + "decoders/pancake-swap-decoder/src/instructions/decrease_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "decrease_liquidity_v2", + "3a7fbc3e4f52c460", + 8, + "decoders/pancake-swap-decoder/src/instructions/decrease_liquidity_v2.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "increase_liquidity", + "2e9cf3760dcdfbb2", + 8, + "decoders/pancake-swap-decoder/src/instructions/increase_liquidity.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "increase_liquidity_event", + "314f69d420221e54", + 8, + "decoders/pancake-swap-decoder/src/instructions/increase_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "increase_liquidity_v2", + "851d59df45eeb00a", + 8, + "decoders/pancake-swap-decoder/src/instructions/increase_liquidity_v2.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_reward", + "5f87c0c4f281e644", + 8, + "decoders/pancake-swap-decoder/src/instructions/initialize_reward.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "liquidity_calculate_event", + "ed7094e63954b4a2", + 8, + "decoders/pancake-swap-decoder/src/instructions/liquidity_calculate_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "liquidity_change_event", + "7ef0afce9e58996b", + 8, + "decoders/pancake-swap-decoder/src/instructions/liquidity_change_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position", + "87802f4d0f98f031", + 8, + "decoders/pancake-swap-decoder/src/instructions/open_position.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position_v2", + "4db84ad67056f1c7", + 8, + "decoders/pancake-swap-decoder/src/instructions/open_position_v2.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position_with_token22_nft", + "4dffae527d1dc92e", + 8, + "decoders/pancake-swap-decoder/src/instructions/open_position_with_token22_nft.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "pool_created_event", + "195e4b2f7063353f", + 8, + "decoders/pancake-swap-decoder/src/instructions/pool_created_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reward_params", + "7034a74b20c9d389", + 8, + "decoders/pancake-swap-decoder/src/instructions/set_reward_params.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/pancake-swap-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/pancake-swap-decoder/src/instructions/swap_event.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_router_base_in", + "457d73daf5baf2c4", + 8, + "decoders/pancake-swap-decoder/src/instructions/swap_router_base_in.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_v2", + "2b04ed0b1ac91e62", + 8, + "decoders/pancake-swap-decoder/src/instructions/swap_v2.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_permissionless_farm_switch", + "967036e9eea10756", + 8, + "decoders/pancake-swap-decoder/src/instructions/toggle_permissionless_farm_switch.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_reward_owner", + "07160c53f22b3079", + 8, + "decoders/pancake-swap-decoder/src/instructions/transfer_reward_owner.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_amm_config", + "313cae889a1c74c8", + 8, + "decoders/pancake-swap-decoder/src/instructions/update_amm_config.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_operation_account", + "7f467728bce33d07", + 8, + "decoders/pancake-swap-decoder/src/instructions/update_operation_account.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_pool_status", + "82576c062ee0757b", + 8, + "decoders/pancake-swap-decoder/src/instructions/update_pool_status.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_reward_infos", + "a3ace0340b9a6adf", + 8, + "decoders/pancake-swap-decoder/src/instructions/update_reward_infos.rs", + ), + upstream_git_discriminator_entry( + "pancake-swap", + Some(crate::PANCAKE_SWAP_PROGRAM_ID), + "pancake", + "amm", + crate::ENTRY_KIND_EVENT, + "update_reward_infos_event", + "6d7fba4e724125ec", + 8, + "decoders/pancake-swap-decoder/src/instructions/update_reward_infos_event.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_all_orders", + "06", + 1, + "decoders/phoenix-v1-decoder/src/instructions/cancel_all_orders.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_all_orders_with_free_funds", + "07", + 1, + "decoders/phoenix-v1-decoder/src/instructions/cancel_all_orders_with_free_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_multiple_orders_by_id", + "0a", + 1, + "decoders/phoenix-v1-decoder/src/instructions/cancel_multiple_orders_by_id.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_multiple_orders_by_id_with_free_funds", + "0b", + 1, + "decoders/phoenix-v1-decoder/src/instructions/cancel_multiple_orders_by_id_with_free_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_up_to", + "08", + 1, + "decoders/phoenix-v1-decoder/src/instructions/cancel_up_to.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_up_to_with_free_funds", + "09", + 1, + "decoders/phoenix-v1-decoder/src/instructions/cancel_up_to_with_free_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "change_fee_recipient", + "6d", + 1, + "decoders/phoenix-v1-decoder/src/instructions/change_fee_recipient.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "change_market_status", + "67", + 1, + "decoders/phoenix-v1-decoder/src/instructions/change_market_status.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "change_seat_status", + "68", + 1, + "decoders/phoenix-v1-decoder/src/instructions/change_seat_status.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "claim_authority", + "65", + 1, + "decoders/phoenix-v1-decoder/src/instructions/claim_authority.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "collect_fees", + "6c", + 1, + "decoders/phoenix-v1-decoder/src/instructions/collect_fees.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_funds", + "0d", + 1, + "decoders/phoenix-v1-decoder/src/instructions/deposit_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "evict_seat", + "6a", + 1, + "decoders/phoenix-v1-decoder/src/instructions/evict_seat.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "force_cancel_orders", + "6b", + 1, + "decoders/phoenix-v1-decoder/src/instructions/force_cancel_orders.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_market", + "64", + 1, + "decoders/phoenix-v1-decoder/src/instructions/initialize_market.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "log", + "0f", + 1, + "decoders/phoenix-v1-decoder/src/instructions/log.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "name_successor", + "66", + 1, + "decoders/phoenix-v1-decoder/src/instructions/name_successor.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_limit_order", + "02", + 1, + "decoders/phoenix-v1-decoder/src/instructions/place_limit_order.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_limit_order_with_free_funds", + "03", + 1, + "decoders/phoenix-v1-decoder/src/instructions/place_limit_order_with_free_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_multiple_post_only_orders", + "10", + 1, + "decoders/phoenix-v1-decoder/src/instructions/place_multiple_post_only_orders.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "place_multiple_post_only_orders_with_free_funds", + "11", + 1, + "decoders/phoenix-v1-decoder/src/instructions/place_multiple_post_only_orders_with_free_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "reduce_order", + "04", + 1, + "decoders/phoenix-v1-decoder/src/instructions/reduce_order.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "reduce_order_with_free_funds", + "05", + 1, + "decoders/phoenix-v1-decoder/src/instructions/reduce_order_with_free_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "request_seat", + "0e", + 1, + "decoders/phoenix-v1-decoder/src/instructions/request_seat.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "request_seat_authorized", + "69", + 1, + "decoders/phoenix-v1-decoder/src/instructions/request_seat_authorized.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "00", + 1, + "decoders/phoenix-v1-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "swap_with_free_funds", + "01", + 1, + "decoders/phoenix-v1-decoder/src/instructions/swap_with_free_funds.rs", + ), + upstream_git_discriminator_entry( + "phoenix-v1", + Some(crate::PHOENIX_V1_PROGRAM_ID), + "phoenix", + "orderbook", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_funds", + "0c", + 1, + "decoders/phoenix-v1-decoder/src/instructions/withdraw_funds.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "claim_social_fee_pda", + "e115fb85a11ec7e2", + 8, + "decoders/pump-fees-decoder/src/instructions/claim_social_fee_pda.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "e445a52e51cb9a1d", + 8, + "decoders/pump-fees-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "create_fee_sharing_config", + "c34e564c6f34fbd5", + 8, + "decoders/pump-fees-decoder/src/instructions/create_fee_sharing_config.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "create_social_fee_pda", + "90e03bd34ef8cadc", + 8, + "decoders/pump-fees-decoder/src/instructions/create_social_fee_pda.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "get_fees", + "e7257e55cf5b3f34", + 8, + "decoders/pump-fees-decoder/src/instructions/get_fees.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_fee_config", + "3ea214857941911b", + 8, + "decoders/pump-fees-decoder/src/instructions/initialize_fee_config.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_fee_program_global", + "23d78254e9387ca7", + 8, + "decoders/pump-fees-decoder/src/instructions/initialize_fee_program_global.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "reset_fee_sharing_config", + "0a02b65f107f81ba", + 8, + "decoders/pump-fees-decoder/src/instructions/reset_fee_sharing_config.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "revoke_fee_sharing_authority", + "12e99e27b9cf3a68", + 8, + "decoders/pump-fees-decoder/src/instructions/revoke_fee_sharing_authority.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "set_authority", + "85fa25156ea31a79", + 8, + "decoders/pump-fees-decoder/src/instructions/set_authority.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "set_claim_rate_limit", + "b9d39faed4315804", + 8, + "decoders/pump-fees-decoder/src/instructions/set_claim_rate_limit.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "set_disable_flags", + "c2d9702372de33be", + 8, + "decoders/pump-fees-decoder/src/instructions/set_disable_flags.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "set_social_claim_authority", + "9336b89a88edb999", + 8, + "decoders/pump-fees-decoder/src/instructions/set_social_claim_authority.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_fee_sharing_authority", + "ca0a4bc8a422d260", + 8, + "decoders/pump-fees-decoder/src/instructions/transfer_fee_sharing_authority.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "update_admin", + "a1b028d53cb8b3e4", + 8, + "decoders/pump-fees-decoder/src/instructions/update_admin.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "update_fee_config", + "68b867f258976b14", + 8, + "decoders/pump-fees-decoder/src/instructions/update_fee_config.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "update_fee_shares", + "bd0d8863bba4ed23", + 8, + "decoders/pump-fees-decoder/src/instructions/update_fee_shares.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_INSTRUCTION, + "upsert_fee_tiers", + "e317960c4d565e04", + 8, + "decoders/pump-fees-decoder/src/instructions/upsert_fee_tiers.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "create_fee_sharing_config_event", + "8569aac8b874fb58", + 8, + "decoders/pump-fees-decoder/src/events/create_fee_sharing_config_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "initialize_fee_config_event", + "598af4e60a38e27e", + 8, + "decoders/pump-fees-decoder/src/events/initialize_fee_config_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "initialize_fee_program_global_event", + "28e99c4e5f0008c7", + 8, + "decoders/pump-fees-decoder/src/events/initialize_fee_program_global_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "reset_fee_sharing_config_event", + "cbcc97e27837d6f3", + 8, + "decoders/pump-fees-decoder/src/events/reset_fee_sharing_config_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "revoke_fee_sharing_authority_event", + "7217653c0ebe993e", + 8, + "decoders/pump-fees-decoder/src/events/revoke_fee_sharing_authority_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "set_authority_event", + "12af8442d0c957f2", + 8, + "decoders/pump-fees-decoder/src/events/set_authority_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "set_claim_rate_limit_event", + "0d8f8febb5133328", + 8, + "decoders/pump-fees-decoder/src/events/set_claim_rate_limit_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "set_disable_flags_event", + "0508b3413137917e", + 8, + "decoders/pump-fees-decoder/src/events/set_disable_flags_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "set_social_claim_authority_event", + "3c767f84ef34fe0e", + 8, + "decoders/pump-fees-decoder/src/events/set_social_claim_authority_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "social_fee_pda_claimed", + "3212c141edd2eaec", + 8, + "decoders/pump-fees-decoder/src/events/social_fee_pda_claimed.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "social_fee_pda_created", + "b7b7da93187c89a9", + 8, + "decoders/pump-fees-decoder/src/events/social_fee_pda_created.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "transfer_fee_sharing_authority_event", + "7c8fc6f54db808ec", + 8, + "decoders/pump-fees-decoder/src/events/transfer_fee_sharing_authority_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "update_admin_event", + "e198ab57f63f42ea", + 8, + "decoders/pump-fees-decoder/src/events/update_admin_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "update_fee_config_event", + "5a1741233ef4bcd0", + 8, + "decoders/pump-fees-decoder/src/events/update_fee_config_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "update_fee_shares_event", + "15bac4b85be4e1cb", + 8, + "decoders/pump-fees-decoder/src/events/update_fee_shares_event.rs", + ), + upstream_git_discriminator_entry( + "pump-fees", + Some(crate::PUMP_FEES_PROGRAM_ID), + "pump", + "fee_program", + crate::ENTRY_KIND_EVENT, + "upsert_fee_tiers_event", + "ab59a9bb7aba21cc", + 8, + "decoders/pump-fees-decoder/src/events/upsert_fee_tiers_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "admin_set_coin_creator", + "f228759149606968", + 8, + "decoders/pump-swap-decoder/src/instructions/admin_set_coin_creator.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "admin_update_token_incentives", + "d10b7357d5177ccc", + 8, + "decoders/pump-swap-decoder/src/instructions/admin_update_token_incentives.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "buy", + "66063d1201daebea", + 8, + "decoders/pump-swap-decoder/src/instructions/buy.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "buy_exact_quote_in", + "c62e1552b4d9e870", + 8, + "decoders/pump-swap-decoder/src/instructions/buy_exact_quote_in.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_cashback", + "253a237ebe35e4c5", + 8, + "decoders/pump-swap-decoder/src/instructions/claim_cashback.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim_token_incentives", + "1004471ccc01281b", + 8, + "decoders/pump-swap-decoder/src/instructions/claim_token_incentives.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_user_volume_accumulator", + "f945a4da9667548a", + 8, + "decoders/pump-swap-decoder/src/instructions/close_user_volume_accumulator.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_coin_creator_fee", + "a039592ab58b2b42", + 8, + "decoders/pump-swap-decoder/src/instructions/collect_coin_creator_fee.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "e445a52e51cb9a1d", + 8, + "decoders/pump-swap-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_config", + "c9cff3724b6f2fbd", + 8, + "decoders/pump-swap-decoder/src/instructions/create_config.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_pool", + "e992d18ecf6840bc", + 8, + "decoders/pump-swap-decoder/src/instructions/create_pool.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/pump-swap-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "disable", + "b9adbb5ad80feee9", + 8, + "decoders/pump-swap-decoder/src/instructions/disable.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "extend_account", + "ea66c2cb96483ee5", + 8, + "decoders/pump-swap-decoder/src/instructions/extend_account.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "init_user_volume_accumulator", + "5e06ca73ff60e8b7", + 8, + "decoders/pump-swap-decoder/src/instructions/init_user_volume_accumulator.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_pool_coin_creator", + "d0089f044aaf103a", + 8, + "decoders/pump-swap-decoder/src/instructions/migrate_pool_coin_creator.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "sell", + "33e685a4017f83ad", + 8, + "decoders/pump-swap-decoder/src/instructions/sell.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "set_coin_creator", + "d295802dbc3a4eaf", + 8, + "decoders/pump-swap-decoder/src/instructions/set_coin_creator.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reserved_fee_recipients", + "6faca2e87259d58e", + 8, + "decoders/pump-swap-decoder/src/instructions/set_reserved_fee_recipients.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "sync_user_volume_accumulator", + "561fc057a3574fee", + 8, + "decoders/pump-swap-decoder/src/instructions/sync_user_volume_accumulator.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_cashback_enabled", + "7367e0ffbd5956c3", + 8, + "decoders/pump-swap-decoder/src/instructions/toggle_cashback_enabled.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_mayhem_mode", + "01096fd0641fffa3", + 8, + "decoders/pump-swap-decoder/src/instructions/toggle_mayhem_mode.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_creator_fees_to_pump", + "8b348655e4e56cf1", + 8, + "decoders/pump-swap-decoder/src/instructions/transfer_creator_fees_to_pump.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_admin", + "a1b028d53cb8b3e4", + 8, + "decoders/pump-swap-decoder/src/instructions/update_admin.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_fee_config", + "68b867f258976b14", + 8, + "decoders/pump-swap-decoder/src/instructions/update_fee_config.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "b712469c946da122", + 8, + "decoders/pump-swap-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "admin_set_coin_creator_event", + "2ddc5d181961ac68", + 8, + "decoders/pump-swap-decoder/src/events/admin_set_coin_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "admin_update_token_incentives_event", + "93fa6c78f71d43de", + 8, + "decoders/pump-swap-decoder/src/events/admin_update_token_incentives_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "buy_event", + "67f4521f2cf57777", + 8, + "decoders/pump-swap-decoder/src/events/buy_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "claim_cashback_event", + "e2d6f62107f293e5", + 8, + "decoders/pump-swap-decoder/src/events/claim_cashback_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "claim_token_incentives_event", + "4facf631cd5bcee8", + 8, + "decoders/pump-swap-decoder/src/events/claim_token_incentives_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "close_user_volume_accumulator_event", + "929fbdac925838f4", + 8, + "decoders/pump-swap-decoder/src/events/close_user_volume_accumulator_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "collect_coin_creator_fee_event", + "e8f5c2eeeada3a59", + 8, + "decoders/pump-swap-decoder/src/events/collect_coin_creator_fee_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "create_config_event", + "6b34598137e25116", + 8, + "decoders/pump-swap-decoder/src/events/create_config_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "create_pool_event", + "b1310cd2a076a774", + 8, + "decoders/pump-swap-decoder/src/events/create_pool_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "deposit_event", + "78f83d531f8e6b90", + 8, + "decoders/pump-swap-decoder/src/events/deposit_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "disable_event", + "6bfdc14ce4ca1b68", + 8, + "decoders/pump-swap-decoder/src/events/disable_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "extend_account_event", + "6161d7905d92167c", + 8, + "decoders/pump-swap-decoder/src/events/extend_account_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "init_user_volume_accumulator_event", + "86240d48e86582d8", + 8, + "decoders/pump-swap-decoder/src/events/init_user_volume_accumulator_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "migrate_pool_coin_creator_event", + "aadd52c793a5f72e", + 8, + "decoders/pump-swap-decoder/src/events/migrate_pool_coin_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "reserved_fee_recipients_event", + "2bbcfa12dd4bbb5f", + 8, + "decoders/pump-swap-decoder/src/events/reserved_fee_recipients_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "sell_event", + "3e2f370aa503dc2a", + 8, + "decoders/pump-swap-decoder/src/events/sell_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "set_bonding_curve_coin_creator_event", + "f2e7eb664163bdd3", + 8, + "decoders/pump-swap-decoder/src/events/set_bonding_curve_coin_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "set_metaplex_coin_creator_event", + "966bc77b7ccf66e4", + 8, + "decoders/pump-swap-decoder/src/events/set_metaplex_coin_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "sync_user_volume_accumulator_event", + "c57aa77c74515bff", + 8, + "decoders/pump-swap-decoder/src/events/sync_user_volume_accumulator_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "update_admin_event", + "e198ab57f63f42ea", + 8, + "decoders/pump-swap-decoder/src/events/update_admin_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "update_fee_config_event", + "5a1741233ef4bcd0", + 8, + "decoders/pump-swap-decoder/src/events/update_fee_config_event.rs", + ), + upstream_git_discriminator_entry( + "pump-swap", + Some(crate::PUMP_SWAP_PROGRAM_ID), + "pump", + "amm", + crate::ENTRY_KIND_EVENT, + "withdraw_event", + "1609851aa02c47c0", + 8, + "decoders/pump-swap-decoder/src/events/withdraw_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_set_creator", + "4519ab8e39ef0d04", + 8, + "decoders/pumpfun-decoder/src/instructions/admin_set_creator.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_set_idl_authority", + "08d960e79068c005", + 8, + "decoders/pumpfun-decoder/src/instructions/admin_set_idl_authority.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "admin_update_token_incentives", + "d10b7357d5177ccc", + 8, + "decoders/pumpfun-decoder/src/instructions/admin_update_token_incentives.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy", + "66063d1201daebea", + 8, + "decoders/pumpfun-decoder/src/instructions/buy.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy_exact_sol_in", + "38fc74089edfcd5f", + 8, + "decoders/pumpfun-decoder/src/instructions/buy_exact_sol_in.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_cashback", + "253a237ebe35e4c5", + 8, + "decoders/pumpfun-decoder/src/instructions/claim_cashback.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_token_incentives", + "1004471ccc01281b", + 8, + "decoders/pumpfun-decoder/src/instructions/claim_token_incentives.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "close_user_volume_accumulator", + "f945a4da9667548a", + 8, + "decoders/pumpfun-decoder/src/instructions/close_user_volume_accumulator.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "collect_creator_fee", + "1416567bc61cdb84", + 8, + "decoders/pumpfun-decoder/src/instructions/collect_creator_fee.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "cpi_event", + "e445a52e51cb9a1d", + 8, + "decoders/pumpfun-decoder/src/instructions/cpi_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create", + "181ec828051c0777", + 8, + "decoders/pumpfun-decoder/src/instructions/create.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_v2", + "d6904cec5f8b31b4", + 8, + "decoders/pumpfun-decoder/src/instructions/create_v2.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "distribute_creator_fees", + "a572670079cef751", + 8, + "decoders/pumpfun-decoder/src/instructions/distribute_creator_fees.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "extend_account", + "ea66c2cb96483ee5", + 8, + "decoders/pumpfun-decoder/src/instructions/extend_account.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "get_minimum_distributable_fee", + "75e17fca865f4423", + 8, + "decoders/pumpfun-decoder/src/instructions/get_minimum_distributable_fee.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "init_user_volume_accumulator", + "5e06ca73ff60e8b7", + 8, + "decoders/pumpfun-decoder/src/instructions/init_user_volume_accumulator.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/pumpfun-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "migrate", + "9beae792ec9ea21e", + 8, + "decoders/pumpfun-decoder/src/instructions/migrate.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_bonding_curve_creator", + "577c34bf3426d6e8", + 8, + "decoders/pumpfun-decoder/src/instructions/migrate_bonding_curve_creator.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sell", + "33e685a4017f83ad", + 8, + "decoders/pumpfun-decoder/src/instructions/sell.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "set_creator", + "fe94ff70cf8eaaa5", + 8, + "decoders/pumpfun-decoder/src/instructions/set_creator.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "set_mayhem_virtual_params", + "3da9bcbf99952a61", + 8, + "decoders/pumpfun-decoder/src/instructions/set_mayhem_virtual_params.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "set_metaplex_creator", + "8a60aed93055c5f6", + 8, + "decoders/pumpfun-decoder/src/instructions/set_metaplex_creator.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "set_params", + "1beab2349302bb8d", + 8, + "decoders/pumpfun-decoder/src/instructions/set_params.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "set_reserved_fee_recipients", + "6faca2e87259d58e", + 8, + "decoders/pumpfun-decoder/src/instructions/set_reserved_fee_recipients.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sync_user_volume_accumulator", + "561fc057a3574fee", + 8, + "decoders/pumpfun-decoder/src/instructions/sync_user_volume_accumulator.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_cashback_enabled", + "7367e0ffbd5956c3", + 8, + "decoders/pumpfun-decoder/src/instructions/toggle_cashback_enabled.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_create_v2", + "1cffe6f0ac6bcbab", + 8, + "decoders/pumpfun-decoder/src/instructions/toggle_create_v2.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_mayhem_mode", + "01096fd0641fffa3", + 8, + "decoders/pumpfun-decoder/src/instructions/toggle_mayhem_mode.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_global_authority", + "e3b54ac4d01561d5", + 8, + "decoders/pumpfun-decoder/src/instructions/update_global_authority.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "admin_set_creator_event", + "4045c0681d1e196b", + 8, + "decoders/pumpfun-decoder/src/events/admin_set_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "admin_set_idl_authority_event", + "f53b46224bb96d5c", + 8, + "decoders/pumpfun-decoder/src/events/admin_set_idl_authority_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "admin_update_token_incentives_event", + "93fa6c78f71d43de", + 8, + "decoders/pumpfun-decoder/src/events/admin_update_token_incentives_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "claim_cashback_event", + "e2d6f62107f293e5", + 8, + "decoders/pumpfun-decoder/src/events/claim_cashback_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "claim_token_incentives_event", + "4facf631cd5bcee8", + 8, + "decoders/pumpfun-decoder/src/events/claim_token_incentives_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "close_user_volume_accumulator_event", + "929fbdac925838f4", + 8, + "decoders/pumpfun-decoder/src/events/close_user_volume_accumulator_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "collect_creator_fee_event", + "7a027f010ebf0caf", + 8, + "decoders/pumpfun-decoder/src/events/collect_creator_fee_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "complete_event", + "5f72619cd42e9808", + 8, + "decoders/pumpfun-decoder/src/events/complete_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "complete_pump_amm_migration_event", + "bde95db95c94ea94", + 8, + "decoders/pumpfun-decoder/src/events/complete_pump_amm_migration_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "create_event", + "1b72a94ddeeb6376", + 8, + "decoders/pumpfun-decoder/src/events/create_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "distribute_creator_fees_event", + "a537817004b3ca28", + 8, + "decoders/pumpfun-decoder/src/events/distribute_creator_fees_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "extend_account_event", + "6161d7905d92167c", + 8, + "decoders/pumpfun-decoder/src/events/extend_account_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "init_user_volume_accumulator_event", + "86240d48e86582d8", + 8, + "decoders/pumpfun-decoder/src/events/init_user_volume_accumulator_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "migrate_bonding_curve_creator_event", + "9ba768dcd56cf303", + 8, + "decoders/pumpfun-decoder/src/events/migrate_bonding_curve_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "minimum_distributable_fee_event", + "a8d884efebb63134", + 8, + "decoders/pumpfun-decoder/src/events/minimum_distributable_fee_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "reserved_fee_recipients_event", + "2bbcfa12dd4bbb5f", + 8, + "decoders/pumpfun-decoder/src/events/reserved_fee_recipients_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "set_creator_event", + "ed347b25f5fb48d2", + 8, + "decoders/pumpfun-decoder/src/events/set_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "set_metaplex_creator_event", + "8ecb06207f69bfa2", + 8, + "decoders/pumpfun-decoder/src/events/set_metaplex_creator_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "set_params_event", + "dfc39ff63e308f83", + 8, + "decoders/pumpfun-decoder/src/events/set_params_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "sync_user_volume_accumulator_event", + "c57aa77c74515bff", + 8, + "decoders/pumpfun-decoder/src/events/sync_user_volume_accumulator_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "trade_event", + "bddb7fd34ee661ee", + 8, + "decoders/pumpfun-decoder/src/events/trade_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "update_global_authority_event", + "b6c3892a23cecff7", + 8, + "decoders/pumpfun-decoder/src/events/update_global_authority_event.rs", + ), + upstream_git_discriminator_entry( + "pumpfun", + Some(crate::PUMP_FUN_PROGRAM_ID), + "pump", + "launch", + crate::ENTRY_KIND_EVENT, + "update_mayhem_virtual_params_event", + "757be4b6a1a8dcd6", + 8, + "decoders/pumpfun-decoder/src/events/update_mayhem_virtual_params_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "admin_cancel_orders", + "0d", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/admin_cancel_orders.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_config_account", + "0e", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/create_config_account.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "03", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "00", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize2", + "01", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/initialize2.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_to_open_book", + "05", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/migrate_to_open_book.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "monitor_step", + "02", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/monitor_step.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "pre_initialize", + "0a", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/pre_initialize.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "set_params", + "06", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/set_params.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "simulate_info", + "0c", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/simulate_info.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_in", + "09", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/swap_base_in.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_in_v2", + "10", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/swap_base_in_v2.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_out", + "0b", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/swap_base_out.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_out_v2", + "11", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/swap_base_out_v2.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_config_account", + "0f", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/update_config_account.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "04", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_pnl", + "07", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/withdraw_pnl.rs", + ), + upstream_git_discriminator_entry( + "raydium-amm-v4", + Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_srm", + "08", + 1, + "decoders/raydium-amm-v4-decoder/src/instructions/withdraw_srm.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "close_position", + "7b86510031446262", + 8, + "decoders/raydium-clmm-decoder/src/instructions/close_position.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_fund_fee", + "a78a4e95dfc2067e", + 8, + "decoders/raydium-clmm-decoder/src/instructions/collect_fund_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "collect_personal_fee_event", + "a6ae69c051a15369", + 8, + "decoders/raydium-clmm-decoder/src/instructions/collect_personal_fee_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_protocol_fee", + "8888fcddc2427e59", + 8, + "decoders/raydium-clmm-decoder/src/instructions/collect_protocol_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "collect_protocol_fee_event", + "ce57114f2d29d53d", + 8, + "decoders/raydium-clmm-decoder/src/instructions/collect_protocol_fee_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_remaining_rewards", + "12eda6c52210d590", + 8, + "decoders/raydium-clmm-decoder/src/instructions/collect_remaining_rewards.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "config_change_event", + "f7bd07776a705f97", + 8, + "decoders/raydium-clmm-decoder/src/instructions/config_change_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "create_amm_config", + "8934edd4d7756c68", + 8, + "decoders/raydium-clmm-decoder/src/instructions/create_amm_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "create_operation_account", + "3f5794216d230868", + 8, + "decoders/raydium-clmm-decoder/src/instructions/create_operation_account.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "create_personal_position_event", + "641e57f9c4df9ace", + 8, + "decoders/raydium-clmm-decoder/src/instructions/create_personal_position_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "create_pool", + "e992d18ecf6840bc", + 8, + "decoders/raydium-clmm-decoder/src/instructions/create_pool.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "decrease_liquidity", + "a026d06f685b2c01", + 8, + "decoders/raydium-clmm-decoder/src/instructions/decrease_liquidity.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "decrease_liquidity_event", + "3ade563a44325538", + 8, + "decoders/raydium-clmm-decoder/src/instructions/decrease_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "decrease_liquidity_v2", + "3a7fbc3e4f52c460", + 8, + "decoders/raydium-clmm-decoder/src/instructions/decrease_liquidity_v2.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "increase_liquidity", + "2e9cf3760dcdfbb2", + 8, + "decoders/raydium-clmm-decoder/src/instructions/increase_liquidity.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "increase_liquidity_event", + "314f69d420221e54", + 8, + "decoders/raydium-clmm-decoder/src/instructions/increase_liquidity_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "increase_liquidity_v2", + "851d59df45eeb00a", + 8, + "decoders/raydium-clmm-decoder/src/instructions/increase_liquidity_v2.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_reward", + "5f87c0c4f281e644", + 8, + "decoders/raydium-clmm-decoder/src/instructions/initialize_reward.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "liquidity_calculate_event", + "ed7094e63954b4a2", + 8, + "decoders/raydium-clmm-decoder/src/instructions/liquidity_calculate_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "liquidity_change_event", + "7ef0afce9e58996b", + 8, + "decoders/raydium-clmm-decoder/src/instructions/liquidity_change_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position", + "87802f4d0f98f031", + 8, + "decoders/raydium-clmm-decoder/src/instructions/open_position.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position_v2", + "4db84ad67056f1c7", + 8, + "decoders/raydium-clmm-decoder/src/instructions/open_position_v2.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "open_position_with_token22_nft", + "4dffae527d1dc92e", + 8, + "decoders/raydium-clmm-decoder/src/instructions/open_position_with_token22_nft.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "pool_created_event", + "195e4b2f7063353f", + 8, + "decoders/raydium-clmm-decoder/src/instructions/pool_created_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "set_reward_params", + "7034a74b20c9d389", + 8, + "decoders/raydium-clmm-decoder/src/instructions/set_reward_params.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/raydium-clmm-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/raydium-clmm-decoder/src/instructions/swap_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_router_base_in", + "457d73daf5baf2c4", + 8, + "decoders/raydium-clmm-decoder/src/instructions/swap_router_base_in.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_v2", + "2b04ed0b1ac91e62", + 8, + "decoders/raydium-clmm-decoder/src/instructions/swap_v2.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_reward_owner", + "07160c53f22b3079", + 8, + "decoders/raydium-clmm-decoder/src/instructions/transfer_reward_owner.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_amm_config", + "313cae889a1c74c8", + 8, + "decoders/raydium-clmm-decoder/src/instructions/update_amm_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_operation_account", + "7f467728bce33d07", + 8, + "decoders/raydium-clmm-decoder/src/instructions/update_operation_account.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_pool_status", + "82576c062ee0757b", + 8, + "decoders/raydium-clmm-decoder/src/instructions/update_pool_status.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_INSTRUCTION, + "update_reward_infos", + "a3ace0340b9a6adf", + 8, + "decoders/raydium-clmm-decoder/src/instructions/update_reward_infos.rs", + ), + upstream_git_discriminator_entry( + "raydium-clmm", + Some(crate::RAYDIUM_CLMM_PROGRAM_ID), + "raydium", + "clmm", + crate::ENTRY_KIND_EVENT, + "update_reward_infos_event", + "6d7fba4e724125ec", + 8, + "decoders/raydium-clmm-decoder/src/instructions/update_reward_infos_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "close_permission_pda", + "9c5420764587467b", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/close_permission_pda.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_creator_fee", + "1416567bc61cdb84", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/collect_creator_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_fund_fee", + "a78a4e95dfc2067e", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/collect_fund_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "collect_protocol_fee", + "8888fcddc2427e59", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/collect_protocol_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_amm_config", + "8934edd4d7756c68", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/create_amm_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_permission_pda", + "878802d889a9b5ca", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/create_permission_pda.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_with_permission", + "3f37fe4131b25979", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/initialize_with_permission.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_EVENT, + "lp_change_event", + "79a3cdc939da753c", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/lp_change_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_input", + "8fbe5adac41e33de", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/swap_base_input.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_output", + "37d96256a34ab4ad", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/swap_base_output.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_EVENT, + "swap_event", + "40c6cde8260871e2", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/swap_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_amm_config", + "313cae889a1c74c8", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/update_amm_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "update_pool_status", + "82576c062ee0757b", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/update_pool_status.rs", + ), + upstream_git_discriminator_entry( + "raydium-cpmm", + Some(crate::RAYDIUM_CPMM_PROGRAM_ID), + "raydium", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "b712469c946da122", + 8, + "decoders/raydium-cpmm-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy_exact_in", + "faea0d7bd59c13ec", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/buy_exact_in.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy_exact_out", + "18d3742869039938", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/buy_exact_out.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_creator_fee", + "1a618acb84ab8dfc", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/claim_creator_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_platform_fee", + "9c27d0874ced3d48", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/claim_platform_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_platform_fee_from_vault", + "75f1c6a8f8da501d", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/claim_platform_fee_from_vault.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_EVENT, + "claim_vested_event", + "15c2725778d3e220", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/claim_vested_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_vested_token", + "3121681ebd9d4f23", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/claim_vested_token.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "collect_fee", + "3cadf767045d8230", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/collect_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "collect_migrate_fee", + "ffba96dfeb76c9ba", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/collect_migrate_fee.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_config", + "c9cff3724b6f2fbd", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/create_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_platform_config", + "b05ac4affd71dc14", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/create_platform_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_vesting_account", + "81b2020dd9ace6da", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/create_vesting_account.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_EVENT, + "create_vesting_event", + "96980bb334d2bf7d", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/create_vesting_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_v2", + "4399af27da102620", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/initialize_v2.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_with_token_2022", + "25be7ede2c9aab11", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/initialize_with_token_2022.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_to_amm", + "cf52c091fecf91df", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/migrate_to_amm.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_to_cpswap", + "885cc8671cda908c", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/migrate_to_cpswap.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_EVENT, + "pool_create_event", + "97d7e20976a173ae", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/pool_create_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "remove_platform_curve_param", + "1b1e3ea95de01891", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/remove_platform_curve_param.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sell_exact_in", + "9527de9bd37c981a", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/sell_exact_in.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sell_exact_out", + "5fc8472208090ba6", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/sell_exact_out.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_EVENT, + "trade_event", + "bddb7fd34ee661ee", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/trade_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_config", + "1d9efcbf0a53db63", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/update_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_platform_config", + "c33c4c81922d438f", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/update_platform_config.rs", + ), + upstream_git_discriminator_entry( + "raydium-launchpad", + Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID), + "raydium", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_platform_curve_param", + "8a908afadc800439", + 8, + "decoders/raydium-launchpad-decoder/src/instructions/update_platform_curve_param.rs", + ), + upstream_git_discriminator_entry( + "raydium-liquidity-locking", + Some(crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), + "raydium", + "liquidity_locking", + crate::ENTRY_KIND_INSTRUCTION, + "collect_clmm_fees_and_rewards", + "1048fac60ea2d413", + 8, + "decoders/raydium-liquidity-locking-decoder/src/instructions/collect_clmm_fees_and_rewards.rs", + ), + upstream_git_discriminator_entry( + "raydium-liquidity-locking", + Some(crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), + "raydium", + "liquidity_locking", + crate::ENTRY_KIND_INSTRUCTION, + "collect_cp_fees", + "081e33c7d1b8f785", + 8, + "decoders/raydium-liquidity-locking-decoder/src/instructions/collect_cp_fees.rs", + ), + upstream_git_discriminator_entry( + "raydium-liquidity-locking", + Some(crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), + "raydium", + "liquidity_locking", + crate::ENTRY_KIND_INSTRUCTION, + "lock_clmm_position", + "bc25b38352965449", + 8, + "decoders/raydium-liquidity-locking-decoder/src/instructions/lock_clmm_position.rs", + ), + upstream_git_discriminator_entry( + "raydium-liquidity-locking", + Some(crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), + "raydium", + "liquidity_locking", + crate::ENTRY_KIND_INSTRUCTION, + "lock_cp_liquidity", + "d89d1d4e26331f1a", + 8, + "decoders/raydium-liquidity-locking-decoder/src/instructions/lock_cp_liquidity.rs", + ), + upstream_git_discriminator_entry( + "raydium-liquidity-locking", + Some(crate::RAYDIUM_LIQUIDITY_LOCKING_PROGRAM_ID), + "raydium", + "liquidity_locking", + crate::ENTRY_KIND_EVENT, + "settle_cp_fee_event", + "1d4ea505f6a75bf4", + 8, + "decoders/raydium-liquidity-locking-decoder/src/instructions/settle_cp_fee_event.rs", + ), + upstream_git_discriminator_entry( + "raydium-stable-swap", + Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID), + "raydium", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "03", + 1, + "decoders/raydium-stable-swap-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "raydium-stable-swap", + Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID), + "raydium", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "00", + 1, + "decoders/raydium-stable-swap-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "raydium-stable-swap", + Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID), + "raydium", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "pre_initialize", + "0a", + 1, + "decoders/raydium-stable-swap-decoder/src/instructions/pre_initialize.rs", + ), + upstream_git_discriminator_entry( + "raydium-stable-swap", + Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID), + "raydium", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_in", + "09", + 1, + "decoders/raydium-stable-swap-decoder/src/instructions/swap_base_in.rs", + ), + upstream_git_discriminator_entry( + "raydium-stable-swap", + Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID), + "raydium", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "swap_base_out", + "0b", + 1, + "decoders/raydium-stable-swap-decoder/src/instructions/swap_base_out.rs", + ), + upstream_git_discriminator_entry( + "raydium-stable-swap", + Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID), + "raydium", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "04", + 1, + "decoders/raydium-stable-swap-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "accept_owner", + "b017291c176f0804", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/accept_owner.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "approve_strategy", + "078da23c47731a92", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/approve_strategy.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "change_amp_factor", + "38eebd23c89d2a42", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/change_amp_factor.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "change_max_supply", + "5db000cd453f5750", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/change_max_supply.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "change_swap_fee", + "e70f843384a540aa", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/change_swap_fee.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "create_strategy", + "98a06b94f5be7fe0", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/create_strategy.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "exec_strategy", + "f92e37391f263d1b", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/exec_strategy.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "pause", + "d316ddfb4a79c12f", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/pause.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_EVENT, + "pool_balance_updated_event", + "ac5272cf1b67d304", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/pool_balance_updated_event.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_EVENT, + "pool_updated_event", + "80275edde6de7f8d", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/pool_updated_event.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "reject_owner", + "eecec6d733b285e4", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/reject_owner.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "shutdown", + "92ccf1d55615fdd3", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/shutdown.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "swap_v2", + "2b04ed0b1ac91e62", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/swap_v2.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_owner", + "f519ddaf6ae5e12d", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/transfer_owner.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "unpause", + "a99004260a8dbcff", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/unpause.rs", + ), + upstream_git_discriminator_entry( + "stabble-stable-swap", + Some(crate::STABBLE_STABLE_SWAP_PROGRAM_ID), + "stabble", + "stable_swap", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "b712469c946da122", + 8, + "decoders/stabble-stable-swap-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "accept_owner", + "b017291c176f0804", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/accept_owner.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "change_max_supply", + "5db000cd453f5750", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/change_max_supply.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "change_swap_fee", + "e70f843384a540aa", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/change_swap_fee.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "pause", + "d316ddfb4a79c12f", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/pause.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_EVENT, + "pool_balance_updated_event", + "ac5272cf1b67d304", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/pool_balance_updated_event.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_EVENT, + "pool_updated_event", + "80275edde6de7f8d", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/pool_updated_event.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "reject_owner", + "eecec6d733b285e4", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/reject_owner.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "shutdown", + "92ccf1d55615fdd3", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/shutdown.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "swap", + "f8c69e91e17587c8", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/swap.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "swap_v2", + "2b04ed0b1ac91e62", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/swap_v2.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_owner", + "f519ddaf6ae5e12d", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/transfer_owner.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "unpause", + "a99004260a8dbcff", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/unpause.rs", + ), + upstream_git_discriminator_entry( + "stabble-weighted-swap", + Some(crate::STABBLE_WEIGHTED_SWAP_PROGRAM_ID), + "stabble", + "weighted_swap", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "b712469c946da122", + 8, + "decoders/stabble-weighted-swap-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "buy", + "66063d1201daebea", + 8, + "decoders/vertigo-decoder/src/instructions/buy.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_EVENT, + "buy_event", + "67f4521f2cf57777", + 8, + "decoders/vertigo-decoder/src/instructions/buy_event.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "claim", + "3ec6d6c1d59f6cd2", + 8, + "decoders/vertigo-decoder/src/instructions/claim.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create", + "181ec828051c0777", + 8, + "decoders/vertigo-decoder/src/instructions/create.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_EVENT, + "pool_created_event", + "195e4b2f7063353f", + 8, + "decoders/vertigo-decoder/src/instructions/pool_created_event.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "quote_buy", + "5309e76e921f280c", + 8, + "decoders/vertigo-decoder/src/instructions/quote_buy.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "quote_sell", + "05b231ce8ce78391", + 8, + "decoders/vertigo-decoder/src/instructions/quote_sell.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "sell", + "33e685a4017f83ad", + 8, + "decoders/vertigo-decoder/src/instructions/sell.rs", + ), + upstream_git_discriminator_entry( + "vertigo", + Some(crate::VERTIGO_PROGRAM_ID), + "vertigo", + "amm", + crate::ENTRY_KIND_EVENT, + "sell_event", + "3e2f370aa503dc2a", + 8, + "decoders/vertigo-decoder/src/instructions/sell_event.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "buy", + "66063d1201daebea", + 8, + "decoders/virtuals-decoder/src/instructions/buy.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_EVENT, + "buy_event", + "67f4521f2cf57777", + 8, + "decoders/virtuals-decoder/src/instructions/buy_event.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "claim_fees", + "52fbe99c0c34b8ca", + 8, + "decoders/virtuals-decoder/src/instructions/claim_fees.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "create_meteora_pool", + "f6fe2125e1b029e8", + 8, + "decoders/virtuals-decoder/src/instructions/create_meteora_pool.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_EVENT, + "graduation_event", + "0af6df7f30629537", + 8, + "decoders/virtuals-decoder/src/instructions/graduation_event.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize", + "afaf6d1f0d989bed", + 8, + "decoders/virtuals-decoder/src/instructions/initialize.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_meteora_accounts", + "350c769efdefb9d6", + 8, + "decoders/virtuals-decoder/src/instructions/initialize_meteora_accounts.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "launch", + "99f15de116454a3d", + 8, + "decoders/virtuals-decoder/src/instructions/launch.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_EVENT, + "launch_event", + "1bc12f82735cef5e", + 8, + "decoders/virtuals-decoder/src/instructions/launch_event.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "sell", + "33e685a4017f83ad", + 8, + "decoders/virtuals-decoder/src/instructions/sell.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_EVENT, + "sell_event", + "3e2f370aa503dc2a", + 8, + "decoders/virtuals-decoder/src/instructions/sell_event.rs", + ), + upstream_git_discriminator_entry( + "virtuals", + Some(crate::VIRTUALS_PROGRAM_ID), + "virtuals", + "launch", + crate::ENTRY_KIND_INSTRUCTION, + "update_pool_creator", + "71e1a6b95ee7601c", + 8, + "decoders/virtuals-decoder/src/instructions/update_pool_creator.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "authority_config_grant", + "ead3ded7323eaecc", + 8, + "decoders/wavebreak-decoder/src/instructions/authority_config_grant.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "authority_config_initialize", + "1793c4080607eefd", + 8, + "decoders/wavebreak-decoder/src/instructions/authority_config_initialize.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "authority_config_revoke", + "6eb5e9767b6dc7e0", + 8, + "decoders/wavebreak-decoder/src/instructions/authority_config_revoke.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "bonding_curve_close", + "052dcb1d060d1b8d", + 8, + "decoders/wavebreak-decoder/src/instructions/bonding_curve_close.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "bonding_curve_collect_fees", + "6e89ba54446a3763", + 8, + "decoders/wavebreak-decoder/src/instructions/bonding_curve_collect_fees.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "bonding_curve_graduate", + "2e9c44d59dd6b83c", + 8, + "decoders/wavebreak-decoder/src/instructions/bonding_curve_graduate.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "bonding_curve_initialize", + "0815f5616586f79c", + 8, + "decoders/wavebreak-decoder/src/instructions/bonding_curve_initialize.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_launch", + "efdfff8627797f3e", + 8, + "decoders/wavebreak-decoder/src/instructions/create_launch.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_lockedlaunch", + "03feee8a55d99cc0", + 8, + "decoders/wavebreak-decoder/src/instructions/create_lockedlaunch.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "create_presale", + "b090c59e3d774b87", + 8, + "decoders/wavebreak-decoder/src/instructions/create_presale.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "graduate_manual", + "455adeab58c2fc38", + 8, + "decoders/wavebreak-decoder/src/instructions/graduate_manual.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "graduate_whirlpool", + "c15beac842495015", + 8, + "decoders/wavebreak-decoder/src/instructions/graduate_whirlpool.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "mint_config_close", + "f890df48b07f438a", + 8, + "decoders/wavebreak-decoder/src/instructions/mint_config_close.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "mint_config_initialize", + "deeac6d259ad210b", + 8, + "decoders/wavebreak-decoder/src/instructions/mint_config_initialize.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "mint_config_update", + "eb782641654f31ec", + 8, + "decoders/wavebreak-decoder/src/instructions/mint_config_update.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permission_config_close", + "f7a53524ddf89a90", + 8, + "decoders/wavebreak-decoder/src/instructions/permission_config_close.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permission_config_initialize", + "7f94ed30b8364912", + 8, + "decoders/wavebreak-decoder/src/instructions/permission_config_initialize.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permission_config_update", + "32120b25ebab9050", + 8, + "decoders/wavebreak-decoder/src/instructions/permission_config_update.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permission_consume_cpi", + "bc0b7c045dddd9f3", + 8, + "decoders/wavebreak-decoder/src/instructions/permission_consume_cpi.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permission_consume_top_level", + "937a0423a413b018", + 8, + "decoders/wavebreak-decoder/src/instructions/permission_consume_top_level.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permission_refund", + "fcf453ecc07017de", + 8, + "decoders/wavebreak-decoder/src/instructions/permission_refund.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "permission_revoke", + "cc5d9ca0a0f64620", + 8, + "decoders/wavebreak-decoder/src/instructions/permission_revoke.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_authority_config_a", + "a6bfea0739b93975", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_authority_config_a.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_authority_config_b", + "88adeee1e8b1ba36", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_authority_config_b.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_authority_config_c", + "0bcd09cd07ffaf9d", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_authority_config_c.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_authority_config_y", + "04ab33013be50717", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_authority_config_y.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_authority_config_z", + "2ec4b041b3fc7c9e", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_authority_config_z.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_bonding_curve_a", + "3de7720124b2683d", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_bonding_curve_a.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_bonding_curve_x", + "ec568ad033f47cb2", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_bonding_curve_x.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_bonding_curve_y", + "023cd3ab516491a4", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_bonding_curve_y.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_bonding_curve_z", + "2a8c30104489f372", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_bonding_curve_z.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_create_a", + "26010f9ad3ce7330", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_create_a.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_create_b", + "4c8c2a7fa0680963", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_create_b.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_create_c", + "5c3e692b75a011c4", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_create_c.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_create_y", + "5d8e29c49e27ffde", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_create_y.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_create_z", + "78f03cd0184e1cbd", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_create_z.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_graduate_a", + "9880a427d00adc7e", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_graduate_a.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_graduate_b", + "b9a0f2c458fac02a", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_graduate_b.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_graduate_c", + "c5965ac963264f0a", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_graduate_c.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_graduate_x", + "23724563e9e76241", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_graduate_x.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_graduate_y", + "6f9f3e145c9e4cef", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_graduate_y.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_graduate_z", + "a7761d20269c11af", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_graduate_z.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_mint_config_a", + "3cc10f54f73a9932", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_mint_config_a.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_mint_config_b", + "51e7fc4c54e1d6b8", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_mint_config_b.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_mint_config_c", + "bacbb74444e473a7", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_mint_config_c.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_mint_config_y", + "b4caee41e917f762", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_mint_config_y.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_mint_config_z", + "210cf1adf67dfeb4", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_mint_config_z.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_permission_a", + "8d63ab0f154ad62d", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_permission_a.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_token_a", + "494e7eabc2a8c30a", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_token_a.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_token_y", + "d96397cc830bf9b7", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_token_y.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "reserved_token_z", + "80c3efe4a8af32eb", + 8, + "decoders/wavebreak-decoder/src/instructions/reserved_token_z.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "token_buy_exact_in", + "cdbd9dfc9b6f6328", + 8, + "decoders/wavebreak-decoder/src/instructions/token_buy_exact_in.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "token_buy_exact_out", + "00dbed01def5267d", + 8, + "decoders/wavebreak-decoder/src/instructions/token_buy_exact_out.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "token_refund", + "f6dfe3a76f62decd", + 8, + "decoders/wavebreak-decoder/src/instructions/token_refund.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "token_sell_exact_in", + "bd5573f5eb52f0e0", + 8, + "decoders/wavebreak-decoder/src/instructions/token_sell_exact_in.rs", + ), + upstream_git_discriminator_entry( + "wavebreak", + Some(crate::WAVEBREAK_PROGRAM_ID), + "wavebreak", + "amm", + crate::ENTRY_KIND_INSTRUCTION, + "token_sell_exact_out", + "1589e00791498652", + 8, + "decoders/wavebreak-decoder/src/instructions/token_sell_exact_out.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "add_market_indexes", + "5ef690af04a4e9fc", + 8, + "decoders/zeta-decoder/src/instructions/add_market_indexes.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "add_perp_market_index", + "7a280e40a912e788", + 8, + "decoders/zeta-decoder/src/instructions/add_perp_market_index.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "admin_crank_event_queue", + "668fdc88179e889d", + 8, + "decoders/zeta-decoder/src/instructions/admin_crank_event_queue.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "admin_force_cancel_orders", + "43347cc0bf20da5b", + 8, + "decoders/zeta-decoder/src/instructions/admin_force_cancel_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "admin_reset_dex_open_orders", + "73c65a11d28bc1ee", + 8, + "decoders/zeta-decoder/src/instructions/admin_reset_dex_open_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "admin_set_order_state", + "6efe15f1a0772cfd", + 8, + "decoders/zeta-decoder/src/instructions/admin_set_order_state.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "apply_funding_event", + "7fca0fb7c8c0040c", + 8, + "decoders/zeta-decoder/src/instructions/apply_funding_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "apply_perp_funding", + "1752e1dedb7ae6fb", + 8, + "decoders/zeta-decoder/src/instructions/apply_perp_funding.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "burn_vault_tokens", + "e9cba5c9af2bbc9f", + 8, + "decoders/zeta-decoder/src/instructions/burn_vault_tokens.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_all_market_orders", + "8bbee6f94da0ce04", + 8, + "decoders/zeta-decoder/src/instructions/cancel_all_market_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order", + "5f81edf00831df84", + 8, + "decoders/zeta-decoder/src/instructions/cancel_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order_by_client_order_id", + "73b2c908afb77b77", + 8, + "decoders/zeta-decoder/src/instructions/cancel_order_by_client_order_id.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order_by_client_order_id_no_error", + "354da79daf8390ab", + 8, + "decoders/zeta-decoder/src/instructions/cancel_order_by_client_order_id_no_error.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order_halted", + "00c0e902fcfb82a9", + 8, + "decoders/zeta-decoder/src/instructions/cancel_order_halted.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_order_no_error", + "5f61d7cc6f33ccb8", + 8, + "decoders/zeta-decoder/src/instructions/cancel_order_no_error.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_trigger_order", + "905443271b19ca8d", + 8, + "decoders/zeta-decoder/src/instructions/cancel_trigger_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "cancel_trigger_order_v2", + "df414307bd033f8e", + 8, + "decoders/zeta-decoder/src/instructions/cancel_trigger_order_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "choose_airdrop_community", + "749cc052f82973ba", + 8, + "decoders/zeta-decoder/src/instructions/choose_airdrop_community.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "clean_zeta_market_halted", + "898c5e12e7e8d9cc", + 8, + "decoders/zeta-decoder/src/instructions/clean_zeta_market_halted.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "clean_zeta_markets", + "7a7f315944e4559d", + 8, + "decoders/zeta-decoder/src/instructions/clean_zeta_markets.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_cross_margin_account", + "cbc4bb3c0daabe45", + 8, + "decoders/zeta-decoder/src/instructions/close_cross_margin_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_cross_margin_account_manager", + "e8b6b689565876fc", + 8, + "decoders/zeta-decoder/src/instructions/close_cross_margin_account_manager.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_margin_account", + "69d729efa6cf0167", + 8, + "decoders/zeta-decoder/src/instructions/close_margin_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_open_orders", + "c8d83fef07e6ff14", + 8, + "decoders/zeta-decoder/src/instructions/close_open_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_open_orders_v2", + "4e98c4a344b37948", + 8, + "decoders/zeta-decoder/src/instructions/close_open_orders_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_open_orders_v3", + "cf0fc64ac5e4b01e", + 8, + "decoders/zeta-decoder/src/instructions/close_open_orders_v3.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_open_orders_v4", + "a765a1f6d03106e1", + 8, + "decoders/zeta-decoder/src/instructions/close_open_orders_v4.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_referrer_accounts", + "e04e378bcbec3e4e", + 8, + "decoders/zeta-decoder/src/instructions/close_referrer_accounts.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "close_spread_account", + "bee4fd10c994a1f0", + 8, + "decoders/zeta-decoder/src/instructions/close_spread_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "collect_treasury_funds", + "f3d504ec1af6b4ae", + 8, + "decoders/zeta-decoder/src/instructions/collect_treasury_funds.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "crank_event_queue", + "438561dfb2bcebb5", + 8, + "decoders/zeta-decoder/src/instructions/crank_event_queue.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit", + "f223c68952e1f2b6", + 8, + "decoders/zeta-decoder/src/instructions/deposit.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_insurance_vault", + "2f35192f6d7a1616", + 8, + "decoders/zeta-decoder/src/instructions/deposit_insurance_vault.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_insurance_vault_v2", + "f22c18135b3b07c9", + 8, + "decoders/zeta-decoder/src/instructions/deposit_insurance_vault_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_permissionless", + "ebf709f8cc340932", + 8, + "decoders/zeta-decoder/src/instructions/deposit_permissionless.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "deposit_v2", + "6d4b4599acda9213", + 8, + "decoders/zeta-decoder/src/instructions/deposit_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "edit_delegated_pubkey", + "89f547592ef91635", + 8, + "decoders/zeta-decoder/src/instructions/edit_delegated_pubkey.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "edit_ma_type", + "e7d03332de934c4e", + 8, + "decoders/zeta-decoder/src/instructions/edit_ma_type.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "edit_trigger_order", + "b42bd770fe741485", + 8, + "decoders/zeta-decoder/src/instructions/edit_trigger_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "edit_trigger_order_v2", + "499fcdb12b557589", + 8, + "decoders/zeta-decoder/src/instructions/edit_trigger_order_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "execute_trigger_order", + "690a6888d78654ab", + 8, + "decoders/zeta-decoder/src/instructions/execute_trigger_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "execute_trigger_order_v2", + "05e4307708d6b796", + 8, + "decoders/zeta-decoder/src/instructions/execute_trigger_order_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "expire_series", + "2da269622c15ab7f", + 8, + "decoders/zeta-decoder/src/instructions/expire_series.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "expire_series_override", + "6816227b56e08246", + 8, + "decoders/zeta-decoder/src/instructions/expire_series_override.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "force_cancel_order_by_order_id", + "b6eb30b3f885d2f0", + 8, + "decoders/zeta-decoder/src/instructions/force_cancel_order_by_order_id.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "force_cancel_order_by_order_id_v2", + "51f33c5adec929de", + 8, + "decoders/zeta-decoder/src/instructions/force_cancel_order_by_order_id_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "force_cancel_orders", + "40b5c43fde4840e8", + 8, + "decoders/zeta-decoder/src/instructions/force_cancel_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "force_cancel_orders_v2", + "0e3e95ca8f113873", + 8, + "decoders/zeta-decoder/src/instructions/force_cancel_orders_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "force_cancel_trigger_order", + "78ecd81cc04fffbc", + 8, + "decoders/zeta-decoder/src/instructions/force_cancel_trigger_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "halt", + "189c087941030552", + 8, + "decoders/zeta-decoder/src/instructions/halt.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_combined_insurance_vault", + "4d12b590db54066a", + 8, + "decoders/zeta-decoder/src/instructions/initialize_combined_insurance_vault.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_combined_socialized_loss_account", + "886c58f5e6e06552", + 8, + "decoders/zeta-decoder/src/instructions/initialize_combined_socialized_loss_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_combined_vault", + "3b6369114977e5fc", + 8, + "decoders/zeta-decoder/src/instructions/initialize_combined_vault.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_cross_margin_account", + "1b1ae432d2d3cd5e", + 8, + "decoders/zeta-decoder/src/instructions/initialize_cross_margin_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_cross_margin_account_manager", + "489a0f1ca5d7d1c7", + 8, + "decoders/zeta-decoder/src/instructions/initialize_cross_margin_account_manager.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_cross_margin_account_manager_v2", + "a6cbb0d2b0348c69", + 8, + "decoders/zeta-decoder/src/instructions/initialize_cross_margin_account_manager_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_insurance_deposit_account", + "55a372798ba72925", + 8, + "decoders/zeta-decoder/src/instructions/initialize_insurance_deposit_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_margin_account", + "43eb4266a7ab78c5", + 8, + "decoders/zeta-decoder/src/instructions/initialize_margin_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_market_indexes", + "5b3fcd901453b178", + 8, + "decoders/zeta-decoder/src/instructions/initialize_market_indexes.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_market_node", + "32761515b3f81780", + 8, + "decoders/zeta-decoder/src/instructions/initialize_market_node.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_market_pda", + "057864bae186080d", + 8, + "decoders/zeta-decoder/src/instructions/initialize_market_pda.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_market_strikes", + "bd2eff217e852bab", + 8, + "decoders/zeta-decoder/src/instructions/initialize_market_strikes.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_market_tif_epoch_cycle", + "c78fad93cacc40cc", + 8, + "decoders/zeta-decoder/src/instructions/initialize_market_tif_epoch_cycle.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_min_lots_and_tick_sizes", + "4419332b7eab5057", + 8, + "decoders/zeta-decoder/src/instructions/initialize_min_lots_and_tick_sizes.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_open_orders", + "37ea1052642a7ec0", + 8, + "decoders/zeta-decoder/src/instructions/initialize_open_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_open_orders_v2", + "dc11551470ae94e3", + 8, + "decoders/zeta-decoder/src/instructions/initialize_open_orders_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_open_orders_v3", + "16bf8b88792754ca", + 8, + "decoders/zeta-decoder/src/instructions/initialize_open_orders_v3.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_perp_sync_queue", + "0a379ae081aea108", + 8, + "decoders/zeta-decoder/src/instructions/initialize_perp_sync_queue.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_referrer_accounts", + "69e448ddda12b375", + 8, + "decoders/zeta-decoder/src/instructions/initialize_referrer_accounts.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_spread_account", + "ce56fb1b5b6f17d3", + 8, + "decoders/zeta-decoder/src/instructions/initialize_spread_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_underlying", + "726cd55caf7c2b13", + 8, + "decoders/zeta-decoder/src/instructions/initialize_underlying.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_whitelist_deposit_account", + "3de773db51f39e8a", + 8, + "decoders/zeta-decoder/src/instructions/initialize_whitelist_deposit_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_whitelist_insurance_account", + "2b2ef09b50045666", + 8, + "decoders/zeta-decoder/src/instructions/initialize_whitelist_insurance_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_whitelist_trading_fees_account", + "c681d8b9f71d69be", + 8, + "decoders/zeta-decoder/src/instructions/initialize_whitelist_trading_fees_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_zeta_group", + "068724e82327fa47", + 8, + "decoders/zeta-decoder/src/instructions/initialize_zeta_group.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_zeta_market", + "74efe2952ea3dd03", + 8, + "decoders/zeta-decoder/src/instructions/initialize_zeta_market.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_zeta_pricing", + "23d1b41df5c77d10", + 8, + "decoders/zeta-decoder/src/instructions/initialize_zeta_pricing.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_zeta_referrals_rewards_wallet", + "f5e5df780786f7f8", + 8, + "decoders/zeta-decoder/src/instructions/initialize_zeta_referrals_rewards_wallet.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_zeta_specific_market_vaults", + "f945ba92886b4f71", + 8, + "decoders/zeta-decoder/src/instructions/initialize_zeta_specific_market_vaults.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_zeta_state", + "44274b8ebf925ede", + 8, + "decoders/zeta-decoder/src/instructions/initialize_zeta_state.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "initialize_zeta_treasury_wallet", + "f939bb66b86825e7", + 8, + "decoders/zeta-decoder/src/instructions/initialize_zeta_treasury_wallet.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate", + "dfb3e27d302e274a", + 8, + "decoders/zeta-decoder/src/instructions/liquidate.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "liquidate_v2", + "0f56553702e1a1eb", + 8, + "decoders/zeta-decoder/src/instructions/liquidate_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "liquidation_event", + "030d155dad884890", + 8, + "decoders/zeta-decoder/src/instructions/liquidation_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_to_cross_margin_account", + "9d356b68b8bd64dc", + 8, + "decoders/zeta-decoder/src/instructions/migrate_to_cross_margin_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "migrate_to_new_cross_margin_account", + "b72dfb6d866cbff3", + 8, + "decoders/zeta-decoder/src/instructions/migrate_to_new_cross_margin_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "order_complete_event", + "1a64c4ea5d799fdf", + 8, + "decoders/zeta-decoder/src/instructions/order_complete_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "override_expiry", + "81c575726c77cf88", + 8, + "decoders/zeta-decoder/src/instructions/override_expiry.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_multi_orders", + "ccd7f3f33beae179", + 8, + "decoders/zeta-decoder/src/instructions/place_multi_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "place_multi_orders_event", + "ee081207a23b6891", + 8, + "decoders/zeta-decoder/src/instructions/place_multi_orders_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_order", + "33c29baf6d82606a", + 8, + "decoders/zeta-decoder/src/instructions/place_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "place_order_event", + "41bf195b1bfcc028", + 8, + "decoders/zeta-decoder/src/instructions/place_order_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_order_v2", + "e86f73c4ed8f3ecc", + 8, + "decoders/zeta-decoder/src/instructions/place_order_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_order_v3", + "925d0ea79f14063a", + 8, + "decoders/zeta-decoder/src/instructions/place_order_v3.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_order_v4", + "f3f8d58fb84f2949", + 8, + "decoders/zeta-decoder/src/instructions/place_order_v4.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_perp_order", + "45a15dca787e4cb9", + 8, + "decoders/zeta-decoder/src/instructions/place_perp_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_perp_order_v2", + "cd5482b43f760acf", + 8, + "decoders/zeta-decoder/src/instructions/place_perp_order_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_perp_order_v3", + "5bf660073516eae1", + 8, + "decoders/zeta-decoder/src/instructions/place_perp_order_v3.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_perp_order_v4", + "a68acd645a6ebf5b", + 8, + "decoders/zeta-decoder/src/instructions/place_perp_order_v4.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_perp_order_v5", + "0718b6199b904b32", + 8, + "decoders/zeta-decoder/src/instructions/place_perp_order_v5.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "place_trigger_order", + "209c32bce89f70ec", + 8, + "decoders/zeta-decoder/src/instructions/place_trigger_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "position_movement", + "75104bf9b37fab93", + 8, + "decoders/zeta-decoder/src/instructions/position_movement.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "position_movement_event", + "44b90d941ce3655f", + 8, + "decoders/zeta-decoder/src/instructions/position_movement_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "prune_expired_tif_orders", + "18e3e2d45d1af2e6", + 8, + "decoders/zeta-decoder/src/instructions/prune_expired_tif_orders.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "prune_expired_tif_orders_v2", + "cc257c399ed3b2d1", + 8, + "decoders/zeta-decoder/src/instructions/prune_expired_tif_orders_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "rebalance_insurance_vault", + "0bc442eb3beddf6f", + 8, + "decoders/zeta-decoder/src/instructions/rebalance_insurance_vault.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "rebalance_insurance_vault_v2", + "b8eefe5ca4c7c967", + 8, + "decoders/zeta-decoder/src/instructions/rebalance_insurance_vault_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "reset_num_flex_underlyings", + "3013fed1c8d3313d", + 8, + "decoders/zeta-decoder/src/instructions/reset_num_flex_underlyings.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_dex_funds", + "a5678e26d3a60ee2", + 8, + "decoders/zeta-decoder/src/instructions/settle_dex_funds.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "settle_positions_halted", + "aa938ba31368a74d", + 8, + "decoders/zeta-decoder/src/instructions/settle_positions_halted.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "take_trigger_order", + "6bcf3be219171fa1", + 8, + "decoders/zeta-decoder/src/instructions/take_trigger_order.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_market_maker", + "cbf7549f68fd9450", + 8, + "decoders/zeta-decoder/src/instructions/toggle_market_maker.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "toggle_zeta_group_perps_only", + "aa734d0ba19df7a9", + 8, + "decoders/zeta-decoder/src/instructions/toggle_zeta_group_perps_only.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "trade_event", + "bddb7fd34ee661ee", + 8, + "decoders/zeta-decoder/src/instructions/trade_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "trade_event_v2_event", + "89a065a2068c0589", + 8, + "decoders/zeta-decoder/src/instructions/trade_event_v2_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_EVENT, + "trade_event_v3_event", + "02051bfb97b66182", + 8, + "decoders/zeta-decoder/src/instructions/trade_event_v3_event.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "transfer_excess_spread_balance", + "acb80c0a346940d5", + 8, + "decoders/zeta-decoder/src/instructions/transfer_excess_spread_balance.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "treasury_movement", + "0122f269d7d39d12", + 8, + "decoders/zeta-decoder/src/instructions/treasury_movement.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "unhalt", + "f98c1bd58082cf71", + 8, + "decoders/zeta-decoder/src/instructions/unhalt.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_admin", + "a1b028d53cb8b3e4", + 8, + "decoders/zeta-decoder/src/instructions/update_admin.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_halt_state", + "d72d35a2958a053f", + 8, + "decoders/zeta-decoder/src/instructions/update_halt_state.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_interest_rate", + "4b08ff297b3b87ee", + 8, + "decoders/zeta-decoder/src/instructions/update_interest_rate.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_ma_type_admin", + "2cb99666701c81ef", + 8, + "decoders/zeta-decoder/src/instructions/update_ma_type_admin.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_maker_rebate_percentage", + "b4ecfd13e7e7dc41", + 8, + "decoders/zeta-decoder/src/instructions/update_maker_rebate_percentage.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_margin_parameters", + "4532aec57bc448ec", + 8, + "decoders/zeta-decoder/src/instructions/update_margin_parameters.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_min_lot", + "0688050ce5926659", + 8, + "decoders/zeta-decoder/src/instructions/update_min_lot.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_oracle", + "7029d112f8e2fcbc", + 8, + "decoders/zeta-decoder/src/instructions/update_oracle.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_oracle_backup_feed", + "e60921cae4d1b462", + 8, + "decoders/zeta-decoder/src/instructions/update_oracle_backup_feed.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_perp_parameters", + "5a87db2aa48661ae", + 8, + "decoders/zeta-decoder/src/instructions/update_perp_parameters.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_pricing_admin", + "49189c1c6e587baf", + 8, + "decoders/zeta-decoder/src/instructions/update_pricing_admin.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_pricing_parameters", + "697fd0863d3d71f7", + 8, + "decoders/zeta-decoder/src/instructions/update_pricing_parameters.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_pricing_v2", + "eb6d8aad0f2533f4", + 8, + "decoders/zeta-decoder/src/instructions/update_pricing_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_pricing_v3", + "df3ab45666fbed52", + 8, + "decoders/zeta-decoder/src/instructions/update_pricing_v3.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_referrals_admin", + "49905c774a6a10c8", + 8, + "decoders/zeta-decoder/src/instructions/update_referrals_admin.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_secondary_admin", + "54e61a4b02b3afea", + 8, + "decoders/zeta-decoder/src/instructions/update_secondary_admin.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_take_trigger_order_fee_percentage", + "e3ea9df6804ae936", + 8, + "decoders/zeta-decoder/src/instructions/update_take_trigger_order_fee_percentage.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_tick_size", + "de7a01dd7b748f6e", + 8, + "decoders/zeta-decoder/src/instructions/update_tick_size.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_treasury_split_token_account", + "0b4ee9b8a2995dcf", + 8, + "decoders/zeta-decoder/src/instructions/update_treasury_split_token_account.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_trigger_admin", + "f1646ed23979776c", + 8, + "decoders/zeta-decoder/src/instructions/update_trigger_admin.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_volatility", + "be6974dde5c6d053", + 8, + "decoders/zeta-decoder/src/instructions/update_volatility.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_zeta_group_expiry_parameters", + "11457968e1ce8cd7", + 8, + "decoders/zeta-decoder/src/instructions/update_zeta_group_expiry_parameters.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_zeta_group_margin_parameters", + "3cd07993f26a0bfe", + 8, + "decoders/zeta-decoder/src/instructions/update_zeta_group_margin_parameters.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_zeta_group_perp_parameters", + "48988c9ec35df71f", + 8, + "decoders/zeta-decoder/src/instructions/update_zeta_group_perp_parameters.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_zeta_pricing_pubkeys", + "a9dd17f8db7a8e9e", + 8, + "decoders/zeta-decoder/src/instructions/update_zeta_pricing_pubkeys.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "update_zeta_state", + "68b614bb03a43c03", + 8, + "decoders/zeta-decoder/src/instructions/update_zeta_state.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw", + "b712469c946da122", + 8, + "decoders/zeta-decoder/src/instructions/withdraw.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_insurance_vault", + "11fad52dac7551e1", + 8, + "decoders/zeta-decoder/src/instructions/withdraw_insurance_vault.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_insurance_vault_v2", + "cb472c94e0f245a5", + 8, + "decoders/zeta-decoder/src/instructions/withdraw_insurance_vault_v2.rs", + ), + upstream_git_discriminator_entry( + "zeta", + Some(crate::ZETA_PROGRAM_ID), + "zeta", + "perps", + crate::ENTRY_KIND_INSTRUCTION, + "withdraw_v2", + "f250a300c4ddc2c2", + 8, + "decoders/zeta-decoder/src/instructions/withdraw_v2.rs", + ), +]; diff --git a/kb_lib/src/upstream_registry_match.rs b/kb_lib/src/upstream_registry_match.rs new file mode 100644 index 0000000..7827df1 --- /dev/null +++ b/kb_lib/src/upstream_registry_match.rs @@ -0,0 +1,651 @@ +// file: kb_lib/src/upstream_registry_match.rs + +//! Matching, filtering and summarizing helpers for the upstream Git registry. + +/// Returns all static upstream registry entries as owned DTOs. +pub(crate) fn upstream_registry_all_entries() -> std::vec::Vec { + let mut entries = std::vec::Vec::new(); + for entry in crate::upstream_registry_generated::UPSTREAM_REGISTRY_ENTRIES { + entries.push(entry.to_dto()); + } + return entries; +} + +/// Searches static upstream registry entries with optional filters. +pub(crate) fn upstream_registry_search( + request: &crate::UpstreamRegistrySearchRequestDto, +) -> crate::UpstreamRegistrySearchResultDto { + let total_entry_count = crate::upstream_registry_generated::UPSTREAM_REGISTRY_ENTRIES.len(); + let mut entries = std::vec::Vec::new(); + for entry in crate::upstream_registry_generated::UPSTREAM_REGISTRY_ENTRIES { + if !matches_request(entry, request) { + continue; + } + entries.push(entry.to_dto()); + if let Some(limit) = request.limit { + if entries.len() >= limit { + break; + } + } + } + let summary = summarize(total_entry_count, entries.as_slice()); + return crate::UpstreamRegistrySearchResultDto { + request: request.clone(), + summary, + entries, + }; +} + +fn matches_request( + entry: &crate::UpstreamRegistryEntry, + request: &crate::UpstreamRegistrySearchRequestDto, +) -> bool { + if !matches_string_filter(entry.decoder_code, &request.decoder_code) { + return false; + } + if !matches_optional_string_filter(entry.program_id, &request.program_id) { + return false; + } + if !matches_string_filter(entry.program_family, &request.program_family) { + return false; + } + if !matches_string_filter(entry.surface_kind, &request.surface_kind) { + return false; + } + if !matches_string_filter(entry.entry_kind, &request.entry_kind) { + return false; + } + if !matches_string_filter(entry.proof_status, &request.proof_status) { + return false; + } + return true; +} + +fn matches_string_filter(value: &str, filter: &std::option::Option) -> bool { + let filter_value = match filter { + Some(filter_value) => filter_value.trim(), + None => return true, + }; + if filter_value.is_empty() { + return true; + } + return value.eq_ignore_ascii_case(filter_value); +} + +fn matches_optional_string_filter( + value: std::option::Option<&str>, + filter: &std::option::Option, +) -> bool { + let filter_value = match filter { + Some(filter_value) => filter_value.trim(), + None => return true, + }; + if filter_value.is_empty() { + return true; + } + let value = match value { + Some(value) => value, + None => return false, + }; + return value.eq_ignore_ascii_case(filter_value); +} + +fn summarize( + total_entry_count: usize, + entries: &[crate::UpstreamRegistryEntryDto], +) -> crate::UpstreamRegistrySummaryDto { + let mut entries_with_program_id_count = 0_usize; + let mut entries_with_discriminator_count = 0_usize; + let mut program_entry_count = 0_usize; + let mut instruction_entry_count = 0_usize; + let mut event_entry_count = 0_usize; + let mut account_entry_count = 0_usize; + let mut upstream_git_unverified_count = 0_usize; + let mut upstream_git_mapped_unverified_count = 0_usize; + let mut upstream_git_local_corpus_observed_count = 0_usize; + let mut upstream_git_local_corpus_materialized_count = 0_usize; + let mut upstream_git_layout_unverified_count = 0_usize; + + for entry in entries { + if entry.program_id.is_some() { + entries_with_program_id_count += 1; + } + if entry.discriminator_hex.is_some() { + entries_with_discriminator_count += 1; + } + match entry.entry_kind.as_str() { + crate::ENTRY_KIND_PROGRAM => program_entry_count += 1, + crate::ENTRY_KIND_INSTRUCTION => instruction_entry_count += 1, + crate::ENTRY_KIND_EVENT => event_entry_count += 1, + crate::ENTRY_KIND_ACCOUNT => account_entry_count += 1, + _ => (), + } + match entry.proof_status.as_str() { + crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED => upstream_git_unverified_count += 1, + crate::PROOF_STATUS_UPSTREAM_GIT_MAPPED_UNVERIFIED => { + upstream_git_mapped_unverified_count += 1; + }, + crate::PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_OBSERVED => { + upstream_git_local_corpus_observed_count += 1; + }, + crate::PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_MATERIALIZED => { + upstream_git_local_corpus_materialized_count += 1; + }, + crate::PROOF_STATUS_UPSTREAM_GIT_LAYOUT_UNVERIFIED => { + upstream_git_layout_unverified_count += 1; + }, + _ => (), + } + } + + return crate::UpstreamRegistrySummaryDto { + total_entry_count, + returned_entry_count: entries.len(), + entries_with_program_id_count, + entries_with_discriminator_count, + program_entry_count, + instruction_entry_count, + event_entry_count, + account_entry_count, + upstream_git_unverified_count, + upstream_git_mapped_unverified_count, + upstream_git_local_corpus_observed_count, + upstream_git_local_corpus_materialized_count, + upstream_git_layout_unverified_count, + }; +} + +/// Matches raw base58 instruction data against upstream registry discriminator entries. +pub(crate) fn upstream_registry_match_instruction_data( + program_id: &str, + data_base58: std::option::Option<&str>, +) -> std::option::Option { + let data = decode_base58_instruction_data(data_base58); + let data = match data { + Some(data) => data, + None => return None, + }; + let mut selected_entry: std::option::Option<&crate::UpstreamRegistryEntry> = None; + let mut selected_len = 0_usize; + for entry in crate::upstream_registry_generated::UPSTREAM_REGISTRY_ENTRIES { + if entry.entry_kind != crate::ENTRY_KIND_INSTRUCTION { + continue; + } + let entry_program_id = match entry.program_id { + Some(entry_program_id) => entry_program_id, + None => continue, + }; + if entry_program_id != program_id { + continue; + } + let discriminator_hex = match entry.discriminator_hex { + Some(discriminator_hex) => discriminator_hex, + None => continue, + }; + let discriminator_len = match discriminator_len_usize(entry.discriminator_len) { + Some(discriminator_len) => discriminator_len, + None => continue, + }; + if !data_prefix_matches_discriminator(data.as_slice(), discriminator_len, discriminator_hex) + { + continue; + } + if discriminator_len > selected_len { + selected_entry = Some(entry); + selected_len = discriminator_len; + } + } + let selected_entry = match selected_entry { + Some(selected_entry) => selected_entry, + None => return None, + }; + return Some(selected_entry.to_dto()); +} + +fn discriminator_len_usize( + discriminator_len: std::option::Option, +) -> std::option::Option { + let discriminator_len = match discriminator_len { + Some(discriminator_len) => discriminator_len, + None => return None, + }; + if discriminator_len == 0 { + return None; + } + return Some(usize::from(discriminator_len)); +} + +fn decode_base58_instruction_data( + data_base58: std::option::Option<&str>, +) -> std::option::Option> { + let data_base58 = match data_base58 { + Some(data_base58) => data_base58.trim(), + None => return None, + }; + if data_base58.is_empty() { + return None; + } + let decoded_result = bs58::decode(data_base58).into_vec(); + match decoded_result { + Ok(decoded) => return Some(decoded), + Err(_) => return None, + } +} + +fn data_prefix_matches_discriminator( + data: &[u8], + discriminator_len: usize, + discriminator_hex: &str, +) -> bool { + if data.len() < discriminator_len { + return false; + } + let data_prefix_hex = bytes_prefix_to_hex(data, discriminator_len); + return data_prefix_hex == discriminator_hex; +} + +fn bytes_prefix_to_hex(data: &[u8], len: usize) -> std::string::String { + let mut text = std::string::String::new(); + let mut index = 0_usize; + while index < len { + let byte = data[index]; + text.push_str(format!("{byte:02x}").as_str()); + index += 1; + } + return text; +} + +#[cfg(test)] +mod tests { + + #[test] + fn registry_contains_openbook_v2_idl_instruction_discriminators_without_local_verification() { + let expected = [ + ("create_market", "67e261ebc8bcfbfe"), + ("close_market", "589af8ba300e7bf4"), + ("create_open_orders_account", "ccb5afde287dbc47"), + ("close_open_orders_account", "b04a73d236b35b67"), + ("place_order", "33c29baf6d82606a"), + ("place_take_order", "032c47031ac7cb55"), + ("consume_events", "dd91b1341f2f3fc9"), + ("consume_given_events", "d1e336046dac2947"), + ("cancel_order", "5f81edf00831df84"), + ("cancel_order_by_client_order_id", "73b2c908afb77b77"), + ("cancel_all_orders", "c453f3ab1164a08f"), + ("deposit", "f223c68952e1f2b6"), + ("settle_funds", "ee40a3604bab1021"), + ("sweep_fees", "afe1624776422294"), + ]; + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + for (entry_name, discriminator_hex) in expected { + let mut found = false; + for entry in all_entries.as_slice() { + if entry.decoder_code == "openbook-v2" + && entry.program_id.as_deref() == Some(crate::OPENBOOK_V2_PROGRAM_ID) + && entry.entry_kind == crate::ENTRY_KIND_INSTRUCTION + && entry.entry_name == entry_name + && entry.discriminator_hex.as_deref() == Some(discriminator_hex) + && entry.discriminator_len == Some(8) + && entry.proof_status == crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED + { + found = true; + break; + } + } + assert!( + found, + "missing OpenBook v2 discriminator entry '{}', '{}'", + entry_name, discriminator_hex + ); + } + } + + #[test] + fn openbook_v2_place_take_order_discriminator_matches_raw_data() { + let data = + bs58::encode([3_u8, 44_u8, 71_u8, 3_u8, 26_u8, 199_u8, 203_u8, 85_u8]).into_string(); + let matched = crate::upstream_registry_match::upstream_registry_match_instruction_data( + crate::OPENBOOK_V2_PROGRAM_ID, + Some(data.as_str()), + ); + let matched = match matched { + Some(matched) => matched, + None => panic!("OpenBook v2 place_take_order discriminator must match"), + }; + assert_eq!(matched.decoder_code, "openbook-v2".to_string()); + assert_eq!(matched.entry_name, "place_take_order".to_string()); + assert_eq!(matched.discriminator_hex, Some("032c47031ac7cb55".to_string())); + } + + #[test] + fn registry_contains_priority_family_program_seeds() { + let expected_codes = [ + "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-whirlpool", + "fluxbeam", + "lifinity-amm-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", + "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", + "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", + ]; + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + for expected_code in expected_codes { + let mut found = false; + for entry in all_entries.as_slice() { + if entry.decoder_code == expected_code + && entry.entry_kind == crate::ENTRY_KIND_PROGRAM + { + found = true; + break; + } + } + assert!(found, "missing upstream registry code '{}'", expected_code); + } + } + + #[test] + fn registry_has_no_duplicate_entry_keys() { + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + let mut seen = std::collections::BTreeSet::new(); + for entry in all_entries.as_slice() { + let key = ( + entry.decoder_code.as_str(), + entry.program_id.as_deref(), + entry.entry_kind.as_str(), + entry.entry_name.as_str(), + entry.discriminator_hex.as_deref(), + ); + assert!( + seen.insert(key), + "duplicate upstream registry entry: decoder={} program_id={:?} kind={} name={} discriminator={:?}", + entry.decoder_code, + entry.program_id, + entry.entry_kind, + entry.entry_name, + entry.discriminator_hex + ); + } + } + + #[test] + fn registry_has_no_duplicate_program_entry_for_same_decoder_and_program_id() { + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + let mut seen = std::collections::BTreeSet::new(); + for entry in all_entries.as_slice() { + if entry.entry_kind != crate::ENTRY_KIND_PROGRAM { + continue; + } + let key = (entry.decoder_code.as_str(), entry.program_id.as_deref()); + assert!( + seen.insert(key), + "duplicate upstream registry program entry: decoder={} program_id={:?}", + entry.decoder_code, + entry.program_id + ); + } + } + + #[test] + fn registry_has_no_duplicate_program_id_for_program_rows() { + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + let mut seen = std::collections::BTreeMap::<&str, &str>::new(); + for entry in all_entries.as_slice() { + if entry.entry_kind != crate::ENTRY_KIND_PROGRAM { + continue; + } + let program_id = match entry.program_id.as_deref() { + Some(program_id) => program_id, + None => continue, + }; + match seen.insert(program_id, entry.decoder_code.as_str()) { + Some(previous_decoder) => panic!( + "duplicate upstream registry program_id {} for {} and {}", + program_id, previous_decoder, entry.decoder_code + ), + None => (), + } + } + } + + #[test] + fn registry_has_no_duplicate_program_discriminator_keys() { + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + let mut seen = std::collections::BTreeSet::new(); + for entry in all_entries.as_slice() { + if entry.entry_kind == crate::ENTRY_KIND_PROGRAM { + continue; + } + let program_id = match entry.program_id.as_deref() { + Some(program_id) => program_id, + None => continue, + }; + let discriminator_hex = match entry.discriminator_hex.as_deref() { + Some(discriminator_hex) => discriminator_hex, + None => continue, + }; + let key = ( + program_id, + entry.entry_kind.as_str(), + entry.entry_name.as_str(), + discriminator_hex, + ); + assert!( + seen.insert(key), + "duplicate upstream registry discriminator key: program_id={} kind={} name={} discriminator={}", + program_id, + entry.entry_kind, + entry.entry_name, + discriminator_hex + ); + } + } + + #[test] + fn registry_does_not_claim_local_corpus_verification_in_bootstrap_tranche() { + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + for entry in all_entries.as_slice() { + assert_eq!(entry.proof_status, crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED); + assert_ne!(entry.proof_status, crate::PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_OBSERVED); + assert_ne!( + entry.proof_status, + crate::PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_MATERIALIZED + ); + } + } + + #[test] + fn registry_contains_all_meteora_damm_v2_instruction_discriminators_without_local_verification() + { + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + let expected_entries = [ + ("add_liquidity", "b59d59438fb63448"), + ("claim_partner_fee", "61ce27695e5e7e94"), + ("claim_position_fee", "b4269a118521a2d3"), + ("claim_protocol_fee", "a5e4853063f9ff21"), + ("claim_reward", "955fb5f25e5a9ea2"), + ("cpi_event", "bcd8a66c1aa68eb6"), + ("initialize_pool", "5fb40aac54aee828"), + ("remove_liquidity", "5055d14818ceb16c"), + ("swap", "f8c69e91e17587c8"), + ("swap2", "414b3f4ceb5b5b88"), + ("update_pool_fees", "76d9cbb33c084659"), + ("withdraw_ineligible_reward", "94ce2ac3f7316708"), + ]; + + for expected_entry in expected_entries { + let mut found = false; + for entry in all_entries.as_slice() { + if entry.decoder_code == "meteora-damm-v2" + && entry.entry_kind == crate::ENTRY_KIND_INSTRUCTION + && entry.entry_name == expected_entry.0 + && entry.discriminator_hex.as_deref() == Some(expected_entry.1) + && entry.discriminator_len == Some(8) + && entry.proof_status == crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED + { + found = true; + break; + } + } + assert!( + found, + "missing upstream Git discriminator entry '{}', '{}'", + expected_entry.0, expected_entry.1 + ); + } + } + + #[test] + fn registry_contains_meteora_damm_v2_event_discriminators_without_local_verification() { + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + let expected_entries = + [("evt_liquidity_change", "c5ab4e7fe0d3570d"), ("evt_swap2", "bd4233a826507599")]; + + for expected_entry in expected_entries { + let mut found = false; + for entry in all_entries.as_slice() { + if entry.decoder_code == "meteora-damm-v2" + && entry.entry_kind == crate::ENTRY_KIND_EVENT + && entry.entry_name == expected_entry.0 + && entry.discriminator_hex.as_deref() == Some(expected_entry.1) + && entry.discriminator_len == Some(8) + && entry.proof_status == crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED + { + found = true; + break; + } + } + assert!(found, "missing upstream Git event entry '{}'", expected_entry.0); + } + } + + #[test] + fn matches_anchor_instruction_data_by_program_id_and_discriminator() { + let data = + [0xb5_u8, 0x9d_u8, 0x59_u8, 0x43_u8, 0x8f_u8, 0xb6_u8, 0x34_u8, 0x48_u8, 0x01_u8]; + let data_base58 = bs58::encode(data).into_string(); + let matched = crate::upstream_registry_match::upstream_registry_match_instruction_data( + crate::METEORA_DAMM_V2_PROGRAM_ID, + Some(data_base58.as_str()), + ); + let matched = match matched { + Some(matched) => matched, + None => panic!("missing meteora-damm-v2 add_liquidity registry match"), + }; + assert_eq!(matched.decoder_code, "meteora-damm-v2"); + assert_eq!(matched.entry_name, "add_liquidity"); + assert_eq!(matched.discriminator_hex.as_deref(), Some("b59d59438fb63448")); + assert_eq!(matched.proof_status, crate::PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED); + } + + #[test] + fn matches_one_byte_instruction_data_by_program_id_and_discriminator() { + let data = [0x00_u8, 0x10_u8, 0x20_u8]; + let data_base58 = bs58::encode(data).into_string(); + let matched = crate::upstream_registry_match::upstream_registry_match_instruction_data( + crate::PHOENIX_V1_PROGRAM_ID, + Some(data_base58.as_str()), + ); + let matched = match matched { + Some(matched) => matched, + None => panic!("missing phoenix-v1 swap registry match"), + }; + assert_eq!(matched.decoder_code, "phoenix-v1"); + assert_eq!(matched.entry_name, "swap"); + assert_eq!(matched.discriminator_hex.as_deref(), Some("00")); + assert_eq!(matched.discriminator_len, Some(1)); + } + + #[test] + fn registry_can_filter_by_program_id_and_family() { + let request = crate::UpstreamRegistrySearchRequestDto { + decoder_code: None, + program_id: Some(crate::RAYDIUM_CPMM_PROGRAM_ID.to_string()), + program_family: Some("raydium".to_string()), + surface_kind: None, + entry_kind: None, + proof_status: None, + limit: None, + }; + let result = crate::upstream_registry_match::upstream_registry_search(&request); + assert!(result.entries.len() >= 2); + for entry in result.entries.as_slice() { + assert_eq!(entry.decoder_code, "raydium-cpmm"); + } + } + + #[test] + fn registry_uses_generic_upstream_git_status_names_only() { + let deprecated_external_repo_prefix = format!("{}{}", "car", "bon"); + let forbidden_terms = [deprecated_external_repo_prefix]; + let all_entries = crate::upstream_registry_match::upstream_registry_all_entries(); + for entry in all_entries.as_slice() { + let payload = format!( + "{} {} {} {} {}", + entry.decoder_code, + entry.program_family, + entry.surface_kind, + entry.proof_status, + entry.notes + ); + for forbidden_term in forbidden_terms.as_slice() { + assert!( + !payload.to_ascii_lowercase().contains(forbidden_term.as_str()), + "forbidden registry term found: {}", + forbidden_term + ); + } + } + } +} diff --git a/kb_lib/src/upstream_registry_types.rs b/kb_lib/src/upstream_registry_types.rs new file mode 100644 index 0000000..b20d4e1 --- /dev/null +++ b/kb_lib/src/upstream_registry_types.rs @@ -0,0 +1,177 @@ +// file: kb_lib/src/upstream_registry_types.rs + +//! Shared DTOs and static-entry types for the upstream Git registry. +//! +//! The registry is a discovery index. It must not be interpreted as local +//! business proof that a DEX, instruction, event, trade, metric or candle has +//! been validated against the current SQLite corpus. + +/// Registry entry kind for an instruction discriminator. +pub const ENTRY_KIND_INSTRUCTION: &str = "instruction"; +/// Registry entry kind for an emitted event discriminator. +pub const ENTRY_KIND_EVENT: &str = "event"; +/// Registry entry kind for an account discriminator or account layout. +pub const ENTRY_KIND_ACCOUNT: &str = "account"; +/// Registry entry kind for a program-level seed row. +pub const ENTRY_KIND_PROGRAM: &str = "program"; + +/// Generic protocol name used for upstream registry matches that are not business-materialized. +pub const UPSTREAM_REGISTRY_PROTOCOL_NAME: &str = "upstream_git"; +/// Generic event kind used for instruction-level upstream registry matches. +pub const UPSTREAM_REGISTRY_INSTRUCTION_MATCH_EVENT_KIND: &str = "upstream_git.instruction_match"; + +/// Generic upstream Git status for an entry that has not been observed locally. +pub const PROOF_STATUS_UPSTREAM_GIT_UNVERIFIED: &str = "upstream_git_unverified"; +/// Generic upstream Git status for an entry wired into a decoder but not observed locally. +pub const PROOF_STATUS_UPSTREAM_GIT_MAPPED_UNVERIFIED: &str = "upstream_git_mapped_unverified"; +/// Generic upstream Git status for an entry observed in the local corpus. +pub const PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_OBSERVED: &str = + "upstream_git_local_corpus_observed"; +/// Generic upstream Git status for an entry materialized in local business tables. +pub const PROOF_STATUS_UPSTREAM_GIT_LOCAL_CORPUS_MATERIALIZED: &str = + "upstream_git_local_corpus_materialized"; +/// Generic upstream Git status for a known layout that is not yet locally validated. +pub const PROOF_STATUS_UPSTREAM_GIT_LAYOUT_UNVERIFIED: &str = "upstream_git_layout_unverified"; + +/// Static registry entry used by generated or hand-curated bootstrap data. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct UpstreamRegistryEntry { + /// Repository name or bootstrap locator that produced the entry. + pub source_repo: std::option::Option<&'static str>, + /// Repository-relative path or bootstrap path that produced the entry. + pub source_path: std::option::Option<&'static str>, + /// Stable decoder code used by the registry. + pub decoder_code: &'static str, + /// Optional Solana program id when already known by the source entry. + pub program_id: std::option::Option<&'static str>, + /// Program family used to group related programs. + pub program_family: &'static str, + /// Surface kind such as AMM, CLMM, launch, aggregator or core Solana. + pub surface_kind: &'static str, + /// Entry kind: instruction, event, account or program. + pub entry_kind: &'static str, + /// Source-level entry name. + pub entry_name: &'static str, + /// Optional discriminator bytes encoded as lowercase hexadecimal. + pub discriminator_hex: std::option::Option<&'static str>, + /// Optional discriminator byte length. + pub discriminator_len: std::option::Option, + /// Current proof status. + pub proof_status: &'static str, + /// Notes that preserve uncertainty and validation requirements. + pub notes: &'static str, +} + +impl UpstreamRegistryEntry { + /// Converts a static entry into an owned DTO for application/UI boundaries. + pub fn to_dto(&self) -> crate::UpstreamRegistryEntryDto { + return crate::UpstreamRegistryEntryDto { + source_repo: self.source_repo.map(std::string::ToString::to_string), + source_path: self.source_path.map(std::string::ToString::to_string), + decoder_code: self.decoder_code.to_string(), + program_id: self.program_id.map(std::string::ToString::to_string), + program_family: self.program_family.to_string(), + surface_kind: self.surface_kind.to_string(), + entry_kind: self.entry_kind.to_string(), + entry_name: self.entry_name.to_string(), + discriminator_hex: self.discriminator_hex.map(std::string::ToString::to_string), + discriminator_len: self.discriminator_len, + proof_status: self.proof_status.to_string(), + notes: self.notes.to_string(), + }; + } +} + +/// Owned registry entry DTO exposed at crate and UI boundaries. +#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct UpstreamRegistryEntryDto { + /// Repository name or bootstrap locator that produced the entry. + pub source_repo: std::option::Option, + /// Repository-relative path or bootstrap path that produced the entry. + pub source_path: std::option::Option, + /// Stable decoder code used by the registry. + pub decoder_code: std::string::String, + /// Optional Solana program id when already known by the source entry. + pub program_id: std::option::Option, + /// Program family used to group related programs. + pub program_family: std::string::String, + /// Surface kind such as AMM, CLMM, launch, aggregator or core Solana. + pub surface_kind: std::string::String, + /// Entry kind: instruction, event, account or program. + pub entry_kind: std::string::String, + /// Source-level entry name. + pub entry_name: std::string::String, + /// Optional discriminator bytes encoded as lowercase hexadecimal. + pub discriminator_hex: std::option::Option, + /// Optional discriminator byte length. + pub discriminator_len: std::option::Option, + /// Current proof status. + pub proof_status: std::string::String, + /// Notes that preserve uncertainty and validation requirements. + pub notes: std::string::String, +} + +/// Search/filter request for registry entries. +#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct UpstreamRegistrySearchRequestDto { + /// Optional decoder-code filter. + pub decoder_code: std::option::Option, + /// Optional program-id filter. + pub program_id: std::option::Option, + /// Optional program-family filter. + pub program_family: std::option::Option, + /// Optional surface-kind filter. + pub surface_kind: std::option::Option, + /// Optional entry-kind filter. + pub entry_kind: std::option::Option, + /// Optional proof-status filter. + pub proof_status: std::option::Option, + /// Optional maximum number of returned entries. + pub limit: std::option::Option, +} + +/// Summary of the current registry snapshot. +#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct UpstreamRegistrySummaryDto { + /// Total static registry entry count before filtering. + pub total_entry_count: usize, + /// Returned entry count after filtering. + pub returned_entry_count: usize, + /// Number of entries that have a program id. + pub entries_with_program_id_count: usize, + /// Number of entries that have a discriminator. + pub entries_with_discriminator_count: usize, + /// Number of program-level seed entries. + pub program_entry_count: usize, + /// Number of instruction entries. + pub instruction_entry_count: usize, + /// Number of event entries. + pub event_entry_count: usize, + /// Number of account entries. + pub account_entry_count: usize, + /// Number of entries still unverified from upstream Git or seed data. + pub upstream_git_unverified_count: usize, + /// Number of entries mapped into decoders but not locally observed. + pub upstream_git_mapped_unverified_count: usize, + /// Number of entries observed in the local corpus. + pub upstream_git_local_corpus_observed_count: usize, + /// Number of entries materialized in local business tables. + pub upstream_git_local_corpus_materialized_count: usize, + /// Number of layout entries still unverified locally. + pub upstream_git_layout_unverified_count: usize, +} + +/// Search result returned by the upstream registry service. +#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct UpstreamRegistrySearchResultDto { + /// Normalized request used for the search. + pub request: crate::UpstreamRegistrySearchRequestDto, + /// Registry summary. + pub summary: crate::UpstreamRegistrySummaryDto, + /// Matching entries. + pub entries: std::vec::Vec, +}