# Dépendances d’interfaces Solana et SPL ## Objectif Le workspace privilégie les interfaces officielles étroites afin d’éviter de recopier des enums, layouts, IDs ou builders déjà publiés par Solana ou SPL. Les dépendances de `[workspace.dependencies]` constituent un catalogue de versions cohérentes ; elles ne sont pas automatiquement ajoutées à toutes les crates. ## Règle de consommation Une crate ajoute une interface uniquement lorsqu’elle utilise réellement au moins un de ses éléments : - enum d’instruction ou d’état ; - encodeur/décodeur officiel ; - type de compte ou paramètre ; - program ID ou sysvar ID ; - modèle RPC appartenant à sa responsabilité. Une déclaration à la racine ne justifie pas une dépendance inutilisée dans une crate feuille. Les features restent minimales et explicites. ## Ordre des formats 1. `wincode` lorsqu’il est officiellement exposé par l’interface ; 2. Borsh lorsqu’il correspond au contrat officiel ou au comportement du runtime ; 3. parseur local borné lorsque l’interface officielle ne fournit son helper qu’avec `bincode`. ### Compatibilité de version `wincode` Le workspace reste épinglé sur `wincode ^0.5`. Les crates Solana modulaires actuellement utilisées avec la feature `wincode` publient leurs implémentations `SchemaRead`/`SchemaWrite` contre `wincode 0.5.x`. Ces traits sont nominalement distincts de ceux de `wincode 0.6.x` : une dépendance directe migrée seule vers `0.6` ne peut donc ni désérialiser `solana_nonce::versions::Versions`, ni sérialiser `solana_transaction::Transaction`. Cargo peut charger les deux versions simultanément, mais les implémentations de traits ne sont pas interchangeables et l’orphan rule interdit de les réimplémenter localement pour ces types externes. Le catalogue `[workspace.dependencies]` ne gouverne que les dépendances réellement consommées par les crates membres ; il ne peut pas contraindre à lui seul une branche transitive compatible avec plusieurs versions. Ajouter `solana-wincode-varint` comme dépendance inutilisée de `kb-lib` serait contraire aux règles du workspace. Comme bot3 est un workspace applicatif, son `Cargo.lock` versionné constitue le verrou reproductible de cette branche : il doit résoudre exactement `solana-wincode-varint 1.0.0` et `wincode 0.5.5`. L’audit `scripts/audit_khadhroony_workspace_rules.py` vérifie le manifeste et ces deux versions avant les contrôles Cargo. La migration vers `wincode 0.6` doit attendre que l’ensemble des crates Solana consommées migre de façon cohérente. Une double dépendance aliasée n’est acceptable que pour des types propres au workspace ; tous les appels portant sur des types Solana doivent utiliser la même version `0.5.x` que celle employée par leurs crates d’origine. Avant toute migration, vérifier avec `cargo tree -d` et `cargo tree -i wincode@`. Le workspace n’ajoute pas de dépendance directe à `bincode`. Une feature officielle `bincode` seule n’est pas activée pour contourner cette règle. ## Interfaces utilisées dans `kb_decoder_solana_core` | Surface | Interface | Features utiles | Stratégie actuelle | |---------------------------|---------------------------------------------------|----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------| | Address Lookup Table | `solana-address-lookup-table-interface ^3.1` | `serde`, `wincode` | enum officielle et `wincode` exact | | Compute Budget | `solana-compute-budget-interface ^3.0` | `borsh`, `serde` | enum officielle pour les fixtures ; parser borné aligné sur le Borsh unchecked du runtime | | System Program | `solana-system-interface ^3.2` | `alloc`, `serde`, `std`, `solana-instruction`, `wincode` | enum officielle et `wincode` | | Vote Program | `solana-vote-interface ^6.0` | `serde`, `wincode` | enum officielle et `wincode::deserialize_exact` | | Stake Program | `solana-stake-interface ^4.3` | `borsh`, `serde`, `wincode` | types/ID officiels + miroir wire privé `wincode` exact, compatible avec le layout historique | | Précompiles signature | sources runtime Agave et crates programme `3.0.0` | aucune nouvelle dépendance consommée | parseurs locaux bornés des tables d’offsets, résolution outer via contrat core `2`, sans cryptographie ni `bincode` | | ZK ElGamal Proof | `solana-zk-elgamal-proof-interface ^0.1` | aucune feature additionnelle | enum `ProofInstruction` et tailles `Pod` officielles ; comportement des comptes vérifié contre le runtime Agave | | ZK Token Proof historique | aucune dépendance runtime dédiée | miroir wire local borné | tags et tailles historiques audités contre `solana-zk-token-sdk 3.1.14`; comparaison Agave `v2.0.0`/`v4.1.1` | | Slashing Program | Agave `v4.1.1`, `solana-program/slashing@fe8da3a` | aucune dépendance ajoutée | parseur local borné du contrat release vérifié ; compte de preuve externe non relu et aucune cryptographie locale | ## Décision pour les précompiles de signature Les crates officielles Ed25519, secp256k1 et secp256r1 exposent les IDs, constantes et structures de layout, mais `kb_program_ids` centralise déjà les IDs et le delta n’exécute aucune vérification cryptographique. Ajouter ces dépendances uniquement pour recopier des tailles ou des structures `Pod` constituerait une dépendance sans consommation fonctionnelle. `kb_decoder_solana_core` reproduit les layouts exacts depuis les sources runtime Agave : table Ed25519/secp256r1 de 14 octets, table secp256k1 de 11 octets, sentinelle `u16::MAX` uniquement pour Ed25519/secp256r1, index `u8` toujours explicite pour secp256k1, règles zéro signature et limite secp256r1. Les fixtures manuelles rendent chaque offset visible et les tests couvrent les références inter-instructions et les bornes. Aucune dépendance `bincode` n’est ajoutée. ## Transaction client dans `kb_execution_solana` `kb_execution_solana` n’importe plus l’agrégat `solana-sdk`. Sa frontière transactionnelle utilise les crates modulaires réellement consommées : `solana-instruction`, `solana-message`, `solana-transaction`, `solana-hash`, `solana-pubkey`, `solana-keypair`, `solana-signer`, `solana-nonce` et `solana-system-interface`. Les exécuteurs spécifiques conservent la même politique et ajoutent uniquement l’interface de programme nécessaire. Le message à signer provient de `solana_transaction::Transaction::message_data()`. La transaction complète utilise `wincode::serialize`, supporté officiellement par les types modulaires `Message` et `Transaction`. Cette stratégie remplace tout appel direct à `bincode` et reproduit le wire attendu par `getFeeForMessage`, `simulateTransaction` et `sendTransaction`. La taille sérialisée est refusée au-delà de 1 232 octets. ## Identifiants natifs, Vote et loaders dans l’exécuteur `solana-sdk-ids` est conservé intentionnellement comme registre officiel modulaire des adresses natives et sysvars. Les chemins `solana_sdk_ids::sysvar::{clock,rent,slot_hashes,instructions}` ne constituent pas un retour au SDK monolithique : ils fournissent uniquement des `Pubkey` canoniques. `solana-instructions-sysvar` ne doit être ajouté que lorsqu’une crate appelle réellement ses fonctions d’introspection d’instructions, pas pour remplacer un simple ID officiel. `kb_executor_solana_core` consomme `solana-vote-interface ^6.0` avec `serde` et `wincode` pour construire les vingt variantes wire Vote actuelles. Il utilise `solana-instruction` pour `Instruction`/`AccountMeta`, `solana-pubkey::Pubkey` pour les adresses publiques, `solana-hash::Hash` pour les hashes et `solana-sdk-ids` pour Rent, Clock et SlotHashes. Les quatre créations composées utilisent `solana-system-interface`; aucune dépendance `solana-sdk` ni feature `bincode` n’est ajoutée à la crate. `kb_decoder_solana_core` et `kb_executor_solana_core` consomment désormais `solana-loader-v3-interface ^8.0` avec `wincode`. Le décodeur désérialise l’enum officielle de façon exacte tout en conservant la compatibilité du booléen optionnel historique des dernières variantes. L’exécuteur appelle les helpers officiels pour onze plans : création de buffer, écriture, déploiement, upgrade, changements d’autorité, fermetures et extension. `solana-loader-v4-interface ^3.1` publie l’enum et les comptes officiels, mais ses helpers de construction sont conditionnés par la feature `bincode` et l’enum ne fournit pas de schéma `wincode`. Pour respecter l’interdiction de `bincode`, `kb_executor_solana_core` reproduit localement le wire borné des sept discriminants (`u32 LE`, champs numériques et vecteur borné) et les métadonnées de comptes exactes pour neuf plans. La crate feuille n’ajoute donc pas une dépendance inutilisée à l’interface v4; le catalogue workspace la conserve comme source normative/versionnée. ## Interfaces officielles non encore consommées | Interface | Propriétaire futur | Décision | |------------------------------------------|------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------| | `solana-feature-gate-interface ^4.0` | `kb_decoder_solana_core` | peut fournir les types officiels ; l’instruction actuelle reste un tag d’un octet vérifié depuis le builder/processor | | `solana-feature-set-interface ^4.0` | classification/diagnostics natifs | ajouter seulement lorsqu’un type est consommé | | `solana-loader-v4-interface ^3.1` | source normative Loader v4 | helpers officiels conditionnés par `bincode`; conserver le miroir wire local borné tant qu’aucun schéma `wincode` n’est publié | | interfaces SPL | crates `kb_decoder_spl_*` et `kb_executor_spl_*` correspondantes | ne pas les rattacher au décodeur natif ni à l’application | | types RPC/account/transaction status | `kb_rpc` | ne pas les ajouter à `kb_app_demo` ; l’application consomme les DTO du workspace | ## Exceptions locales actuelles ### SPL Memo v1, v3 et v4 `kb_decoder_spl_memo` et `kb_executor_spl_memo` consomment `spl-memo-interface ^2.1` sans feature additionnelle. La version effectivement résolue pendant les validations est 2.1.0. Elle publie les trois IDs exacts et un builder générique recevant explicitement le Program ID. Ce builder place les octets exacts du message dans `Instruction::data` et transforme chaque pubkey fournie en compte readonly signer, sans sérialisation intermédiaire. L’exécuteur appelle ce builder pour les trois générations et compare chaque plan au résultat officiel. Les différences runtime restent explicites : v1 ignore les comptes, v3/v4 les vérifient. La bibliothèque ne lie toutefois aucune génération à un cluster ou au dry-run : la simulation obligatoire établit la disponibilité effective du Program ID ciblé, puis les politiques communes gouvernent l’autorisation d’envoi et Mainnet. La démo du jalon retient séparément v4 sur Devnet. La taille packet finale reste contrôlée par `kb_execution_solana` après compilation du message. Le décodeur ne dépend pas du builder pour lire le wire : il analyse directement les octets base64 retenus par le core, avec une borne de 4 096 octets, puis valide l’UTF‑8. La source historique v1 prouve que les comptes sont ignorés ; les processors v3/v4 exigent au contraire que chaque compte fourni soit signer avant de valider l’UTF‑8. Ces règles restent séparées dans `docs/SPL_MEMO_MATRIX.json` et les tests comparent les trois IDs locaux aux constantes de l’interface officielle. L’archive source `0.4.2` ne contenait pas de `Cargo.lock`. Les compilations et validations `0.4.3` ont résolu `spl-memo-interface 2.1.0`, sans mise à jour automatique de la contrainte workspace. Cette version exacte a construit les trois générations et le parcours v4 Devnet réel. ### SPL Token classique Le catalogue workspace déclare `spl-token-interface ^3.0` sans feature. Le tag officiel `interface@v3.0.0` publie la version `3.0.0`, sans feature optionnelle ni dépendance à `bincode`. `kb_decoder_spl_token` consomme l'ID officiel et utilise `TokenInstruction::unpack` dans les tests différentiels. Le wire de production reste un parseur local borné afin de conserver les tailles consommées, les suffixes acceptés par les processors, les diagnostics UTF-8 et la structure interne de `Batch`, que l'enum officielle représente seulement par son tag parent. La surface compte 28 tags : `0..24`, `38` (`WithdrawExcessLamports`), `45` (`UnwrapLamports`) et `255` (`Batch`). L'interface `3.0.0` fournit un builder pour chacun. La source historique `program/src/processor.rs` ne suffit toutefois pas à prouver les deux nouveaux tags : le processor p-token `1.0.0` sous le même Program ID implémente explicitement `UnwrapLamports` et `Batch`. La publication de l'interface, la constructibilité, le binaire déployé par cluster et le résultat de simulation restent quatre preuves séparées dans `docs/SPL_TOKEN_MATRIX.json`. Le processor p-token lit les champs numériques avec des contrôles de longueur minimale et peut donc ignorer des octets suffixes selon l'opération. Le décodeur les conserve et les signale au lieu de les accepter silencieusement. `Batch` est découpé selon les paires `account_count/data_len`, interdit les données enfant vides et appelle uniquement le processor interne, ce qui rend un batch imbriqué invalide. Le décodeur ajoute des bornes défensives de 64 enfants, 512 comptes cumulés et 16 384 octets par instruction. La résolution `3.0.0` et les tests différentiels du décodeur ont été confirmés dans le workspace le 15 juillet 2026. `kb_executor_spl_token` consomme les builders officiels de cette même interface. Les variantes `InitializeMint`, `InitializeAccount`, `InitializeMultisig` et `InitializeAccount2` restent decode-only dans la politique d'exécution ; les opérations anciennes toujours publiées et utilisables, comme `Transfer` ou `SetAuthority`, ne sont pas confondues avec des opérations obsolètes. Les signatures officielles de `unwrap_lamports` et `batch` ont été auditées au commit `46eaacd`. Leur constructibilité est donc prouvée. Leur déploiement sur le programme classique Devnet a été observé le 16 juillet 2026 par deux simulations sans signature ni envoi : `Batch` avec un enfant `TransferChecked` de montant nul a réussi en 270 compute units, puis `UnwrapLamports` d'un lamport depuis un compte wrapped SOL auxiliaire classique a réussi en 140 compute units. Localnet, Testnet et Mainnet restent des preuves séparées. L'exécuteur ne bloque aucun cluster et laisse l'autorisation d'envoi aux politiques communes. Sur Devnet, le programme classique a également confirmé un `TransferChecked` complet et un lifecycle sans ATA couvrant `InitializeAccount3`, `MintToChecked`, `TransferChecked`, `ApproveChecked`, `Revoke`, `BurnChecked` et `CloseAccount`. Sur Mainnet, un corpus canonique de 370 instructions a été décodé et matérialisé sans entrée unsupported, failed ou unmatched. Localnet n'a pas été exercé. La matrice conserve donc indépendamment la version d'interface, le processor de référence, le builder, les observations réelles et le résultat de simulation/soumission par instruction. ### SPL Associated Token Account Le catalogue workspace déclare `spl-associated-token-account-interface ^2.0` avec la feature `borsh`. Cargo a résolu la version `2.0.0` pendant le jalon bot2 `0.4.5`. Depuis bot3 `0.1.0-pre.007`, `kb-lib::decoder::spl::associated_token_account` consomme réellement le Program ID et le helper officiel de dérivation en production, puis l'enum et les builders dans ses tests différentiels. L'ancien exécuteur n'est pas encore porté ; le pipeline et la démo restent donc hors de cette tranche. L'interface publie exactement trois variantes Borsh actuelles : `Create` (`0`), `CreateIdempotent` (`1`) et `RecoverNested` (`2`). Le processor accepte aussi historiquement une donnée vide comme `Create`; cette forme reste décodable mais n'est pas produite par le builder actuel. La dérivation canonique utilise les seeds `[wallet, Token Program ID, mint]` sous le Program ID ATA. Le Token Program fait donc partie de l'adresse et distingue nécessairement les ATA classiques des ATA Token-2022 d'un même wallet et mint. Le décodeur conserve les comptes, flags, doublons, chemins outer/inner, transactions échouées, adresses observées et dérivées, ainsi que les rôles distincts de `RecoverNested`. Les tests différentiels comparent les trois builders et les vecteurs PDA au helper officiel. Dans bot2, l'exécuteur validé utilisait les mêmes builders pour les trois variantes, imposait simulation et dry-run par défaut, puis laissait au pipeline stateful les contrôles de mint, owner, compte existant, rent, signataires et postconditions. Cette capacité reste une preuve de référence tant que les modules exécuteur et pipeline correspondants ne sont pas portés dans bot3. Les preuves Devnet du 16 juillet 2026 couvrent `CreateIdempotent` pour SPL Token classique et Token-2022, y compris création, réutilisation, replay post-exécution idempotent et ATA Token-2022 avec extension `ImmutableOwner`. Elles couvrent aussi un `RecoverNested` classique contrôlé : le solde brut a été transféré vers l'ATA wallet, le compte nested a été fermé et les deux faits lifecycle/risk ont été matérialisés sans dupliquer les CPI SPL Token. Le décodage général des instructions et extensions Token-2022 reste réservé à `0.4.6`. ### Token-2022 — audit initial `0.4.6-pre.001` Le catalogue workspace déclare `spl-token-2022-interface ^3.1` avec `serde` et `spl-elgamal-registry-interface ^0.2` sans feature additionnelle. La résolution opérateur confirme respectivement `3.1.1` avec `default + serde` et `0.2.1` avec `default`. Dans bot3, `kb-lib` les consomme comme dépendances de développement pour les tests différentiels ; le code de production utilise les parseurs locaux bornés déjà prouvés contre ces interfaces. La matrice inventorie 48 tags de premier niveau et 29 types TLV de production, dont le récent `PermissionedBurnExtension` `46` et son TLV `PermissionedBurn` `28`. Les sous-discriminants, comptes, layouts, tailles, builders et processors restent explicitement `pending`. L'interface ElGamal `0.2.1` confirme le Program ID `regVYJW7tcT8zipN5YiBvHsvR5jXW1uLFxaHSbugABg` et la seed PDA `elgamal-registry`. Le registre garde toutefois une matrice, un dispatch et une politique d'exécution séparés du programme natif ZK ElGamal Proof. Les TLV Token Metadata/Token Group et les pointeurs Transfer Hook ne donnent aucun Program ID universel aux programmes externes qui implémentent ces interfaces. L'interface Token-2022 `3.1.1` publie le commit exact `e18f9c6f9bf6044b934f48e3090e8e59e4820f02` (`interface@v3.1.1`). Au même commit, le processor porte la version `11.0.0` et son lock source résout Token Group `0.7.2`, Token Metadata `1.0.0` et le registre ElGamal `0.2.1`. Son dispatch tente d'abord les 48 tags Token-2022, puis les cinq discriminants Token Metadata et les quatre discriminants Token Group. Cette incorporation ne donne pas de Program ID universel aux interfaces : elle décrit seulement leur exécution directe par Token-2022. L'égalité avec les binaires cluster reste à prouver séparément. Le `Cargo.lock` opérateur confirme le graphe réellement consommé par l'interface `3.1.1` : ZK ElGamal Proof `0.1.3`, extraction de preuve confidentielle `0.6.1`, Token Group `0.7.2`, Token Metadata `1.0.1` et TLV `0.9.1`. Token Metadata apparaît directement sous `spl-token-2022-interface` dans `cargo tree -p ... -e features`. Le processor source `11.0.0` audité figeait encore Token Metadata `1.0.0`. La publication officielle `1.0.1` ne change ni wire, ni discriminant, ni builder : elle ajoute seulement, avant Borsh, une validation bornée des longueurs de chaînes de `Initialize`, `UpdateField` et `RemoveKey`. Cette garde plus sûre devient normative pour le décodeur ; `UpdateAuthority` et `Emit` restent sans chaîne. La migration `0.1.0-pre.008` conserve ces contrats dans `kb_lib::decoder::spl::token_2022` et isole le registre dans `kb_lib::decoder::spl::elgamal_registry`. Les targets de tracing, matrices et Program IDs restent distincts ; aucun pointeur TLV n’est interprété comme une preuve de l’état du programme externe pointé. ### ZK ElGamal Proof `kb_decoder_solana_core` consomme directement `solana-zk-elgamal-proof-interface ^0.1`. L’enum `ProofInstruction` fournit les treize discriminants et les types de `proof_data` fournissent les tailles `Pod` exactes pour séparer le contexte du corps de preuve inline. Le runtime Agave reste la source normative pour la sélection entre preuve inline et preuve stockée dans un compte, les positions de comptes optionnels et l’acceptation des octets suffixes de `CloseContextState`. Aucune dépendance à `bytemuck` n’est ajoutée directement : le décodeur ne convertit pas les octets en preuve cryptographique et n’appelle aucun vérificateur. Il utilise uniquement `size_of` sur les types officiels, puis conserve longueur, SHA-256 et préfixe borné. Le contenu d’un compte de preuve externe n’est pas récupéré par RPC pendant un replay historique. ### ZK Token Proof historique `kb_decoder_solana_core` ne dépend plus de `solana-zk-token-sdk`. Cette crate historique est dépréciée et entraînait `bincode` transitivement. Le workspace conserve une table wire locale limitée aux tags `0..16`, aux tailles exactes de contexte/preuve et à l’offset `u32 LE`, auditée contre la version historique `3.1.14`; aucun code de preuve ni sérialiseur historique n’est recopié. Le comportement est documenté depuis deux références runtime distinctes : Agave `v2.0.0` pour le vérificateur historique et Agave `v4.1.1` pour le stub actuel sans effet. Aucun corpus mainnet n’ayant été observé, les tests sont synthétiques et n’exigent pas de backfill. ### Stake Program `solana-stake-interface 4.3.1` publie `StakeInstruction` avec Serde et conserve ses builders derrière la feature `bincode`. La feature `wincode` fournit les schémas nécessaires aux types d’état, mais pas directement à l’enum d’instruction. Le décodeur et l’exécuteur consomment donc l’ID et les types sémantiques officiels, avec un miroir wire privé commun dans son ordre de variantes et de champs. Aucun helper `bincode` n’est activé. L’exécuteur reproduit les vingt-quatre helpers clients actuels : initialize/create, checked/seed, split/merge, create-and-delegate, quatre authorize, delegate, withdraw, deactivate, lockup, minimum delegation, delinquent deactivation et move. Les helpers `redelegate` et `redelegate_with_seed` sont explicitement exclus parce que la source officielle les marque dépréciés et « will not be enabled » ; ils restent uniquement dans le miroir historique du décodeur. Le contrat des comptes est aligné sur les builders officiels. Les contrôles stateful du processor BPF — état de compte, rent, epochs, compatibilité et autorités courantes — restent à l’orchestration localnet/devnet. ### Config Program `solana-config-interface 2.x` expose son module d’instruction derrière sa feature `bincode`. Le décodeur et l’exécuteur conservent donc un wire local borné pour `ConfigKeys` : compact-u16 canonique, booléens stricts, ordre exact des signataires, rejet des doublons et payload métier opaque. Le builder de création reproduit la taille `max_config_space + serialized_size(ConfigKeys)` et l’initialisation `ConfigKeys vide + T::default()` à partir d’octets déjà sérialisés ; il n’active aucun helper `bincode`. ### BPF Loader v2 `solana-loader-v2-interface 3.x` publie ses helpers d’instruction derrière `bincode`. Le décodeur conserve le layout local vérifié tant qu’aucun schéma officiel `wincode` n’est disponible. ### Feature Gate `solana-feature-gate-interface 4.x` publie la séquence d’activation `transfer -> allocate -> assign` et `RevokePendingActivation`, mais les helpers restent derrière sa feature `bincode`. L’exécuteur utilise `Feature::size_of()` et reproduit ces instructions à partir des interfaces System étroites ; la révocation reste exactement `vec![0]` avec feature, incinerator et System Program dans l’ordre officiel. ### Slashing Program La source normative est SIMD-0204 et le contrat du programme Slashing publié : deux instructions, un payload DuplicateBlockProof de 305 octets, un report PDA dérivé de `node_pubkey + slot LE + type`, et une instruction Ed25519 précédente dont les offsets pointent vers le payload Slashing. Aucune crate de sérialisation générale n’est nécessaire. L’exécuteur construit le plan atomique et laisse au pipeline stateful le compte de preuve, le rent et les fenêtres epoch. ### ZK ElGamal Proof dans l’exécuteur `kb_executor_solana_core` dépend directement de `solana-zk-elgamal-proof-interface ^0.1` pour les types POD et leurs tailles. Les layouts d’instruction sont simples et officiels : discriminant + preuve inline, ou discriminant + offset `u32 LE`; les comptes de contexte suivent `ContextStateInfo`. La fermeture reproduit le builder officiel. Aucune vérification cryptographique n’est recalculée côté client. ### Loaders v3 et v4 La migration Loader v3 est terminée dans `pre.020` : le décodeur utilise `wincode::deserialize_exact` et l’exécuteur utilise les helpers officiels de `solana-loader-v3-interface 8.x`. Les payloads tronqués, suffixés, les longueurs et les contrats de comptes restent bornés par les tests. Loader v4 conserve un parser et un constructeur locaux limités aux sept discriminants publiés. Le layout est suffisamment petit pour être audité explicitement : tag `u32 LE`, `Write { offset, Vec }`, `Copy { destination_offset, source_offset, length }`, `SetProgramLength { new_size }` et quatre variantes unitaires. Cette exception évite d’activer `bincode` uniquement pour appeler les helpers de l’interface. ## `solana-sdk` `solana-sdk` avec la feature `full` peut rester disponible au niveau workspace pour les applications ou outils qui ont réellement besoin de l’agrégat complet. Les crates feuille doivent préférer les interfaces étroites afin de réduire les features transitives, les temps de compilation et les risques de dépendances inutilisées. ## Vérification avant ajout Pour chaque nouvelle interface : 1. lire ses features et ses modules réellement compilés ; 2. identifier le format officiel de sérialisation ; 3. confirmer la version compatible avec Agave ciblée ; 4. ajouter la dépendance uniquement à la crate propriétaire ; 5. créer une fixture depuis l’encodeur officiel lorsque disponible ; 6. tester les payloads tronqués, inconnus, suffixés et les comptes invalides ; 7. documenter toute divergence entre l’interface et le runtime. ### Metaplex Token Metadata — audit et premier décodage `0.4.7-pre.002` Le catalogue workspace déclare `mpl-token-metadata ^5.1` avec la seule feature `serde`. La publication officielle résolue reste `5.1.1`; elle fournit les modules générés `accounts`, `instructions`, `types` et `errors` issus de l’IDL Metaplex, sans introduire Anchor. La crate officielle utilise Borsh `< 1.0`; le décodeur référence donc explicitement `borsh 0.10` sous l’alias workspace `borsh_0_10`, distinct de Borsh 1.x utilisé par d’autres interfaces du workspace. Le dépôt officiel `metaplex-foundation/mpl-token-metadata` confirme le Program ID `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s`. L’IDL officiel audité porte la version `1.14.0` et le blob `5df4a24f62c2743125be096cc174680790c92c18`; l’inventaire Rust généré des instructions porte le blob `3c42eec629f82e44ba690a7c4bd2177cc78f1d49`. `kb_decoder_metadata_metaplex_token_metadata` implémente désormais `InstructionDecoder` pour `CreateMetadataAccountV3` et `UpdateMetadataAccountV2`. Les arguments sont lus avec les types Borsh officiels et projetés avec la feature `serde`; les payloads, chaînes, créateurs, frais, comptes et suffixes sont bornés. L’enregistrement dans le registre runtime reste différé jusqu’à validation de ce premier groupe. Les metadata Token-2022 incorporées, Metaplex Core, Bubblegum et le JSON externe restent des provenances ou composants distincts.