# ksp-interface-lib `ksp-interface-lib` possède les contrats passifs KSP qui doivent être partagés entre plusieurs composants sans imposer leur runtime d'origine. Sa surface couvre actuellement deux familles distinctes : les contrats wire Program génériques et un petit ensemble de faits d'acquisition provider-neutral dont la sémantique commune a été démontrée. La crate reste une façade de représentation. Elle ne possède ni transport réseau, ni event bus, ni worker/job, ni persistence, ni exécution, ni comportement métier Program. ## Ownership La crate réutilise les primitives fondamentales déjà possédées par `ksp-core-lib` : ```text Pubkey Error / ErrorCode / Result Program IDs fondamentaux ``` `Pubkey` est réexporté depuis le crate-root Interface afin qu'un consumer n'introduise aucun wrapper d'identité parallèle. Les Program IDs restent possédés et répertoriés par Core. Le graphe normal reste strictement : ```text ksp-interface-lib └── ksp-core-lib └── solana-pubkey ``` La crate ne possède aucune feature Cargo, aucune `dev-dependency` et aucune `build-dependency` runtime propre. ## Surface publique La façade crate-root expose : ```text Pubkey ProgramAccountMeta MAX_PROGRAM_INSTRUCTION_ACCOUNTS ProgramInstruction MAX_PROGRAM_INSTRUCTION_DATA_LEN ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED SlotLifecycleStage SlotLifecycleEvent TransactionSignature TransactionExecutionOutcome TransactionExecutionEvent ``` Aucun module interne n'est public. ## Contrats Program passifs ### `ProgramAccountMeta` `ProgramAccountMeta` représente un compte ordonné d'une instruction avec : ```text pubkey is_signer is_writable ``` Les champs restent privés. Les constructeurs publics sont `readonly(pubkey, is_signer)` et `writable(pubkey, is_signer)`, complétés par les accessors `pubkey()`, `is_signer()` et `is_writable()`. La structure n'applique aucune sémantique spécifique à un programme et n'exige pas que la `Pubkey` appartienne au registry des Program IDs Core. ### `ProgramInstruction` `ProgramInstruction` représente un contrat passif borné : ```text program_id accounts: Vec data: Vec ``` `ProgramInstruction::try_new` consomme directement les deux `Vec`, conserve l'ordre et les doublons des accounts et préserve les octets opaques de `data` sans décodage. Les cas vides sont valides et une `program_id` inconnue du registry KSP reste admissible. ### Bornes d'admission | Limite | Valeur | |------------------------------------|----------| | `MAX_PROGRAM_INSTRUCTION_ACCOUNTS` | `255` | | `MAX_PROGRAM_INSTRUCTION_DATA_LEN` | `10_240` | Ces valeurs sont des **bornes d'admission Interface**. Elles ne constituent pas une garantie qu'une instruction donnée respecte à elle seule toutes les contraintes d'une transaction Solana complète. Un dépassement utilise le code commun : ```text interface.program_instruction_limit_exceeded ``` Le contexte d'erreur est limité aux métadonnées sûres `field`, `actual_len` et `maximum_len`. Aucun payload arbitraire ni account meta hostile n'est recopié dans l'erreur. Le `Debug` de `ProgramInstruction` est volontairement borné : il affiche `program_id`, `account_count` et `data_len`, jamais les accounts complets ni les octets du payload. ## Faits passifs d'acquisition Les événements Interface sont des **projections provider-neutral supplémentaires**. Ils ne remplacent jamais les DTOs riches de `ksp-onchain-transport-lib` et ne deviennent jamais la source de vérité durable d'un backlog. La conversion depuis un DTO HTTP/WS/gRPC/provider appartient à la composition ou au consumer qui connaît les deux contrats. `ksp-interface-lib` ne dépend donc pas de Transport. ### `SlotLifecycleEvent` `SlotLifecycleEvent` conserve exactement : ```text slot: u64 stage: SlotLifecycleStage ``` Les stages actuellement représentés sont : ```text Processed FirstShredReceived Completed CreatedBank Dead OptimisticallyConfirmed Rooted ``` `SlotLifecycleStage` est `#[non_exhaustive]` afin qu'un consumer externe traite explicitement l'évolution future de l'enum. Parent, timestamp, diagnostics de slot mort, source/provider, filter/session metadata et autres détails Transport ne sont pas copiés dans ce contrat minimal. ### `TransactionExecutionEvent` `TransactionExecutionEvent` conserve exactement : ```text slot: u64 signature: TransactionSignature outcome: TransactionExecutionOutcome ``` `TransactionSignature` contient exactement les 64 bytes canoniques déjà décodés d'une signature Solana. Son `Debug` ne rend pas les bytes. `TransactionExecutionOutcome` distingue uniquement : ```text Succeeded Failed ``` L'enum est `#[non_exhaustive]`. Le contrat ne contient aucun log, payload RAW, erreur provider, commitment, provenance, network id, source metadata ni détail d'exécution arbitraire. Une source ambiguë ou insuffisante doit rester dans son owner Transport au lieu de forcer un événement Interface. ## Codecs et runtime La crate n'ajoute aucun codec ou runtime par réflexe : ```text serde / serde_json absents borsh absent tant qu'aucun wire réel ne le requiert wincode absent tant qu'aucun wire réel ne le requiert bincode interdit pour les codecs wire KSP transport/runtime réseau absent logging runtime absent ``` Des codecs/layouts/discriminants spécifiques peuvent être ajoutés uniquement lorsqu'un protocole réel en démontre le besoin et que leur ownership wire appartient bien à Interface. Les événements passifs ne constituent pas un comportement runtime. La crate ne dépend donc pas de `ksp-logging-lib` et ne possède ni `constants.rs` ni `TRACING_TARGET`. ## Frontières `ksp-interface-lib` ne possède pas : ```text RPC / WebSocket / gRPC provider DTOs Transport sessions / reconnect / backpressure Config / environnement persistence / Store / cursor / retention notifications post-commit Store worker / job / scheduler / event bus Program decoding / recognition / proofs execution policy / signers RawTransaction / RawAccountState ``` Les données persistantes/replayables restent dans `ksp-store-api`. Les notifications post-commit de données persistées restent un contrat Store API lorsqu'un publisher/consumer réel les justifie. Les faits réseau riches restent Transport-owned. ## Références - [Usage public](USAGE.md) - [Architecture Wire + Program](../../docs/architecture/006-WIRE_AND_PROGRAM.md) - [Architecture Acquisition/Workers/Jobs](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md)