Portefeuille
Le Wallet gère les paires de clés ed25519, signe les messages et se connecte optionnellement à un nœud RPC pour les requêtes on-chain.
Gestion des Clés
Créer un Nouveau Portefeuille
use savitri_sdk::Wallet;
// Paire de clés aléatoire (cryptographiquement sécurisée)
let wallet = Wallet::new();
println!("Adresse : {}", wallet.address()); // 64 caractères hex (clé publique 32 octets)
Importer depuis une Clé Privée
// Depuis des octets bruts
let private_key: [u8; 32] = [/* votre clé */];
let wallet = Wallet::from_private_key(&private_key)?;
// Depuis une chaîne hexadécimale
let wallet = Wallet::from_private_key_hex("aabbccdd...64hexchars")?;
// Avec le préfixe 0x
let wallet = Wallet::from_private_key_hex("0xaabbccdd...64hexchars")?;
Exporter les Clés
// Clé publique (sûre à partager)
let pubkey = wallet.public_key();
println!("Clé publique : {}", hex::encode(pubkey.as_bytes()));
// Adresse (dérivée de la clé publique)
println!("Adresse : {}", wallet.address());
// Clé privée (NE JAMAIS partager ou journaliser)
let privkey: [u8; 32] = wallet.private_key();
Signature
Signer un Message
let message = b"Hello, Savitri!";
let signature: [u8; 64] = wallet.sign_message(message);
Vérifier une Signature
wallet.verify_signature(message, &signature)?;
// Retourne Ok(()) si valide, Err si invalide
Le schéma de signature utilise Ed25519 (ed25519-dalek). Pour la signature des transactions, le message est d'abord haché avec SHA-256 :
message = from_hex || to_hex || amount_le_u64 || nonce_le_u64 || fee_le_u128
hash = SHA-256(message)
sig = Ed25519_sign(hash)
Intégration RPC
Connectez un portefeuille à un nœud pour les requêtes on-chain :
// Créer avec connexion RPC
let wallet = Wallet::with_rpc("http://localhost:8545")?;
// Ou se connecter ultérieurement
let mut wallet = Wallet::new();
wallet.connect_rpc("http://localhost:8545")?;
// Consulter le solde (nécessite RPC)
let balance: String = wallet.get_balance().await?;
println!("Solde : {}", balance);
// Consulter le nonce (nécessite RPC)
let nonce: u64 = wallet.get_nonce().await?;
println!("Nonce : {}", nonce);
// Accéder au client RPC sous-jacent
if let Some(rpc) = wallet.rpc() {
let height = rpc.get_block_number().await?;
println!("Hauteur : {}", height);
}
Sécurité
- Zéroïsation : Le matériel de clé privée est zéroïsé lorsque le portefeuille est libéré (trait
Dropvia la cratezeroize). - Comportement du clone : Les portefeuilles clonés n'héritent PAS de la connexion RPC (ils démarrent déconnectés).
- Pas de persistance : Le portefeuille ne sauvegarde pas les clés sur le disque. Utilisez votre propre stockage sécurisé.
{
let wallet = Wallet::new();
// ... utiliser le portefeuille ...
} // le portefeuille est libéré ici — les octets de la clé privée sont zéroïsés en mémoire