use bdk::{ bitcoin::Network, database::MemoryDatabase, keys::{ bip39::{Language, Mnemonic, WordCount}, DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey, }, miniscript, template::Bip84, KeychainKind, Wallet, }; use std::{ fs::{self, File}, io::Write, path::PathBuf, }; pub fn make_mnemonic() -> String { let mnemonic: GeneratedKey<_, miniscript::Segwitv0> = Mnemonic::generate((WordCount::Words12, Language::English)).unwrap(); mnemonic.to_string() } pub(crate) fn write(mnemonic_path: &PathBuf) -> Result<(), std::io::Error> { let mnemonic = make_mnemonic(); let mut file = File::create(mnemonic_path)?; println!("mnemonic: {mnemonic}"); file.write(mnemonic.as_bytes())?; Ok(()) } /// Creates a Signet Bitcoin descriptor wallet from a mnemonic pub fn create_wallet(mnemonic_words: String) -> anyhow::Result> { let mnemonic = Mnemonic::parse(mnemonic_words).unwrap(); // Generate the extended key let xkey: ExtendedKey = mnemonic.into_extended_key()?; // Get private key from the extended key let xprv = xkey.into_xprv(Network::Signet).unwrap(); // Create a BDK wallet using BIP 84 descriptor ("m/84h/1h/0h/0" and "m/84h/1h/0h/1") let wallet = Wallet::new( Bip84(xprv, KeychainKind::External), Some(Bip84(xprv, KeychainKind::Internal)), Network::Testnet, MemoryDatabase::default(), )?; Ok(wallet) } pub(crate) fn load_from_file(side_dir: &PathBuf) -> anyhow::Result> { let mnemonic_path = crate::utils::side_paths(side_dir.clone()).1; // TODO: this tuple stinks let mnemonic_words = fs::read_to_string(mnemonic_path).expect("couldn't read bitcoin key file"); println!("Creating wallet from mnemonic: {mnemonic_words}"); create_wallet(mnemonic_words) }