This commit is contained in:
Dave Hrycyszyn
2024-06-24 08:02:17 +01:00
parent d6c118ca3b
commit 643a0d7f52
5 changed files with 120 additions and 61 deletions

View File

@@ -1,40 +1,59 @@
use bitcoin::secp256k1::{rand, Keypair, Secp256k1, SecretKey};
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,
str::FromStr,
};
pub fn make_keypair() -> bitcoin::secp256k1::Keypair {
let secp = Secp256k1::new();
let (secret_key, _) = secp.generate_keypair(&mut rand::thread_rng());
Keypair::from_secret_key(&secp, &secret_key)
pub fn make_mnemonic() -> String {
let mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
Mnemonic::generate((WordCount::Words12, Language::English)).unwrap();
mnemonic.to_string()
}
pub(crate) fn write(key_path: &PathBuf) -> Result<(), std::io::Error> {
let key_pair = make_keypair();
let mut file = File::create(key_path)?;
let pub_str = key_pair.public_key().to_string();
let priv_str = key_pair.display_secret().to_string();
println!("private key: {priv_str}");
let out = format!("{pub_str}/{priv_str}");
println!("out: {out}");
file.write(out.as_bytes())?;
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(())
}
pub(crate) fn load_from_file(side_dir: &PathBuf) -> bitcoin::secp256k1::Keypair {
let bitcoin_key_path = crate::utils::side_paths(side_dir.clone()).1; // TODO: this tuple stinks
pub fn create_wallet(mnemonic_words: String) -> anyhow::Result<Wallet<MemoryDatabase>> {
let mnemonic = Mnemonic::parse(mnemonic_words).unwrap();
let data = fs::read_to_string(bitcoin_key_path).expect("couldn't read bitcoin key file");
println!("bitcoin keys: {:?}", data);
// Generate the extended key
let xkey: ExtendedKey = mnemonic.into_extended_key()?;
let secret_key_data = data.split("/").collect::<Vec<&str>>()[1];
let secp = Secp256k1::new();
let secret_key =
SecretKey::from_str(secret_key_data).expect("couldn't load secret key from file");
Keypair::from_secret_key(&secp, &secret_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::Signet,
MemoryDatabase::default(),
)?;
Ok(wallet)
}
pub(crate) fn load_from_file(side_dir: &PathBuf) -> anyhow::Result<Wallet<MemoryDatabase>> {
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)
}