58 KiB
Plan 0.2.6 — Wallet Desk
1. Objet et statut de 0.2.6-pre.001
0.2.6 crée crates/ksp-app-wallet-desk, une application Tauri spécialisée et mince qui valide la composition réelle :
ksp-config-lib
+ Config composite
+ ksp-wallet-lib
+ ksp-onchain-transport-lib HTTP
+ ksp-logging-lib
La base auditée est la release stable fournie v0.2.5, avec workspace.package.version = 0.2.5 avant ouverture. La base ne contient encore ni crate ksp-app-wallet-desk, ni document std.wallet, ni composite Wallet Desk.
0.2.6-pre.001 reste une tranche d'audit, conception, inventaire et sizing. Elle ne crée pas encore la crate Tauri ni les fichiers Config runtime. Son rôle est de produire une trajectoire suffisamment détaillée pour que les prereleases suivantes implémentent des objectifs positifs et mesurables sans renégocier les frontières au fil des corrections.
Les validations opérateur du 2026-08-20 ont ensuite confirmé la base pre.001 : cargo fmt --all, python3 scripts/audit_rust_workspace_rules.py, cargo check --workspace et cargo clippy --workspace --all-targets sont verts, sans warning signalé. Le présent plan intègre les corrections documentaires de pre.001-fix.001 puis pre.001-fix.002 sans modifier la version Cargo, car aucun fichier code/build/runtime/configuration exécutable n'est touché. pre.001-fix.002 aligne en particulier le workflow frontend sur la règle KSP : npm direct sert uniquement à installer ou mettre à jour les dépendances ; les cycles dev/build passent exclusivement par Cargo/Tauri.
0.2.6-pre.002 matérialise ensuite la première tranche technique : la crate ksp-app-wallet-desk rejoint le workspace avec le shell splash/main du gabarit Config Desk, le bootstrap Config + Logging commun, les ports 1432/1433, Bootstrap, Font Awesome, DataTables/Select, SimpleBar, resize-observer-polyfill, TS-RS et le bridge frontend -> Rust -> ksp-logging-lib. Cette tranche ne branche encore ni std.wallet, ni inventory filesystem réel, ni ksp-wallet-lib, ni Transport : ces responsabilités restent dans les prereleases déjà dimensionnées.
0.2.6-pre.003 matérialise la composition Config prévue : cfg.std.wallet/schema.std.wallet, le composite cfg.composite.ksp-app-wallet-desk, les profils Wallet default/temporary/tests, ResolvedWalletConfig et les adapters qui peuvent consommer un profil déjà sélectionné par composite sans perdre la provenance Composite. Wallet Desk valide les composants logging/transport/wallet, crée la racine et le sous-répertoire effectif absents avec logs debug, refuse les objets filesystem invalides/symlinks de sous-répertoire avec logs error, et expose uniquement les chemins/profils non secrets dans le statut runtime. Aucun inventory .kspwallet n’est encore effectué. pre.003-fix.001 corrige les deux régressions de tests révélées par la validation workspace et le warning Clippy, puis rend visibles les événements trace frontend. pre.003-fix.002 corrige ensuite le canari d’inventaire .env.example qui confondait un fragment d’identifiant Rust avec une variable KSP, remplace le profil temporaire wallet_desk_dev par une famille Logging réutilisable (console_*, file_info, superdev, supertrace) et fait sélectionner temporairement supertrace par le composite Wallet Desk afin de conserver la visibilité des actions frontend sans profil spécifique à l’application. pre.003-fix.003 corrige uniquement les canaris révélés par la validation de fix.002 : conformité clippy::implicit_return et séparation explicite entre fragment lexical KSP incorporé dans un identifiant et nom d’environnement concret suffixé. pre.003-fix.004 ferme le dernier défaut Clippy de cette série en ajoutant les return explicites aux cinq closures restantes du test de composition supertrace, sans changer les profils Logging ni le composite. pre.004 matérialise ensuite l’inventory locked réel. Sa validation opérateur confirme le comportement fonctionnel et le workspace complet, mais révèle deux warnings unused_imports sur des réexports crate-root internes uniquement utiles aux unit tests ; pre.004-fix.001 les limite à #[cfg(test)] : ils disparaissent du build runtime mais restent disponibles au crate-root pour les unit tests, conformément aux règles d’exports KSP, sans changement de comportement. pre.005 matérialise ensuite la création native dans Wallet Desk et le premier lifecycle durable WalletSession : création no-clobber sous la racine Config via create_wallet_file_v1, session OWNER conservée uniquement en Rust après création, sélection locked durable, Lock/Deselect/Refresh/changement de wallet avec drop des handles et purge frontend des projections protégées/passwords. Les unlock VIEW/OWNER de wallets existants restent strictement pre.006. pre.005-fix.001 corrige le gate de compilation/tests révélé par l'opérateur sans modifier le lifecycle : la variante WalletSession::Owner contient désormais Box<WalletOwner> afin de fermer clippy::large_enum_variant, et le canari de sécurité définit explicitement request_start avant de contrôler les champs password request-only. pre.006 matérialise ensuite les unlock existants : VIEW/OWNER manuel, découverte Config des candidats KSP_SECRET_WALLET_PASS_*, ordre déterministe filename normalisé -> numérique -> nommé, actions configurées explicites et jamais automatiques, PrivilegedOperation pendant Argon2, puis sessions View/Owner Rust-only avec candidate count seul projeté vers l’UI. pre.006-fix.001 corrige les deux canaris desktop_security qui inspectaient trop largement le texte de WalletAuthorizedDto : la documentation du compteur de candidats contient légitimement le mot password, mais aucun champ password n’est sérialisé ; le test filtre désormais uniquement les lignes de champs pub(crate) de la structure.
2. Sources relues et hiérarchie appliquée
L'audit suit l'ordre d'autorité demandé :
- archive KSP stable
v0.2.5fournie ; - règles KSP versionnées ;
- architecture, plans et validations actuels ;
- contrats publics réellement exposés par les crates ;
- sources officielles actuelles Tauri/frontend ;
- archive bot3 fournie, uniquement comme référence historique.
Les documents obligatoires du prompt d'ouverture ont été relus avant conception. Les surfaces ont ensuite été réauditées dans :
ksp-core-lib
ksp-logging-lib
ksp-config-lib
ksp-onchain-transport-lib
ksp-wallet-lib
ksp-app-config-desk
Le plan historique docs/plans/007-V0_2_0_SERIES_PLANNING.md reste historique. La séquence active est celle de ROADMAP.md et docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md.
3. Frontières architecturales
Direction autorisée :
ksp-app-wallet-desk
-> ksp-config-lib
-> ksp-wallet-lib
-> ksp-onchain-transport-lib
-> ksp-core-lib lorsque nécessaire
-> ksp-logging-lib
-> Tauri / frontend dependencies
Interdictions :
ksp-wallet-lib -X-> Config / Transport / Tauri / Store / execution policy
ksp-app-wallet-desk -X-> cryptographie Wallet directe
ksp-app-wallet-desk -X-> solana-keypair / solana-signer / solana-signature directs
ksp-app-wallet-desk -X-> client RPC Solana alternatif
frontend -X-> keypair ou secret key material
frontend -X-> localStorage/sessionStorage pour les passwords
frontend -X-> lecture directe de .env
La seule intégration directe tracing tolérée reste l'adapter Tauri imposé par tauri-plugin-tracing. La façade applicative continue de passer par ksp-logging-lib.
4. ksp-app-config-desk comme gabarit Tauri
4.1 Structure réutilisée
Wallet Desk reprend le gabarit déjà validé :
frontend/
frontend/ts/
frontend/sass/
frontend/ts/bindings/
Vite + TypeScript
Bootstrap
Font Awesome
DataTables Bootstrap 5
DataTables Select Bootstrap 5
SimpleBar
resize-observer-polyfill
splash + main window
TS-RS à la frontière DTO applicative
capabilities Tauri explicites
bridge frontend -> Rust -> ksp-logging-lib
npm direct uniquement pour installer/mettre à jour les dépendances de package.json
beforeDevCommand = frontend dev déclenché automatiquement par cargo tauri dev
beforeBuildCommand = build frontend de production déclenché automatiquement par cargo tauri build
SimpleBar et resize-observer-polyfill sont conservés comme éléments du gabarit desktop, même si Wallet Desk ne les consomme pas tous dès le premier écran métier. Ils évitent de recréer un shell divergent du template éprouvé.
4.2 DataTables et sélection des wallets
Le tableau d'inventaire des wallets utilise datatables.net-bs5. datatables.net-select-bs5 est également conservé afin que la sélection de ligne reste cohérente avec le template et qu'un wallet puisse être sélectionné sans implémenter une logique de table parallèle.
Le tableau doit fournir au minimum :
état lock/unlock
filename
format_version
VIEW enabled/disabled
inspection status
La recherche, le tri et la pagination sont fournis par DataTables. Les données locked ne contiennent jamais Pubkey, alias ni notes.
4.3 Font Awesome
Font Awesome est utilisé pour les états lisibles rapidement :
fa-lock wallet verrouillé
fa-lock-open wallet actuellement ouvert
fa-eye / eye-slash selon état VIEW si utile
fa-triangle-exclamation pour une entrée invalide/diagnostic
Une icône n'est jamais l'unique information accessible : texte, title/ARIA ou colonne d'état accompagne l'icône.
4.4 Ports de développement
Config Desk utilise 1430 et son HMR 1431. Wallet Desk réserve :
Vite dev : 1432
HMR : 1433
4.5 Logging à reprendre/refondre
Le pattern validé est :
frontend helper
-> invoke emit_frontend_log
-> DTO validé côté Rust
-> ksp-logging-lib::{trace,debug,info,warn,error}!
Les helpers Wallet journalisent des événements sémantiques sans payload sensible, par exemple :
wallet_inventory_refresh_started
wallet_selected
wallet_unlock_view_succeeded
wallet_unlock_owner_failed
wallet_balance_refresh_succeeded
wallet_directory_created
wallet_export_cancelled
Ils ne sérialisent jamais aveuglément les request DTOs.
La configuration standard Logging expose aussi des profils opératoires réutilisables :
console_error / console_warn / console_info / console_debug / console_trace
console seule au niveau correspondant
file_info
console désactivée
fichier global info pour tous les targets KSP
superdev
console debug
un fichier debug par target KSP racine
supertrace
console debug
un fichier trace par target KSP racine
local_dev est conservé pour compatibilité avec Config Desk et les scénarios historiques. Pendant le développement de Wallet Desk, le composite sélectionne explicitement supertrace; ce choix reste une donnée de composition et pourra être resserré ultérieurement sans modifier l’application. Les fichiers par target utilisent des filtres de préfixe, de sorte que les sous-targets frontend (ksp-app-wallet-desk.frontend.*) restent routés dans le fichier de leur target racine.
5. Audit de la surface publique ksp-wallet-lib
La release stable 0.2.5 possède déjà la logique métier nécessaire. Wallet Desk compose et projette ; il ne réimplémente rien.
5.1 Locked projection
LockedWalletInfo expose uniquement :
format_version
view_enabled
Aucune Pubkey, aucun alias et aucune note ne sont disponibles avant autorisation.
5.2 Authorized projection
WalletInfo expose après autorisation :
format_version
capability
pubkey
alias
notes
5.3 Handles Rust
WalletView et WalletOwner restent possédés par l'état Rust de l'application.
WalletOwner fournit déjà :
sign
update_alias
add_note
update_note
delete_note
rotate_owner_password
rotate_view_password
disable_view
recreate_view
export_transfer
export_transfer_file
Le frontend ne reçoit aucun handle ni secret interne.
5.4 Persistence et transfer
Les APIs publiques stables couvrent déjà :
create_wallet_file_v1
inspect_locked_wallet_file_v1
open_wallet_view_file_v1
open_wallet_owner_file_v1
inspect_wallet_transfer_file
import_wallet_transfer_file_v1
export_wallet_transfer_file
Les formats transfer retenus sont :
Solana CLI JSON
Solana keypair Base58 complet
5.5 wallet.state_conflict
Un conflit d'état provoque :
message UI explicite
-> abandon du handle courant
-> purge de la projection autorisée et de la balance
-> nouvelle inspection locked
-> unlock requis de nouveau
Aucun retry aveugle ni overwrite forcé.
6. Config Wallet : racine globale + sous-répertoire de profil
6.1 Besoin d'étendre le registre Config
ConfigFileRegistry::defaults() connaît actuellement Logging, Transport et le schéma composite, mais pas Wallet. La tranche Config doit donc ajouter durablement :
cfg.std.wallet
schema.std.wallet
cfg.composite.ksp-app-wallet-desk
Fichiers physiques prévus :
config/std.wallet.json
config/schemas/std.wallet.schema.json
config/examples/std.wallet.example.json
config/composite.ksp-app-wallet-desk.json
config/examples/composite.ksp-app-wallet-desk.example.json
6.2 Shape de std.wallet
wallets_directory est global. Chaque profil peut ajouter un sous-répertoire relatif optionnel :
{
"format_version": 1,
"wallets_directory": "${KSP_WALLETS_DIRECTORY:-wallets}",
"default_profile": "default",
"profiles": [
{
"profile_id": "default"
},
{
"profile_id": "tests",
"wallets_subdirectory": "tests"
},
{
"profile_id": "temporary",
"wallets_subdirectory": "temporary"
}
]
}
Le profil default utilise directement la racine globale. Les profils tests, temporary ou futurs profils de scénario peuvent isoler leurs wallets sans introduire une seconde variable globale ni dupliquer le root.
Le champ wallets_subdirectory :
- est optionnel ;
- est relatif ;
- peut contenir plusieurs composants relatifs si le schema final le permet ;
- refuse chemin absolu,
..et toute résolution hors dewallets_directory; - reste une donnée non secrète de Config.
Le nom exact est retenu comme wallets_subdirectory pour rendre explicite sa relation avec wallets_directory.
6.3 ResolvedWalletConfig
ksp-config-lib doit fournir un adapter public analogue aux adapters Logging/Transport, par exemple :
ResolvedWalletConfig
file_id
source_path
profile_id
selection_source
wallets_directory
wallets_subdirectory
effective_wallets_directory
provenance sûre
effective_wallets_directory est :
wallets_directory
ou
wallets_directory / wallets_subdirectory
Config résout et valide les chemins mais n'énumère pas les wallets.
6.4 Création automatique des répertoires
Après résolution Config, Wallet Desk garantit l'existence du répertoire global et du répertoire effectif de profil avec une opération Rust create_dir_all ou équivalente.
Comportement :
absent -> tentative de création
créé/prêt -> debug
échec création -> error + erreur runtime explicite
existe mais n'est pas un répertoire -> error + refus d'inventory
Le log de succès inclut au minimum le profil et un indicateur created=true/false. Le log d'échec est error. Aucun échec de création n'est traité comme un inventaire vide normal.
La création est une responsabilité de composition de Wallet Desk après résolution Config, pas une raison d'ajouter du filesystem Wallet dans ksp-wallet-lib.
6.5 Composite Wallet Desk
Shape de référence :
{
"format_version": 1,
"default_profile": "devnet",
"profiles": [
{
"profile_id": "devnet",
"documents": [
{"component_id": "logging", "file_id": "cfg.std.logging", "profile_id": "supertrace"},
{"component_id": "transport", "file_id": "cfg.std.transport", "profile_id": "devnet_public"},
{"component_id": "wallet", "file_id": "cfg.std.wallet", "profile_id": "default"}
]
},
{
"profile_id": "tests",
"documents": [
{"component_id": "logging", "file_id": "cfg.std.logging", "profile_id": "supertrace"},
{"component_id": "transport", "file_id": "cfg.std.transport", "profile_id": "devnet_public"},
{"component_id": "wallet", "file_id": "cfg.std.wallet", "profile_id": "tests"}
]
}
]
}
Le composite référence des file_id, jamais des filenames physiques.
7. Passwords provenant de Config / .env
7.1 Évolution du contrat d'ouverture
Pour 0.2.6, les passwords Wallet peuvent être fournis de deux façons :
1. saisie éphémère dans l'UI
2. secret KSP géré par Config depuis process env ou .env
Les secrets .env sont donc explicitement autorisés pour cette application sous le namespace :
KSP_SECRET_WALLET_PASS_*
Cela ne place pas les passwords dans les documents JSON Config : Config reste seulement le propriétaire de l'environnement et de .env.
7.2 Noms supportés
Exemples opérateur :
KSP_SECRET_WALLET_PASS_01
KSP_SECRET_WALLET_PASS_02
KSP_SECRET_WALLET_PASS_MY_WALLET
KSP_SECRET_WALLET_PASS_TREASURY
Les suffixes peuvent représenter un numéro, le filename ou son stem normalisé, ou un alias de filename/opérateur. Ils ne représentent jamais l'alias interne protégé stocké dans le .kspwallet.
Le filename locked peut produire un candidat déterministe. La normalisation exacte doit être testée et documentée dans la tranche Config/secret-provider ; direction retenue :
strip .kspwallet
-> uppercase ASCII
-> caractères hors [A-Z0-9] remplacés par _
-> runs de _ compactés
-> _ de bord supprimés
Les collisions de labels sont possibles et ne deviennent pas une identité Wallet.
7.3 Alias de filename et alias interne Wallet
L'alias interne du wallet (WalletInfo.alias) reste une metadata protégée et n'intervient jamais dans la résolution des KSP_SECRET_WALLET_PASS_*. Wallet Desk n'ouvre donc jamais un wallet pour découvrir cet alias afin de choisir un secret.
Un suffixe nommé correspond uniquement au filename/stem normalisé ou à un alias de filename/opérateur défini pour identifier le fichier côté exploitation. Cet alias de filename n'est pas une identité interne du wallet et peut être connu avant unlock. Les noms de variables restent côté Rust/Config et ne sont pas renvoyés au frontend ni journalisés.
7.4 Découverte et ordre des candidats
Le moteur Config possède déjà une vue sûre des noms d'environnement présents. Wallet Desk utilise uniquement les APIs Config publiques ; aucun accès std::env direct n'est autorisé.
Ordre de tentative proposé :
1. candidat correspondant au filename normalisé
2. candidats numériques (_01, _02, ...) dans l'ordre numérique
3. candidats correspondant aux alias de filename/opérateur dans un ordre déterministe
Les valeurs provenant de Config restent entièrement côté Rust. Chaque String obtenue de Config est déplacée immédiatement dans ViewPassword ou OwnerPassword, qui possède la zeroization à la destruction. Cette règle concerne les secrets Config/.env ; elle n'interdit pas les passwords saisis par l'utilisateur de transiter du frontend vers Rust dans la request Tauri qui exécute l'opération demandée.
7.5 Tentative explicite, pas d'auto-unlock silencieux
Argon2id rend chaque tentative volontairement coûteuse. Wallet Desk ne doit donc pas essayer toutes les variables au simple clic de sélection d'une ligne.
L'UX distingue :
Unlock VIEW avec saisie
Unlock OWNER avec saisie
Unlock VIEW avec secret configuré
Unlock OWNER avec secret configuré
Une action « secret configuré » tente les candidats jusqu'au premier succès pour la capability demandée. Pour une saisie manuelle, le password est envoyé une seule fois par IPC HTML/TypeScript -> Rust, converti immédiatement en wrapper Wallet puis purgé côté frontend. Rust ne renvoie jamais ce password. Le frontend peut recevoir :
candidate_count
success/failure
capability obtenue
mais jamais la valeur d'un secret Config ni un password saisi. Les noms/suffixes de variables Config ne sont pas exposés au frontend. Les logs peuvent enregistrer le nombre de candidats et le résultat, pas leurs noms ni leurs valeurs.
7.6 .env.example
La tranche Config ajoute une documentation de pattern dans .env.example, par exemple :
# Wallet Desk password candidates. Values are secrets and never committed.
# Additional KSP_SECRET_WALLET_PASS_<LABEL> variables are supported.
KSP_SECRET_WALLET_PASS_01=
Aucun password réel n'entre dans l'archive ou le repository.
8. Audit Transport : balance minimale
Aucun nouveau wrapper Transport n'est nécessaire. La surface stable expose :
HttpTransportPool::get_balance(
&HttpRoleName,
&ksp_core_lib::Pubkey,
Option<&GetBalanceConfig>,
) -> Result<GetBalanceResult>
Le résultat fournit :
lamports
slot
api_version optionnelle
Le frontend ne fournit pas la Pubkey à la commande de refresh. Rust l'extrait du handle VIEW/OWNER autorisé.
Le DTO garde lamports comme entier exact. L'affichage SOL est une présentation dérivée.
9. Runtime Rust et machine d'état
États principaux :
NoSelection
Locked
ViewOpen
OwnerOpen
PrivilegedOperation
Représentation conceptuelle :
WalletSession
NoSelection
Locked { wallet_id, path, locked_info }
View { wallet_id, path, wallet: WalletView }
Owner { wallet_id, path, wallet: WalletOwner }
Le chemin complet reste côté Rust. Le frontend manipule un wallet_id/filename validé pour les opérations root-scoped.
Le changement de wallet, lock, deselect ou wallet.state_conflict :
drop handle Rust
-> purge WalletAuthorizedDto
-> purge balance
-> purge inputs password
-> retour Locked ou NoSelection
Pour getBalance, Rust copie uniquement la Pubkey puis libère le mutex session avant l'I/O réseau.
10. Inventory et stratégie de chemins
10.1 Racine effective
L'inventory utilise exclusivement :
ResolvedWalletConfig::effective_wallets_directory()
Le répertoire est créé/préparé au bootstrap selon la section Config. Un échec de préparation est un état d'erreur, pas directory_missing silencieux.
10.2 Enumeration
L'inventory est :
non récursive
extension exacte .kspwallet
fichiers réguliers seulement
symlinks d'entrée exclus
répertoires exclus
refresh manuel
refresh automatique après opération locale réussie
pas de filesystem watcher en 0.2.6
Chaque candidat est inspecté via inspect_locked_wallet_file_v1.
10.3 Résolution root-scoped
Create/import/select utilisent un filename validé :
pas de chemin absolu
pas de . ou ..
pas de séparateur injecté
extension .kspwallet requise
join sous effective_wallets_directory
contrôle containment/canonicalisation lorsque pertinent
Le filename est une identité de stockage affichable. Son stem/une forme normalisée peut servir d'alias de filename pour la résolution opérateur de KSP_SECRET_WALLET_PASS_*, mais il n'est jamais confondu avec l'alias interne protégé WalletInfo.alias.
10.4 Source import / destination export
L'import :
source externe via picker natif
-> inspection Rust
-> nouveau .kspwallet sous effective_wallets_directory
L'export OWNER :
destination externe choisie par save picker
-> export fichier Rust no-clobber
-> aucun contenu exporté secret dans une réponse IPC
11. Screen map
11.1 Shell
Mono-fenêtre après splash :
Header
application/runtime status
profile composite
current wallet state
action lock lorsque autorisé
Sidebar SimpleBar
Dashboard
Wallets
Create / Import
Details
Security
Diagnostics
11.2 Dashboard
Affiche :
Config composite profile
Logging status
Transport profile / cluster
Wallet global root
Wallet profile/subdirectory
effective wallet directory status
selected filename
Locked / VIEW / OWNER
last balance status
configured wallet-secret candidate count, sans noms
11.3 Wallets
DataTable principal :
status icon lock/open
filename
format_version
VIEW enabled
inspection status
Sélection de ligne via DataTables Select. La ligne du wallet ouvert utilise l'état fa-lock-open; les autres restent fa-lock.
11.4 Locked wallet / Unlock
Actions :
Unlock VIEW avec password saisi
Unlock OWNER avec password saisi
Unlock VIEW avec secret configuré
Unlock OWNER avec secret configuré
Deselect
11.5 Create
Formulaire :
filename
OWNER password + confirmation
VIEW password optionnel + confirmation
alias initial / notes initiales si l'API stable le permet directement
Destination sous le répertoire effectif, no-clobber.
11.6 Import
Flow :
picker source
-> inspection Pubkey + format sûre
-> destination filename
-> nouveaux credentials KSP
-> alias/notes éventuels
-> import no-clobber
11.7 Details
Après VIEW/OWNER :
capability
Pubkey
alias
notes
balance lamports
balance SOL formatée
RPC slot / api_version
transport profile
refresh
11.8 Security OWNER
metadata administration
rotate OWNER
rotate VIEW
disable VIEW
recreate VIEW
export OWNER file
11.9 Diagnostics
Surface sûre :
profils Config sélectionnés
répertoire Wallet effectif
nombre d'entrées inventory
nombre de secrets Wallet configurés
cluster / endpoint provider sûr sans URL credentialée
dernier code d'erreur par domaine
outil de logging contrôlé
12. Command map
| Command | Entrée frontend | Sortie sûre | Délégation |
|---|---|---|---|
get_runtime_status |
— | WalletRuntimeStatusDto |
Config/app state |
list_wallets |
— | Vec<WalletInventoryEntryDto> |
app filesystem + Wallet inspect |
refresh_wallets |
— | inventory DTO | app filesystem + Wallet inspect |
select_wallet |
wallet id | LockedWalletDto |
app resolver + Wallet inspect |
deselect_wallet |
— | session DTO | app state |
create_wallet |
create request | WalletAuthorizedDto OWNER |
Wallet create file |
unlock_wallet_view |
password | authorized VIEW | Wallet open VIEW |
unlock_wallet_owner |
password | authorized OWNER | Wallet open OWNER |
unlock_wallet_view_with_configured_secret |
— | authorized VIEW / operation result | Config env + Wallet open VIEW |
unlock_wallet_owner_with_configured_secret |
— | authorized OWNER / operation result | Config env + Wallet open OWNER |
lock_wallet |
— | LockedWalletDto |
drop handle + inspect |
refresh_wallet_balance |
— | WalletBalanceDto |
Transport getBalance |
inspect_import_source |
native picker path | transfer inspection DTO | Wallet inspect transfer |
import_wallet |
import request | authorized OWNER | Wallet import file |
update_wallet_alias |
alias mutation | authorized DTO | WalletOwner |
add_wallet_note |
note create | authorized DTO | WalletOwner |
update_wallet_note |
note update | authorized DTO | WalletOwner |
delete_wallet_note |
note id | authorized DTO | WalletOwner |
rotate_owner_password |
rotation request | operation result | WalletOwner |
rotate_view_password |
rotation request | operation result | WalletOwner |
disable_view |
confirmation | authorized DTO | WalletOwner |
recreate_view |
new VIEW password | authorized DTO | WalletOwner |
export_wallet_owner |
format + save path | operation result | Wallet export file |
emit_frontend_log |
redacted payload | () |
Logging facade |
Aucune commande de signature arbitraire n'est ajoutée dans cette release.
13. DTO map
DTOs attendus :
WalletRuntimeStatusDto
WalletInventoryEntryDto
WalletSessionDto
LockedWalletDto
WalletAuthorizedDto
WalletBalanceDto
WalletCreateRequestDto
WalletSelectionRequestDto
WalletUnlockPasswordDto
WalletConfiguredSecretStatusDto
WalletImportRequestDto
WalletTransferInspectionDto
WalletAliasMutationDto
WalletNoteCreateDto
WalletNoteUpdateDto
WalletPasswordRotationDto
WalletSecurityStatusDto
WalletOperationResultDto
CommandErrorDto
FrontendLogPayloadDto
13.1 Locked DTO
Contient au maximum :
wallet_id / filename
format_version
view_enabled
session state icon/status
13.2 Authorized DTO
Contient :
wallet_id / filename
format_version
capability
pubkey
alias
notes
security status sûr
13.3 Secrets
Les DTOs de request contenant un password :
- ne dérivent pas un
Debugrévélant la valeur ; - ne sont pas
Clonesans besoin ; - sont convertis immédiatement en
OwnerPassword/ViewPassword; - ne sont jamais inclus dans un
CommandErrorDtoou un log.
Les commandes *_with_configured_secret n'ont aucun champ password. À l'inverse, les commands manuelles d'unlock, de création/import et de changement/recréation de password acceptent les passwords nécessaires dans leurs request DTOs frontend -> Rust ; ces champs ne sont jamais présents dans les DTOs de réponse.
14. Threat model desktop
| Menace | Mesure 0.2.6 |
|---|---|
| Password saisi conservé frontend | transmission request-only HTML/TS -> Rust, aucun storage, champ vidé en finally, pas de state global secret |
Password .env exposé au frontend |
résolution exclusivement Rust via Config |
| Confusion alias filename / alias interne | les suffixes KSP_SECRET_WALLET_PASS_* ciblent uniquement filename/stem ou alias de filename/opérateur ; jamais WalletInfo.alias |
| Multiples Argon2 involontaires | tentative de secrets configurés seulement sur action explicite |
| Password dans logs | logging sémantique sans request payload |
| Secret renvoyé Rust -> frontend | aucun password, keypair ou export secret en réponse IPC ; seuls les passwords saisis transitent frontend -> Rust dans les request DTOs |
| Identity leak locked | DTO locked issu de LockedWalletInfo + filename uniquement |
| Path traversal | chemins root-scoped validés sous le répertoire effectif |
| Symlink escape inventory | entrées symlink exclues ; containment vérifié |
| State stale | wallet.state_conflict => drop handle + refresh locked |
| RPC credential leak | aucune URL brute credentialée dans DTO/log UI |
| Frontend forge capability | capability déterminée depuis handle Rust |
| Export accidentel | OWNER + modal Bootstrap + save picker + no-clobber |
| Browser dialog natif non instrumenté | confirmations applicatives via Bootstrap modal |
La compromission complète du processus ou de l'OS reste hors modèle de sécurité.
15. Tauri security : capabilities d'abord, CSP inchangée par défaut
15.1 Capabilities
La réduction de la surface IPC repose d'abord sur les capabilities/permissions Tauri explicites.
Baseline :
core:default
tracing:default
Lorsque les pickers sont réellement ajoutés :
dialog:allow-open
dialog:allow-save
Aucun plugin filesystem n'est nécessaire pour l'inventory : Rust effectue les opérations côté application.
15.2 CSP
Config Desk utilise actuellement :
{"csp": null}
Wallet Desk réutilise ce comportement du gabarit par défaut. 0.2.6 n'introduit donc pas une CSP personnalisée comme nouveau chantier sans besoin concret.
La documentation Tauri décrit aussi la CSP comme une défense WebView contre XSS/chargement de contenu non autorisé, mais ce constat ne justifie pas à lui seul de diverger du template KSP déjà validé. Le frontend Wallet Desk reste local et le RPC est effectué côté Rust.
La CSP sera réauditée seulement si un besoin réel apparaît, par exemple :
chargement de contenu distant
WebSocket/fetch côté WebView
asset protocol / convertFileSrc
intégration nécessitant des sources supplémentaires
Une telle évolution devra être testée sur Linux/WebKitGTK et les autres plateformes ciblées avant adoption.
16. Logging et redaction
Interactions à instrumenter en debug/trace :
navigation
DataTable init/destroy/refresh
wallet select/deselect
wallet directory ready/created
create/import result
unlock manual VIEW/OWNER result
unlock configured-secret VIEW/OWNER result
lock
balance refresh
metadata mutation
rotation/disable/recreate
modal open/confirm/cancel
export start/result
state conflict
DOM/state replacement significatif
Règles de niveau :
répertoire créé/prêt correctement -> debug
échec création/résolution répertoire -> error
unlock incorrect -> warn/debug selon code final sans password
state conflict -> warn
erreur Transport -> warn/error selon nature
Interdictions :
password
secret bytes/keypair
transfer payload secret
KSP_SECRET value
nom complet KSP_SECRET_WALLET_PASS_* si son suffixe peut révéler une identité
RPC URL credentialée
Les logs restent uniques par lancement selon la politique KSP.
17. Create / Import / Export
17.1 Create
create_wallet :
répertoire effectif Config
-> filename validé
-> OwnerPassword/ViewPassword
-> create_wallet_file_v1
-> no-clobber
-> session OWNER
-> inventory refresh
17.2 Import
picker open
-> inspect_wallet_transfer_file
-> choix destination sous root effectif
-> nouveaux credentials KSP
-> import_wallet_transfer_file_v1
-> no-clobber
-> session OWNER
La source n'est jamais parsée en TypeScript.
17.3 Export
OWNER
-> choix format
-> modal Bootstrap
-> save picker
-> export_wallet_transfer_file
-> status seulement
Aucun export texte/clipboard n'est prévu en 0.2.6.
18. Administration OWNER
Le scope positif de 0.2.6 inclut :
update alias
notes CRUD
rotate OWNER password
rotate VIEW password
disable VIEW
recreate VIEW
OWNER file export CLI JSON/Base58
Les contrôles OWNER sont masqués ou désactivés sous VIEW et l'autorisation réelle est toujours revérifiée côté Rust.
19. Tests déterministes Rust
19.1 Config
Couvrir :
registre cfg.std.wallet/schema/composite
schema std.wallet
KSP_WALLETS_DIRECTORY process/.env/fallback
wallets_directory global
wallets_subdirectory absent
wallets_subdirectory simple/nested autorisé selon schema
absolute/traversal subdirectory rejetés
effective_wallets_directory
composite -> profils logging/wallet/transport exacts
filemap overrides conservés
19.2 Répertoire/inventory
Couvrir :
root absent créé
profile subdirectory absent créé
création réussie -> chemin disponible
création impossible -> erreur
existing non-directory -> erreur
regular .kspwallet accepted
wrong extension ignored
subdirectory entry ignored
symlink entry ignored
filename traversal rejected
no-clobber create/import
invalid wallet safe diagnostic
19.3 Secret provider Config
Couvrir :
aucun std::env direct hors Config
filtre KSP_SECRET_WALLET_PASS_*
filename normalization déterministe
ordre filename -> numeric -> named
process > .env conservé par Config
valeurs non présentes dans Debug/log/DTO
VIEW configured-secret success/failure
OWNER configured-secret success/failure
aucun essai automatique lors de select
suffixes filename/alias de filename testés sans dépendre de WalletInfo.alias
19.4 Session/DTO
Couvrir :
Locked DTO sans pubkey/alias/notes
VIEW projection
OWNER projection
lock purge
selection change purge
state_conflict purge
password Debug redacted/absent
responses sans secret fields
VIEW ne peut pas muter OWNER
19.5 Balance
Avec serveur HTTP local/fixture :
VIEW -> handle pubkey -> getBalance
OWNER -> même chemin
0 lamport accepté
lamports exact
slot/api_version mappés
Transport error sûr
credential absent erreur/log
20. Validation frontend
Aucun script npm applicatif n'est lancé directement pour valider Wallet Desk. npm est utilisé directement uniquement lors de l'installation initiale ou de la mise à jour des dépendances déclarées dans package.json :
cd crates/ksp-app-wallet-desk
npm i -D
# ou, lors d'une mise à jour des packages déjà déclarés :
npm update
cd ../..
Le cycle normal de développement/validation frontend passe par Tauri depuis la racine du workspace :
cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json
Tauri déclenche alors automatiquement le script configuré dans beforeDevCommand. Les contrôles fonctionnels frontend à forte valeur portent notamment sur :
DataTable init/refresh/destroy sans duplication
row selection -> wallet selection
lock icon -> open icon -> lock icon
password input cleared in finally
VIEW/OWNER projection purge au lock
OWNER controls absents/inactifs sous VIEW
secret-configured action ne reçoit aucune valeur secret en TS
modal requis avant opérations privilégiées
SimpleBar/resize lifecycle sans fuite d'event listener
Le build frontend de production n'est jamais lancé directement avec npm. Il est déclenché par Tauri via beforeBuildCommand uniquement lors du cargo tauri build final.
21. Smoke Devnet opt-in
Scénario :
Config composite Devnet
-> profil Wallet test/temporary
-> répertoire créé automatiquement
-> wallet éphémère test-only
-> open VIEW ou OWNER
-> Pubkey
-> HttpTransportPool getBalance
-> réponse RPC valide, y compris 0 lamport
Le smoke :
- est opt-in ;
- n'utilise aucun wallet de production ;
- peut utiliser un password généré/test-only en mémoire ;
- n'exige pas de wallet financé ;
- nettoie son espace temporaire ;
- documente distinctement skip réseau et succès exécuté.
22. Audit dépendances frontend/Tauri
Le gabarit Config Desk stable contient déjà :
@fltsci/tauri-plugin-tracing ^0.3
@fortawesome/fontawesome-free ^7.3
@tauri-apps/api ^2.11
bootstrap ^5.3
datatables.net-bs5 ^3.0
datatables.net-select-bs5 ^4.0
resize-observer-polyfill ^1.5
simplebar ^6.3
Wallet Desk reprend cette baseline. Au 2026-08-20, l'audit externe confirme notamment :
@fortawesome/fontawesome-free 7.3.1
datatables.net-bs5 3.0.1
datatables.net-select-bs5 4.0.0
resize-observer-polyfill 1.5.1
Les ranges du template couvrent ces générations. simplebar ^6.3 est conservé depuis le template validé ; la version exacte sera réaudité au moment de création du package.json comme toute dépendance effectivement ajoutée.
Le plugin Dialog n'est ajouté qu'à la tranche import/export qui le consomme et sa version Rust/npm est vérifiée à ce moment.
Sources d'audit actuelles :
https://v2.tauri.app/security/
https://v2.tauri.app/security/capabilities/
https://v2.tauri.app/security/csp/
https://v2.tauri.app/plugin/dialog/
https://www.npmjs.com/package/datatables.net-bs5
https://www.npmjs.com/package/datatables.net-select-bs5
https://www.npmjs.com/package/resize-observer-polyfill
https://www.npmjs.com/package/@fortawesome/fontawesome-free
23. Sizing : principes
Le forecast d'ouverture était utile mais trop compact. Le sizing révisé cherche à :
- garder une tranche Config cohérente avant les usages Wallet ;
- poser le shell complet avec son vrai gabarit frontend dès le début ;
- séparer inventory, secrets/unlock, réseau et administration ;
- ne pas mélanger import/export secret avec les premières projections ;
- garder une vraie tranche de compliance/intégration avant la documentation finale ;
- réserver explicitement une dernière tranche à README/USAGE/docs/validation/graphes/prompt suivant et build final.
Le numéro final reste souple. Si une tranche révèle un manque, un fix ou une prerelease supplémentaire est préférable à comprimer le travail.
24. Forecast souple détaillé des prereleases
pre.001 — audit, UX, composition et sizing
Livrables :
réaudit base v0.2.5
réaudit Config Desk / Config / Wallet / Transport / Logging
screen map
command + DTO map
modèle std.wallet root + profile subdirectory
stratégie KSP_SECRET_WALLET_PASS_*
stratégie inventory/path
threat model
sizing et forecast
Cette tranche se termine par le présent plan/delta et les validations opérateur Rust de base.
pre.002 — crate Tauri et shell complet du gabarit
État : matérialisé dans le delta 0.2.6-pre.002, sous réserve des validations opérateur Cargo/Tauri.
Objectifs/livrables :
crates/ksp-app-wallet-desk
package.json / Vite / TS / SCSS
ports 1432/1433
splash + main
Bootstrap
Font Awesome
DataTables + Select
SimpleBar + resize-observer-polyfill
TS-RS foundation
logging frontend/Rust
capabilities initiales
installation npm uniquement si package.json vient d'être créé/modifié
parcours cargo tauri dev via beforeDevCommand
Le shell peut afficher des données mockées/runtime minimales, mais doit déjà valider navigation, scroll, layout et logging.
pre.003 — std.wallet, composite et préparation des répertoires
Livrables de la tranche :
cfg.std.wallet / schema.std.wallet enregistrés dans Config
wallets_directory global = ${KSP_WALLETS_DIRECTORY:-wallets}
wallets_subdirectory optionnel, relatif et multi-composants normaux
profils default / temporary / tests
ResolvedWalletConfig avec root/subdirectory/effective path/provenance
resolve_logging_config_profile / resolve_wallet_config_profile pour profils composites
cfg.composite.ksp-app-wallet-desk = logging(supertrace) + transport + wallet
.env.example documente KSP_WALLETS_DIRECTORY et le pattern futur KSP_SECRET_WALLET_PASS_*
bootstrap Wallet Desk valide les trois component_id/file_id requis
création automatique du root et du sous-répertoire effectif absents
rejet d'un root non-directory et d'un composant de sous-répertoire symlink/non-directory
debug sur répertoires prêts/créés ; error sur préparation impossible
profils Logging génériques : console_error/warn/info/debug/trace, file_info, superdev et supertrace ; local_dev conservé pour compatibilité
composite Wallet Desk temporairement sur supertrace : console debug + un fichier trace par target KSP racine
trace frontend metadata-only sur clics boutons/navigation/tabs et actions shell
status DTO/UI : profil composite, profils Logging/Wallet, root/subdirectory/effective directory
Tests de tranche : registre/schema, composition et provenance, precedence environnement, containment syntaxique, création idempotente des répertoires, rejet non-directory/symlink et contrats desktop. L’inventory .kspwallet reste strictement pre.004.
pre.004 — inventory DataTables et inspection locked
Objectifs :
enumeration .kspwallet non récursive
path safety + symlink policy
inspect_locked_wallet_file_v1
WalletInventoryEntryDto / LockedWalletDto
DataTable réel
row selection
Font Awesome lock/open/error states
refresh manuel + après opérations locales futures
À la fin de cette tranche, l'application sait lister et sélectionner un wallet sans révéler son identité protégée.
État matérialisé par pre.004 :
ksp-app-wallet-desk -> ksp-wallet-lib ajouté explicitement
effective_wallets_directory comme unique racine d'inventory
read_dir asynchrone non récursif
filename UTF-8 + suffixe exact .kspwallet
regular file uniquement ; symlink/non-file exclus
inspection via inspect_locked_wallet_file_v1
ligne invalide conservée avec CommandErrorDto sûr
WalletInventoryEntryDto / LockedWalletDto / WalletSelectionRequestDto
list_wallets / refresh_wallets / select_wallet
DataTable réel + refresh + sélection
fa-lock pour valid locked ; fa-triangle-exclamation pour invalid
selection revalidée côté Rust, filename single-component uniquement
root symlink désormais rejeté lors de la préparation Config
aucun Pubkey / alias / notes / password dans la projection locked
La sélection de pre.004 reste une projection locked sans handle durable : le WalletSession Rust et les handles OWNER/VIEW arrivent en pre.005/pre.006. Un refresh invalide donc la sélection frontend pour éviter de conserver une projection potentiellement stale.
Validation opérateur pre.004 : inventory/tests/workspace/Tauri dev verts, avec deux warnings unused_imports sur WalletInspectionStatusDto et WalletInventoryStateDto réexportés au crate-root uniquement pour les unit tests. pre.004-fix.001 place ces réexports sous #[cfg(test)] ; les unit tests conservent crate::WalletInspectionStatusDto et crate::WalletInventoryStateDto, tandis que les builds non-test ne portent plus ces imports inutilisés. Aucun DTO TS-RS, aucune commande Tauri, aucune règle de path safety et aucun comportement frontend ne changent.
pre.005 — création Wallet et lifecycle de session Rust
Objectifs :
AppState / WalletSession
create_wallet_file_v1
form create
OWNER + VIEW optionnel
no-clobber
session OWNER après création
select/deselect
lock/drop handle
purge frontend protégée
Cette tranche pose le lifecycle avant d'ajouter les providers de password existants.
État matérialisé par pre.005 :
WalletSession Rust = NoSelection | Locked | Owner
create_wallet -> create_wallet_file_v1 -> session OWNER
select_wallet -> session Locked
deselect_wallet -> drop handle/path state -> NoSelection
lock_wallet -> drop OWNER -> re-inspect -> Locked
refresh_wallets -> deselect backend -> inventory
Le formulaire Create transmet OWNER/VIEW passwords uniquement frontend -> Rust. WalletCreateRequestDto n'est ni Debug ni Clone; les wrappers OwnerPassword/ViewPassword prennent immédiatement possession des String. Les réponses ne contiennent aucun password ni secret key. Après création, WalletAuthorizedDto peut exposer Pubkey, alias et notes parce que la session OWNER est explicitement autorisée. Les valeurs protégées ne sont pas journalisées.
Après création, l'inventory est relu avec list_wallets sans détruire la session OWNER nouvellement créée. En revanche, un Refresh utilisateur appelle refresh_wallets, qui purge d'abord la session Rust afin que l'UI et le backend ne divergent jamais. Lock, deselect, sélection d'un autre wallet et échec de transition purgent aussi les projections protégées et inputs frontend.
Les unlock manuels/configurés d'un wallet existant restent strictement pre.006.
pre.006 — unlock manuel + KSP_SECRET_WALLET_PASS_*
État matérialisé :
Locked -> PrivilegedOperation -> ViewOpen / OwnerOpen
unlock VIEW/OWNER manuel via WalletUnlockRequestDto request-only
ConfigManagement::environment_report pour découvrir les candidats sans valeur
ConfigManagement::reveal_effective_environment_value uniquement pendant l’action explicite
normalisation stem : uppercase ASCII, hors [A-Z0-9] -> _, runs compactés, bords supprimés
ordre : filename normalisé, puis numériques en ordre numérique, puis nommés lexicographiques
aucun auto-unlock lors de select_wallet
frontend reçoit uniquement configured_secret_candidate_count
VIEW disabled refuse l’action VIEW avant KDF
OwnerPassword/ViewPassword prennent immédiatement possession des String révélés/saisis
Lock/Deselect/Refresh/changement de wallet détruisent les handles autorisés
Le frontend Security expose quatre actions distinctes : VIEW manuel, OWNER manuel, VIEW configuré et OWNER configuré. Les noms/suffixes/valeurs des secrets Config ne traversent jamais IPC et ne sont pas journalisés ; les logs se limitent au wallet_id root-scoped, capability, candidate_count et résultat. PrivilegedOperation évite de tenir un mutex pendant Argon2 et empêche une complétion de KDF obsolète de réinstaller un handle après changement de session. Tests spécifiques : normalisation/ordre, requests non Clone/Debug, redaction, candidate-count only et non-auto-unlock.
pre.007 — détails autorisés + balance HTTP
Objectifs :
WalletAuthorizedDto
Pubkey / alias / notes
HttpTransportPool depuis composite
getBalance VIEW
getBalance OWNER
lamports + SOL formaté + slot/api_version
refresh manuel
diagnostics Transport sûrs
À ce point le MVP obligatoire est complet : wallet autorisé + identité + balance réseau.
pre.008 — import Solana CLI JSON / Base58
Objectifs :
plugin Dialog open minimal
picker source
inspect transfer sûr
import destination root-scoped
nouveaux OWNER/VIEW credentials
no-clobber
inventory/session refresh
Le contenu secret de la source importée reste côté Rust. Les nouveaux passwords éventuellement saisis dans l'UI transitent uniquement dans la request Tauri HTML/TypeScript -> Rust, puis sont purgés côté frontend ; ils ne reviennent jamais dans une réponse.
pre.009 — metadata OWNER
Objectifs :
update alias
notes add/update/delete
controls OWNER
projection refresh
wallet.state_conflict UX
DataTable/details coherence après mutation
pre.010 — rotations credentials
Objectifs :
rotate OWNER password
rotate VIEW password
password confirmation UX
configured-secret interaction après rotation
session/projection coherence
redaction tests
pre.011 — strong VIEW disable/recreate
Objectifs :
disable_view
recreate_view
security status DTO
VIEW enabled/disabled dans DataTable
modals Bootstrap privilégiés
réouverture VIEW vérifiée
pre.012 — export OWNER fichier
Objectifs :
plugin Dialog save minimal
choix CLI JSON/Base58
confirmation OWNER
export_transfer_file
no-clobber
aucun export texte/clipboard
leak audit ciblé
pre.013 — intégration, compliance, sécurité et smoke
Objectifs :
tests déterministes de composition Config -> Wallet -> Transport
inventory/path adversarial
dto/debug/log secret audit
frontend state purge/security checks
capabilities audit
cargo tree / inverse tree pertinents
Devnet smoke opt-in
validation/009 ou numéro courant dédié à 0.2.6
workspace checkpoint complet
Cette tranche doit produire la preuve que les surfaces ajoutées fonctionnent ensemble avant la documentation de clôture.
pre.014 — documentation finale, candidate build et prompt suivant
Dernière tranche prévue avant rel.001 :
crates/ksp-app-wallet-desk/README.md
crates/ksp-app-wallet-desk/USAGE.md
docs/architecture / inventory / dependency graph synchronisés si impactés
docs/validation 0.2.6 finalisée
ROADMAP / functional sequence / CHANGELOG synchronisés
dépendances et versions finales réauditées
commandes smoke documentées
prompt de démarrage 0.2.7 préparé
validation Rust workspace finale
parcours fonctionnel cargo tauri dev final
cargo tauri build en toute dernière opération
Si le build final ou la documentation révèle une correction technique, utiliser pre.014-fix.NNN ou insérer une tranche supplémentaire. pre.014 n'est pas une obligation de clôture artificielle.
rel.001 — publication stable
Après preuves finales :
version stable 0.2.6
commit rel.001
publication/tag v0.2.6 selon workflow KSP
aucune nouvelle fonctionnalité introduite dans rel.001
25. Validation continue
Après toute modification Rust :
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
Tests ciblés pendant le développement. Aux checkpoints globaux :
cargo test --workspace
Lors de la création initiale de package.json ou d'une modification de ses dépendances, npm est utilisé directement uniquement pour installer ou mettre à jour les packages :
cd crates/ksp-app-wallet-desk
npm i -D
# ou, pour mettre à jour les packages déclarés :
npm update
cd ../..
Le parcours normal de développement et de validation fonctionnelle frontend passe par :
cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json
Tauri exécute automatiquement le beforeDevCommand configuré. Aucun script npm applicatif de contrôle, développement ou build n'est lancé directement par l'opérateur.
Candidate finale :
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-app-wallet-desk
cargo test --workspace
cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json
cargo tauri build -c crates/ksp-app-wallet-desk/tauri.conf.json
cargo tauri build -c crates/ksp-app-wallet-desk/tauri.conf.json reste la toute dernière opération de validation. Il déclenche lui-même le build frontend via beforeBuildCommand. Le smoke Devnet opt-in est exécuté séparément avant cette dernière opération lorsqu'il appartient au checkpoint final.
26. Hors périmètre confirmé
modification du wire .kspwallet V1 sans défaut démontré
WalletPolicy / execution policy
transaction build/simulate/send
WebSocket / gRPC
Store
hardware wallet / Ledger
remote signer
mobile / browser extension
cloud custody
trading
clipboard/text secret export
filesystem watcher
RPC direct depuis frontend
prix offchain pendant 0.2.6
27. TODO 0.2.11 — intégration prix offchain
La visualisation de prix reste hors 0.2.6.
Une application spécialisée doit d'abord valider les sources offchain, normalisation, cache, rafraîchissement et UX. Ensuite 0.2.11 intégrera cette capacité dans Wallet Desk via le composant partagé retenu, sans dupliquer la logique de récupération de prix.
Aucune API fictive de prix n'est introduite dans Wallet Desk en 0.2.6.
28. Critères de sortie 0.2.6
La release stable est clôturable si :
ksp-app-wallet-deskexiste comme application Tauri spécialisée ;- le gabarit frontend réutilise Bootstrap, Font Awesome, DataTables, DataTables Select, SimpleBar et resize-observer-polyfill ;
- Config composite sélectionne Logging/Wallet/Transport par
file_id; wallets_directoryest global etwallets_subdirectorypermet l'isolation par profil ;- le répertoire Wallet effectif absent est créé automatiquement, avec succès loggé en debug et échec en error ;
- l'inventory
.kspwalletest root-scoped et symlink-safe ; - locked ne révèle ni Pubkey, ni alias, ni notes ;
- VIEW/OWNER restent exclusivement côté Rust ;
- saisie manuelle et
KSP_SECRET_WALLET_PASS_*permettent l'ouverture ; les passwords manuels transitent uniquement frontend -> Rust et les secrets Config restent exclusivement côté Rust ; - aucune tentative de liste de secrets n'est déclenchée silencieusement à la sélection ;
- create/select/open VIEW/OWNER fonctionnent sur des fichiers réels ;
- Pubkey/alias/notes apparaissent seulement après autorisation ;
getBalancefonctionne avec VIEW et OWNER via Transport ;- import, metadata, rotations, disable/recreate VIEW et export fichier délèguent à Wallet ;
- aucun secret Wallet n'entre dans les documents JSON Config, les logs ou le storage frontend ;
- les secrets Wallet en process env/
.envrestent possédés et résolus par Config ; - capabilities Tauri sont auditées et la CSP n'est modifiée que si un besoin concret le justifie ;
- tests Rust, parcours frontend via
cargo tauri devet smoke retenu sont documentés/validés ; - README/USAGE, validation, roadmap et prompt
0.2.7sont synchronisés ; - le build Tauri final est vert et exécuté en dernière opération.
29. Suite après pre.001-fix.002
Les validations opérateur de pre.001 sont vertes. pre.001-fix.001 puis pre.001-fix.002 sont des correctifs documentaires : ils ne modifient pas workspace.package.version, qui reste 0.2.6-pre.1. pre.001-fix.002 corrige la règle et le plan pour supprimer toute validation frontend standalone par script npm et réserver les commandes npm directes à l'installation/mise à jour des dépendances.
La séquence Git attendue conserve l'historique réel :
v0.2.6-pre.001
v0.2.6-pre.001-fix.001
v0.2.6-pre.001-fix.002
Après application/commit du fix documentaire, pre.002 démarre la crate Tauri et le shell complet du gabarit, avec Bootstrap, Font Awesome, DataTables/Select, SimpleBar, resize-observer-polyfill, splash/main et logging bridge.