# Plan `0.2.4` — HTTP Blocks + Economics + compliance HTTP finale ## Statut Ce plan ouvre `0.2.4` par `0.2.4-pre.001` sur la base stable attendue `v0.2.3`. `0.2.1` a stabilisé la foundation HTTP et 4 wrappers typed, `0.2.2` les 22 wrappers Accounts/Tokens/Cluster et `0.2.3` les 11 wrappers Transactions. La surface acquise au démarrage est donc : ```text 52 méthodes HTTP courantes enregistrées 14 méthodes historiques Deprecated / runtime Removed 37 wrappers typed courants 15 wrappers typed restant sous HttpRpcCoverageRelease::V0_2_4 ``` La mission de `0.2.4` est strictement de compléter les **10 Blocks + 5 Economics** déjà affectées à `V0_2_4`, puis de fermer la compliance HTTP globale **52/52 current + 14/14 historical** sous la règle `KSP-TRANSPORT-007`. ## Gate de sizing `pre.001` Question obligatoire : ```text Les 15 wrappers Blocks/Economics, leurs DTOs/wires, les overloads/legacy, les tests, la compliance 52+14 et la documentation peuvent-ils être clôturés proprement dans cette release/session ? ``` Réponse : ```text OUI. ``` Aucun split de release n'est nécessaire avant implémentation. Le volume est supérieur à `0.2.3` en nombre de wrappers mais reste inférieur à `0.2.2`. La complexité est surtout concentrée dans `getBlock`, `getBlockProduction`, `getInflationReward` et la compliance finale ; ces fils sont donc isolés dans des prereleases dédiées. Si une tranche réelle dépasse le budget KSP d'environ 15–20 minutes, une prerelease supplémentaire sera créée **dans `0.2.4`** sans déplacer silencieusement une méthode vers `0.2.5`. ## Sources normatives réauditées le 2026-08-18 Documentation publique : ```text https://solana.com/docs/rpc/http https://solana.com/docs/rpc/json-structures ``` Pages Blocks : ```text https://solana.com/docs/rpc/http/getblock https://solana.com/docs/rpc/http/getblockcommitment https://solana.com/docs/rpc/http/getblockheight https://solana.com/docs/rpc/http/getblockproduction https://solana.com/docs/rpc/http/getblocks https://solana.com/docs/rpc/http/getblockswithlimit https://solana.com/docs/rpc/http/getblocktime https://solana.com/docs/rpc/http/getfirstavailableblock https://solana.com/docs/rpc/http/getrecentperformancesamples https://solana.com/docs/rpc/http/minimumledgerslot ``` Pages Economics : ```text https://solana.com/docs/rpc/http/getinflationgovernor https://solana.com/docs/rpc/http/getinflationrate https://solana.com/docs/rpc/http/getinflationreward https://solana.com/docs/rpc/http/getstakeminimumdelegation https://solana.com/docs/rpc/http/getsupply ``` La documentation Solana actuelle relie encore plusieurs définitions/source examples à **Agave `v3.1.8`**. Ce pointeur documentaire n'est donc pas utilisé comme preuve que `v3.1.8` représente le runtime stable actuel. Le cross-audit runtime a été effectué contre **Agave `v4.2.1`**, release patch publiée le 2026-08-13 dans la branche stable `4.2.x`. `v4.2.0` est explicitement publiée comme stable pour Mainnet Beta, Devnet et Testnet ; `v4.3.0-beta.0`, plus récente en date, reste une prerelease et n'est pas la baseline normative de cette release KSP. Sources primaires Agave ciblées : ```text https://github.com/anza-xyz/agave/releases/tag/v4.2.1 https://github.com/anza-xyz/agave/blob/v4.2.1/rpc/src/rpc.rs https://github.com/anza-xyz/agave/blob/v4.2.1/rpc-client-types/src/config.rs https://github.com/anza-xyz/agave/blob/v4.2.1/rpc-client-types/src/response.rs ``` SIMDs primaires ciblés par l'audit `KSP-TRANSPORT-007` : ```text https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0096-reward-collected-priority-fee-in-entirety.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0118-partitioned-epoch-reward-distribution.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0123-block-revenue-distribution.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0180-vote-account-leader-schedule.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0185-vote-account-v4.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0186-loaded-transaction-data-size-specification.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0291-commission-rate-in-basis-points.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0298-bank-hash-in-block-footer.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0307-add-block-footer.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0490-upgrade-stake-to-v5.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0550-double-disinflation.md https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0553-resource-fee-burn.md ``` ## Inventaire officiel réaudité L'index HTTP Solana actuel contient toujours exactement les catégories suivantes : ```text Accounts 6 Tokens 5 Transactions 11 Blocks 10 Cluster 15 Economics 5 -- Current 52 ``` La navigation Deprecated conserve les 14 noms historiques déjà enregistrés par KSP : ```text confirmTransaction getConfirmedBlock getConfirmedBlocks getConfirmedBlocksWithLimit getConfirmedSignaturesForAddress2 getConfirmedTransaction getFeeCalculatorForBlockhash getFeeRateGovernor getFees getRecentBlockhash getSignatureConfirmation getSignatureStatus getSnapshotSlot getStakeActivation ``` La partition KSP reste donc inchangée : ```text 0.2.1 = 4 0.2.2 = 22 0.2.3 = 11 0.2.4 = 15 -- current = 52 historical = 14 ``` Les 15 descriptors `V0_2_4` sont déjà classés `Read / RetrySafe`. `getBlock` reste le seul de ces descriptors marqué `StableWithDeprecatedLegacy` à cause de son second paramètre bare encoding encore accepté pour compatibilité. ## Règle de complétude `KSP-TRANSPORT-007` Un wrapper de cette release n'est complet que s'il expose sans perte toutes les possibilités RPC retenues par l'audit : paramètres ordonnés, objets de config, overloads, formes legacy encore supportées, contraintes déterministes utiles, variantes de réponse et distinctions `omitted`/`null` nécessaires. Pour `0.2.4`, cela impose notamment : - de ne pas réduire `getBlocks` à la seule forme `[start, end, config]` ; - de conserver le bare encoding legacy de `getBlock` sans le présenter comme forme recommandée ; - de préserver `transactionDetails = full ou signatures ou none ou accounts` et les conséquences sur la présence des champs de bloc ; - de préserver les champs wire riches des transactions/meta/rewards sans importer un client RPC Solana haut niveau ; - de conserver les `null` positionnels de `getInflationReward` et le champ runtime `commissionBps` lorsqu'il est présent ; - de ne pas inventer de limite d'adresses `getInflationReward` si aucune limite sémantique fixe n'est établie par la documentation/runtime courant ; la limite générale de taille de requête HTTP n'est pas transformée artificiellement en cardinalité métier KSP. ## Audit SIMD lié à `KSP-TRANSPORT-007` Le statut d'un SIMD n'est pas, à lui seul, le critère d'implémentation de Transport. La règle est la suivante : - si la baseline Solana/Agave stable expose déjà un paramètre, un champ ou une variante wire provenant d'une évolution SIMD, KSP doit le préserver même si le document SIMD n'a pas encore le statut `Activated` ; - si un SIMD modifie seulement la sémantique d'une valeur calculée par le runtime sans modifier son wire, KSP ne doit ni recalculer ni figer cette valeur localement ; - si un SIMD `Draft`/`Review` propose une extension RPC absente de la baseline stable retenue, KSP ne l'invente pas mais l'inscrit dans la watchlist et la réaudite avant le wrapper concerné puis à la compliance finale. ### SIMD applicables à la baseline `v4.2.1` **SIMD-0118 — Partitioned Epoch Rewards Distribution** est `Activated` et a un impact direct sur `getBlock`. Le wire stable `UiConfirmedBlock` expose `numRewardPartitions` sous forme optionnelle. La future structure de bloc KSP doit donc : - conserver `num_reward_partitions`/`numRewardPartitions` sans synthétiser `0` lorsqu'il est absent ; - utiliser `SolanaWireField` ou une représentation équivalente capable de préserver au minimum l'omission, et de ne pas écraser un éventuel `null` de compatibilité ; - couvrir par fixture un bloc avec `numRewardPartitions` présent et un bloc où le champ est omis ; - ne pas déduire localement le nombre de partitions à partir des rewards ou de l'epoch. **SIMD-0291 — Commission Rate in Basis Points** est encore en `Review`, mais Agave stable `v4.2.1` expose déjà les champs RPC de compatibilité correspondants. Il affecte trois surfaces KSP : - `getVoteAccounts.inflationRewardsCommissionBps` : déjà couvert et testé dans la surface `0.2.2`; aucune remédiation n'est requise ; - `getBlock.rewards[].commissionBps` : à couvrir dans `0.2.4` avec un reward wire de bloc dédié, distinct du reward d'inflation ; - `getInflationReward[].commissionBps` : à couvrir dans `0.2.4` dans le DTO `SolanaInflationReward` ou nom final équivalent. Pour les deux nouveaux wires de rewards, `commission` reste nullable et `commissionBps` doit préserver son caractère optionnel/omis. Les deux structures ne doivent pas être fusionnées artificiellement : le reward de bloc possède notamment `pubkey`, `lamports`, `postBalance` et `rewardType`, alors que le reward d'inflation possède `epoch`, `effectiveSlot`, `amount` et `postBalance`. La surface `getTransaction` de `0.2.3` ne nécessite pas de correction SIMD-0291 : `meta` est déjà conservé losslessly en `SolanaWireField`, ce qui préserve les rewards imbriqués et leurs extensions sans décodage métier. ### SIMDs déjà absorbés ou sans nouveau wire HTTP **SIMD-0185 — Vote Account v4** est `Accepted`. Les nouvelles données de vote account peuvent faire évoluer les sous-arbres retournés par les parsers `jsonParsed`, mais `SolanaParsedAccountData.parsed` reste un `serde_json::Value` lossless. Agave `v4.2.1` n'ajoute pas les collector fields de Vote Account v4 au DTO dédié `RpcVoteAccountInfo`; aucune extension spéculative de `SolanaVoteAccountInfo` n'est donc ajoutée maintenant. **SIMD-0186 — Loaded Transaction Data Size Specification** est `Accepted` et précise la sémantique consensus de la taille de données chargées. La surface `simulateTransaction` de `0.2.3` expose déjà `loadedAccountsDataSize` via `SolanaWireField` et couvre son omission : aucune nouvelle structure n'est requise. Transport ne doit pas recalculer cette valeur à partir des comptes de la transaction ; il restitue le résultat runtime. **SIMD-0385 — Transaction V1 Format** est encore en `Review`. Agave `v4.2.1` possède déjà du plumbing V1 dans ses types transaction-status, mais le contrat KSP acquis est volontairement générique : `SolanaTransactionVersion::Number(u8)` n'est pas limité à `0`, et les payloads JSON restent lossless. `0.2.4` doit conserver cette propriété dans `getBlock` et ajouter une canary déterministe avec une version numérique non nulle afin d'interdire une régression vers un modèle `legacy ou v0` seulement. **SIMD-0096 — Reward full priority fee to validator** est `Activated`, mais change la distribution économique des priority fees sans changer le wire HTTP que KSP doit décoder. Transport continue à restituer les valeurs runtime ; aucune structure spécifique n'est ajoutée. **SIMD-0550 — Double Disinflation Rate** est en `Review` et précise explicitement que `getInflationRate` et `getInflationGovernor` refléteront la nouvelle schedule sans changement d'API. KSP ne doit donc figer ni `initial`, ni `taper`, ni le taux courant : les DTOs restent des valeurs runtime `f64` et aucune formule d'inflation n'est réimplémentée dans Transport. Un réaudit avant la tranche Economics et à la clôture vérifie qu'aucun nouveau champ n'a été ajouté par la baseline stable. ### Watchlist obligatoire pendant `0.2.4` **SIMD-0180 — Vote Account Address Keyed Leader Schedule** est en `Review`. Son volet RPC demande explicitement que les endpoints historiques de leader schedule et slot leader continuent à retourner l'identité validator afin de préserver la compatibilité, tout en prévoyant de nouveaux endpoints vote-account-keyed. Le wrapper KSP `getLeaderSchedule` acquis en `0.2.2` ne doit donc pas être modifié spéculativement. En revanche, le réaudit d'inventaire de `pre.009` doit détecter si de nouveaux endpoints ont rejoint la surface HTTP officielle : ce serait alors une évolution de l'inventaire RPC, pas un changement silencieux du wire de `getLeaderSchedule`. **SIMD-0307 — Add Block Footer** est en `Review` et propose précisément une extension de `getBlock` : option de config `footer` et champs footer dans la réponse. Ces éléments sont absents de `RpcBlockConfig` et `UiConfirmedBlock` dans Agave stable `v4.2.1`; ils ne doivent donc pas être inventés dans `pre.002`. **SIMD-0298 — Add `bank_hash` to block footer** est encore au statut `Idea` et prévoit d'étendre ce même footer avec `bank_hash`. Les deux SIMDs doivent être réaudités ensemble au début de la tranche `getBlock` et à `pre.009`. Si une baseline stable expose alors le footer, `KSP-TRANSPORT-007` impose de couvrir toutes ses options et tous ses champs stables, y compris `bankHash` s'il fait partie du wire effectivement livré. **SIMD-0490 — Upgrade BPF Stake Program to v5.0.0** est en `Review` et prévoit notamment une hausse du minimum de délégation ainsi que son exposition par le RPC de minimum delegation. Pour `getStakeMinimumDelegation`, KSP doit donc traiter la valeur contextualisée comme une valeur runtime opaque en lamports : aucun minimum `1 lamport`, `1 SOL` ou autre ne doit être codé en dur ou validé côté Transport. Le SIMD sera réaudité avant `pre.007` et à `pre.009`. **SIMD-0553 — Base Inclusion and Resource-based Fee** est en `Draft`. Il change la sémantique du total de fees de `getFeeForMessage`, `simulateTransaction` et `getTransaction.meta.fee` sans imposer actuellement de changement de forme JSON. Les wrappers `0.2.3` doivent donc rester pass-through/lossless et ne pas recalculer le fee. La compliance finale `52/52` réauditera cette proposition afin de détecter une éventuelle extension stable de schéma apparue pendant la release. Les SIMDs `Review` liés au block-revenue sharing, notamment SIMD-0123, peuvent modifier à terme la provenance/sémantique des rewards, mais n'ajoutent pas de champ HTTP stable dans la baseline `v4.2.1`. Le reward wire de KSP doit donc rester fidèle aux champs effectivement retournés et ne pas encoder une taxonomie économique non présente sur le wire. ## Matrice Blocks — 10 wrappers | Méthode | Requête à couvrir | Résultat à préserver | Contraintes / décisions `KSP-TRANSPORT-007` | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `getBlock` | `slot`; second paramètre absent, bare encoding legacy, ou config `{commitment, encoding, transactionDetails, maxSupportedTransactionVersion, rewards}` | `object ou null`; `previousBlockhash`, `blockhash`, `parentSlot`, transactions/signatures/rewards selon config, `numRewardPartitions`, `blockTime`, `blockHeight` | commitment runtime au moins `confirmed`; réutiliser les encodings/version/transaction wire de `0.2.3`; préserver omission vs null; `numRewardPartitions` suit SIMD-0118; les rewards préservent `commissionBps` de SIMD-0291; garder les erreurs runtime de bloc/version comme erreurs RPC, sans les masquer | | `getBlockCommitment` | `slot` uniquement | `{commitment: array ou null, totalStake: u64}` | aucune config à inventer; préserver commitment nullable | | `getBlockHeight` | config contextuelle optionnelle `{commitment, minContextSlot}` | `u64` | réutiliser `SolanaContextConfig`; `minContextSlot` est transmis tel quel au runtime | | `getBlockProduction` | config optionnelle `{commitment, identity, range:{firstSlot,lastSlot?}}` | `SolanaRpcResponse<{byIdentity, range}>` | `identity` typée Pubkey; validation locale déterministe `lastSlot >= firstSlot` lorsque les deux sont fournis; préserver les couples `[leaderSlots, blocksProduced]` | | `getBlocks` | `[start]`, `[start,end]`, `[start,config]`, `[start,end,config]`; config `{commitment,minContextSlot}` | `Vec` | commitment au moins `confirmed`; transmettre `minContextSlot`; conserver l'overload untagged du second paramètre; `end < start` donne `[]`; rejeter localement une différence `end-start > 500_000` | | `getBlocksWithLimit` | `start`, `limit`, config contextuelle optionnelle `{commitment,minContextSlot}` | `Vec` | commitment au moins `confirmed`; transmettre `minContextSlot`; `limit <= 500_000`; `limit = 0` est valide et donne `[]` | | `getBlockTime` | `slot` uniquement | `i64 ou null` | préserver l'absence de timestamp; les cas cleaned/skipped/not available restent des erreurs RPC runtime, pas des valeurs synthétiques | | `getFirstAvailableBlock` | aucun paramètre | `u64` | requête exacte `params: []`; aucune config | | `getRecentPerformanceSamples` | `limit?` | tableau de `{slot,numTransactions,numSlots,samplePeriodSecs,numNonVoteTransactions?}` | défaut runtime `720`; maximum `720`; rejeter avant I/O `limit > 720`; préserver `numNonVoteTransactions` nullable/ancien runtime | | `minimumLedgerSlot` | aucun paramètre | `u64` | requête exacte `params: []`; conserver les erreurs ledger/runtime | ### Clarification runtime `pre.004` — config des ranges Blocks Le réaudit d’implémentation de `pre.004` confirme dans Agave `v4.2.1` que `getBlocks` et `getBlocksWithLimit` consomment tous deux `RpcContextConfig`, et non un simple objet commitment. Le wrapper `RpcBlocksConfigWrapper` permet en plus à `getBlocks` de recevoir soit `end_slot`, soit cette config en deuxième position. KSP doit donc réutiliser `SolanaContextConfig` et préserver les deux champs stables : ```text commitment minContextSlot ``` La documentation publique n’affiche actuellement que `commitment` sur ces pages ; la source runtime stable prime ici conformément à `KSP-TRANSPORT-007`. ### `getBlock` — stratégie wire `getBlock` est le plus gros fil de la release et reçoit une prerelease dédiée. Les primitives déjà acquises de `rpc_transactions` doivent être réutilisées lorsque le wire est réellement commun : ```text SolanaTransactionEncoding SolanaEncodedTransaction SolanaTransactionVersion SolanaWireField ``` `SolanaConfirmedTransaction` ne doit **pas** être réutilisé tel quel pour un élément de bloc : ce DTO contient `slot` et `blockTime`, qui appartiennent au résultat top-level de `getTransaction` et non à chaque élément `transactions[]` d'un bloc. Un type wire de transaction de bloc dédié peut en revanche composer les primitives ci-dessus et préserver `transaction`, `meta` et `version` sans décodage Program. Les champs top-level dont la présence dépend de la config (`transactions`, `signatures`, `rewards`, `numRewardPartitions`) doivent utiliser une représentation capable de distinguer une omission d'un `null` lorsqu'une telle distinction existe sur le wire. `numRewardPartitions` est explicitement rattaché à SIMD-0118 et doit être couvert en présent/omis. Le reward wire de bloc doit conserver `commission` nullable et `commissionBps` optionnel/omis de SIMD-0291. Les transactions `accounts` ne doivent pas être forcées dans une structure `full` plus riche que le wire réellement retourné. Une version de transaction numérique différente de `0` doit rester représentable afin de ne pas régresser la compatibilité préparée pour SIMD-0385. ## Matrice Economics — 5 wrappers | Méthode | Requête à couvrir | Résultat à préserver | Contraintes / décisions `KSP-TRANSPORT-007` | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `getInflationGovernor` | config commitment optionnelle | `{initial,terminal,taper,foundation,foundationTerm}` en `f64` | réutiliser `SolanaCommitmentConfig`; aucun contexte de réponse | | `getInflationRate` | aucun paramètre | `{total,validator,foundation,epoch}` | requête exacte `params: []` | | `getInflationReward` | liste ordonnée d'adresses; config optionnelle `{epoch,commitment,minContextSlot}` | `Vec>` positionnel | ordre/cardinalité identiques aux entrées; préserver `commission: u8 ou null` et `commissionBps: u16` optionnel/omis de Agave `v4.2.1` conformément à SIMD-0291; aucune limite fixe d'adresses inventée | | `getStakeMinimumDelegation` | config contextuelle optionnelle `{commitment,minContextSlot}` | `SolanaRpcResponse` | réutiliser `SolanaContextConfig` / `SolanaRpcResponse`; restituer la valeur runtime en lamports sans minimum codé en dur; surveiller SIMD-0490 | | `getSupply` | config optionnelle `{commitment,excludeNonCirculatingAccountsList}` | `SolanaRpcResponse<{total,circulating,nonCirculating,nonCirculatingAccounts}>` | le booléen runtime par défaut est `false`; préserver la liste ordonnée retournée lorsqu'elle est demandée | ### Extension runtime `commissionBps` La documentation publique actuelle de `getInflationReward` énumère encore uniquement `commission`. Agave `v4.2.1` définit cependant aussi : ```text commission_bps: Option ``` sérialisé en `commissionBps` lorsqu'il est présent. Ce champ correspond à l'évolution SIMD-0291 et doit être conservé dans le DTO KSP pour ne pas perdre une capacité/extension du runtime stable courant. Le DTO doit préserver séparément `commission` nullable et `commissionBps` optionnel/omis; il ne doit pas convertir les basis points en pourcentage ni dériver l'un des deux champs depuis l'autre. ## Contraintes locales retenues Les validations déterministes suivantes doivent être réalisées avant I/O : ```text getBlock commitment >= confirmed getBlocks commitment >= confirmed getBlocks end-start <= 500_000 lorsqu'end >= start getBlocksWithLimit commitment >= confirmed getBlocksWithLimit limit <= 500_000 getRecentPerformanceSamples limit <= 720 getBlockProduction lastSlot >= firstSlot lorsqu'ils sont tous deux présents ``` `getBlocks(end < start)` et `getBlocksWithLimit(limit = 0)` sont des cas valides qui doivent produire un tableau vide plutôt qu'une erreur locale. Ne pas reproduire localement les validations qui nécessiteraient un décodage disproportionné ou l'état du ledger : disponibilité réelle d'un bloc, slot cleaned/skipped, support effectif d'une version de transaction par le caller, présence historique des metadata, epoch disponible, minContextSlot atteint, etc. Ces cas restent des erreurs/réponses RPC validées par le flux central. ## Réutilisation des contrats existants ### À réutiliser directement ```text SolanaCommitment SolanaCommitmentConfig SolanaContextConfig SolanaRpcContext SolanaRpcResponse SolanaTransactionEncoding SolanaEncodedTransaction SolanaTransactionVersion SolanaWireField ``` ### À introduire dans `0.2.4` Noms définitifs ajustables pendant l'implémentation, responsabilités fixes : ```text config getBlock moderne + enum transactionDetails config/range/result getBlockProduction block commitment result confirmed block + transaction-in-block + reward wire, avec `numRewardPartitions` SIMD-0118 et `commissionBps` SIMD-0291 performance sample inflation governor/rate/reward, avec reward d'inflation distinct et `commissionBps` SIMD-0291 supply result/config ``` La déduplication ne doit pas fusionner des contrats ayant des sémantiques différentes uniquement parce que leurs champs se ressemblent. ## Architecture d'exécution Les 15 wrappers restent `Read / RetrySafe` et passent exclusivement par : ```text wrapper typed -> descriptor central -> execute_standard_rpc -> pool/admission -> executor HTTP -> validation JSON-RPC -> decode typed ``` Interdits : ```text client HTTP parallèle reqwest direct dans un wrapper retry/deadline/admission bypass Transport -> Config Transport -> Store/Program tracing direct solana-rpc-client / solana-client pour masquer les possibilités RPC ``` ## Dépendances Aucune nouvelle dépendance n'est nécessaire au vu de l'audit `pre.001`. En particulier : ```text solana-rpc-client NON solana-client NON crate SDK Block NON base64/bs58 NON pour cette release ``` Les primitives `serde`/`serde_json`, `ksp-core-lib::Pubkey` et les wires Transaction déjà présents suffisent à exprimer les contrats sans introduire un SDK RPC haut niveau. ## Tests déterministes attendus Chaque wrapper doit couvrir : - request JSON exacte ; - absence de config et objet vide lorsque ces deux formes sont significatives ; - tous les overloads/configs/encodings pertinents ; - réponse typed nominale ; - `null` et omission lorsque le wire les distingue ; - ordre et cardinalité ; - erreur JSON-RPC propagée ; - validation déterministe avant I/O lorsqu'elle est retenue par ce plan. Cas de régression obligatoires spécifiques : ```text getBlock bare encoding legacy getBlock transactionDetails full/signatures/none/accounts getBlock result null getBlock numRewardPartitions présent/omis (SIMD-0118) getBlock rewards commission nullable + commissionBps présent/omis (SIMD-0291) getBlock transaction version numérique non nulle conservée (canary SIMD-0385) getBlocks [start,config] vs [start,end,config] + minContextSlot transmis getBlocks range > 500_000 rejetée avant I/O getBlocksWithLimit 0 et > 500_000 + minContextSlot transmis getRecentPerformanceSamples défaut/720/>720 getBlockProduction lastSlot < firstSlot rejeté avant I/O getInflationReward ordre + null positionnels + commission/commissionBps présent/omis (SIMD-0291) getStakeMinimumDelegation valeur runtime arbitraire sans minimum codé en dur (watch SIMD-0490) getSupply excludeNonCirculatingAccountsList true/false/omitted ``` ## Compliance finale HTTP La dernière prerelease doit ajouter une preuve explicite que les **52 méthodes courantes enregistrées** possèdent désormais toutes un wrapper typed public réel. Un appel raw/générique ne compte pas. Canaries finales : ```text current registry == 52 historical registry == 14 V0_2_1 exact == 4 V0_2_2 exact == 22 V0_2_3 exact == 11 V0_2_4 exact == 15 typed wrappers current == 52/52 historical Deprecated/Removed == 14/14 KSP-TRANSPORT-007 audited current == 52/52 ``` La compliance `KSP-TRANSPORT-007` des 37 wrappers de `0.2.1`–`0.2.3` reste acquise par `docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`; la clôture `0.2.4` vérifie qu'aucune régression n'a été introduite et applique la même règle aux 15 nouveaux wrappers. Le réaudit final inclut explicitement l'état des SIMD susceptibles de modifier la surface HTTP ou sa sémantique observable, au minimum SIMD-0180, SIMD-0298, SIMD-0307, SIMD-0385, SIMD-0490, SIMD-0550 et SIMD-0553, afin qu'une évolution devenue stable pendant la session ne soit pas oubliée. Il réaudite aussi l'inventaire officiel lui-même afin de détecter d'éventuels nouveaux endpoints issus de SIMD-0180 ou d'une autre évolution d'interface. ## Smokes live Les smokes restent opt-in et secondaires par rapport aux fixtures locales. Le smoke Transport pur peut être étendu uniquement avec quelques reads robustes, par exemple `getBlockHeight`, `getFirstAvailableBlock`, `minimumLedgerSlot`, `getInflationRate` ou `getStakeMinimumDelegation`. Éviter un `getBlock` dépendant d'un slot fixe ou tout scénario fragile lié à des récompenses d'un epoch précis. Le smoke historique Config -> Transport reste une exception transitoire de composition et ne devient pas la destination générale des futurs scénarios cross-crates. ## Prévision souple des prereleases ```text pre.001 audit officiel actuel + Agave stable + matrice + wires + contraintes + sizing pre.002 primitives/configs/results Blocks/Economics partagés + reward wires SIMD-0118/0291 + fixtures communes pre.003 Blocks simples : getBlockCommitment, getBlockHeight, getBlockTime, getFirstAvailableBlock, minimumLedgerSlot pre.004 ranges/performance : getBlocks, getBlocksWithLimit, getRecentPerformanceSamples pre.005 getBlockProduction + range/identity/result contextualisé pre.006 réaudit SIMD-0298/0307 + getBlock moderne + bare encoding legacy + transactionDetails + wire bloc riche + SIMD-0118/0291 + canary version numérique SIMD-0385 pre.007 réaudit SIMD-0490/0550 + Economics simples : getInflationGovernor, getInflationRate, getStakeMinimumDelegation, getSupply pre.008 getInflationReward + null positionnels + commissionBps SIMD-0291 + invariants pre.009 réaudit SIMD HTTP (0180/0298/0307/0385/0490/0550/0553 minimum) + réaudit inventaire officiel + compliance finale 52/52 + 14/14 + KSP-TRANSPORT-007 + docs + smokes + graphes + prompt 0.2.5 — Wallet foundation rel.001 publication strictement publicationnelle ``` Cette prévision peut être redécoupée si une tranche dépasse le budget réel. Elle ne doit pas être compressée artificiellement pour conserver un numéro de prerelease prévu. ## Hors périmètre ```text Wallet / .kspwallet WebSocket LaserStream Yellowstone gRPC Store/Program/Materializer modèle métier de transaction/bloc client RPC Solana haut niveau réécriture des deltas historiques ``` ## Critères de clôture `0.2.4` - 15/15 wrappers `V0_2_4` publics, typed et `KSP-TRANSPORT-007` conformes ; - 52/52 méthodes HTTP courantes avec wrapper typed ; - 14/14 historiques conservées en compliance ; - aucun bypass du flux central Transport ; - aucune nouvelle dépendance injustifiée ; - tests déterministes complets ; - smokes live pertinents validés par preuve opérateur ; - graphes Cargo Transport/Config réaudités ; - README/USAGE/matrices/validation synchronisés ; - prompt `0.2.5 — Wallet foundation` finalisé ; - dernière prerelease candidate complète ; - `0.2.4-rel.001` strictement publicationnelle. ## Questions ouvertes Aucune question bloquante pour `pre.002`. Les noms Rust exacts des DTOs peuvent encore être ajustés pendant l'implémentation. En revanche, les formes RPC, overloads, distinctions wire et limites fixées dans ce plan ne doivent pas être réduits pour simplifier l'API KSP.