30 KiB
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
wincodelorsqu’il est officiellement exposé par l’interface ;- Borsh lorsqu’il correspond au contrat officiel ou au comportement du runtime ;
- 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@<version>.
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-lib::executor::solana::transaction
kb-lib::executor::solana::transaction 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 MdPubkey 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_onchain_transport |
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-lib::executor::solana::transaction 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 le type public
kb_lib::DcSplToken2022Decoder et isole le registre dans
kb_lib::DcSplElgamalRegistryDecoder. 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<UpgradeableLoaderInstruction> 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<u8> }, 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 :
- lire ses features et ses modules réellement compilés ;
- identifier le format officiel de sérialisation ;
- confirmer la version compatible avec Agave ciblée ;
- ajouter la dépendance uniquement à la crate propriétaire ;
- créer une fixture depuis l’encodeur officiel lorsque disponible ;
- tester les payloads tronqués, inconnus, suffixés et les comptes invalides ;
- documenter toute divergence entre l’interface et le runtime.
Metaplex Token Metadata — port maximal 0.1.0-pre.009
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_lib::DcMetadataMetaplexTokenMetadataDecoder implémente désormais la couverture exhaustive des
58 discriminateurs 0..=57. Les arguments sont lus avec les types Borsh officiels lorsque le SDK
les expose, ou avec un miroir local borné du wire publié pour les variantes historiques. Les
payloads, chaînes, créateurs, frais, comptes et suffixes sont bornés.
Le même composant inventorie les 15 variantes Key 0..=14 et décode les quatorze layouts
représentant un compte réel. Les parseurs utilisent solana-pubkey ^4.2 pour vérifier owner,
PDA et bump, puis les comptes historiques reçoivent une politique de matérialisation historique
distincte de leur interdiction d’exécution. Uninitialized reste une sentinelle explicitement
refusée et toute variante future absente de l’inventaire fait échouer les tests.
Les metadata Token‑2022 incorporées, Metaplex Core, Bubblegum et le JSON externe restent des provenances ou composants distincts. Aucun fetch HTTP, IPFS ou Arweave n’appartient au replay canonique de cette tranche.