# Delta `0.2.1-pre.002` — fondation crate/settings/JSON-RPC/descriptors ## Base requise ```text release : 0.2.1 prerelease : pre.002 identifiant de commit attendu : v0.2.1-pre.002 workspace.package.version : 0.2.1-pre.2 base : v0.2.1-pre.001-fix.001 ``` Le user a confirmé avoir commité `v0.2.1-pre.001` puis `v0.2.1-pre.001-fix.001` avant l'ouverture de cette tranche. ## Objectif Matérialiser la fondation Rust de `ksp-onchain-transport-lib` sans ouvrir encore le client/pool HTTP : - ajouter la crate au workspace ; - stabiliser les codes d'erreur Transport ; - posséder les settings runtime publics et leur validation ; - posséder les envelopes JSON-RPC 2.0 HTTP ; - matérialiser le registre central des méthodes/statuts issu de la matrice `pre.001` ; - installer la base de warnings KSP de statut sans dépendance directe à `tracing` ; - ajouter les tests unitaires/intégration correspondant à ces contrats. ## Version Cargo Conformément à `VER-ID-009` : ```text 0.2.1-pre.1 -> 0.2.1-pre.2 ``` Toutes les crates membres continuent d'hériter `version.workspace = true`. ## Workspace et dépendances Nouveau membre : ```text crates/ksp-onchain-transport-lib ``` Dépendances directes de la crate : ```text ksp-core-lib ksp-logging-lib reqwest.workspace = true serde.workspace = true serde_json.workspace = true ``` `reqwest` reste centralisé au workspace : ```toml reqwest = { version = "^0.13", default-features = false } ``` Le `pre.001` avait vérifié le 2026-08-17 la génération `reqwest 0.13` et observé `0.13.4`. Cette tranche n'active volontairement aucune feature TLS/JSON/client : `reqwest` est utilisé uniquement pour `Url::parse` dans la validation de `HttpEndpointUrl`. Conformément à `RUST-DEP-001` / `RUST-DEP-003`, les features réseau et Tokio seront ajoutés seulement lorsque `pre.003` introduira un vrai client HTTP async. Aucune dépendance directe vers : ```text ksp-config-lib ksp-store-api ksp-store-lib ksp-program-api ksp-program-lib tracing ``` ## Contrats publics Transport ### Settings runtime La crate expose : ```text HttpTransportSettings HttpEndpointSettings HttpEndpointRoleSettings HttpRoleLimits HttpRetrySettings HttpEndpointUrl HttpProviderName HttpClusterName HttpRoleName HttpRequestKind ``` Décisions : - Transport reste totalement constructible/testable sans Config ; - `provider`, `cluster`, `role` et `request_kind` sont des descriptors ouverts, pas des enums fermées ; - `HttpEndpointUrl` accepte uniquement HTTP/HTTPS, conserve la valeur runtime réelle mais redacted systématiquement son `Debug` ; - `HttpTransportSettings::validate()` vérifie notamment endpoints activés, identités/roles uniques, timeouts positifs, request kinds, wildcard, limites et backoff cohérents ; - `NonZeroU32` empêche structurellement les zéros sur RPS/burst/concurrence lorsqu'ils sont configurés ; - aucun accès direct à `.env` ou `std::env::var*` n'existe dans Transport. ### Codes d'erreur Le domaine unique reste : ```text onchain_transport ``` Codes stabilisés/réservés : ```text invalid_settings endpoint_selection_failed http_connection_failed http_request_failed timeout rate_limited json_encode_failed json_decode_failed json_rpc_protocol_invalid rpc_application_error method_removed invalid_response ``` Ils utilisent exclusivement `ksp_core_lib::Error` / `ErrorCode`. ## JSON-RPC HTTP La fondation expose : ```text JsonRpcRequest JsonRpcSuccessResponse JsonRpcErrorObject JsonRpcErrorResponse JsonRpcResponse parse_json_rpc_response_text parse_json_rpc_response_value ``` Invariants : - request ids KSP numériques `u64` ; - `jsonrpc` exactement `"2.0"` ; - id de réponse exactement égal à celui de la requête ; - présence exclusive de `result` ou `error` ; - JSON `null` conservé comme résultat valide ; - erreur JSON syntaxique distincte d'une violation protocolaire ; - application error RPC préservée dans `JsonRpcResponse::Error`, puis mappable vers `rpc_application_error` ; - le mapping KSP ne copie pas le message/data distant dans le contexte générique ; - `Debug` des requests masque les paramètres ; `Debug` des succès masque le résultat ; `Debug` des erreurs masque message/data distants. Ce dernier point empêche un log/debug accidentel d'une transaction, d'un token provider ou d'une réponse massive tout en laissant les getters explicites accessibles au consumer légitime. ## Registre central des méthodes `rpc_method.rs` matérialise exactement : ```text 52 méthodes current 14 méthodes historiques Deprecated / Removed ``` Chaque descriptor possède : ```text method category request_kind documentation_status runtime_status request_form_status operation_kind transport_retry_class replacement coverage_release ``` La distribution de couverture est encodée et testée : ```text 0.2.1 : 4 0.2.2 : 22 0.2.3 : 11 0.2.4 : 15 ---- 52 current ``` Cas structurants déjà encodés : ```text getTransaction -> StableWithDeprecatedLegacy getBlock -> StableWithDeprecatedLegacy sendTransaction -> WriteSubmission / NeverAfterDispatch requestAirdrop -> WriteSubmission / NeverAfterDispatch simulateTransaction -> Simulation / RetrySafe 14 historiques -> Deprecated / Removed / NotApplicable ``` `HttpRpcMethodDescriptor::ensure_runtime_supported()` centralise le comportement de statut : - Stable + Supported : succès silencieux ; - Deprecated/Unstable + Supported : `warn` via `ksp-logging-lib` ; - Removed : `warn` puis erreur `method_removed`, sans simuler un appel supporté. Le target utilisé est toujours le nom Cargo réel via `env!("CARGO_PKG_NAME")`; aucune dépendance directe `tracing` n'est introduite. ## Tests ajoutés 40 tests Rust sont définis : - validation des settings et erreurs structurées ; - HTTP/HTTPS uniquement ; - redaction URL et `Debug` global settings ; - endpoint enabled, doublons endpoint/rôle, wildcard, burst/RPS, timeouts, backoff ; - sérialisation JSON-RPC request ; - parse success/error/null ; - id mismatch, version, `result xor error`, invalid JSON ; - redaction des payloads request/result/error dans `Debug` ; - mapping RPC application error ; - registre 52 + 14 et unicité ; - distribution 4/22/11/15 ; - canaris exacts `getBalance/getGenesisHash/getHealth/getVersion` ; - request forms deprecated de `getTransaction/getBlock` ; - no-resend descriptors write ; - warning path Unstable supporté ; - erreur `method_removed` ; - tests d'intégration de la façade publique ; - canary de firewall des dépendances directes du manifest. Les vrais tests unitaires sont physiquement sous `unit_tests/` et rattachés aux modules de production via `#[cfg(test)]` + `#[path = ...]`. `tests/` est réservé aux tests d'intégration publics. ## Fichiers ajoutés ```text crates/ksp-onchain-transport-lib/Cargo.toml crates/ksp-onchain-transport-lib/src/error.rs crates/ksp-onchain-transport-lib/src/json_rpc.rs crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/rpc_method.rs crates/ksp-onchain-transport-lib/src/settings.rs crates/ksp-onchain-transport-lib/unit_tests/json_rpc.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_method.rs crates/ksp-onchain-transport-lib/unit_tests/settings.rs crates/ksp-onchain-transport-lib/tests/dependency_boundary.rs crates/ksp-onchain-transport-lib/tests/public_api.rs deltas/0.2.1/pre.002.md ``` ## Fichiers modifiés ```text Cargo.toml ROADMAP.md docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md ``` ## Fichiers supprimés Aucun. ## Validations exécutées dans l'environnement d'échange Le conteneur ne fournit ni `cargo`, ni `rustc`, ni `rustfmt`. Les validations exécutables disponibles ont donc été limitées aux contrôles statiques suivants : - parsing TOML du `Cargo.toml` racine et du manifest de la nouvelle crate ; - contrôle `workspace.package.version = 0.2.1-pre.2` ; - contrôle présence du nouveau membre workspace ; - contrôle des headers `file:` et newline finale sur tous les nouveaux fichiers ; - scan production : aucun `use`, `?`, `unwrap`, `expect`, `panic!`, `pub mod` ; - scan manifest : aucune dépendance directe Config/Store/Program/`tracing` ; - scan production : aucune lecture directe `std::env::var*` ; - audit heuristique de rustdoc sur les éléments publics ; - comparaison automatique du registre Rust avec la matrice `008` : 52 current identiques, dans le même ordre, et 14 historiques identiques ; - contrôle de distribution de release : `4 / 22 / 11 / 15` ; - contrôle des deux seuls marqueurs `StableWithDeprecatedLegacy` : `getTransaction`, `getBlock` ; - contrôle des fences Markdown et headers des documents modifiés ; - contrôle des lignes Rust > 160 colonnes après formatage manuel : aucune. ## Validations non exécutées Obligatoires sur le checkout de développement avant commit : ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib cargo test --workspace cargo tree -p ksp-onchain-transport-lib cargo tree -p ksp-onchain-transport-lib -d cargo tree -p ksp-onchain-transport-lib -e features cargo tree -p ksp-onchain-transport-lib -e normal ``` Les `cargo tree` sont désormais obligatoires parce que `reqwest` entre réellement dans le graphe à cette tranche. Les doublons significatifs doivent être examinés avant validation du commit. Aucun build Tauri n'est requis : aucune application Tauri/frontend n'est modifiée. ## Décisions prises - conserver un identifiant JSON-RPC KSP numérique `u64` pour les requêtes émises ; - préserver les payloads JSON dynamiques via `serde_json::Value` sans introduire de DTO Solana SDK massif ; - redacter les `Debug` wire susceptibles de contenir des secrets/payloads massifs ; - encoder dès maintenant la couverture release et la retry class dans le registre central ; - ne pas activer de features réseau `reqwest` ni Tokio avant leur premier usage réel ; - ne pas introduire Config, Store, Program, Solana SDK haut niveau, base64, bs58, WebSocket ou gRPC. ## Questions ouvertes / reports explicites Aucune question bloquante pour `pre.003`. À décider avec l'implémentation réelle de `pre.003` : - features `reqwest 0.13` exactes nécessaires au client async/TLS ; - ownership précis du `reqwest::Client` par endpoint logique ; - structures runtime du pool, fairness et snapshots ; - première utilisation effective de Tokio et des primitives `sync` si nécessaires. ## Suite ```text 0.2.1-pre.003 ``` Mission prévue : endpoint client + pool logique + rôles/capabilities + priorité/fairness/fallback + snapshots sûrs, sans encore ouvrir rate-limit/concurrence/retry effectif de `pre.004` au-delà des structures strictement nécessaires.