Aller au contenu principal

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 Drop via la crate zeroize).
  • 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