rustywallet_export/
wif.rs1use crate::types::Network;
4use rustywallet_keys::prelude::PrivateKey;
5use rustywallet_keys::prelude::Network as KeysNetwork;
6use sha2::{Sha256, Digest};
7
8pub fn export_wif(key: &PrivateKey, network: Network, compressed: bool) -> String {
27 let keys_network = match network {
28 Network::Mainnet => KeysNetwork::Mainnet,
29 Network::Testnet => KeysNetwork::Testnet,
30 };
31
32 if compressed {
33 key.to_wif(keys_network)
34 } else {
35 encode_wif_uncompressed(&key.to_bytes(), keys_network)
37 }
38}
39
40fn encode_wif_uncompressed(key: &[u8; 32], network: KeysNetwork) -> String {
42 let version = match network {
43 KeysNetwork::Mainnet => 0x80,
44 KeysNetwork::Testnet => 0xEF,
45 };
46
47 let mut payload = Vec::with_capacity(37);
49 payload.push(version);
50 payload.extend_from_slice(key);
51
52 let hash1 = Sha256::digest(&payload);
54 let hash2 = Sha256::digest(hash1);
55 payload.extend_from_slice(&hash2[0..4]);
56
57 bs58::encode(payload).into_string()
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_export_wif_compressed_mainnet() {
66 let key = PrivateKey::random();
67 let wif = export_wif(&key, Network::Mainnet, true);
68 assert!(wif.starts_with('K') || wif.starts_with('L'));
69 assert_eq!(wif.len(), 52);
70 }
71
72 #[test]
73 fn test_export_wif_uncompressed_mainnet() {
74 let key = PrivateKey::random();
75 let wif = export_wif(&key, Network::Mainnet, false);
76 assert!(wif.starts_with('5'));
77 assert_eq!(wif.len(), 51);
78 }
79
80 #[test]
81 fn test_export_wif_compressed_testnet() {
82 let key = PrivateKey::random();
83 let wif = export_wif(&key, Network::Testnet, true);
84 assert!(wif.starts_with('c'));
85 }
86
87 #[test]
88 fn test_export_wif_uncompressed_testnet() {
89 let key = PrivateKey::random();
90 let wif = export_wif(&key, Network::Testnet, false);
91 assert!(wif.starts_with('9'));
92 }
93}