v0.5.2-pre.001

This commit is contained in:
2026-08-10 14:09:39 +02:00
parent 9849aa7084
commit 0bd5bbf1c4
6 changed files with 737 additions and 87 deletions

View File

@@ -1,8 +1,34 @@
<!-- file: ks-wallet/CHANGELOG.md -->
<!-- version: 6 -->
<!-- version: 9 -->
# CHANGELOG — ks-wallet
## `0.5.2-pre.001`
- caractérise précisément le format legacy `<alias>.json`, ses permissions Unix, ses erreurs, sa publication directe dans le chemin final et ses limites datomicité/TOCTOU ;
- inventorie les consommateurs `ks-wallet`, les usages directs de `solana_keypair` / `solana_signer`, les variables/configurations wallet et les workflows CLI qui dépendent encore du keypair Solana brut ;
- définit le contrat fonctionnel `0.5.2` autour de la gestion multi-wallet par alias, des wallets temporaires/jetables, du mot de passe modifiable, de la signature sans exposition du secret et de limport/export explicite ;
- retient comme cible un conteneur natif binaire versionné `<alias>.kswallet`, sans fixer prématurément KDF/AEAD ou layout binaire ;
- impose un mot de passe valide pour tout export contenant ou permettant de reconstruire le secret ;
- définit la migration legacy comme import vers un nouveau `.kswallet` avec conservation de la pubkey, écriture atomique et rollback, sans réécriture destructive du `.json` ;
- corrige README/USAGE/TODO afin daligner les objectifs sur ce contrat simplifié ;
- ne modifie aucune API runtime, aucun fichier wallet et nintroduit encore aucun nouveau format persistant.
### `pre.001-delta-fix-001`
- corrige la version Cargo de `0.5.2-pre.001` vers le SemVer valide `0.5.2-pre.1` ;
- simplifie profondément le plan initial, retire lexclusion erronée de lexport privé contrôlé et supprime lhypothèse dun alias principal universel par profil ;
- formalise lextension native `.kswallet`, le wallet temporaire et lobligation de password pour tout export secret.
### `pre.001-delta-fix-002`
- précise que `ks-wallet` découvrira les wallets persistants par scan borné des `<alias>.kswallet` dans son répertoire résolu, sans faire confiance au seul nom de fichier ;
- distingue explicitement changement de password et rotation de keypair : le password rechiffre la même keypair, tandis quun nouveau secret Ed25519 implique une nouvelle pubkey ;
- rend obligatoires limport **et** lexport du format keypair JSON standard utilisé par les binaires Solana ;
- ajoute une matrice de compatibilité à établir pour Phantom, Solflare, Backpack, Trust Wallet, Coinbase/Base et les autres wallets Solana techniquement documentés ;
- borne `0.5.2` à un adaptateur wallet tiers dexemple en plus du format Solana CLI obligatoire, avec report des autres adaptateurs faisables au TODO pour une version ultérieure non déterminée ;
- interdit de synthétiser une recovery phrase supposée restaurer une keypair arbitraire lorsque la mnemonic/seed dorigine nest pas disponible.
## `0.5.1-pre.002`
- renomme `kb-wallet` en `ks-wallet` et `kb_wallet` en `ks_wallet` ;

View File

