# Delta `0.2.2-pre.002` — primitives RPC Accounts/Tokens/Cluster et wire commun ## Base requise Livraison précédente corrigée : ```text 0.2.2-pre.001-fix.001 workspace.package.version = "0.2.2-pre.1" ``` Le plan canonique attendu est `docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md` version 3, qui inclut le réaudit Agave `v4.2.1`. ## Objectif Installer les primitives/configurations/résultats partagés nécessaires aux 22 wrappers `0.2.2`, sans encore implémenter les cinq wrappers Accounts prévus pour `pre.003`. La tranche mutualise les contrats nés avec les canaris `0.2.1`, fixe les formes wire Account/Token/Cluster et ajoute des fixtures déterministes pour les variantes nullable/versionnées identifiées pendant `pre.001` et son fix. ## Version Cargo Conformément à `VER-ID-009`, la nouvelle prerelease synchronise le signal technique : ```text 0.2.2-pre.1 -> 0.2.2-pre.2 ``` Aucune dépendance ou feature Cargo n'est ajoutée. ## Implémentation ### RPC commun Un nouveau module commun possède désormais : ```text SolanaCommitment SolanaCommitmentConfig SolanaContextConfig SolanaRpcContext SolanaRpcResponse ``` `SolanaCommitment` et `SolanaRpcContext` ont été déplacés hors du module canari sans casser leurs réexports crate-root. `GetBalanceConfig` conserve son nom, ses champs internes, son constructeur, ses getters et sa forme `Debug` `0.2.1`; seule sa sérialisation réutilise désormais `SolanaContextConfig`. Les helpers internes de décodage : - convertissent les erreurs serde vers `ERROR_CODE_INVALID_RESPONSE` ; - convertissent explicitement les chaînes de public key vers `ksp_core_lib::Pubkey` ; - n'incluent pas la valeur de public key invalide dans les diagnostics. ### Accounts Les primitives suivantes sont ajoutées : ```text SolanaAccountEncoding SolanaDataSliceConfig SolanaAccountInfoConfig SolanaLargestAccountsFilter SolanaLargestAccountsConfig SolanaMemcmpBytes SolanaMemcmpFilter SolanaProgramAccountFilter SolanaProgramAccountsConfig SolanaParsedAccountData SolanaAccountData SolanaAccount SolanaKeyedAccount SolanaAccountBalance SolanaProgramAccountsResult ``` `SolanaAccountData` préserve les trois familles de wire : chaîne legacy, tuple encodé et `jsonParsed`. Le contenu `parsed` reste un `serde_json::Value`; aucun décodage Program/SPL n'entre dans Transport. `space` reste `Option`. `SolanaProgramAccountFilter` conserve `dataSize`, `memcmp` et `tokenAccountState`. Les bytes `memcmp` peuvent rester base58/base64 textuels ou raw sans ajouter `bs58`/`base64`; les limites de cardinalité et de taille seront appliquées par les wrappers/validation `pre.003` conformément au plan. ### Tokens Les primitives suivantes sont ajoutées : ```text SolanaTokenAccountSelector SolanaTokenAmount SolanaTokenAccountBalance ``` Le selector est un enum `Mint | ProgramId`, ce qui interdit par construction un objet contenant simultanément les deux clés. `uiAmount` reste `Option` et `amount`/`uiAmountString` restent des chaînes exactes du wire. ### Cluster Les DTOs/configs partagés suivants sont ajoutés : ```text SolanaClusterNode SolanaEpochInfo SolanaEpochSchedule SolanaSnapshotSlotInfo SolanaLeaderScheduleConfig SolanaLeaderScheduleRequest SolanaLeaderSchedule SolanaVoteAccountsConfig SolanaEpochCredits SolanaVoteAccountInfo SolanaVoteAccountStatus ``` Le DTO node conserve tous les endpoints comme chaînes optionnelles et inclut `clientId: Option` confirmé dans Agave `v4.2.1`. `SolanaVoteAccountInfo` inclut `inflationRewardsCommissionBps: Option` sans le dériver de `commission`, ainsi que les triples epoch credits sous un petit DTO nommé. `SolanaLeaderScheduleRequest` encode explicitement les overloads current-epoch/config et slot/config. ## Fixtures déterministes ajoutées ```text crates/ksp-onchain-transport-lib/fixtures/http/account_data.variants.json crates/ksp-onchain-transport-lib/fixtures/http/token_amount.null_ui.json crates/ksp-onchain-transport-lib/fixtures/http/cluster_node.v4_2_1.json crates/ksp-onchain-transport-lib/fixtures/http/vote_account.v4_2_1.json ``` Elles couvrent notamment legacy/encoded/jsonParsed Account data, `space: null`, `uiAmount: null`, `clientId`, champs Cluster absents et présence de `inflationRewardsCommissionBps`. Un test supplémentaire vérifie l'absence de ce dernier champ pour une forme de noeud plus ancienne. ## Fichiers ajoutés ```text crates/ksp-onchain-transport-lib/src/rpc_common.rs crates/ksp-onchain-transport-lib/src/rpc_accounts.rs crates/ksp-onchain-transport-lib/src/rpc_tokens.rs crates/ksp-onchain-transport-lib/src/rpc_cluster.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_common.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_accounts.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_tokens.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_cluster.rs crates/ksp-onchain-transport-lib/fixtures/http/account_data.variants.json crates/ksp-onchain-transport-lib/fixtures/http/token_amount.null_ui.json crates/ksp-onchain-transport-lib/fixtures/http/cluster_node.v4_2_1.json crates/ksp-onchain-transport-lib/fixtures/http/vote_account.v4_2_1.json deltas/0.2.2/pre.002.md ``` ## Fichiers modifiés ```text Cargo.toml crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/rpc_canary.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_canary.rs crates/ksp-onchain-transport-lib/tests/public_api.rs ``` ## Fichiers supprimés Aucun. ## Fichiers volontairement inchangés ```text CHANGELOG.md ROADMAP.md docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md crates/ksp-onchain-transport-lib/Cargo.toml crates/ksp-onchain-transport-lib/src/executor.rs crates/ksp-onchain-transport-lib/src/rpc_method.rs crates/ksp-config-lib/** config/** ``` Le plan ne change pas : `pre.003` reste consacré aux cinq wrappers Accounts. ## Validations exécutées - reconstruction locale de l'état `v0.2.1 + pre.001 + pre.001-fix.001` à partir des archives fournies ; - relecture de `RULES_RUST.md`, `FILE_CONTRACTS.md`, `VERSION_WORKFLOW.md` et du plan `009` version 3 ; - recoupement des structures account/token Agave `v4.2.1` (`UiAccount`, `UiAccountData`, `UiAccountEncoding`, `UiTokenAmount`) ; - recoupement des extensions Cluster/Vote Agave `v4.2.1` (`client_id`, `inflation_rewards_commission_bps`) ; - contrôle statique des réexports crate-root et de l'absence de nouvelle dépendance Cargo ; - contrôle statique de l'absence de wrapper `0.2.2` ajouté prématurément dans cette tranche ; - contrôle des fixtures JSON avec un parseur JSON local ; - contrôle du contenu de l'archive d'échange après génération. ## Validations non exécutées Le sandbox ne fournit pas `cargo` ni `rustfmt`. Les commandes suivantes n'ont donc pas été déclarées comme réussies et doivent être exécutées sur le checkout de développement avant commit : ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib ``` Conformément à `RUST-*`, `cargo test --workspace` reste requis au point de contrôle de session/clôture approprié. Aucun `cargo tree` supplémentaire n'est requis par ce delta, puisqu'aucune dépendance ni feature n'a changé. ## Décisions prises - conserver les quatre canaris `0.2.1` et leurs noms publics ; - centraliser les primitives réellement communes plutôt que créer un mega DTO ; - utiliser `ksp_core_lib::Pubkey` dans les DTOs publics, avec conversion wire explicite ; - ne pas activer `serde` sur `solana-pubkey` uniquement pour les réponses RPC ; - ne pas ajouter `base64`, `bs58`, SPL ou client RPC haut niveau ; - conserver les champs provider/versionnés optionnels au lieu de les rendre obligatoires ; - ne pas ajouter de logs par DTO : l'observabilité reste au niveau du transport/executor. ## Questions ouvertes Aucune question bloquante pour `pre.003`. Le formatage final exact doit être produit par le `rustfmt` canonique du dépôt lors de l'application locale, puisque le binaire n'est pas disponible dans le sandbox d'échange. ## Suite `0.2.2-pre.003` : implémenter les cinq wrappers Accounts (`getAccountInfo`, `getLargestAccounts`, `getMinimumBalanceForRentExemption`, `getMultipleAccounts`, `getProgramAccounts`) avec validation de cardinalité/filtres, décodage via les DTOs de cette tranche, serveur HTTP local et fixtures déterministes.