# Delta `0.2.3-pre.003` — quatre premiers wrappers HTTP Transactions Read ## Base requise Livraison précédente corrigée et validée localement par l'opérateur : ```text 0.2.3-pre.002-fix.001 workspace.package.version = "0.2.3-pre.2.fix.1" ``` La validation opérateur du 2026-08-18 a confirmé : ```text cargo fmt --all OK cargo check --workspace OK cargo clippy --workspace --all-targets OK cargo test -p ksp-onchain-transport-lib OK ``` Résultats Transport de cette base : ```text 145 unit tests 14 public API tests 8 release completeness tests 0 warning signalé par check/clippy ``` Le plan canonique reste `docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md` version 3. ## Objectif Implémenter les quatre premiers wrappers Transaction `Read / RetrySafe` prévus par le plan : ```text getFeeForMessage getLatestBlockhash getTransactionCount isBlockhashValid ``` Tous passent par le chemin HTTP commun : ```text wrapper typé -> descriptor Transaction audité -> execute_standard_rpc -> pool/admission/retry/deadline -> executor HTTP -> validation JSON-RPC -> décodage DTO KSP ``` Aucun wrapper n'appelle `reqwest` directement et aucune boucle de retry locale n'est ajoutée. ## Version Cargo Conformément à `VER-ID-009` : ```text 0.2.3-pre.2.fix.1 -> 0.2.3-pre.3 ``` Aucune dépendance ni feature Cargo n'est ajoutée. ## Surface typée ajoutée ### `getFeeForMessage` Signature publique conceptuelle : ```text role + message base64 opaque + Option -> SolanaRpcResponse> ``` Le wrapper : - conserve le message sérialisé comme chaîne opaque et ne tente ni base64 decode ni désérialisation locale ; - sérialise `commitment` et `minContextSlot` lorsqu'ils sont présents ; - omet la config lorsqu'elle est absente ou vide ; - préserve `value: null` sous `Option::None` ; - laisse une erreur de décodage/paramètre distante dans le domaine `RPC_APPLICATION_ERROR`. ### `getLatestBlockhash` Signature publique conceptuelle : ```text role + Option -> SolanaRpcResponse ``` Le wrapper active en production le décodeur `SolanaLatestBlockhash` préparé en `pre.002` et conserve : ```text blockhash lastValidBlockHeight context.slot context.apiVersion? ``` Un blockhash de réponse vide est rejeté comme `ERROR_CODE_INVALID_RESPONSE`. KSP ne décode pas cryptographiquement la chaîne. ### `getTransactionCount` Signature publique conceptuelle : ```text role + Option -> u64 ``` La méthode conserve la forme simple du résultat tout en sérialisant la config contextuelle optionnelle dans le tableau `params` exact. ### `isBlockhashValid` Signature publique conceptuelle : ```text role + blockhash opaque + Option -> SolanaRpcResponse ``` Le blockhash d'entrée est transmis tel quel au runtime : `pre.003` n'ajoute ni `solana-hash`, ni validation base58, ni normalisation silencieuse. ## Infrastructure Transaction activée `rpc_transactions.rs` ajoute un helper interne unique pour les wrappers de cette famille : ```text execute_transaction_rpc -> transaction_descriptor -> execute_standard_rpc ``` `transaction_descriptor` refuse de fonctionner si la méthode demandée n'est pas classée : ```text HttpRpcCategory::Transactions HttpRpcCoverageRelease::V0_2_3 ``` Les trois réponses contextuelles de cette tranche réutilisent un décodeur interne commun qui préserve `SolanaRpcContext` avant de décoder la valeur métier. Seuls les helpers réellement utilisés deviennent production-live dans cette tranche : ```text SolanaLatestBlockhash::decode_wire WireLatestBlockhash invalid_transaction_wire ``` Les décodeurs/configs préparatoires des sept wrappers suivants restent sous `#[cfg(test)]` jusqu'à leur tranche propriétaire afin de conserver une build non-test sans `dead_code` artificiel. ## Fixtures HTTP déterministes ajoutées ```text crates/ksp-onchain-transport-lib/fixtures/http/get_fee_for_message.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_fee_for_message.null.json crates/ksp-onchain-transport-lib/fixtures/http/get_fee_for_message.error.json crates/ksp-onchain-transport-lib/fixtures/http/get_latest_blockhash.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_latest_blockhash.invalid_empty.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction_count.success.json crates/ksp-onchain-transport-lib/fixtures/http/is_blockhash_valid.success.json ``` Les tests utilisent un serveur HTTP loopback local et n'accèdent pas à Internet. ## Couverture de tests ajoutée Sept tests HTTP unitaires couvrent : - `getFeeForMessage` avec paramètres exacts et config contextuelle complète ; - `getFeeForMessage` avec `value: null` et config absente ; - propagation d'une erreur JSON-RPC applicative pour un message refusé par le runtime ; - `getLatestBlockhash` avec config explicitement vide, donc omise ; - rejet d'un blockhash vide renvoyé par le provider ; - `getTransactionCount` avec commitment ; - `isBlockhashValid` avec blockhash opaque, commitment et `minContextSlot`. Le test public compile explicitement les quatre nouvelles méthodes sur `HttpTransportPool`. Une canarie release fige le sous-ensemble `pre.003` : ```text getFeeForMessage getLatestBlockhash getTransactionCount isBlockhashValid ``` et vérifie pour chacune : ```text Transactions / V0_2_3 / Read / RetrySafe ``` La couverture typed complète `0.2.3 exact == 11` reste volontairement fermée : les sept wrappers restants appartiennent aux tranches `pre.004` à `pre.007`. Après application, la cible Transport attendue devient : ```text 152 unit tests 15 public API tests 9 release completeness tests ``` ## Fichiers ajoutés ```text crates/ksp-onchain-transport-lib/fixtures/http/get_fee_for_message.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_fee_for_message.null.json crates/ksp-onchain-transport-lib/fixtures/http/get_fee_for_message.error.json crates/ksp-onchain-transport-lib/fixtures/http/get_latest_blockhash.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_latest_blockhash.invalid_empty.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction_count.success.json crates/ksp-onchain-transport-lib/fixtures/http/is_blockhash_valid.success.json deltas/0.2.3/pre.003.md ``` ## Fichiers modifiés ```text Cargo.toml crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/rpc_transactions.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_transactions.rs crates/ksp-onchain-transport-lib/tests/public_api.rs crates/ksp-onchain-transport-lib/tests/release_completeness.rs ``` ## Fichiers supprimés Aucun. ## Fichiers volontairement inchangés ```text CHANGELOG.md ROADMAP.md docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md crates/ksp-onchain-transport-lib/Cargo.toml crates/ksp-onchain-transport-lib/README.md crates/ksp-onchain-transport-lib/USAGE.md crates/ksp-onchain-transport-lib/src/executor.rs crates/ksp-onchain-transport-lib/src/rpc_method.rs crates/ksp-config-lib/** config/** ``` Aucune méthode `0.2.4` n'est avancée. ## Validations exécutées - prise en compte de la validation opérateur propre de `pre.002-fix.001` comme base ; - contrôle JSON syntaxique des sept nouvelles fixtures ; - contrôle différentiel exact contre la base validée ; - contrôle statique que les quatre wrappers passent par `execute_transaction_rpc -> execute_standard_rpc` ; - contrôle statique de l'absence de `reqwest`, `tracing`, client RPC parallèle ou boucle de retry dans `rpc_transactions.rs` ; - contrôle statique de l'absence de nouvelle dépendance/feature Cargo ; - contrôle statique des helpers préparatoires restés sous `#[cfg(test)]` ; - contrôle statique de l'absence de `unwrap`, `expect`, `panic!` et `?` dans la source de production modifiée ; - contrôle statique des lignes Rust modifiées à `<= 160` colonnes ; - contrôle que `CHANGELOG.md`, `ROADMAP.md`, le plan `010`, `executor.rs` et `rpc_method.rs` restent inchangés. ## Validations non exécutées Le sandbox d'échange ne fournit pas `cargo`, `rustc` ou `rustfmt`. Les commandes suivantes doivent être exécutées sur le checkout opérateur avant commit : ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib ``` `cargo test --workspace` reste réservé au checkpoint de clôture/session. Aucun `cargo tree` n'est requis par cette tranche puisqu'aucune dépendance ni feature n'a changé. Le commit attendu après application et validations suit `VER-GIT-001` : ```text v0.2.3-pre.003 ``` ## Décisions prises - réutiliser `SolanaContextConfig` et `SolanaRpcResponse` sans créer de DTO de config redondant ; - ne pas décoder localement les messages ou blockhashs d'entrée ; - omettre une config contextuelle explicitement vide ; - activer en production uniquement les helpers wire réellement consommés par cette tranche ; - centraliser la sélection des descriptors Transaction sans contourner `execute_standard_rpc` ; - conserver les erreurs JSON-RPC applicatives comme non-retryables au niveau applicatif. ## Questions ouvertes Aucune question bloquante pour `pre.004`. ## Suite `0.2.3-pre.004` : implémenter `getRecentPrioritizationFees`, `getSignaturesForAddress` et `getSignatureStatuses`, avec limites locales exactes `128 / 1000 / 256`, ordre serveur, pagination et `null` positionnels.