@@ -1,46 +1,58 @@
<!-- file: ks-wallet/README.md -->
<!-- version: 3 -->
<!-- version: 6 -->
# ks-wallet
`ks-wallet` fournit actuellement une frontière locale minimale de portefeuille pour les démonstrations et tests dintégration.
`ks-wallet` fournit la frontière wallet Solana générale du workspace Khadhroony.
## État actuel
La crate est une ébauche fonctionnelle, pas un gestionnaire de wallets complet.
En `0.5.2-pre.001`, la crate reste une ébauche fonctionnelle basée sur le format legacy Solana JSON. La restructuration `0.5.2` est encore au stade plan/caractérisation et ne modifie pas le runtime.
Elle fournit :
La crate fournit actuellement :
- alias validés ;
- wallet temporaire en mémoire ;
- stockage local JSON dun keypair Solana ;
- chargement ou création atomique ;
- résumé non secret ;
- stockage local JSON d'un keypair Solana ;
- création exclusive avec refus d'écrasement et reprise des courses `load_or_create` ;
- résumé sans matériau cryptographique secret, mais contenant encore un chemin local interne ;
- accès au trait `Signer` sans exposition des octets ;
- signature de messages ;
- permissions Unix privées et contrôles de fichiers ;
- effacement des buffers secrets utilisés lors de la lecture ou écriture.
- effacement des buffers secrets temporaires utilisés lors de la lecture ou écriture.
## Hors capacités actuelles
La persistance legacy écrit encore directement le contenu dans le chemin final : elle n'est pas une publication atomique crash-safe par fichier temporaire + renommage.
Les fonctions suivantes ne sont pas encore implémentées :
## Cible `0.5.2`
- chiffrement par mot de passe ;
- plusieurs wallets gérés comme collection ;
- sélection persistante du wallet actif ;
- import/export contrôlé ;
- changement de mot de passe ;
- verrouillage et déverrouillage ;
- sauvegarde et restauration ;
- politiques de sécurité complètes.
`ks-wallet` doit devenir capable de :
- découvrir dans le store les fichiers `<alias>.kswallet` valides et gérer plusieurs wallets persistants accessibles par alias ;
- conserver des wallets temporaires/jetables pour tests et scénarios ;
- stocker les wallets persistants dans un format natif binaire `<alias>.kswallet` ;
- protéger chaque wallet persistant par un mot de passe modifiable ;
- fournir une capacité de signature sans exposer les bytes privés ;
- importer le format legacy et d'autres formats explicitement supportés ;
- exporter volontairement vers des formats externes supportés ;
- exiger un mot de passe valide pour tout export contenant le secret ;
- préserver exactement la même keypair lors d'un changement de mot de passe ;
- importer et exporter obligatoirement le format keypair JSON des binaires Solana ;
- documenter les formats compatibles des principaux wallets Solana, implémenter un adaptateur tiers d'exemple et reporter les autres au TODO.
Le format `.kswallet` sera propre à `ks-wallet`, mais sa protection cryptographique utilisera des primitives standards. Changer le mot de passe ne change jamais la keypair : une modification réelle du secret Ed25519 produirait une autre pubkey et donc un autre wallet. Le détail du KDF, de l'AEAD et du layout binaire sera fixé dans les tranches techniques après validation du plan et des dépendances réellement résolues.
## Relations
`ks-wallet` fournit un signer. Les limites de dépense, la simulation, lautorisation opérateur et lenvoi sont gérés par `ks-lib`, `ks-pipeline-demo-scenarios` et les applications.
`ks-wallet` possède et gère le wallet. Les exécuteurs et `ks-lib` doivent dépendre d'une capacité de signature, pas du format de stockage ni des octets privés.
`ks-config` peut sélectionner un alias ou une identité non sensible, mais ne stocke aucun mot de passe ni matériau secret.
Une application desktop doit projeter les informations autorisées dans ses propres DTO Tauri ; `ks-wallet` ne réintroduit pas TS-RS.
## Documentation
- [USAGE.md](USAGE.md)
- [TODO.md](TODO.md)
- [CHANGELOG.md](CHANGELOG.md)
- [plan temporaire `0.5.2`](../docs/plans/V0_5_2_KS_WALLET_RESTRUCTURING_PLAN.md)
- [ROADMAP général](../ROADMAP.md)

View File

