224 lines
6.7 KiB
Markdown
224 lines
6.7 KiB
Markdown
<!-- file: deltas/0.2.5/pre.008.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.5-pre.008` — import/export Solana CLI JSON + keypair Base58
|
|
|
|
## Base
|
|
|
|
```text
|
|
0.2.5-pre.7.fix.1
|
|
```
|
|
|
|
Le checkpoint opérateur de cette base a validé `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --workspace --all-targets`, `cargo test -p ksp-wallet-lib` et `cargo test --workspace` sans warning.
|
|
|
|
Version workspace cible :
|
|
|
|
```text
|
|
0.2.5-pre.8
|
|
```
|
|
|
|
## Objectif
|
|
|
|
Cette tranche matérialise les premiers adapters explicites d'import/export de keypair Solana autour du format natif `.kspwallet` V1 :
|
|
|
|
```text
|
|
Solana CLI JSON : tableau JSON de 64 octets
|
|
Solana keypair Base58 : Base58 canonique de la keypair complète de 64 octets
|
|
```
|
|
|
|
Elle ne crée aucun format Wallet alternatif, ne migre aucun ancien format KSP/bot2/bot3 et ne modifie pas `format_version = 1`.
|
|
|
|
## Audit upstream `solana-keypair 3.1.2`
|
|
|
|
Le réaudit de la source officielle actuelle confirme :
|
|
|
|
- `Keypair::to_bytes()` retourne exactement 64 octets ;
|
|
- `Keypair::try_from(&[u8])` exige 64 octets et vérifie que la moitié publique correspond bien à la clé dérivée du secret ;
|
|
- `Keypair::try_from_base58_string` décode la représentation Base58 de 64 octets puis passe par cette validation stricte ;
|
|
- `Keypair::to_base58_string` encode la keypair complète de 64 octets ;
|
|
- `read_keypair` / `write_keypair` matérialisent le format JSON Solana sous forme de 64 valeurs octet.
|
|
|
|
KSP réutilise donc `solana-keypair` déjà possédée par Wallet et n'ajoute pas de dépendance directe `bs58`.
|
|
|
|
## API de transfert
|
|
|
|
Nouveaux contrats publics :
|
|
|
|
```text
|
|
WalletTransferFormat
|
|
WalletTransferInspection
|
|
inspect_wallet_transfer
|
|
inspect_wallet_transfer_file
|
|
import_wallet_transfer_v1
|
|
import_wallet_transfer_file_v1
|
|
WalletOwner::export_transfer
|
|
WalletOwner::export_transfer_file
|
|
```
|
|
|
|
`WalletTransferFormat` distingue explicitement :
|
|
|
|
```text
|
|
solana_cli_json
|
|
solana_keypair_base58
|
|
```
|
|
|
|
Le terme Base58 désigne ici la **keypair complète de 64 octets**, jamais un seed 32 octets ambigu.
|
|
|
|
## Inspection sûre
|
|
|
|
L'inspection exige un format explicite, valide réellement la keypair et ne retourne que :
|
|
|
|
```text
|
|
Pubkey KSP Core
|
|
format de transfert reconnu
|
|
```
|
|
|
|
Aucun secret, seed, keypair brute ou contenu source n'est exposé par `WalletTransferInspection` ou son `Debug`.
|
|
|
|
Bornes pré-parser :
|
|
|
|
```text
|
|
Solana CLI JSON : 1024 octets
|
|
Base58 : 128 octets
|
|
```
|
|
|
|
Pour les APIs fichier, Wallet ouvre d'abord la source puis vérifie les metadata du fichier réellement ouvert avant la lecture bornée à `maximum + 1`.
|
|
|
|
## Import
|
|
|
|
Tout import :
|
|
|
|
```text
|
|
valide la keypair externe
|
|
conserve exactement l'identité/keypair Solana importée
|
|
crée de nouveaux admin key/content keys/salts/nonces/key slots KSP
|
|
applique les metadata KSP fournies par le caller
|
|
crée éventuellement le slot VIEW demandé
|
|
sérialise un nouveau `.kspwallet` V1
|
|
publie avec la sémantique native no-clobber
|
|
```
|
|
|
|
Une destination existante retourne `wallet.destination_exists`. Un import ne remplace jamais un `.kspwallet` existant. L'import depuis fichier ne modifie pas le fichier source.
|
|
|
|
## Export OWNER-only
|
|
|
|
Seule `WalletOwner` expose l'export secret. `WalletView` ne possède aucune méthode équivalente.
|
|
|
|
L'export en mémoire retourne un buffer contenant le secret au caller ; sa documentation exige d'en minimiser la durée de vie et de le zeroizer quand approprié.
|
|
|
|
L'export fichier :
|
|
|
|
```text
|
|
temp file same-directory
|
|
write
|
|
sync temp
|
|
persist_noclobber
|
|
sync fichier publié
|
|
parent-directory sync best-effort sur Unix
|
|
```
|
|
|
|
Une destination existante n'est jamais écrasée. Sur Unix, Wallet tente `0600` comme hygiène filesystem ; cette permission n'est pas transformée en garantie cryptographique du format V1.
|
|
|
|
## Canari externe déterministe
|
|
|
|
Un vecteur indépendant du code Rust Wallet est figé pour le seed Ed25519 `[7; 32]` :
|
|
|
|
```text
|
|
Pubkey Base58
|
|
GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB
|
|
|
|
Keypair complète Base58
|
|
99eUso3aSbE9tqGSTXzo3TLfKb9RkMTURrHKQ1K7Zh3StnzFNUx8FKCPPPPpR479qsw5zv2WNBKmgiz7WqgAJfM
|
|
```
|
|
|
|
Le test fixe aussi les 64 octets exacts et vérifie que les adapters JSON/Base58 produisent la même identité publique. Ce canari évite de valider les adapters uniquement par un round-trip circulaire interne à `solana-keypair`.
|
|
|
|
## Tests/canaris ajoutés
|
|
|
|
La tranche couvre notamment :
|
|
|
|
```text
|
|
inventaire stable des deux formats + codes/labels/extensions
|
|
inspection JSON + Base58 sans exposition du secret
|
|
vecteur externe déterministe seed [7; 32]
|
|
rejet JSON court
|
|
rejet keypair 64 octets dont la moitié publique est incohérente
|
|
rejet Base58 invalide/non canonique/avec whitespace périphérique
|
|
import JSON -> nouveau `.kspwallet` + identité/metadata conservées
|
|
second import même destination -> wallet.destination_exists
|
|
import fichier non destructif + source surdimensionnée rejetée
|
|
export OWNER JSON et Base58 -> mêmes 64 octets importés
|
|
export fichier OWNER no-clobber
|
|
permission 0600 vérifiée sur Unix
|
|
canari API publique pre.008
|
|
canari de frontière interdisant une dépendance directe `bs58`
|
|
```
|
|
|
|
## Dépendances
|
|
|
|
Aucune nouvelle dépendance tierce.
|
|
|
|
La tranche réutilise exclusivement les dépendances Wallet déjà acquises, notamment `solana-keypair 3.1.2`, `serde_json`, `tempfile` et `zeroize`.
|
|
|
|
Les frontières restent :
|
|
|
|
```text
|
|
Wallet -X-> Config
|
|
Wallet -X-> Transport
|
|
Wallet -X-> ExecutionPolicy
|
|
Wallet -X-> Store
|
|
Wallet -X-> Tauri
|
|
Wallet -X-> tracing direct
|
|
Wallet -X-> solana-pubkey direct
|
|
Wallet -X-> bs58 direct
|
|
```
|
|
|
|
`Pubkey` reste exposée par `ksp-core-lib`; la keypair secrète reste encapsulée dans `ksp-wallet-lib`.
|
|
|
|
## Documentation
|
|
|
|
Mise à jour :
|
|
|
|
```text
|
|
docs/formats/KSPWALLET_V1.md
|
|
docs/plans/000-README.md
|
|
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
|
|
docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md
|
|
docs/IDEAS.md
|
|
ROADMAP.md
|
|
```
|
|
|
|
`pre.009` devient la prochaine tranche : sécurité/interoperabilité/compliance finale et audits de dépendances/arbres.
|
|
|
|
## Validation statique de préparation
|
|
|
|
Le sandbox de préparation ne possède pas Cargo/Rust. Les contrôles statiques ont vérifié :
|
|
|
|
- pas de nouveau `unwrap`/`expect`/`panic`/`?` dans les chemins production ajoutés ;
|
|
- seuls des traits nécessaires sont importés avec `use` ;
|
|
- aucun accès Config/Transport/Tauri/env/`tracing` direct/`solana-pubkey` direct ;
|
|
- aucune dépendance `bs58` ajoutée ;
|
|
- incréments de versions de fichiers cohérents ;
|
|
- liens Markdown locaux des documents modifiés résolus ;
|
|
- archive delta limitée aux fichiers ajoutés/modifiés.
|
|
|
|
## Validation opérateur requise
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-wallet-lib
|
|
cargo test --workspace
|
|
|
|
cargo tree -p ksp-wallet-lib
|
|
cargo tree -p ksp-wallet-lib -d
|
|
cargo tree -i solana-keypair@3.1.2
|
|
```
|
|
|
|
## Commit attendu
|
|
|
|
```text
|
|
v0.2.5-pre.008
|
|
```
|