81 KiB
0.2.1-pre.001 — plan ksp-onchain-transport-lib HTTP Solana foundation
1. Statut et conclusion exécutive
Ce document ouvre 0.2.1 à partir de la base stable fournie 0.2.0 et exécute le gate de sizing imposé par le prompt 006 avant toute grosse implémentation. Sa version initiale appartient à 0.2.1-pre.001; le split de releases présenté dans cette version du plan est le recalibrage documentaire de 0.2.1-pre.001-fix.001.
État
0.2.1-rel.001: clôturé stable. La foundation HTTP réduite est publiée après validation opérateur complète depre.007, des graphes Cargo et du smoke Devnet opt-in.0.2.2devient la prochaine release active.
Conclusion du gate :
Périmètre monolithique 0.2.1 décrit par le prompt 006 : NON clôturable raisonnablement dans cette session.
0.2.1 réduite après split : OUI, clôturable raisonnablement dans cette session.
Le périmètre initial combinait simultanément : 52 méthodes HTTP courantes typées, 14 méthodes historiques deprecated à classifier, les formes de paramètres legacy encore documentées, la crate foundation, le protocole JSON-RPC, l'ownership des modèles wire, les pools, rôles, priorités, limites, concurrence, retry/backoff, erreurs, logging, Config standard, adapter Config -> Transport, tests, fixtures, smoke tests et documentation. Cette combinaison dépasse la discipline KSP de tranches d'environ 15–20 minutes et ne permet pas de garantir la clôture complète de la release dans la même session.
Le split conserve l'inventaire exhaustif : aucune méthode n'est masquée. Les 52 méthodes courantes et les 14 pages deprecated restent verrouillées dans la matrice ci-dessous et sont affectées explicitement à une release de la série HTTP.
2. Sources relues et base stable auditée
2.1 Sources internes KSP
Relues pour cette tranche :
ROADMAP.md;docs/000-README.md;docs/IDEAS.md;docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md;docs/plans/007-V0_2_0_SERIES_PLANNING.md;docs/architecture/002-LAYERS_AND_DEPENDENCIES.md;docs/architecture/003-COMPONENT_CONTRACTS.md;docs/architecture/004-COMPONENT_INVENTORY.md;docs/architecture/005-DEPENDENCY_GRAPH.md;docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md;docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md;docs/rules/RULES_KSP.md;docs/rules/RULES_DEPENDENCIES.md;docs/rules/RULES_RUST.md;docs/rules/PROMPT_STRUCTURE.md;docs/rules/VERSION_WORKFLOW.md;docs/rules/FILE_CONTRACTS.md;- contrats publics actuels de
ksp-core-lib,ksp-logging-libetksp-config-lib.
2.2 Base fournie
L'archive khadhroony-solana-project-v0.2.0.zip contient :
workspace.package.version = "0.2.0"
et exactement les quatre crates déjà stabilisées :
ksp-core-lib
ksp-logging-lib
ksp-config-lib
ksp-app-config-desk
Aucune crate Transport n'existe encore. L'archive ne contient pas .git, donc le tag v0.2.0 ne peut pas être revérifié localement depuis ce zip. Le contenu technique fourni correspond néanmoins à la version stable attendue.
2.3 Contrats KSP qui conditionnent Transport
ksp-core-libpossède l'uniqueError,ErrorCodeetResult<T>KSP. Transport déclarera ses codes dans son domaine mais ne créera pas une hiérarchie d'erreurs concurrente.ksp-logging-libpossède la façade de tracing et les macros KSP ; Transport ne dépendra pas directement detracing.ksp-config-libpossède déjà registry, documents, profils, interpolation d'environnement, sensibilité/provenance et adapters de runtime. Le nouvel adapter sera donc Config -> settings Transport, jamais l'inverse.- Les règles d'architecture interdisent Transport -> Store et Transport -> Program. Les réponses restent wire/transport et préservent l'information nécessaire aux futures couches RAW/CORE.
3. Audit détaillé du transport bot3
Archive de référence :
khadhroony-bot3_v0.5.3-pre.005-fix010.zip
workspace.package.version = "0.5.3-pre.5"
3.1 Dépendances historiques
ks-onchain-transport/Cargo.toml dépend directement de :
futures-util
base64
bs58
ks-config
ks-core
ks-lib
reqwest
serde
serde_json
tokio
tokio-tungstenite
tracing
Décision KSP :
| Élément bot3 | Décision | Motif |
|---|---|---|
reqwest async HTTP |
adapter | besoin HTTP réel, version/features à réauditer |
serde / serde_json |
reprendre | contrat JSON-RPC/wire naturel et déjà workspace |
tokio |
reprendre | runtime async déjà workspace ; sync devra être ajouté si Semaphore est retenu |
base64 / bs58 |
différer | ne les ajouter qu'à la première méthode qui doit réellement encoder/valider ces wires |
futures-util |
abandonner pour HTTP foundation | usage surtout live/stream ; pas nécessaire par anticipation |
tokio-tungstenite |
abandonner pour 0.2.1 |
WebSocket hors périmètre |
ks-config |
abandonner comme dépendance Transport | ownership inversé dans KSP |
ks-lib |
abandonner | couplage aux modèles canonical/Program contraire à RAW/CORE |
tracing direct |
abandonner | ksp-logging-lib est propriétaire |
3.2 Inventaire des méthodes bot3
Le registre STANDARD_HTTP_METHODS contient 52 noms uniques, tous avec le contrat TypedAdapter. La comparaison nom par nom avec l'index HTTP officiel audité le 2026-08-17 donne :
current Solana HTTP index : 52
bot3 STANDARD_HTTP_METHODS: 52
missing in bot3 : 0
extra in bot3 : 0
Bot3 constitue donc une bonne preuve historique pour les noms de la surface courante, mais pas une source normative des paramètres, statuts, modèles ni frontières KSP.
3.3 Settings/roles bot3 utiles
Bot3 possède :
- endpoint :
name,enabled,provider,cluster,url,connect_timeout_ms,request_timeout_ms,max_idle_connections_per_host,roles; - rôle :
role,enabled,request_kinds,priority,requests_per_second,burst_capacity,max_concurrent_requests,max_subscriptions,pause_after_rate_limit_ms; - wildcard
*pourrequest_kinds; - limiteur token-bucket approximé +
Semaphore; - cooldown après rate-limit ;
- snapshots sans URL afin de limiter la fuite de secrets.
À reprendre : identité/provider/cluster, rôles ouverts, priorités, RPS/burst/concurrence, cooldown et snapshots redacted.
À abandonner pour HTTP : max_subscriptions appartient au futur WebSocket et ne sera pas prérempli dans le contrat HTTP.
3.4 Pool bot3 : force et faiblesse
Le pool historique fait un round-robin entre clients pouvant gérer le rôle/la méthode. Le client choisit localement le rôle correspondant de plus faible priorité. Cette architecture ne produit toutefois pas une sélection globale nette « meilleure priorité sur tous les endpoints, puis round-robin dans le tier ».
KSP refond donc la sélection au niveau du pool logique : priorité globale, fairness dans un même tier, fallback sur endpoint indisponible/cooldown/saturé, et deadline commune.
3.5 Retry/rate-limit bot3
Bot3 sait reconnaître HTTP 429, lire Retry-After, appliquer un backoff exponentiel borné et imposer un cooldown. Ces invariants sont utiles mais la politique n'est pas suffisamment liée à la nature de la méthode. En particulier, KSP doit empêcher tout resend ambigu de sendTransaction/requestAirdrop au nom d'un retry « transport » générique.
3.6 Couplages de modèles à supprimer
Bot3 lie certaines méthodes techniques à ks-lib, notamment autour des signatures/transactions et de modèles canoniques. KSP interdit le pattern :
getTransaction -> modèle CORE/DECODE canonique
getTransaction/getBlock devront préserver le wire et les variations d'encoding sans normaliser vers Store/Program.
4. Audit officiel Solana HTTP — 2026-08-17
4.1 Sources normatives
Sources externes utilisées :
- index HTTP Solana : https://solana.com/docs/rpc/http ;
- structures JSON RPC Solana : https://solana.com/docs/rpc/json-structures ;
- pages individuelles
/docs/rpc/http/<method>; - index/pages Deprecated :
/docs/rpc/deprecated/<method>; - JSON-RPC 2.0 : https://www.jsonrpc.org/specification ;
- changelog Agave : https://github.com/anza-xyz/agave/blob/master/CHANGELOG.md pour vérifier la suppression runtime des endpoints v1 historiques.
La documentation Solana indique JSON-RPC 2.0 sur HTTP POST, Content-Type: application/json, jsonrpc = "2.0", id, method et paramètres ordonnés.
4.2 Surface courante
L'index officiel contient 52 méthodes HTTP courantes :
Accounts 6
Tokens 5
Transactions 11
Blocks 10
Cluster 15
Economics 5
Total 52
Aucune page HTTP courante marquée Unstable Method ou Experimental n'a été trouvée pendant l'audit. Les résultats officiels portant explicitement le marqueur Unstable Method concernent actuellement des méthodes WebSocket/PubSub et restent hors 0.2.1.
4.3 Surface Deprecated séparée
La navigation officielle Deprecated contient 14 méthodes. Les pages indiquent qu'elles étaient attendues supprimées en solana-core v2.0. Le changelog Agave confirme ensuite le retrait des endpoints RPC v1 obsolete/deprecated dans la ligne v2.
Conséquence KSP :
- elles restent dans le registre/matrice de conformité historique ;
- leur statut documentaire est
Deprecated; - leur statut runtime KSP initial est
Removed; - aucune méthode callable ne simulera un succès ;
- aucune tentative de warning « à l'utilisation » n'est nécessaire tant qu'elles sont réellement non exécutables ;
- leur disponibilité devra être revérifiée depuis les sources officielles si une release future réouvre ce point.
4.4 Deprecated au niveau d'une forme de requête
Deux méthodes courantes et stables documentent encore une forme de paramètres legacy explicitement deprecated :
getTransaction: second paramètreencodingsous forme de string nue ;getBlock: second paramètreencodingsous forme de string nue.
KSP doit donc distinguer :
method documentation status
request-form documentation status
runtime support status
Un simple enum au niveau méthode ne suffit pas à représenter fidèlement la documentation actuelle.
getBlocks possède également un overload backward-compatible où le deuxième paramètre peut être l'objet config, mais la page actuelle ne le marque pas deprecated. Cette forme doit être sérialisée/testée sans warning.
5. Matrice exhaustive — 52 méthodes HTTP courantes
Colonnes : nom, catégorie, paramètres/config à préserver, forme de résultat, statut documentaire, disponibilité runtime, niveau bot3, release KSP assignée, preuve minimale et source normative.
| Méthode | Catégorie | Params / config | Résultat | Statut | Runtime | Bot3 | Release | Tests minimaux | Source |
|---|---|---|---|---|---|---|---|---|---|
getAccountInfo |
Accounts | pubkey ; config? {commitment, encoding, dataSlice, minContextSlot} | RpcResponse<Account / null> | Stable | Supporté | typed_adapter | 0.2.2 |
params/encoding/dataSlice ; account/null ; RPC error | Solana |
getBalance |
Accounts | pubkey ; config? {commitment, minContextSlot} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.1 |
params/config ; value u64 ; context/error | Solana |
getLargestAccounts |
Accounts | config? {commitment, filter, sortResults} | RpcResponse<[LargestAccount]> | Stable | Supporté | typed_adapter | 0.2.2 |
config/filter/sort ; array | Solana |
getMinimumBalanceForRentExemption |
Accounts | data_len ; config? {commitment} | u64 | Stable | Supporté | typed_adapter | 0.2.2 |
data length/config ; u64 | Solana |
getMultipleAccounts |
Accounts | pubkeys <= 100 ; config? {commitment, minContextSlot, dataSlice, encoding} | RpcResponse<[Account / null]> | Stable | Supporté | typed_adapter | 0.2.2 |
max/params ; mixed account/null ; encoding | Solana |
getProgramAccounts |
Accounts | program pubkey ; config? {commitment, minContextSlot, withContext, encoding, dataSlice, filters, sortResults} | [KeyedAccount] ou RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | 0.2.2 |
filters/dataSlice ; withContext false/true ; errors | Solana |
getTokenAccountBalance |
Tokens | token account ; config? {commitment} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.2 |
config ; token amount | Solana |
getTokenAccountsByDelegate |
Tokens | delegate ; filter {mint / programId} ; config? {commitment,minContextSlot,dataSlice,encoding} | RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | 0.2.2 |
mint/programId exclusifs ; config ; array | Solana |
getTokenAccountsByOwner |
Tokens | owner ; filter {mint / programId} ; config? {commitment,minContextSlot,dataSlice,encoding} | RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | 0.2.2 |
mint/programId exclusifs ; config ; array | Solana |
getTokenLargestAccounts |
Tokens | mint ; config? {commitment} | RpcResponse<[TokenLargestAccount]> | Stable | Supporté | typed_adapter | 0.2.2 |
config ; array | Solana |
getTokenSupply |
Tokens | mint ; config? {commitment} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.2 |
config ; TokenAmount | Solana |
getFeeForMessage |
Transactions | message base64 ; config? {commitment,minContextSlot} | RpcResponse<u64 / null> | Stable | Supporté | typed_adapter | 0.2.3 |
message/config ; fee/null ; error | Solana |
getLatestBlockhash |
Transactions | config? {commitment,minContextSlot} | RpcResponse<{blockhash,lastValidBlockHeight}> | Stable | Supporté | typed_adapter | 0.2.3 |
config ; object | Solana |
getRecentPrioritizationFees |
Transactions | pubkeys? <= 128 | [{slot,prioritizationFee}] | Stable | Supporté | typed_adapter | 0.2.3 |
no params / addresses ; max ; array | Solana |
getSignaturesForAddress |
Transactions | address ; config? {commitment,minContextSlot,limit,before,until} | [SignatureInfo] | Stable | Supporté | typed_adapter | 0.2.3 |
pagination/config ; nullable memo/blockTime/status | Solana |
getSignatureStatuses |
Transactions | signatures <= 256 ; config? {searchTransactionHistory} | RpcResponse<[SignatureStatus / null]> | Stable | Supporté | typed_adapter | 0.2.3 |
max ; cache/history ; object/null | Solana |
getTransaction |
Transactions | signature ; config? {commitment,maxSupportedTransactionVersion,encoding} ; legacy bare encoding deprecated | TransactionResponse / null | Stable; forme legacy deprecated | Supporté | typed_adapter | 0.2.3 |
config + legacy warning ; all encodings ; null ; error | Solana |
getTransactionCount |
Transactions | config? {commitment,minContextSlot} | u64 | Stable | Supporté | typed_adapter | 0.2.3 |
config ; u64 | Solana |
isBlockhashValid |
Transactions | blockhash ; config? {commitment,minContextSlot} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.3 |
hash/config ; bool | Solana |
requestAirdrop |
Transactions | pubkey ; lamports ; config? {commitment,recentBlockhash} | signature | Stable | Supporté | typed_adapter | 0.2.3 |
serialization ; signature/error ; no-resend policy | Solana |
sendTransaction |
Transactions | signed transaction ; config? {encoding,skipPreflight,preflightCommitment,maxRetries,minContextSlot} | signature | Stable | Supporté | typed_adapter | 0.2.3 |
all configs ; RPC error ; timeout/no-resend | Solana |
simulateTransaction |
Transactions | transaction ; config? {commitment,encoding,replaceRecentBlockhash,sigVerify,minContextSlot,innerInstructions,accounts} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.3 |
configs compatibles/incompatibles ; logs/accounts/null/error | Solana |
getBlock |
Blocks | slot ; config? {commitment,encoding,transactionDetails,maxSupportedTransactionVersion,rewards} ; legacy bare encoding deprecated | BlockResponse / null | Stable; forme legacy deprecated | Supporté | typed_adapter | 0.2.4 |
config + legacy warning ; transactionDetails variants ; null | Solana |
getBlockCommitment |
Blocks | slot | {commitment:[u64] / null,totalStake:u64} | Stable | Supporté | typed_adapter | 0.2.4 |
slot ; commitment null/array | Solana |
getBlockHeight |
Blocks | config? {commitment,minContextSlot} | u64 | Stable | Supporté | typed_adapter | 0.2.4 |
config ; u64 | Solana |
getBlockProduction |
Blocks | config? {commitment,identity,range} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.4 |
identity/range/config ; map | Solana |
getBlocks |
Blocks | startSlot ; endSlot? ou config? ; config? {commitment,minContextSlot} | [u64] | Stable | Supporté | typed_adapter | 0.2.4 |
overload 1/2/3 params ; max range 500k ; empty | Solana |
getBlocksWithLimit |
Blocks | startSlot ; limit <= 500000 ; config? {commitment,minContextSlot} | [u64] | Stable | Supporté | typed_adapter | 0.2.4 |
limit boundaries ; config ; array | Solana |
getBlockTime |
Blocks | slot | i64 | Stable | Supporté | typed_adapter | 0.2.4 |
success ; unavailable/error variant | Solana |
getFirstAvailableBlock |
Blocks | aucun | u64 | Stable | Supporté | typed_adapter | 0.2.4 |
empty params ; u64 | Solana |
getRecentPerformanceSamples |
Blocks | limit? <= 720 | [PerformanceSample] | Stable | Supporté | typed_adapter | 0.2.4 |
no params/limit ; nullable numNonVoteTransactions | Solana |
minimumLedgerSlot |
Blocks | aucun | u64 | Stable | Supporté | typed_adapter | 0.2.4 |
empty params ; u64 | Solana |
getClusterNodes |
Cluster | aucun | [ClusterNode] | Stable | Supporté | typed_adapter | 0.2.2 |
nullable endpoints/features ; array | Solana |
getEpochInfo |
Cluster | config? {commitment,minContextSlot} | EpochInfo | Stable | Supporté | typed_adapter | 0.2.2 |
config ; transactionCount null | Solana |
getEpochSchedule |
Cluster | aucun | EpochSchedule | Stable | Supporté | typed_adapter | 0.2.2 |
empty params ; object | Solana |
getGenesisHash |
Cluster | aucun | string base58 | Stable | Supporté | typed_adapter | 0.2.1 |
empty params ; hash string ; error | Solana |
getHealth |
Cluster | aucun | "ok" ou RPC unhealthy error | Stable | Supporté | typed_adapter | 0.2.1 |
healthy ; unhealthy RPC error | Solana |
getHighestSnapshotSlot |
Cluster | aucun | {full:u64,incremental:u64 / null} | Stable | Supporté | typed_adapter | 0.2.2 |
incremental null ; no snapshot/error | Solana |
getIdentity |
Cluster | aucun | {identity:string} | Stable | Supporté | typed_adapter | 0.2.2 |
empty params ; identity | Solana |
getLeaderSchedule |
Cluster | slot? / config? / null ; config? {commitment,identity} | map identity->[slot_index] / null | Stable | Supporté | typed_adapter | 0.2.2 |
all overloads ; filter ; null | Solana |
getMaxRetransmitSlot |
Cluster | aucun | u64 | Stable | Supporté | typed_adapter | 0.2.2 |
empty params ; u64 | Solana |
getMaxShredInsertSlot |
Cluster | aucun | u64 | Stable | Supporté | typed_adapter | 0.2.2 |
empty params ; u64 | Solana |
getSlot |
Cluster | config? {commitment,minContextSlot} | u64 | Stable | Supporté | typed_adapter | 0.2.2 |
config ; u64 | Solana |
getSlotLeader |
Cluster | config? {commitment,minContextSlot} | string pubkey | Stable | Supporté | typed_adapter | 0.2.2 |
config ; pubkey | Solana |
getSlotLeaders |
Cluster | startSlot ; limit 1..5000 | [string pubkey] | Stable | Supporté | typed_adapter | 0.2.2 |
limit boundaries ; array | Solana |
getVersion |
Cluster | aucun | {solana-core:string,feature-set:u32 / null} | Stable | Supporté | typed_adapter | 0.2.1 |
empty params ; feature-set present/null | Solana |
getVoteAccounts |
Cluster | config? {commitment,votePubkey,keepUnstakedDelinquents,delinquentSlotDistance} | {current:[VoteAccount],delinquent:[VoteAccount]} | Stable | Supporté | typed_adapter | 0.2.2 |
filters/config ; both sets | Solana |
getInflationGovernor |
Economics | config? {commitment} | InflationGovernor | Stable | Supporté | typed_adapter | 0.2.4 |
config ; f64 fields | Solana |
getInflationRate |
Economics | aucun | {total,validator,foundation:f64,epoch:u64} | Stable | Supporté | typed_adapter | 0.2.4 |
empty params ; object | Solana |
getInflationReward |
Economics | addresses ; config? {commitment,epoch,minContextSlot} | [InflationReward / null] | Stable | Supporté | typed_adapter | 0.2.4 |
addresses/config ; reward/null ; commission null | Solana |
getStakeMinimumDelegation |
Economics | config? {commitment,minContextSlot} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.4 |
config ; value | Solana |
getSupply |
Economics | config? {commitment,excludeNonCirculatingAccountsList} | RpcResponse | Stable | Supporté | typed_adapter | 0.2.4 |
config true/false ; list semantics | Solana |
6. Matrice exhaustive — 14 méthodes Deprecated historiques
| Méthode | Statut doc | Runtime actuel | Remplacement / direction | Bot3 HTTP | Contrat KSP | Source |
|---|---|---|---|---|---|---|
confirmTransaction |
Deprecated | Removed (Agave v2+) | getSignatureStatuses |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getConfirmedBlock |
Deprecated | Removed (Agave v2+) | getBlock |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getConfirmedBlocks |
Deprecated | Removed (Agave v2+) | getBlocks |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getConfirmedBlocksWithLimit |
Deprecated | Removed (Agave v2+) | getBlocksWithLimit |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getConfirmedSignaturesForAddress2 |
Deprecated | Removed (Agave v2+) | getSignaturesForAddress |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getConfirmedTransaction |
Deprecated | Removed (Agave v2+) | getTransaction |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getFeeCalculatorForBlockhash |
Deprecated | Removed (Agave v2+) | isBlockhashValid / getFeeForMessage |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getFeeRateGovernor |
Deprecated | Removed (Agave v2+) | getFeeForMessage |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getFees |
Deprecated | Removed (Agave v2+) | getFeeForMessage |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getRecentBlockhash |
Deprecated | Removed (Agave v2+) | getLatestBlockhash |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getSignatureConfirmation |
Deprecated | Removed (Agave v2+) | getSignatureStatuses |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getSignatureStatus |
Deprecated | Removed (Agave v2+) | getSignatureStatuses |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getSnapshotSlot |
Deprecated | Removed (Agave v2+) | getHighestSnapshotSlot |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
getStakeActivation |
Deprecated | Removed (Agave v2+) | approche alternative documentée |
absent du registre HTTP bot3 | descripteur historique en 0.2.1, aucune exécution simulée |
Solana |
6.1 Écart bot3 / documentation actuelle
La décision runtime = Removed repose ici sur le changelog officiel Agave v2+, qui documente la suppression des endpoints RPC v1 obsolètes/dépréciés. Aucun POST JSON-RPC live vers un provider public ou privé n’a été exécuté pendant pre.001; une divergence propre à un provider devra donc être documentée comme extension/comportement provider, sans réintroduire ces méthodes dans le contrat standard KSP.
Résumé nom par nom :
- les 52 courantes sont toutes présentes dans bot3 et toutes marquées
TypedAdapter; - les 14 Deprecated de la navigation officielle sont absentes du registre HTTP standard bot3 ;
- elles ne doivent pas être recopiées comme wrappers callables aujourd'hui puisque le runtime Agave v2 les a retirées ;
- le nouvel inventaire KSP sera donc plus complet que bot3 sur la metadata documentaire, tout en exposant moins de faux support runtime.
7. Split obligatoire de la série HTTP
Le split retenu est :
| Release | Mission | Surface courante assignée |
|---|---|---|
0.2.1 |
HTTP transport foundation | 4 canaris : getBalance, getGenesisHash, getHealth, getVersion + registre 52/14 + infrastructure complète foundation |
0.2.2 |
HTTP Accounts + Tokens + Cluster | 5 Accounts restants + 5 Tokens + 12 Cluster restants = 22 |
0.2.3 |
HTTP Transactions | 11 |
0.2.4 |
HTTP Blocks + Economics + compliance finale | 10 Blocks + 5 Economics = 15 + gate exhaustif 52 courantes / 14 historiques |
La présence d'un appel JSON-RPC raw/générique dans 0.2.1 ne comptera pas comme couverture typée des méthodes affectées à 0.2.2–0.2.4.
Ces trois releases HTTP complémentaires représentent trois sessions nominales au maximum, pas trois chats obligatoires. Si une release est entièrement clôturée plus vite que prévu, la même session peut ouvrir puis clôturer la suivante après un nouveau gate de sizing positif. Les frontières restent strictement séparées : numéro de release, prereleases, version, delta, validations et clôture stable.
Wallet est décalé à 0.2.5 et Wallet Desk à 0.2.6. Le premier getBalance reste volontairement dans 0.2.1, donc ce split ne retire pas la capacité réseau minimale dont Wallet Desk aura besoin.
8. Périmètre exact de la 0.2.1 réduite
0.2.1 doit clôturer :
- création de
ksp-onchain-transport-lib; - settings publics Transport et validation ;
- JSON-RPC 2.0 request/result/error envelopes ;
- registre exhaustif des 52 courantes + 14 historiques deprecated ;
- metadata méthode + forme de requête + runtime + retry class ;
- endpoint client HTTP async ;
- pool logique, rôles ouverts, capabilities/request kinds, priorité et fallback ;
- RPS/burst/concurrence/cooldown ;
- timeout et retry transport borné ;
- mapping vers
ksp_core_lib::Error; - observabilité via
ksp-logging-lib; - 4 méthodes typées canari ;
std.transport+ schema + exemple + adapter Config -> settings Transport ;- tests/fixtures/canaries/smoke opt-in ;
README.md/USAGE.md;- preuve que les familles restantes sont explicitement reportées, sans perdre l'inventaire.
9. Contrats publics Transport décidés
Les noms pourront être ajustés seulement si une contrainte Rust concrète apparaît, mais l'ownership et la sémantique sont fixés.
9.1 Settings principaux
pub struct HttpTransportSettings {
pub endpoints: Vec<HttpEndpointSettings>,
pub retry: HttpRetrySettings,
}
pub struct HttpEndpointSettings {
pub name: String,
pub enabled: bool,
pub provider: String,
pub cluster: String,
pub url: HttpEndpointUrl,
pub connect_timeout: Duration,
pub request_timeout: Duration,
pub max_idle_connections_per_host: Option<usize>,
pub roles: Vec<HttpEndpointRoleSettings>,
}
pub struct HttpEndpointRoleSettings {
pub role: HttpRoleName,
pub enabled: bool,
pub request_kinds: Vec<HttpRequestKind>,
pub priority: u32,
pub limits: HttpRoleLimits,
}
pub struct HttpRoleLimits {
pub requests_per_second: Option<NonZeroU32>,
pub burst_capacity: Option<NonZeroU32>,
pub max_concurrent_requests: Option<NonZeroU32>,
pub pause_after_rate_limit: Option<Duration>,
}
pub struct HttpRetrySettings {
pub max_retries: u32,
pub initial_backoff: Duration,
pub max_backoff: Duration,
}
Décisions :
- Transport utilise
Duration; Config traduit ses scalaires*_msvers ce contrat runtime ; provider,cluster,roleetrequest_kindrestent des descriptors ouverts/newtypes validés, pas des enums fermées ;*reste un wildcard valide pourrequest_kinds;- URL est encapsulée dans un type KSP avec
Debugredacted ;reqwest::Urln'est pas un type public du contrat ; - aucune lecture directe de l'environnement dans Transport ;
- aucun champ WS/gRPC anticipé.
9.2 Validation minimale
Refuser au minimum :
- nom endpoint vide/dupliqué ;
- URL non HTTP(S) ou invalide ;
- aucun endpoint activé ;
- rôle vide/dupliqué sur un endpoint ;
- request kind vide ;
- limites incohérentes (
burstsans RPS, zéro lorsque la valeur est présente, backoff max < initial, etc.) ; - timeout nul lorsque la sémantique exige une deadline positive.
Un endpoint enabled = false reste valide dans le document/snapshot mais n'est jamais candidat à la sélection.
10. Descriptor central des méthodes
Contrat conceptuel :
pub struct HttpRpcMethodDescriptor {
pub method: &'static str,
pub category: HttpRpcCategory,
pub request_kind: &'static str,
pub documentation_status: RpcDocumentationStatus,
pub runtime_status: RpcRuntimeStatus,
pub operation_kind: RpcOperationKind,
pub transport_retry_class: TransportRetryClass,
pub replacement: Option<&'static str>,
}
pub enum RpcDocumentationStatus {
Stable,
Deprecated,
Unstable,
}
pub enum RpcRuntimeStatus {
Supported,
Removed,
}
pub enum RpcRequestFormStatus {
Stable,
Deprecated,
}
pub enum RpcOperationKind {
Read,
Simulation,
WriteSubmission,
}
Le descripteur est la source unique pour :
- nom JSON-RPC ;
- routing/request kind ;
- statut documentaire ;
- statut runtime ;
- warning deprecated/unstable ;
- remplacement historique ;
- politique de retry transport ;
- canary de complétude.
Les warnings ne sont pas dispersés dans 52 méthodes.
11. JSON-RPC et API raw/générique
0.2.1 fournit les envelopes JSON-RPC 2.0 KSP :
request : jsonrpc, id, method, params
success : jsonrpc, id, result
failure : jsonrpc, id, error { code, message, data? }
Invariants :
jsonrpcdoit être exactement2.0;- l'
idde réponse doit correspondre à la requête ; resulteterrorsont mutuellement exclusifs ;- une réponse invalide devient
invalid_response/json_rpc_protocol, jamais un faux résultat ; - le
datad'une erreur RPC peut être préservé commeserde_json::Value, mais n'est pas loggué massivement par défaut.
Une API raw/générique peut exister pour l'extensibilité/provider interop. Elle ne remplace pas la surface typée normative et n'est pas une preuve de couverture des releases 0.2.2–0.2.4.
Pour la surface standard connue, l'exécuteur consulte le registry. Une méthode runtime = Removed est refusée comme méthode standard au lieu d'être envoyée en prétendant qu'elle est supportée.
12. Pool, rôles, capabilities et sélection
12.1 Unité de pool
Le pool sélectionne un endpoint/client HTTP logique. Le pooling de sockets/keep-alive reste la responsabilité du client reqwest sous-jacent.
12.1.1 Politique client concrétisée par pre.003
Chaque endpoint construit un reqwest::Client partageable qui conserve le pooling de sockets sous-jacent. Le builder KSP applique les connect_timeout, request_timeout et max_idle_connections_per_host déjà possédés par les settings.
Décisions de sécurité/déterminisme :
- backend HTTPS : feature
reqwest/rustlsexplicite ; - redirects automatiques désactivés : une URL provider éventuellement porteuse de credential n'est jamais redirigée implicitement vers une autre destination ;
- proxies système/environnement implicites désactivés via le builder
reqwest; une future prise en charge de proxy devra être un contrat Config/Transport explicite ; User-AgentKSP stable :ksp-onchain-transport-lib/<version>;- URL conservée uniquement dans les settings privés du client logique et absente des snapshots/
Debugpublics.
12.2 Algorithme de sélection
Pour une requête :
- déterminer le
request_kinddepuis le descriptor standard ou le caller raw ; - filtrer endpoints disabled ;
- filtrer rôles disabled ;
- filtrer rôle exact + capability (
request_kindou*) ; - exclure temporairement les candidats en cooldown/rate-limit ;
- ordonner par
prioritycroissante ; - round-robin équitable entre candidats du meilleur tier ;
- si capacité/concurrence indisponible, essayer les pairs puis le tier de priorité suivant ;
- si tous les candidats sont temporairement bloqués, attendre jusqu'au premier candidat admissible sans dépasser la deadline de requête ;
- si aucun endpoint ne peut satisfaire le rôle/méthode, retourner une erreur
endpoint_selectionstructurée.
12.3 Concurrence et rate limit
Chaque couple endpoint/rôle possède son état runtime :
- token bucket RPS/burst si configuré ;
- semaphore de concurrence si configuré ;
- cooldown après
429; - deadline commune de requête.
Aucune boucle active de health-check n'est ajoutée en 0.2.1. Le health est passif : succès/échecs récents, cooldown et état Enabled/Disabled/Available/Degraded/RateLimited dans des snapshots sûrs.
12.4 Thread-safety
Les clients/pools sont partageables entre tâches : Arc sur état commun, primitives Tokio pour concurrence asynchrone, atomics lorsque suffisants. Aucune mutex synchrone ne doit couvrir un await réseau.
13. Retry, backoff et timeout
13.1 Retry transport autorisé
Retry uniquement quand l'opération est classée retry-safe et qu'aucun résultat exploitable n'a été obtenu :
- erreur de connexion clairement retryable ;
- certaines erreurs HTTP provider temporaires ;
429avec cooldown/Retry-After;- timeout pour les opérations read/simulation retry-safe.
Backoff exponentiel borné :
initial_backoff <= computed_backoff <= max_backoff
attempts <= max_retries
Retry-After peut allonger la pause dans la borne décidée par le transport ; aucune attente non bornée.
13.2 Write/submission
sendTransaction et requestAirdrop sont classés WriteSubmission / NeverAfterDispatch.
Le transport KSP ne renvoie pas automatiquement une transaction sur timeout ou erreur ambiguë après dispatch. Le paramètre Solana sendTransaction.maxRetries appartient au comportement du nœud RPC et ne devient pas la politique de retry HTTP KSP.
simulateTransaction reste une simulation et peut être retry-safe au niveau transport.
13.3 Retry métier interdit
Aucune décision du type « RPC application error => refaire l'opération métier » n'est introduite dans Transport.
14. Stratégie d'erreurs
Les erreurs utilisent ksp_core_lib::Error et des constantes ErrorCode::new("onchain_transport", ...) dans la crate Transport.
Codes candidats à stabiliser dans pre.002 :
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
Chaque erreur ajoute uniquement du contexte sûr : endpoint name/provider/cluster, méthode, rôle, attempt, code HTTP/RPC. L'URL complète et tout secret sont exclus des contextes/logs.
15. Ownership des modèles de réponse
15.1 Principe
Transport représente le wire nécessaire à l'appel et à sa future persistence RAW. Il ne produit pas CORE, DECODE ou SPECIALIZED.
15.2 Primitives communes
Introduire des types transport seulement lorsqu'ils ajoutent un invariant wire utile. Les champs dynamiques/évolutifs peuvent rester serde_json::Value aux frontières appropriées plutôt que de forcer une dépendance SDK massive.
Décisions :
RpcResponse<T>pour les réponses contextuelles ;RpcContextavec slot/API version lorsque documenté ;TokenAmountconservantamount: String,decimals,uiAmount: Option<f64>,uiAmountString;Accounttransport préservant encoding/data sans décodage Program ;- signatures/hash/identités comme wire string/newtype KSP, sauf bénéfice clair à utiliser une primitive
ksp-core-libdéjà autorisée ; getTransaction/getBlock: top-level typé + payloads encoding-dependent lossless/flexibles ;- distinction stricte JSON
nullvs champ absent lorsque le contrat le nécessite.
15.3 Dépendances SDK
Ne pas introduire solana-client ni un SDK client haut niveau pour obtenir des DTOs. Une dépendance Solana additionnelle devra répondre à un besoin wire précis et respecter le firewall KSP.
16. Config standard Transport et adapter
16.1 Identifiants retenus
Selon les conventions de ksp-config-lib :
FILE_ID_STD_TRANSPORT = "cfg.std.transport"
FILE_ID_SCHEMA_STD_TRANSPORT = "schema.std.transport"
DEFAULT_STD_TRANSPORT_FILENAME = "std.transport.json"
DEFAULT_STD_TRANSPORT_SCHEMA_FILENAME = "std.transport.schema.json"
Fichiers :
config/std.transport.json
config/schemas/std.transport.schema.json
config/examples/std.transport.example.json
16.2 Forme candidate du document
{
"format_version": 1,
"default_profile": "devnet_public",
"retry": {
"max_retries": 2,
"initial_backoff_ms": 100,
"max_backoff_ms": 2000
},
"profiles": [
{
"profile_id": "devnet_public",
"http_endpoints": [
{
"name": "solana_devnet_public",
"enabled": true,
"provider": "solana-public",
"cluster": "devnet",
"url": "https://api.devnet.solana.com",
"connect_timeout_ms": 5000,
"request_timeout_ms": 15000,
"max_idle_connections_per_host": 8,
"roles": [
{
"role": "default",
"enabled": true,
"request_kinds": ["*"],
"priority": 100,
"limits": {
"requests_per_second": null,
"burst_capacity": null,
"max_concurrent_requests": 8,
"pause_after_rate_limit_ms": 1000
}
}
]
}
]
}
]
}
Le moteur Config existant résout profil + environnement. L'adapter transforme ensuite ce document effectif vers HttpTransportSettings et convertit les millisecondes en Duration.
16.3 Secrets/env
Transport ne lit jamais l'environnement.
Le schema autorise une URL résolue par le mécanisme de placeholders Config existant. La sensibilité KSP_SECRET_* doit être propagée/redacted dans l'adapter et les snapshots.
Aucune nouvelle variable .env.example n'est nécessaire en pre.001. Le profil standard peut utiliser l'URL publique Devnet sans secret. Une variable provider réellement consommée sera ajoutée dans la même tranche que son usage réel, pas par anticipation.
16.4 Config Desk
Aucune UI Transport dédiée. Le document reste éditable via le moteur générique Config Desk existant.
17. Dépendances externes candidates
Audit du 2026-08-17 :
reqwestcourant observé :0.13.4;tokiocourant observé :1.53.1, tandis que le workspace utilise déjà^1.53;serde/serde_jsonsont déjà des dépendances workspace^1.0;- bot3 utilisait également
base64etbs58, à différer jusqu'au premier besoin d'encoding explicite.
Décision concrétisée par pre.002 :
reqwest = ^0.13, default-features = false au workspace
serde.workspace = true
serde_json.workspace = true
ksp-core-lib path/workspace
ksp-logging-lib path/workspace
pre.002 utilisait reqwest uniquement pour le parsing/validation robuste de HttpEndpointUrl. pre.003 crée réellement les clients HTTP logiques et active donc localement la feature rustls de reqwest 0.13 dans ksp-onchain-transport-lib, tandis que le workspace conserve default-features = false sans feature d’usage globale. Aucune feature json n'est nécessaire : KSP possède déjà son encodage JSON-RPC via serde_json. Aucune dépendance Tokio directe n'est ajoutée tant que pre.004 n'utilise pas effectivement ses primitives de concurrence/attente.
Ne pas ajouter :
solana-client
tokio-tungstenite
gRPC stack
futures-util uniquement pour anticipation live
base64/bs58 avant besoin concret
tracing direct
Les commandes cargo tree sont obligatoires dans la tranche qui ajoute effectivement reqwest.
18. Logging et observabilité
Target KSP :
ksp-onchain-transport-lib
Ce target est possédé explicitement par src/constants.rs via pub(crate) const TRACING_TARGET: &str = "ksp-onchain-transport-lib"; les appels de logging utilisent crate::TRACING_TARGET conformément à DEP-LOG-010/011. env!("CARGO_PKG_NAME") reste réservé aux usages où l’identité Cargo est réellement la donnée recherchée, par exemple le User-Agent HTTP.
Événements :
- création client/pool ;
- sélection endpoint/rôle ;
- début/fin requête en debug/trace ;
- retry/attempt ;
- timeout ;
- 429/cooldown/backoff ;
- endpoint degraded/unavailable ;
- RPC application error ;
- forme deprecated/unstable utilisée ;
- snapshots de santé importants.
Interdits par défaut :
- URL complète si elle peut porter un token ;
- API key/provider token ;
- body massif ;
- transaction complète ;
- réponse complète.
Les erreurs reqwest utiles sont remappées/réémises via ksp-logging-lib; aucun target externe n'est activé globalement par Transport.
Pendant le développement actif jusqu'à pre.006, std.logging.json autorisait debug uniquement pour ksp-onchain-transport-lib et routait ces événements vers un fichier dédié. pre.007 applique KSP-APP-031 : le target et le sink dédié reviennent à info, avec le fichier transport/onchain/ksp-onchain-transport.log. La console et file.all.info restent également à info. Un développement/correctif futur peut relever temporairement uniquement ce target/sink via Config Desk conformément à DEP-LOG-012.
19. Architecture de tests
19.1 Unit tests
Sous unit_tests/ miroir de src/ :
- settings validation ;
- URL redaction ;
- endpoint/role/request-kind matching ;
- priority/fairness/fallback ;
- limiter RPS/burst ;
- max concurrent ;
- cooldown ;
- retry/backoff borné ;
- timeout ;
- JSON-RPC request/success/error/id mismatch ;
- RPC error mapping ;
- method/request-form status ;
- warning path deprecated/unstable ;
- aucune fuite de secret dans
Debug/snapshot.
19.2 Tests par méthode
Chaque méthode de la matrice obtient dans sa release assignée au minimum :
- sérialisation de request ;
- désérialisation du succès ;
- optional/null significatifs ;
- erreur significative ;
- configs/overloads pertinents.
Fixtures JSON déterministes, pas d'Internet pour les tests par défaut.
19.3 Smoke réseau opt-in
0.2.1 peut valider sur Devnet, de manière ignorée/opt-in :
getHealth
getVersion
getGenesisHash
getBalance
Le test obtient son endpoint depuis les mécanismes Config/fixtures de test ; Transport ne lit pas directement l'env.
19.4 Canaries architecturales
Automatiser autant que possible :
Transport -X-> Config
Transport -X-> Store
Transport -X-> Program
Transport -X-> tracing direct
registre current == 52 noms audités
registre deprecated historique == 14 noms audités
4 méthodes typed de 0.2.1 présentes
aucune méthode reportée déclarée typed-complete avant sa release
La canary de méthode utilise un inventaire statique versionné/audité ; elle ne scrape pas Internet pendant cargo test.
20. Hors périmètre confirmé de la 0.2.1 réduite
Explicitement reportés :
- les 48 méthodes courantes non canari selon la matrice
0.2.2–0.2.4; - WebSocket Solana ;
- LaserStream ;
- Yellowstone gRPC ;
- Wallet et Wallet Desk ;
- Store/RAW persistence ;
- Program/decoders/materializers ;
- execution policy et orchestration métier ;
- workers/jobs ;
- Tauri Transport dédiée ;
- off-chain/trading/ML.
Le report des 48 méthodes n'est pas une suppression de l'obligation exhaustive : elles restent listées nom par nom dans ce plan et réservées à des releases déjà numérotées.
21. Critères de clôture de la 0.2.1 réduite
La release peut devenir stable seulement si :
- crate
ksp-onchain-transport-libpropre ; - aucune dépendance vers Config/Store/Program/tracing direct ;
- settings publics et validation documentés ;
- JSON-RPC 2.0 et error mapping testés ;
- registry 52 current + 14 historical exact ;
- statuts centralisés et request-form deprecated supporté pour la foundation du mécanisme ;
- pool/priority/fallback/limites/concurrence/timeout/retry testés ;
- write retry policy inscrite dans les descriptors même si les méthodes write arrivent en
0.2.3; - snapshots/Debug ne révèlent pas les secrets ;
getBalance,getGenesisHash,getHealth,getVersionsont typés et testés ;- Config standard + schema + example + adapter fonctionnent dans le bon sens ;
- README/USAGE expliquent API raw vs typed et limites de couverture de
0.2.1; - tests ciblés/workspace et cargo tree passent sur le poste de développement ;
- prompt
0.2.2 — HTTP Accounts + Tokens + Clusterprêt dans la dernière prerelease ; - aucune méthode de la matrice n'est perdue du planning HTTP global.
22. Prévision souple des prereleases de la 0.2.1 réduite
| Tranche | Objectif |
|---|---|
pre.001 |
audit KSP + bot3 + docs officielles, matrice 52+14, architecture, split et sizing |
pre.002 |
réalisé : crate/workspace, codes erreur, settings/validation, JSON-RPC, descriptors/status, base Logging |
pre.003 |
réalisé : endpoint client + pool logique + rôles/capabilities + priorité/fairness/fallback + snapshots sûrs |
pre.004 |
réalisé : RPS/burst/concurrence/cooldown + deadline commune + retry/backoff + classification retry/no-resend |
pre.005 |
réalisé : exécution HTTP JSON-RPC + getHealth, getVersion, getGenesisHash, getBalance + fixtures déterministes + centralisation des canaries workspace dans Core |
pre.006 |
réalisé : std.transport schema/document/example + registry Config + adapter Config -> Transport + sensibilité/provenance/env tests |
pre.007 |
réalisé et validé : completeness/canaries, smoke opt-in, README/USAGE, docs finales, prompt 0.2.2, validations Cargo et cargo tree |
Ce découpage est révisable si une tranche dépasse le budget ; la release réduite, contrairement au scope initial, reste raisonnablement clôturable dans la session.
22.1 État après 0.2.1-pre.002
pre.002 matérialise la fondation sans ouvrir le client/pool de pre.003 :
- nouvelle crate
ksp-onchain-transport-lib, membre du workspace,workspace.package.version = 0.2.1-pre.2; - dépendances directes :
ksp-core-lib,ksp-logging-lib,serde,serde_json,reqwestsans features par défaut ; aucune dépendance Config/Store/Program/tracingdirecte ; - settings runtime publics : URL redacted, provider/cluster/role/request-kind ouverts, endpoints/rôles/limites/retry et validation structurelle ;
- douze codes d'erreur
onchain_transportréservés/stabilisés selon la stratégie du §14 ; - JSON-RPC HTTP KSP : request numérique KSP, sérialisation, parse success/error, validation
jsonrpc = 2.0, id exact et exclusivitéresult/error, avecnullrésultat préservé ; Debugdes requests/réponses n'expose pas les params, résultats ou payloads d'erreur distants par défaut ;- registre central exact de 52 méthodes current + 14 historiques, avec catégorie, request kind, statut documentaire/runtime, forme legacy, operation kind, retry class, remplacement et release de couverture ;
getTransactionetgetBlockportent explicitementStableWithDeprecatedLegacy;sendTransactionetrequestAirdropportentWriteSubmission / NeverAfterDispatch;- contrôle central
ensure_runtime_supported(): warning KSP pour surfaces non stables supportées, warning +method_removedpour les historiques supprimées ; - 40 tests Rust ajoutés (unitaires + intégration), dont redaction, invariants JSON-RPC, matrice 4/22/11/15 et canary de firewall du manifest.
Les éléments annoncés pour pre.003 dans cet état historique sont désormais concrétisés au §22.2 ; rate limiting, concurrence et retry effectif restent reportés.
22.2 État après 0.2.1-pre.003
pre.003 matérialise la première couche de routing HTTP sans encore exécuter de JSON-RPC :
workspace.package.version = 0.2.1-pre.3;reqwestrestedefault-features = falseet active uniquementrustlspour rendre les endpoints HTTPS réellement constructibles ;HttpEndpointClientencapsule unreqwest::Client, applique connect/request timeout et limite idle-per-host, désactive redirect et proxy système implicites, et n'expose jamais l'URL dansDebug/snapshot ;HttpEndpointSnapshot,HttpEndpointRoleSnapshotetHttpTransportPoolSnapshotexposent uniquement identité/provider/cluster/routing/status sûrs ;HttpTransportPoolvalide les settings puis construit un client logique par endpoint ;- sélection exacte rôle + capability, wildcard
*, priorité globale croissante et round-robin par rôle/request-kind dans le meilleur tier ; - endpoint ou rôle disabled exclus ; un tier inférieur devient donc fallback lorsqu'aucun candidat du tier supérieur n'est sélectionnable ;
select_for_methoddérive la capability depuis le registre RPC central et refuse une méthode historiqueRemovedavant routing ;- aucune mutex synchrone ne couvre un
awaitréseau : le seul verrou actuel protège brièvement les curseurs de fairness, avant toute I/O ; - le contrat d'availability réserve
Disabled,Available,Degraded,RateLimited;pre.003ne produit que les deux premiers, les transitions runtime appartenant àpre.004. - la suite Transport compte désormais 53 tests déclarés, dont les nouvelles preuves de redaction client/pool, priorité, fairness, fallback, capability et contrat public du pool.
Restent volontairement à pre.004 : token bucket RPS/burst, semaphore de concurrence, cooldown/429, deadline effective, retry/backoff et mutations passives Degraded/RateLimited.
22.3 État après 0.2.1-pre.004
pre.004 matérialise la résilience runtime du pool sans encore exécuter les quatre méthodes JSON-RPC canari :
workspace.package.version = 0.2.1-pre.4;- limiteur token-bucket par couple endpoint/rôle avec RPS et burst ; lorsque RPS est configuré sans burst explicite, la capacité initiale dérive d'une seconde de RPS ;
- semaphore Tokio par rôle pour
max_concurrent_requests, avec permit détenu pendant la durée de l'admission/exécution et notification des waiters à la libération ; - cooldown par rôle après rate-limit provider, utilisant la valeur configurée ou un fallback runtime borné ; un
Retry-Afterdéjà résolu en durée peut prolonger ce cooldown dans une borne défensive ; - sélection runtime par priorité puis round-robin, avec tentative des pairs et tiers inférieurs lorsqu'un candidat est temporairement bloqué par RPS, cooldown ou concurrence ;
- si tous les candidats sont temporairement bloqués, attente du premier signal/candidat admissible sans dépasser une deadline commune ; par défaut, cette deadline utilise le plus petit
request_timeoutdes endpoints structurellement compatibles ; - snapshots sûrs enrichis avec availability de rôle, limites, requêtes en vol, cooldown restant et compteurs success/failure/rate-limit, sans URL ni secret ;
- transitions passives
Available -> Degraded/RateLimitedsur observations runtime et retourDegraded -> Availableaprès succès ; - policy centralisée
evaluate_transport_retry(): backoff exponentiel borné, budgetmax_retries, causes transport explicitement retryables, RPC application errors hors retry, et respect strict deTransportRetryClass::NeverAfterDispatchpour empêcher un resend automatique après dispatch ambigu ; - après
pre.004-fix.001/.002, les features d’usage sont activées localement par crate : Transport portereqwest/rustls,serde/derive,tokio/macros+sync+timeettokio/rtseulement en dev ; le root conserve version/default-features sans activation de features d’usage ; - la suite Transport compte désormais 72 tests déclarés, avec preuves supplémentaires sur limiter, concurrence, cooldown, deadline, fallback runtime, santé passive, policy de retry et consommation publique de l'admission async.
La tranche ne parse pas encore elle-même le header HTTP Retry-After et n'exécute pas de POST JSON-RPC : ces signaux seront raccordés à l'exécuteur HTTP avec les méthodes canari de pre.005.
Restent à pre.005 : exécution HTTP JSON-RPC réelle et wrappers typés getHealth, getVersion, getGenesisHash, getBalance, avec fixtures déterministes et raccordement des erreurs HTTP/429/timeout à la résilience maintenant disponible.
22.4 État après 0.2.1-pre.005
pre.005 matérialise la première exécution réseau HTTP complète et les quatre canaris typés de la release :
workspace.package.version = 0.2.1-pre.5;- exécuteur générique
execute_standard_rpc: allocation d'id JSON-RPC KSP, admission via pool, POSTapplication/json, deadline commune, mapping connexion/timeout/status HTTP, parsing JSON-RPC et mise à jour de santé passive ; - HTTP
429raccordé au cooldown de rôle et à la policy de retry avec parsing défensif deRetry-Aftersous forme delta-seconds ; statuts temporaires408/500/502/503/504raccordés au retry borné ; - les retries réacquièrent capacité RPS/concurrence et restent bornés par la même deadline ; la classification
NeverAfterDispatchreste centralisée pour empêcher les futurs write/submission de se resoumettre après ambiguïté ; - wrappers typés
getHealth,getGenesisHash,getVersion,getBalance, avecksp_core_lib::Pubkey, commitment/minContextSlot optionnels, DTO de contexte/balance/version et validation de forme ; - fixtures JSON déterministes et serveur HTTP local de tests : les canaris prouvent le POST réel et les formes request/response ; tests supplémentaires sur récupération après 429 et timeout reqwest ;
- les deux canaries de dépendances générales quittent
ksp-onchain-transport-lib/tests/dependency_boundary.rset sont centralisées sousksp-core-lib/tests/workspace_dependencies.rs, conformément àDEP-CARGO-007; - Transport compte désormais 78 tests déclarés ; Core porte 2 canaries workspace supplémentaires dans sa surface d'intégration.
pre.005-fix.001 normalise ensuite le contrat de target KSP : Transport et Config possèdent désormais leur TRACING_TARGET principal dans src/constants.rs, les targets comportementaux ne dépendent plus de env!("CARGO_PKG_NAME") ni de littéraux dispersés, et une canarie workspace Core protège cette convention. L’usage Cargo de CARGO_PKG_NAME pour le User-Agent Transport reste volontaire et autorisé.
Restent à pre.006 : document/schema/exemple std.transport, enregistrement Config, adapter Config -> Transport et tests de sensibilité/provenance/env.
22.5 État après 0.2.1-pre.006
pre.006 matérialise la frontière de configuration standard du Transport sans créer de dépendance inverse :
workspace.package.version = 0.2.1-pre.6;config/std.transport.jsonetconfig/schemas/std.transport.schema.jsondeviennent des ressources Config gérées, aveccfg.std.transport/schema.std.transportdans le registry ;- le document standard possède
retryen global et desendpointspar profil ;devnet_publicest le profil autonome par défaut etmainnet_publicreste sélectionnable explicitement ; config/examples/std.transport.example.jsonillustre un pool mixte public/privé, y compris une URL complète provenant d’unKSP_SECRET_*;.env.exampleinventorie les deux overrides publics standard et l’override secret d’exemple sans committer de credential réel ;ksp-config-libdépend désormais deksp-onchain-transport-libdans la direction autorisée Config -> Transport, tandis que le firewall Transport -> Config reste inchangé ;ConfigDocumentEngine::load_resolved_transport_configsélectionne le profil, résout l’environnement, convertit les scalaires*_msenDuration, construit les rôles/limites/endpoints puis délègue la validation finale àHttpTransportSettings::validate();ResolvedTransportConfigconserve le profil, la provenance détaillée et la projection safe, et expose les settings runtime réels ; sonDebugn’expose pas les URLs secrètes ;- les tests couvrent le document committé, les origines global/profile, la precedence process >
.env, la provenance JSON Pointer, la redactionKSP_SECRET_*et l’échec d’une URL secrète invalide sans fuite de canary ; DEP-TRANSPORT-005explicite maintenant que Config peut dépendre des crates Transport pour posséder les adapters, jamais l’inverse.
pre.006-fix.002, déclenché par l’audit complet du workspace avant clôture, corrige une fuite diagnostique potentielle : les reqwest::Error attachées à ksp_core_lib::Error sont désormais neutralisées par without_url() avant with_source, avec une canarie timeout portant un secret dans la query de l’endpoint. Le même audit remet aussi en conformité les fins de ligne des fichiers courants concernés par GEN-FILE-005 et corrige le rustdoc Transport devenu obsolète après l’introduction de l’adapter Config -> Transport. Les écarts purement documentaires sans impact code/config restent volontairement réservés à pre.007.
22.6 État candidat après 0.2.1-pre.007
pre.007 ferme le périmètre de développement de la foundation sans ajouter de méthode HTTP typed au-delà des quatre canaris :
workspace.package.version = 0.2.1-pre.7;- revérification officielle du 2026-08-17 : l’index Solana HTTP courant expose toujours 52 méthodes et la navigation Deprecated conserve les 14 noms historiques audités ;
- deux canaries d’intégration publiques figent la partition
52 current / 14 historical / 4-22-11-15et le set exact des quatre canaris0.2.1; - la candidate déclare 80 tests Transport et 114 tests Config, dont un unique smoke Devnet Config
ignored; - un smoke Devnet
ignoredsousksp-config-libvalide de manière opt-in la chaîne Config ->devnet_public-> Transport ->getHealth/getGenesisHash/getVersion/getBalance, sans lecture d’environnement dans Transport ; ce placement est une exception transitoire et non un modèle pour les futurs smokesConfig + autre crate; ksp-onchain-transport-lib/README.mdetUSAGE.mddocumentent frontières, API raw vs typed, résilience, sécurité, Config et utilisation ;docs/validation/003-V0_2_1_ONCHAIN_HTTP.mddevient la matrice durable de clôture ;- le niveau de référence du sink Transport dédié revient de
debugàinfoavant stable ; - les écarts documentaires résiduels issus de l’audit complet sont normalisés : convention
bindings/gen, README Config et inventaire composant HTTP ; prompts/007-V0_2_2_START_PROMPT.mdprépare0.2.2 — HTTP Accounts + Tokens + Clusteravec un nouvel audit officiel et gate de sizing ;CHANGELOG.mdest mis à jour dansrel.001avec la synthèse stable0.2.1.
Les validations Cargo, cargo tree et le smoke Devnet opt-in de cette candidate ont été exécutés avec succès sur le dépôt canonique. rel.001 reste strictement publicationnel : version stable, statuts ROADMAP/plan/validation, entrée CHANGELOG et delta de release. Le commit v0.2.1-rel.001 doit être validé avant création du tag stable v0.2.1.
22.7 Clôture stable 0.2.1-rel.001
La publication stable est autorisée par les preuves opérateur du 2026-08-17 : cargo fmt --all, cargo check --workspace, cargo clippy --workspace --all-targets, tests ciblés Transport/Config/Core/Config Desk, cargo test --workspace, graphes cargo tree Transport et Config, puis smoke Devnet explicite. Le smoke live a atteint les quatre canaris avec le profil devnet_public.
TODO architectural conservé pour la suite : ksp-config-lib ne doit jamais devenir la destination générale des smoke tests cross-crates. Le test actuel Config -> Transport -> Devnet reste temporairement sous Config uniquement parce qu'aucune crate/surface d'intégration ou d'orchestration n'existe encore ; il devra migrer dès qu'une telle surface sera disponible, et les futurs smokes Config + autre crate devront viser cette surface dédiée.
23. Séquence 0.2.x recalibrée
0.2.1 HTTP transport foundation + 4 canaris
0.2.2 HTTP Accounts + Tokens + Cluster
0.2.3 HTTP Transactions
0.2.4 HTTP Blocks + Economics + compliance HTTP finale
0.2.5 wallet foundation (.kspwallet)
0.2.6 Wallet Desk
0.2.7 standard Solana WebSocket
0.2.8 Helius LaserStream WebSocket
0.2.9 Yellowstone gRPC standard foundation
0.2.10 off-chain price transport
0.2.11 price visualization desk
0.2.12 interface/wire foundation
0.2.13 program-api foundation
Le découpage 0.2.2–0.2.4 est un maximum nominal de trois sessions. Une session peut clôturer plusieurs releases successives si, après la clôture complète de chacune, le sizing de la suivante reste positif. Cette optimisation de session ne fusionne jamais les releases elles-mêmes.
Chaque release HTTP 0.2.2–0.2.4 commence par une revérification officielle temporelle de sa famille et de l'index global. Si Solana ajoute/supprime/change une méthode entre-temps, la matrice est mise à jour explicitement plutôt que de conserver aveuglément l'état du 2026-08-17.
24. Gate de sizing — réponse obligatoire
Question :
La release 0.2.1 peut-elle raisonnablement être entièrement clôturée dans cette session de chat
avec des prereleases de ~15–20 minutes ?
Réponse pour le périmètre du prompt 006 :
NON.
Motif : 52 méthodes typed + 14 deprecated historiques + toute la foundation/résilience/Config/tests/docs constituent plusieurs releases cohérentes et non une seule release de session.
Réponse après split, pour la 0.2.1 réduite définie par ce plan :
OUI, raisonnablement.
La grosse implémentation ne doit commencer qu'à pre.002, sur ce périmètre réduit.
25. Validations de pre.001
Exécutées dans le sandbox :
- lecture des sources internes obligatoires ;
- inspection des manifests et contrats publics KSP ;
- audit ciblé de l'archive bot3 et de
ks-onchain-transport/Config historique ; - comparaison locale automatisée des 52 noms bot3 avec les 52 noms de l'index officiel audité : aucun manque/extra ;
- consultation des sources officielles Solana/JSON-RPC/Agave ;
- audit des versions candidates
reqwest/tokiodepuis leurs registres officiels ; - vérification de l'absence de
.gitdans l'archive KSP.
Non exécutées :
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
cargo tree ...
Le binaire cargo n'est pas disponible dans ce sandbox (cargo: command not found). Aucune réussite Cargo n'est donc déclarée. Aucune dépendance ni source Rust n'étant ajoutée dans pre.001, les cargo tree seront particulièrement utiles à pre.002, après ajout réel de reqwest.