This commit is contained in:
2026-07-23 16:37:12 +02:00
parent 99c345f2f2
commit 0da75c1311
2159 changed files with 230833 additions and 0 deletions

View File

@@ -0,0 +1,272 @@
<!-- file: docs/SOLANA_INTERFACE_DEPENDENCIES.md -->
<!-- version: 28 -->
# Dépendances dinterfaces 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 lorsquelle utilise réellement au moins un de ses éléments :
- enum dinstruction 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` lorsquil est officiellement exposé par linterface ;
2. Borsh lorsquil correspond au contrat officiel ou au comportement du runtime ;
3. parseur local borné lorsque linterface officielle ne fournit son helper quavec `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 lorphan rule interdit de les réimplémenter localement pour ces types externes.
La migration vers `wincode 0.6` doit attendre que lensemble des crates Solana consommées migre de façon cohérente. Une double dépendance aliasée nest 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 dorigine. Avant toute migration, vérifier avec `cargo tree -d` et `cargo tree -i wincode@<version>`.
Le workspace najoute pas de dépendance directe à `bincode`. Une feature officielle `bincode` seule nest 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 doffsets, 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 nexé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` nest ajoutée.
## Transaction client dans `kb_execution_solana`
`kb_execution_solana` nimporte plus lagré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 linterface 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 lexé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 lorsquune crate appelle réellement ses fonctions dintrospection dinstructions, 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` nest 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 lenum officielle de façon exacte tout en conservant la compatibilité du booléen optionnel historique des dernières variantes. Lexécuteur appelle les helpers officiels pour onze plans : création de buffer, écriture, déploiement, upgrade, changements dautorité, fermetures et extension.
`solana-loader-v4-interface ^3.1` publie lenum et les comptes officiels, mais ses helpers de construction sont conditionnés par la feature `bincode` et lenum ne fournit pas de schéma `wincode`. Pour respecter linterdiction 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 najoute donc pas une dépendance inutilisée à linterface 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 ; linstruction actuelle reste un tag dun octet vérifié depuis le builder/processor |
| `solana-feature-set-interface ^4.0` | classification/diagnostics natifs | ajouter seulement lorsquun 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 quaucun schéma `wincode` nest publié |
| interfaces SPL | crates `kb_decoder_spl_*` et `kb_executor_spl_*` correspondantes | ne pas les rattacher au décodeur natif ni à lapplication |
| types RPC/account/transaction status | `kb_rpc` | ne pas les ajouter à `kb_app_demo` ; lapplication 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.
Lexé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 lautorisation denvoi 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 lUTF8. 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 lUTF8. Ces règles restent séparées dans `docs/SPL_MEMO_MATRIX.json` et les tests comparent les trois IDs locaux aux constantes de linterface officielle.
Larchive 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 `0.4.5`. Les crates
`kb_decoder_spl_associated_token_account` et `kb_executor_spl_associated_token_account` consomment
réellement l'enum, les builders, le Program ID et le helper officiel de dérivation ; le pipeline et
la démo consomment ensuite leurs contrats typés sans recopier l'interface.
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. L'exécuteur
utilise les mêmes builders pour les trois variantes, impose simulation et dry-run par défaut, puis
laisse au pipeline stateful les contrôles de mint, owner, compte existant, rent, signataires et
postconditions.
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`, consommées par
`kb_decoder_spl_token_2022` pour poursuivre l'audit. 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.
### ZK ElGamal Proof
`kb_decoder_solana_core` consomme directement `solana-zk-elgamal-proof-interface ^0.1`. Lenum `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 lacceptation des octets suffixes de `CloseContextState`.
Aucune dépendance à `bytemuck` nest ajoutée directement : le décodeur ne convertit pas les octets en preuve cryptographique et nappelle aucun vérificateur. Il utilise uniquement `size_of` sur les types officiels, puis conserve longueur, SHA-256 et préfixe borné. Le contenu dun compte de preuve externe nest 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 à loffset `u32 LE`, auditée contre la version historique `3.1.14`; aucun code de preuve ni sérialiseur historique nest 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 nayant été observé, les tests sont synthétiques et nexigent 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 à lenum dinstruction. Le décodeur et lexécuteur consomment donc lID et les types sémantiques officiels, avec un miroir wire privé commun dans son ordre de variantes et de champs. Aucun helper `bincode` nest activé.
Lexé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 à lorchestration localnet/devnet.
### Config Program
`solana-config-interface 2.x` expose son module dinstruction derrière sa feature `bincode`. Le décodeur et lexé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 linitialisation `ConfigKeys vide + T::default()` à partir doctets déjà sérialisés ; il nactive aucun helper `bincode`.
### BPF Loader v2
`solana-loader-v2-interface 3.x` publie ses helpers dinstruction derrière `bincode`. Le décodeur conserve le layout local vérifié tant quaucun schéma officiel `wincode` nest disponible.
### Feature Gate
`solana-feature-gate-interface 4.x` publie la séquence dactivation `transfer -> allocate -> assign` et `RevokePendingActivation`, mais les helpers restent derrière sa feature `bincode`. Lexé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 lordre 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 nest nécessaire. Lexé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 lexé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 dinstruction 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 nest 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<UpgradeableLoaderInstruction>` et lexé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<u8> }`, `Copy { destination_offset, source_offset, length }`, `SetProgramLength { new_size }` et quatre variantes unitaires. Cette exception évite dactiver `bincode` uniquement pour appeler les helpers de linterface.
## `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 lagré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 lencodeur officiel lorsque disponible ;
6. tester les payloads tronqués, inconnus, suffixés et les comptes invalides ;
7. documenter toute divergence entre linterface 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 lIDL Metaplex, sans introduire Anchor. La crate officielle utilise Borsh `< 1.0`; le décodeur référence donc explicitement `borsh 0.10` sous lalias workspace `borsh_0_10`, distinct de Borsh 1.x utilisé par dautres interfaces du workspace.
Le dépôt officiel `metaplex-foundation/mpl-token-metadata` confirme le Program ID `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s`. LIDL officiel audité porte la version `1.14.0` et le blob `5df4a24f62c2743125be096cc174680790c92c18`; linventaire 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. Lenregistrement 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.