# Delta `0.2.8-pre.005` — contrat typed Helius `transactionSubscribe` ## 1. Objet Cette tranche matérialise le contrat de requête Helius LaserStream WebSocket `transactionSubscribe` : filtres, options, `tokenAccounts`, validations déterministes, acknowledgement numérique et wire `transactionUnsubscribe`. Elle ne publie volontairement **pas encore** de handle live transaction : `transactionNotification`, le registry actor, les remaps de remote IDs et les races reconnect/unsubscribe doivent arriver atomiquement en `pre.006` afin de ne jamais exposer un abonnement public incapable de livrer correctement ses notifications. Le checkpoint opérateur de `pre.004-fix.002` est intégralement vert. Version workspace : ```text 0.2.8-pre.5 ``` Livraison / commit attendu : ```text 0.2.8-pre.005 v0.2.8-pre.005 ``` Aucun tag prerelease. ## 2. Audit Helius courant verrouillé La documentation Helius relue le 2026-08-23 confirme pour `transactionSubscribe` : ```text filter.vote bool optionnel filter.failed bool optionnel filter.signature signature exacte optionnelle filter.accountInclude liste OR, <= 50_000 adresses filter.accountExclude liste d'exclusion, <= 50_000 adresses filter.accountRequired liste AND, <= 50_000 adresses filter.tokenAccounts none | balanceChanged | all options.commitment processed | confirmed | finalized options.encoding base58 | base64 | jsonParsed options.transactionDetails full | signatures | accounts | none options.showRewards bool optionnel options.maxSupportedTransactionVersion requis pour transactionDetails = accounts | full subscribe result integer subscription id unsubscribe params [subscriptionId] unsubscribe result bool late notifications possibles brièvement après unsubscribe ``` `tokenAccounts = none` est équivalent à l'omission du champ. `balanceChanged` et `all` étendent le matching d'un `accountInclude` wallet aux token accounts qu'il possède selon les règles Helius documentées. ## 3. Contrat public typed Nouveau module ciblé : ```text crates/ksp-onchain-transport-lib/src/ws_helius_transactions.rs ``` Il publie depuis le crate-root : ```text HeliusTokenAccountsFilter HeliusTransactionSubscribeEncoding HeliusTransactionSubscribeFilter HeliusTransactionSubscribeOptions HeliusTransactionSubscribeRequest ``` Le contrat réutilise les types KSP existants lorsqu'ils sont wire-identiques : ```text commitment -> SolanaCommitment transactionDetails -> SolanaTransactionDetails account filters -> ksp_core_lib::Pubkey ``` Aucun DTO Solana commun n'est recopié sous un nom Helius sans nécessité wire. ## 4. Sémantique des filtres et options `HeliusTransactionSubscribeFilter` conserve explicitement la différence entre : ```text champ omis liste présente mais vide [] liste présente avec valeurs ``` pour `accountInclude`, `accountExclude` et `accountRequired`. Chaque liste est validée indépendamment avec la limite Helius : ```text 0 ..= 50_000 accepté 50_001 rejeté avant I/O ``` Les erreurs déterministes n'incluent aucune signature ni adresse du filtre ; elles transportent uniquement le nom du champ et les cardinalités sûres. `HeliusTransactionSubscribeOptions` impose avant I/O : ```text transactionDetails = full -> maxSupportedTransactionVersion requis transactionDetails = accounts -> maxSupportedTransactionVersion requis transactionDetails = signatures -> version optionnelle transactionDetails = none -> version optionnelle ``` La distinction suivante est préservée sur le wire : ```text options = None -> params = [filter] options = Some(default) -> params = [filter, {}] ``` ## 5. Wire subscribe/unsubscribe préparé Les helpers crate-private préparés pour l'intégration actor de `pre.006` verrouillent : ```text transactionSubscribe transactionUnsubscribe subscribe result integer -> u64 unsubscribe params -> [remote_subscription_id] unsubscribe result -> bool ``` Les décodeurs refusent les formes de réponse d'un type différent au lieu de les coercer. Ces helpers restent crate-private : aucun raw provider-extension API public n'est introduit. ## 6. Réutilisation du moteur physique Une fixture locale passe réellement : ```text HeliusLaserStreamWsSession -> physical_session() crate-private -> WsSession::execute_json_rpc -> actor/socket unique existant -> transactionSubscribe -> transactionUnsubscribe ``` Elle vérifie les méthodes, params, acknowledgements et résultat d'unsubscribe exacts contre un peer WebSocket local. Aucun second : ```text actor socket pending map reconnect loop subscription engine ``` n'est ajouté. ## 7. Sécurité et surface différée `Debug` pour le filtre/requête expose seulement des indicateurs, modes et cardinalités ; il ne rend ni la signature exacte ni les valeurs des comptes filtrés. `HeliusLaserStreamWsSession` n'expose toujours pas : ```text pub async fn transaction_subscribe(...) ``` Cette absence est verrouillée par release-completeness. Le handle live arrive en `pre.006` avec : ```text transactionNotification registry local/remote reconnect + resubscribe unsubscribe races late notifications backpressure ciblée ``` Le heartbeat Helius reste réservé à `pre.007`. ## 8. Canaries et non-régressions Les nouveaux tests couvrent : ```text strings wire exactes tokenAccounts/encoding serialization complète filtre/options omission vs [] explicite borne 50_000 / rejet 50_001 pour les trois listes règle conditionnelle maxSupportedTransactionVersion ack subscribe numérique strict wire/result unsubscribe strict Debug sans signature/adresses round-trip local via actor physique partagé public API des nouveaux types absence du live handle avant pre.006 ``` Les surfaces acquises restent inchangées : ```text SolanaStandardWsSession 9 familles standard HeliusLaserStreamWsSession 6 familles standard supportées HTTP 52 current + 14 historiques Config Helius mainnet + devnet, secret/redaction/provenance validés ``` Aucune nouvelle dépendance Rust n'est ajoutée. ## 9. Preuve opérateur héritée Le checkpoint `pre.004-fix.002` fourni le 2026-08-23 est intégralement vert : ```text cargo fmt --all OK python3 scripts/audit_rust_workspace_rules.py clean cargo check --workspace OK cargo clippy --workspace --all-targets OK cargo test -p ksp-config-lib OK 110/110 + ownership/public API cargo test -p ksp-onchain-transport-lib OK 314 unit + 38 public + 26 completeness + 4 doctests cargo test --workspace OK ``` `pre.004`, `pre.004-fix.001` et `pre.004-fix.002` sont donc `DONE` avant cette tranche. ## 10. Fichiers de la livraison Nouveaux : ```text crates/ksp-onchain-transport-lib/src/ws_helius_transactions.rs crates/ksp-onchain-transport-lib/unit_tests/ws_helius_transactions.rs deltas/0.2.8/pre.005.md ``` Modifiés : ```text Cargo.toml crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/ws_protocol_session.rs crates/ksp-onchain-transport-lib/tests/public_api.rs crates/ksp-onchain-transport-lib/tests/release_completeness.rs docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md ``` Aucun fichier Config, schema, `.env`, README/USAGE, ROADMAP ou CHANGELOG n'est modifié. ## 11. Validation de préparation et gate opérateur Validation statique disponible dans le sandbox de préparation : ```text python3 scripts/audit_rust_workspace_rules.py General Rust rule audit: clean Rust export completeness audit: 0 candidate(s) KSP workspace Rust rule audit: clean ``` Le sandbox ne fournit pas Cargo/rustfmt ; la tranche reste donc `PREPARED` jusqu'au checkpoint opérateur suivant : ```bash cargo fmt --all python3 scripts/audit_rust_workspace_rules.py cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib cargo test --workspace ```