@@ -1,19 +1,29 @@
<!-- file: ks-wallet/TODO.md -->
<!-- version: 4 -->
<!-- version: 7 -->
# TODO — ks-wallet
## Série `0.5.x`
## `0.5.2`
- [ ] `0.5.2` - caractériser le format legacy `<alias>.json` contenant le tableau JSON standard du keypair Solana.
- [ ] `0.5.2` - définir un conteneur persistant versionné avant dintroduire le chiffrement.
- [ ] `0.5.2` - séparer identité publique, matériau secret, état verrouillé/déverrouillé et capacité de signature.
- [ ] Migration - définir import legacy, écriture atomique, rollback et conservation de la clé publique.
- [ ] Fonctionnalité - gérer plusieurs wallets persistants et la sélection du wallet actif si retenue.
- [ ] Sécurité - ajouter chiffrement/déchiffrement et changement de secret seulement après validation du format.
- [ ] Sécurité - ajouter verrouillage/déverrouillage explicites et invalidation de session.
- [ ] Fonctionnalité - ajouter import/export, sauvegarde/restauration avec contrats de sécurité explicites.
- [ ] Sécurité - interdire tout secret wallet dans config générale, logs, erreurs, diagnostics ou Tauri.
- [ ] Intégration - relier la sélection du wallet aux profils et signers sans exposer les octets secrets.
- [ ] Tests - ajouter une API externe de caractérisation, corruption, concurrence, récupération et migration.
- [ ] Documentation - produire un guide de sécurité avant tout usage hors démonstration.
- [ ] caractériser par tests externes le format legacy `<alias>.json`, ses erreurs et ses permissions.
- [ ] définir l'identité publique minimale d'un wallet et le lookup par alias.
- [ ] gérer plusieurs wallets persistants sans wallet actif global mutable et les découvrir par scan borné des `<alias>.kswallet` du store résolu.
- [ ] conserver/généraliser les wallets temporaires ou jetables purement en mémoire.
- [ ] spécifier puis implémenter le format natif binaire versionné `<alias>.kswallet`.
- [ ] sélectionner et documenter KDF/AEAD/paramètres après vérification des dépendances résolues.
- [ ] créer/ouvrir un wallet persistant avec mot de passe sans exposer les bytes privés.
- [ ] permettre le changement de mot de passe en rechiffrant exactement la même keypair et donc en conservant la même pubkey.
- [ ] fournir une capacité de signature compatible avec les consommateurs sans dépendance de `ks-lib` vers `ks-wallet`.
- [ ] importer le legacy Solana JSON vers `.kswallet` avec écriture atomique, rollback et vérification de pubkey.
- [ ] importer et exporter le format keypair JSON standard des binaires Solana.
- [ ] produire une matrice documentée des formats Phantom, Solflare, Backpack, Trust Wallet, Coinbase/Base et autres wallets Solana pertinents.
- [ ] implémenter dans `0.5.2` un seul adaptateur wallet tiers d'exemple, choisi selon simplicité et qualité de la spécification officielle.
- [ ] reporter les autres adaptateurs tiers faisables vers une version ultérieure non déterminée après validation de la matrice.
- [ ] ne jamais synthétiser une recovery phrase supposée préserver une keypair arbitraire sans mnemonic/seed d'origine.
- [ ] exiger le mot de passe valide pour tout export contenant le secret.
- [ ] définir les collisions d'alias et de pubkey sans écrasement silencieux.
- [ ] normaliser la sélection par alias dans `ks-config` sans secret.
- [ ] adapter les consommateurs et le desktop uniquement via des surfaces non sensibles.
- [ ] retirer secrets et chemins locaux inutiles des logs, erreurs, diagnostics et DTO.
- [ ] tester permissions privées, atomicité, corruption, concurrence réellement utilisée et non-divulgation.
- [ ] produire le guide de sécurité et la documentation finale avant clôture de `0.5.2`.

View File

