# Delta `0.2.3-pre.005` — `getTransaction` complet, forme moderne et compatibilité legacy ## Base requise Livraison précédente validée localement par l'opérateur : ```text 0.2.3-pre.004 workspace.package.version = "0.2.3-pre.4" ``` 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 161 unit tests 16 public API tests 10 release completeness tests 0 warning signalé par check/clippy ``` ## Objectif Implémenter `getTransaction` comme huitième wrapper Transaction `Read / RetrySafe` de `0.2.3`, sans réduire la méthode à un sous-ensemble de convenance. La tranche couvre : ```text forme moderne objet forme bare encoding legacy dépréciée commitment encoding maxSupportedTransactionVersion result = null transaction chaîne legacy transaction tuple base58/base64 transaction JSON/jsonParsed meta lossless version legacy/numérique/omise/null transactionIndex valeur/omission/null erreurs RPC applicatives ``` Après cette tranche : ```text 8 / 11 wrappers Transactions exécutés ``` Restent différés : ```text requestAirdrop sendTransaction simulateTransaction ``` ## Règle générale de complétude RPC La précision opérateur formulée avant cette tranche devient une règle durable : un wrapper de transport KSP n'est pas considéré complet lorsqu'il n'expose qu'un sous-ensemble arbitraire des possibilités d'une méthode RPC. `KSP-TRANSPORT-007` est ajouté dans `docs/rules/RULES_KSP.md` : - tous les paramètres et champs de config audités doivent rester accessibles ; - les variantes/overloads courants doivent être exposés ; - les formes legacy encore supportées restent accessibles avec statut explicite ; - les contraintes déterministes connues sont appliquées localement lorsque KSP peut le faire sans prendre une responsabilité wire étrangère ; - les variantes, `null` et omissions significatives de réponse sont préservés ; - un sous-arbre riche peut rester `serde_json::Value` lorsqu'il est conservé losslessly ; - toute limitation volontaire doit être explicitement documentée. `docs/architecture/003-COMPONENT_CONTRACTS.md` est synchronisé avec cette règle. Le plan `docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md` passe en version 4 et demande désormais une canarie de complétude sémantique pour les wrappers de la release, pas uniquement une canarie du nombre de méthodes. ## Version Cargo Conformément à `VER-ID-009` : ```text 0.2.3-pre.4 -> 0.2.3-pre.5 ``` Aucune dépendance ni feature Cargo n'est ajoutée. ## Surface moderne `getTransaction` API publique : ```text HttpTransportPool::get_transaction( role, signature, Option<&SolanaGetTransactionConfig>, ) -> Result> ``` La signature reste une chaîne base58 opaque pour Transport : KSP ne prend pas de dépendance `solana-signature` uniquement pour répliquer la validation du provider. Le second paramètre possède trois usages intentionnels : ```text None -> second paramètre omis Some(default config) -> objet moderne explicite {} Some(config) -> objet moderne avec tous les champs fournis ``` Cette distinction permet d'exposer réellement la forme objet moderne sans empêcher la forme sans second paramètre. `SolanaGetTransactionConfig` conserve : ```text commitment encoding maxSupportedTransactionVersion ``` La documentation publique courante borne `commitment` à : ```text confirmed finalized ``` `processed` est donc rejeté localement avec `ERROR_CODE_INVALID_RPC_PARAMETERS` avant I/O. `maxSupportedTransactionVersion` reste un `Option` plutôt qu'une constante figée à `0`, afin de ne pas fermer la surface KSP aux futures versions wire que le runtime pourra supporter. ## Encodings complets La documentation publique moderne expose : ```text base58 base64 json jsonParsed ``` Agave `v4.2.1` utilise encore `UiTransactionEncoding` pour `RpcTransactionConfig` et accepte également l'alias historique : ```text binary ``` KSP conserve donc les cinq labels dans `SolanaTransactionEncoding` : ```text Binary Base58 Base64 Json JsonParsed ``` `Binary` est une compatibilité runtime/legacy et n'est pas présenté comme le choix moderne recommandé. Les cinq labels sont exercés par le wrapper moderne afin de garantir que KSP ne filtre pas une possibilité supportée par le runtime ciblé. ## Forme legacy bare encoding La documentation Solana courante conserve : ```text getTransaction(signature, "") ``` mais marque explicitement cette forme bare comme dépréciée. KSP expose donc séparément : ```text HttpTransportPool::get_transaction_legacy(role, signature, encoding) ``` Cette API : - est annotée `#[deprecated]` côté Rust ; - émet un `warn` via `ksp-logging-lib` lorsqu'elle est appelée ; - sérialise exactement la chaîne d'encoding comme second paramètre ; - accepte les cinq labels du runtime `v4.2.1` ; - réutilise exactement le même executor/décodeur que la forme moderne. Le wrapper legacy ne crée donc ni nouveau client HTTP ni logique de retry parallèle. ## Réponse complète et lossless `getTransaction` renvoie : ```text Option ``` `result = null` devient `None` sans être confondu avec une erreur RPC. Un résultat présent conserve : ```text slot blockTime transaction meta version transactionIndex ``` ### Transaction `SolanaEncodedTransaction` devient production-live et conserve les formes Agave : ```text LegacyBinary(String) Binary { data, Base58|Base64 } Json(serde_json::Value) ``` La variante `Json` couvre `json` et `jsonParsed` sans réimplémenter les structures Program-specific du SDK Solana. Aucun champ n'est supprimé. ### Metadata `meta` reste : ```text SolanaWireField ``` Cette représentation conserve : ```text Omitted Null Value(object) ``` La fixture riche couvre notamment les champs actuels : ```text err status legacy fee preBalances postBalances innerInstructions logMessages preTokenBalances postTokenBalances rewards loadedAddresses returnData computeUnitsConsumed costUnits ``` Le choix lossless permet aussi de transporter de nouveaux champs provider/Agave sans les effacer avant qu'un modèle KSP plus spécialisé soit justifié. ### Version et transaction index `version` conserve : ```text Omitted Null Legacy Number(u8) ``` `transactionIndex`, présent dans Agave `v4.2.1` mais pas historiquement chez tous les providers, conserve également : ```text Omitted Null Value(u32) ``` Les fixtures préparatoires de `pre.002` qui vérifient déjà ces trois états restent actives. ## Helpers activés en production Seuls les helpers nécessaires à `getTransaction` quittent `#[cfg(test)]` : ```text SolanaTransactionBinaryEncoding::from_wire SolanaGetTransactionConfig::to_json_value SolanaEncodedTransaction::decode_wire SolanaTransactionVersion::decode_wire SolanaConfirmedTransaction::decode_wire decode_binary_transaction_tuple decode_transaction_version_field WireConfirmedTransaction ``` Les helpers write/simulation de `pre.006`–`pre.007` restent staged/test-only. Aucun `#[allow(dead_code)]` global n'est ajouté. ## Fixtures HTTP déterministes ajoutées ```text get_transaction.null.json get_transaction.binary_legacy.json get_transaction.base58.json get_transaction.base64.json get_transaction.json.json get_transaction.json_parsed.json get_transaction.error_unsupported_version.json ``` Elles couvrent les formes de résultat et les encodings sans décoder les bytes transactionnels. ## Couverture de tests ajoutée Sept tests unitaires HTTP supplémentaires couvrent : - second paramètre omis et objet moderne vide explicite ; - config moderne complète ; - rejet local de `commitment=processed` ; - cinq encodings runtime via la forme moderne ; - cinq encodings via la forme bare legacy dépréciée ; - préservation d'un `jsonParsed` riche ; - préservation du JSON brut, du meta courant, de la version et de `transactionIndex` ; - erreur RPC `unsupported transaction version` préservée comme `RPC_APPLICATION_ERROR`. Les tests préparatoires existants continuent en plus à couvrir : - tuple avec encoding non binaire rejeté ; - forme de version inconnue rejetée ; - `meta/version/transactionIndex` omis/null/présents. Un test public compile les deux request forms depuis la crate root. Une nouvelle canarie release porte le sous-ensemble Read Transaction exécuté à huit méthodes et vérifie que `getTransaction` conserve `StableWithDeprecatedLegacy` : ```text getFeeForMessage getLatestBlockhash getRecentPrioritizationFees getSignaturesForAddress getSignatureStatuses getTransaction getTransactionCount isBlockhashValid ``` Les trois opérations write/simulation restent différées. Après application, la cible Transport attendue devient : ```text 168 unit tests 17 public API tests 11 release completeness tests ``` ## Fichiers modifiés ```text Cargo.toml 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 docs/rules/RULES_KSP.md docs/architecture/003-COMPONENT_CONTRACTS.md docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md ``` Fichiers ajoutés : ```text crates/ksp-onchain-transport-lib/fixtures/http/get_transaction.null.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction.binary_legacy.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction.base58.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction.base64.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction.json.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction.json_parsed.json crates/ksp-onchain-transport-lib/fixtures/http/get_transaction.error_unsupported_version.json deltas/0.2.3/pre.005.md ``` `CHANGELOG.md`, `ROADMAP.md`, `rpc_method.rs`, `executor.rs` et `resilience.rs` restent inchangés. ## Validations attendues ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib ``` L'environnement de préparation du delta ne possède pas Cargo/Rustfmt ; ces commandes ne sont donc pas déclarées réussies avant preuve opérateur.