# Delta `0.2.6-pre.007` — identité autorisée + balance HTTP ## Base requise ```text 0.2.6-pre.006-fix.001 appliquée workspace.package.version = 0.2.6-pre.6.fix.1 ``` Le checkpoint opérateur de `pre.006-fix.001` est entièrement vert : formatage, audit structurel, `cargo check`, Clippy, tests Wallet Desk, workspace complet et `cargo tauri dev`. Les quatre chemins d'unlock VIEW/OWNER manuel/configuré ont été vérifiés en runtime. ## Type de livraison ```text ksp-general-0.2.6-pre.007.zip ``` Cette tranche modifie Config, le runtime Wallet Desk et le frontend. Le signal technique devient : ```text workspace.package.version = 0.2.6-pre.7 commit = v0.2.6-pre.007 ``` Aucun tag stable. ## Objet Fermer le MVP obligatoire de Wallet Desk en composant réellement : ```text Config composite -> Wallet VIEW/OWNER autorisé -> Pubkey Rust-only comme source RPC -> HttpTransportPool -> getBalance -> balance sûre frontend ``` Aucun nouveau wrapper HTTP n'est ajouté : `ksp-onchain-transport-lib::HttpTransportPool::get_balance` est réutilisé directement. ## Config -> Transport avec provenance composite `ksp-config-lib` ajoute : ```text ConfigDocumentEngine::resolve_transport_config_profile ``` Cette API est l'équivalent Transport des adapters déjà disponibles pour Logging et Wallet. Elle accepte un `ResolvedConfigProfile` sélectionné par composite, impose `cfg.std.transport`, valide le descriptor et conserve : ```text selection_source = Composite ``` Wallet Desk ne recharge donc pas `devnet_public` comme une sélection explicite indépendante du composite. ## Runtime Transport Wallet Desk Nouveau module : ```text src/transport_runtime.rs ``` Au bootstrap : ```text cfg.composite.ksp-app-wallet-desk -> component transport -> resolve_transport_config_profile -> HttpTransportPool::new -> validation locale d'une route getBalance / role default ``` Le pool est conservé dans `AppState` et partagé par les refresh de balance. Les diagnostics sûrs exposent uniquement : ```text transport profile role = default cluster(s) provider(s) endpoint_count available_endpoint_count ``` Les URLs Transport restent absentes des DTOs/frontend/logs applicatifs. ## Balance autorisée Nouvelle commande : ```text refresh_wallet_balance ``` Elle ne reçoit **aucun argument frontend**. Rust verrouille brièvement `WalletSession`, accepte uniquement : ```text View Owner ``` puis copie : ```text wallet_id capability Pubkey ``` Le mutex est libéré avant l'I/O réseau. `Locked`, `NoSelection` et `PrivilegedOperation` ne peuvent pas effectuer le RPC. Appel : ```text HttpTransportPool::get_balance( role = default, pubkey = issue du handle VIEW/OWNER Rust, commitment = confirmed, ) ``` Après l'I/O, le backend vérifie que le même wallet/capability/Pubkey est encore autorisé. Si un Lock, Deselect ou changement de wallet est intervenu entre-temps, la réponse stale est rejetée au lieu d'être reprojetée. ## `WalletBalanceDto` Le nouveau DTO expose : ```text wallet_id lamports decimal string exacte sol decimal exact à 9 décimales slot api_version optionnelle transport_profile transport_role ``` `lamports` traverse IPC comme chaîne décimale afin d'éviter toute perte de précision JavaScript sur un `u64` supérieur à `Number.MAX_SAFE_INTEGER`. La représentation SOL est dérivée sans floating point : ```text 0 -> 0.000000000 1 -> 0.000000001 1_000_000_000 -> 1.000000000 ``` ## Frontend Le Dashboard affiche maintenant les diagnostics Transport sûrs. La vue Details devient fonctionnelle après VIEW/OWNER : ```text Pubkey alias notes lamports SOL RPC slot RPC api_version Transport profile / role Refresh balance ``` Le bouton `Refresh balance` reste désactivé tant que la session n'est pas VIEW ou OWNER. Lock/Deselect/Refresh inventory/changement de wallet purgent la projection de balance avec les autres données autorisées. Le frontend ignore également une réponse de balance qui ne correspond plus au `activeWalletId` courant, en complément de la vérification backend. ## Tests et canaris Ajouts/renforcements : ```text Config Transport adapter composite -> provenance Composite composite Wallet Desk -> HttpTransportPool -> route getBalance format lamports/SOL exact sans flottant commande refresh_wallet_balance présente Pubkey obtenue via wallet.pubkey() côté Rust commitment confirmed refresh frontend sans pubkey ni endpoint URL UI Details / diagnostics Transport présents ``` Le smoke réseau réel reste effectué via `cargo tauri dev` avec un wallet VIEW/OWNER autorisé ; aucun wallet financé n'est requis, une réponse `0` lamport est valide. ## Dépendances Wallet Desk consomme maintenant directement la crate KSP interne déjà présente dans le workspace : ```text ksp-onchain-transport-lib ``` Aucune dépendance tierce Cargo ou npm n'est ajoutée et aucune capability Tauri supplémentaire n'est nécessaire. **Aucune commande npm directe n'est nécessaire.** ## Validation opérateur requise ```bash cargo fmt --all python3 scripts/audit_rust_workspace_rules.py cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-config-lib cargo test -p ksp-app-wallet-desk cargo test --workspace KSP_WALLETS_DIRECTORY=var/wallet-desk-pre007 \ cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json ``` Dans l'application : ```text créer ou sélectionner un vrai .kspwallet -> unlock VIEW ou OWNER -> Details -> Refresh balance -> vérifier lamports / SOL / slot / api_version -> Lock -> vérifier purge de la balance et bouton désactivé ``` Le RPC `getBalance` peut retourner `0` lamport : ce résultat doit être affiché comme un succès normal. Toujours aucun `cargo tauri build` à ce stade. ## Suite `pre.008` ajoutera l'import Solana CLI JSON / Base58 avec picker natif minimal, inspection sûre de la source, nouveaux credentials KSP et destination no-clobber sous la racine Wallet effective.