@@ -1,11 +1,11 @@
<!-- file: ks-wallet/USAGE.md -->
<!-- version: 3 -->
<!-- version: 6 -->
# Utilisation de ks-wallet
## Objectif
## Statut
La crate fournit des wallets temporaires en mémoire ou persistés localement pour les démonstrations et tests dintégration.
En `0.5.2-pre.001`, cette page décrit l'API runtime **actuelle**. La cible multi-wallet/password/`.kswallet` est planifiée mais n'est pas encore implémentée.
## Valider un alias
@@ -24,7 +24,7 @@ assert_eq!(alias.as_str(), "devnet-operator");
Un alias doit contenir entre 1 et 64 octets, commencer par un caractère alphanumérique ASCII et ne contenir ensuite que des caractères alphanumériques, `_` ou `-`.
## Générer un wallet en mémoire
## Générer un wallet temporaire en mémoire
```rust
let alias = match ks_wallet::WalletAlias::parse(
@@ -36,14 +36,15 @@ let alias = match ks_wallet::WalletAlias::parse(
},
};
let wallet =
ks_wallet::TemporaryWallet::generate(alias);
let wallet = ks_wallet::TemporaryWallet::generate(alias);
let summary = wallet.summary();
assert!(summary.storage_path.is_none());
println!("public key={}", summary.public_key);
```
Cette capacité est durable : `0.5.2` doit continuer à permettre des wallets temporaires/jetables pour tests, démonstrations et scénarios sans imposer une persistance ou un mot de passe.
## Signer un message
```rust
@@ -61,9 +62,11 @@ println!("signature={signature}");
`as_signer()` retourne une référence au trait Solana `Signer` sans exposer les octets du keypair.
Pour une API async qui conserve la référence au travers dun `await` et impose un futur `Send`, `as_sync_signer()` préserve explicitement le marqueur `Sync` du keypair concret. Cette vue ne change ni la clé utilisée ni les règles dautorisation de la couche dexécution.
Pour une API async qui conserve la référence au travers d'un `await` et impose un futur `Send`, `as_sync_signer()` préserve explicitement le marqueur `Sync` du keypair concret.
## Créer un stockage local
Cette frontière de signature doit rester disponible après restructuration : les consommateurs ne doivent pas connaître le format persistant.
## Stockage legacy actuel
```rust
let store = match ks_wallet::TemporaryWalletStore::new(
@@ -74,14 +77,17 @@ let store = match ks_wallet::TemporaryWalletStore::new(
return std::result::Result::Err(error);
},
};
println!(
"wallet directory={}",
store.directory().display()
);
```
## Créer un wallet persistant
Le store actuel persiste un keypair au format Solana JSON dans :
```text
<alias>.json
```
Ce format est **legacy** pour `0.5.2`.
### Créer un wallet legacy persistant
```rust
let alias = match ks_wallet::WalletAlias::parse(
@@ -104,9 +110,9 @@ let summary = wallet.summary();
assert!(summary.storage_path.is_some());
```
`create` refuse décraser un fichier existant.
`create` refuse d'écraser un fichier existant.
## Charger ou créer atomiquement
### Charger ou créer sans écrasement
```rust
let alias = match ks_wallet::WalletAlias::parse(
@@ -128,57 +134,67 @@ let wallet = match store.load_or_create(alias).await {
println!("wallet={}", wallet.public_key());
```
## Vérifier lexistence et le chemin
`load_or_create` utilise une création exclusive et reprend la lecture lorsqu'une création concurrente a déjà réservé le même alias.
```rust
let path = store.wallet_path(&alias);
let exists = match store.exists(&alias).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(error);
},
};
Le contenu legacy est toutefois écrit directement dans le chemin final. La publication n'est pas encore crash-safe/atomique par fichier temporaire + renommage.
println!("path={}, exists={exists}", path.display());
## Cible persistante `0.5.2`
Le nouveau stockage natif doit utiliser :
```text
<alias>.kswallet
```
## Politique non secrète
Le fichier `.kswallet` sera un conteneur binaire versionné protégé par le mot de passe propre au wallet.
```rust
let policy = ks_wallet::WalletPolicy {
signing_enabled: true,
lamport_spend_limit: std::option::Option::Some(
1_000_000,
),
};
L'API cible doit permettre conceptuellement :
assert!(policy.signing_enabled);
```text
create persistent(alias, password)
open/unlock(alias, password)
change password(alias, old password, new password)
scan/discover <alias>.kswallet
list identities
lookup by alias
sign without exposing private bytes
```
`WalletPolicy` transporte une intention de politique. Son application effective appartient à la couche dexécution.
Le store découvrira les wallets persistants en scannant son répertoire résolu (racine `KS_WALLETS_DIRECTORY`, `wallets` par défaut, puis éventuel sous-répertoire configuré) pour les `<alias>.kswallet` valides. Le scan ne doit pas faire confiance au seul nom du fichier.
## Erreurs et invariants
Le changement de mot de passe rechiffre la même keypair. Il n'existe pas de rotation normale du secret Ed25519 conservant la même pubkey : une nouvelle clé secrète signifie une nouvelle identité Solana.
- les octets secrets ne sont jamais exposés par lAPI publique ;
- les résumés ne contiennent que lalias, la clé publique et le chemin ;
- un fichier existant nest pas écrasé ;
Les noms Rust définitifs et le modèle runtime exact seront décidés dans les prereleases d'implémentation.
## Import/export cible
`ks-wallet` doit obligatoirement importer **et exporter** le format keypair JSON standard des binaires Solana, en plus de son import legacy qui correspond actuellement à ce même wire format. Il doit aussi pouvoir convertir vers/depuis les autres formats explicitement supportés.
Un export public peut exposer les données autorisées telles que l'alias et la pubkey.
**Tout export contenant ou permettant de reconstruire la clé privée doit obligatoirement demander et valider le mot de passe du wallet.**
L'export vers Solana CLI utilise son tableau JSON de 64 octets. Pour Phantom, Solflare, Backpack, Trust Wallet, Coinbase/Base et les autres wallets examinés, une matrice de compatibilité doit d'abord confirmer le contrat exact depuis des sources officielles. Un seul adaptateur wallet tiers sera implémenté dans `0.5.2` à titre d'exemple ; les autres formats techniquement faisables seront reportés au TODO. Aucun format universel externe n'est supposé, et une recovery phrase ne doit jamais être synthétisée en prétendant représenter une keypair arbitraire si la seed/mnemonic d'origine n'est pas disponible.
## Invariants
- les octets secrets ne sont pas exposés par l'API publique par commodité ;
- aucun mot de passe ni secret n'est projeté vers Tauri ;
- `ks-config` ne stocke pas les mots de passe ;
- les résumés publics ne doivent pas exposer inutilement les chemins locaux ;
- un fichier existant n'est pas écrasé silencieusement ;
- les liens symboliques et fichiers non réguliers sont refusés ;
- sur Unix, les permissions privées sont vérifiées ;
- les buffers secrets temporaires sont effacés ;
- les buffers secrets temporaires sont effacés lorsque possible ;
- cette crate ne décide pas si une transaction est autorisée.
## Tests de référence
## Tests de référence actuels
- validation des alias ;
- génération et signature sans persistance ;
- création, chargement et `load_or_create` ;
- refus décrasement ;
- création exclusive, chargement et `load_or_create` ;
- refus d'écrasement ;
- rejet des keypairs corrompus ;
- vérification des permissions Unix privées ;
- rejet des liens symboliques et permissions trop ouvertes.
- vérification des permissions Unix privées.
## Limites durables
- le format persistant actuel est le tableau JSON standard du keypair Solana ;
- la crate ne signe pas automatiquement une transaction ;
- elle ne transmet aucun secret à une interface frontend.
La matrice `0.5.2` ajoutera notamment : legacy externalisé, `.kswallet`, password/changement de password, multi-wallet, migration, import/export, atomicité et canaris de non-divulgation.