11 KiB
Delta 0.2.2-pre.004 — cinq wrappers HTTP Tokens typés
Base requise
Livraison précédente corrigée et validée localement par l'opérateur :
0.2.2-pre.003-fix.001
workspace.package.version = "0.2.2-pre.3.fix.1"
La validation opérateur du 2026-08-18 a confirmé :
cargo fmt --all OK
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test -p ksp-onchain-transport-lib OK
Résultats Transport de cette base :
98 unit tests
10 public API tests
3 release completeness tests
0 warning signalé par check/clippy
Le plan canonique reste docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md version 3.
Objectif
Clôturer la famille Tokens attribuée à 0.2.2 avec cinq wrappers publics typés :
getTokenAccountBalance
getTokenAccountsByDelegate
getTokenAccountsByOwner
getTokenLargestAccounts
getTokenSupply
Tous passent par la foundation HTTP commune :
wrapper typé
-> descriptor audité
-> execute_standard_rpc
-> pool/admission/retry/deadline
-> reqwest HTTP
-> JSON-RPC validation
-> décodage DTO KSP
Aucun wrapper Token ne contacte reqwest directement et aucune crate SPL n'est ajoutée.
Version Cargo
Conformément à VER-ID-009 :
0.2.2-pre.3.fix.1 -> 0.2.2-pre.4
Aucune dépendance ni feature Cargo n'est ajoutée ou retirée.
Réaudit ciblé du contrat courant
Les pages RPC Solana courantes ont été revérifiées le 2026-08-18 pour cette tranche :
https://solana.com/docs/rpc/http/gettokenaccountbalance
https://solana.com/docs/rpc/http/gettokenaccountsbydelegate
https://solana.com/docs/rpc/http/gettokenaccountsbyowner
https://solana.com/docs/rpc/http/gettokenlargestaccounts
https://solana.com/docs/rpc/http/gettokensupply
Le contrat reste cohérent avec le plan 009 :
getTokenAccountBalance,getTokenLargestAccountsetgetTokenSupplyacceptent uncommitmentoptionnel ;getTokenAccountsByDelegateetgetTokenAccountsByOwnerprennent un selector exclusif{mint}ou{programId}puis une config Account optionnelle ;- les cinq réponses sont contextualisées ;
- les deux méthodes de liste renvoient des
pubkey + accountet réutilisent donc le DTO Account générique ; TokenAmount.uiAmountreste nullable ;uiAmountStringreste la représentation textuelle à préserver ;getTokenLargestAccountsrenvoie les 20 plus gros token accounts côté RPC, sans que KSP invente un tri supplémentaire.
Le réaudit complémentaire Agave v4.2.1 déjà fixé en pre.001-fix.001 reste la référence d'implémentation ciblée ; aucune divergence
nouvelle nécessitant un changement de DTO n'a été identifiée pour cette tranche.
Surface typée Tokens
getTokenAccountBalance
Signature publique conceptuelle :
role + token account Pubkey + Option<SolanaCommitmentConfig>
-> SolanaRpcResponse<SolanaTokenAmount>
Le wrapper préserve amount, decimals, uiAmount nullable et uiAmountString, et conserve une erreur JSON-RPC distante comme erreur
applicative RPC.
getTokenAccountsByDelegate
Signature publique conceptuelle :
role + delegate Pubkey + SolanaTokenAccountSelector + Option<SolanaAccountInfoConfig>
-> SolanaRpcResponse<Vec<SolanaKeyedAccount>>
Le selector KSP empêche par construction les objets contenant simultanément mint et programId. La config Account réutilise les encodings,
dataSlice, commitment et minContextSlot activés en pre.003.
getTokenAccountsByOwner
Signature publique conceptuelle :
role + owner Pubkey + SolanaTokenAccountSelector + Option<SolanaAccountInfoConfig>
-> SolanaRpcResponse<Vec<SolanaKeyedAccount>>
Le wrapper partage le même chemin privé de sérialisation/décodage que la variante Delegate afin d'éviter deux implémentations de wire parallèles.
Un config Account explicitement vide est omis du tableau params.
getTokenLargestAccounts
Signature publique conceptuelle :
role + mint Pubkey + Option<SolanaCommitmentConfig>
-> SolanaRpcResponse<Vec<SolanaTokenAccountBalance>>
L'ordre retourné par le serveur est conservé. Chaque address est validée et convertie en ksp_core_lib::Pubkey sans recopier une valeur wire
invalide dans le diagnostic.
getTokenSupply
Signature publique conceptuelle :
role + mint Pubkey + Option<SolanaCommitmentConfig>
-> SolanaRpcResponse<SolanaTokenAmount>
amount reste une chaîne exacte et KSP ne convertit pas la supply en type métier SPL ni en entier borné localement.
Mutualisation activée en production
Les helpers Token préparés en pre.002 deviennent production-live uniquement parce qu'ils ont maintenant des consommateurs runtime réels :
- sérialisation de
SolanaTokenAccountSelector; - décodage
SolanaTokenAmount; - décodage
SolanaTokenAccountBalance; - wire structs Token privés.
SolanaAccountInfoConfig::is_empty devient pub(crate) pour permettre aux deux wrappers de liste Token de réutiliser la règle d'omission de
config vide déjà utilisée par Accounts. Cette modification reste interne à la crate et n'élargit pas l'API publique externe.
Les helpers Cluster préparatoires restent inchangés et ne deviennent pas production-live avant pre.005/pre.006.
Validation locale des paramètres
Aucun nouveau code d'erreur local n'est nécessaire dans cette tranche :
- le selector
Mint | ProgramIdgarantit exactement une variante par construction ; - les owner/delegate/mint/token-account sont des
Pubkeytypées avant l'appel ; - les configs Account/Commitment réutilisent les types déjà validés ;
- aucune cardinalité supplémentaire documentée ne doit être imposée côté client.
ERROR_CODE_INVALID_RPC_PARAMETERS introduit en pre.003 reste inchangé.
Fixtures HTTP déterministes ajoutées
crates/ksp-onchain-transport-lib/fixtures/http/get_token_account_balance.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_account_balance.error.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_accounts_by_delegate.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_accounts_by_owner.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_accounts_by_owner.invalid_pubkey.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_largest_accounts.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_largest_accounts.invalid_address.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_supply.success.json
Les tests utilisent un serveur HTTP loopback et n'accèdent pas à Internet.
Couverture de tests ajoutée
Les tests Token couvrent notamment :
- request exacte de chacune des cinq méthodes ;
- selector
programIdpour Delegate ; - selector
mintpour Owner ; - config Account complète et omission d'un config explicitement vide ;
- commitment optionnel ;
uiAmount: null;- montant/supply textuel exact ;
- conservation de l'ordre pour
getTokenLargestAccounts; - décodage
jsonParseddes accounts sous forme JSON opaque Transport ; - erreur JSON-RPC applicative ;
- rejet d'une
pubkeyouaddressinvalide dans une réponse typée.
Le test public compile explicitement les cinq méthodes depuis HttpTransportPool.
Un canari release fige l'ensemble Tokens 0.2.2 exact :
getTokenAccountBalance
getTokenAccountsByDelegate
getTokenAccountsByOwner
getTokenLargestAccounts
getTokenSupply
Il vérifie également Read + RetrySafe pour chacun. Les 12 wrappers Cluster restent hors de cette tranche.
Après application, la cible Transport attendue devient :
106 unit tests
11 public API tests
4 release completeness tests
Fichiers ajoutés
crates/ksp-onchain-transport-lib/fixtures/http/get_token_account_balance.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_account_balance.error.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_accounts_by_delegate.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_accounts_by_owner.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_accounts_by_owner.invalid_pubkey.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_largest_accounts.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_largest_accounts.invalid_address.json
crates/ksp-onchain-transport-lib/fixtures/http/get_token_supply.success.json
deltas/0.2.2/pre.004.md
Fichiers modifiés
Cargo.toml
crates/ksp-onchain-transport-lib/src/lib.rs
crates/ksp-onchain-transport-lib/src/rpc_accounts.rs
crates/ksp-onchain-transport-lib/src/rpc_tokens.rs
crates/ksp-onchain-transport-lib/unit_tests/rpc_tokens.rs
crates/ksp-onchain-transport-lib/tests/public_api.rs
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
Fichiers supprimés
Aucun.
Fichiers volontairement inchangés
deltas/0.2.2/pre.003.md
deltas/0.2.2/pre.003-fix.001.md
docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md
ROADMAP.md
CHANGELOG.md
crates/ksp-onchain-transport-lib/src/rpc_common.rs
crates/ksp-onchain-transport-lib/src/rpc_cluster.rs
crates/ksp-onchain-transport-lib/src/rpc_method.rs
crates/ksp-config-lib/**
config/**
Les deltas déjà publiés restent des traces historiques et ne sont pas réécrits.
Contrôles statiques effectués pendant la préparation
workspace.package.versionvaut0.2.2-pre.4;- les huit nouvelles fixtures JSON sont syntaxiquement valides ;
- les cinq wrappers utilisent
execute_standard_rpc; - aucun
reqwestdirect n'est ajouté dansrpc_tokens.rs; - aucun
#[allow(dead_code)]ou suppression de lint n'est ajouté ; - aucun helper Cluster n'est activé en production ;
- aucune dépendance ou feature Cargo n'est ajoutée ;
- aucune crate SPL n'est importée ;
- la surface publique Accounts de
pre.003reste présente ; - les deltas historiques restent inchangés.
Validations Rust non exécutées dans le sandbox
Le sandbox de préparation ne fournit pas la toolchain Cargo utilisée par le checkout opérateur. Les commandes suivantes doivent donc être rejouées après application :
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
Les validations ne sont pas déclarées réussies tant qu'elles n'ont pas été exécutées sur le checkout opérateur.
Questions ouvertes
Aucune question bloquante.
Suite
Après validation et commit de 0.2.2-pre.004, poursuivre avec 0.2.2-pre.005 pour les sept wrappers Cluster simples :
getClusterNodes
getEpochInfo
getEpochSchedule
getHighestSnapshotSlot
getIdentity
getMaxRetransmitSlot
getMaxShredInsertSlot