use bdk::{ bitcoin::{bip32::ExtendedPrivKey, Network}, keys::{ bip39::{Language, Mnemonic, WordCount}, DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey, }, miniscript, template::Bip84, KeychainKind, }; 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 get( mnemonic_words: String, ) -> anyhow::Result<(Bip84, Option>)> { 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(); let external_descriptor = Bip84(xprv, KeychainKind::External); let internal_descriptor = Some(Bip84(xprv, KeychainKind::Internal)); Ok((external_descriptor, internal_descriptor)) } pub(crate) fn load_from_file( side_dir: &PathBuf, ) -> anyhow::Result<(Bip84, Option>)> { 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}"); get(mnemonic_words) }