Splitting key load / wallet creation so we can use keys in esplora client
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
use crate::{keys, utils};
|
use crate::{keys, utils};
|
||||||
|
|
||||||
|
use bdk::bitcoin::bip32::ExtendedPrivKey;
|
||||||
use bdk::bitcoin::psbt::PartiallySignedTransaction;
|
use bdk::bitcoin::psbt::PartiallySignedTransaction;
|
||||||
use bdk::blockchain::Blockchain;
|
use bdk::bitcoin::Network;
|
||||||
use bdk::database::MemoryDatabase;
|
use bdk::database::MemoryDatabase;
|
||||||
|
use bdk::template::Bip84;
|
||||||
use bdk::wallet::AddressIndex::{self, New};
|
use bdk::wallet::AddressIndex::{self, New};
|
||||||
use bdk::wallet::AddressInfo;
|
use bdk::wallet::AddressInfo;
|
||||||
use bdk::{blockchain::ElectrumBlockchain, electrum_client, SyncOptions};
|
use bdk::{blockchain::ElectrumBlockchain, electrum_client, SyncOptions};
|
||||||
@@ -11,8 +13,11 @@ use bdk::{FeeRate, SignOptions, TransactionDetails, Wallet};
|
|||||||
pub async fn run() -> Result<(), anyhow::Error> {
|
pub async fn run() -> Result<(), anyhow::Error> {
|
||||||
let dave = utils::home(&"dave".to_string());
|
let dave = utils::home(&"dave".to_string());
|
||||||
let sammy = utils::home(&"sammy".to_string());
|
let sammy = utils::home(&"sammy".to_string());
|
||||||
let dave_wallet = keys::bitcoin::load_from_file(&dave).unwrap();
|
let dave_keys = keys::bitcoin::load_from_file(&dave).unwrap();
|
||||||
let sammy_wallet = keys::bitcoin::load_from_file(&sammy).unwrap();
|
let sammy_keys = keys::bitcoin::load_from_file(&sammy).unwrap();
|
||||||
|
|
||||||
|
let dave_wallet = create_wallet(dave_keys)?;
|
||||||
|
let sammy_wallet = create_wallet(sammy_keys)?;
|
||||||
|
|
||||||
let dave_address = dave_wallet.get_address(AddressIndex::Peek(0))?.to_string();
|
let dave_address = dave_wallet.get_address(AddressIndex::Peek(0))?.to_string();
|
||||||
let sammy_address = sammy_wallet.get_address(AddressIndex::Peek(0))?.to_string();
|
let sammy_address = sammy_wallet.get_address(AddressIndex::Peek(0))?.to_string();
|
||||||
@@ -36,14 +41,30 @@ pub async fn run() -> Result<(), anyhow::Error> {
|
|||||||
println!("About to sign the transaction: {:?}", details);
|
println!("About to sign the transaction: {:?}", details);
|
||||||
|
|
||||||
dave_wallet.sign(&mut psbt, SignOptions::default())?;
|
dave_wallet.sign(&mut psbt, SignOptions::default())?;
|
||||||
let signed_tx = psbt.extract_tx();
|
let _signed_tx = psbt.extract_tx();
|
||||||
|
|
||||||
println!("Broadcasting...");
|
// println!("Broadcasting...");
|
||||||
blockchain.broadcast(&signed_tx).expect("broadcast error");
|
// blockchain.broadcast(&signed_tx).expect("broadcast error");
|
||||||
println!("Transaction ID: {:?}", signed_tx.txid());
|
// println!("Transaction ID: {:?}", signed_tx.txid());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a BDK wallet using BIP 84 descriptor ("m/84h/1h/0h/0" and "m/84h/1h/0h/1")
|
||||||
|
pub fn create_wallet(
|
||||||
|
keys: (Bip84<ExtendedPrivKey>, Option<Bip84<ExtendedPrivKey>>),
|
||||||
|
) -> anyhow::Result<Wallet<MemoryDatabase>> {
|
||||||
|
let (external_descriptor, internal_descriptor) = keys;
|
||||||
|
|
||||||
|
let wallet = Wallet::new(
|
||||||
|
external_descriptor,
|
||||||
|
internal_descriptor,
|
||||||
|
Network::Testnet,
|
||||||
|
MemoryDatabase::default(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(wallet)
|
||||||
|
}
|
||||||
|
|
||||||
fn display_balance(wallet: &Wallet<MemoryDatabase>) {
|
fn display_balance(wallet: &Wallet<MemoryDatabase>) {
|
||||||
println!(
|
println!(
|
||||||
"Wallet balance for {} after syncing: {:?} sats on network {}",
|
"Wallet balance for {} after syncing: {:?} sats on network {}",
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
use bdk::{
|
use bdk::{
|
||||||
bitcoin::Network,
|
bitcoin::{bip32::ExtendedPrivKey, Network},
|
||||||
database::MemoryDatabase,
|
|
||||||
keys::{
|
keys::{
|
||||||
bip39::{Language, Mnemonic, WordCount},
|
bip39::{Language, Mnemonic, WordCount},
|
||||||
DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey,
|
DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey,
|
||||||
},
|
},
|
||||||
miniscript,
|
miniscript,
|
||||||
template::Bip84,
|
template::Bip84,
|
||||||
KeychainKind, Wallet,
|
KeychainKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
@@ -32,7 +31,9 @@ pub(crate) fn write(mnemonic_path: &PathBuf) -> Result<(), std::io::Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Signet Bitcoin descriptor wallet from a mnemonic
|
/// Creates a Signet Bitcoin descriptor wallet from a mnemonic
|
||||||
pub fn create_wallet(mnemonic_words: String) -> anyhow::Result<Wallet<MemoryDatabase>> {
|
pub fn get(
|
||||||
|
mnemonic_words: String,
|
||||||
|
) -> anyhow::Result<(Bip84<ExtendedPrivKey>, Option<Bip84<ExtendedPrivKey>>)> {
|
||||||
let mnemonic = Mnemonic::parse(mnemonic_words).unwrap();
|
let mnemonic = Mnemonic::parse(mnemonic_words).unwrap();
|
||||||
|
|
||||||
// Generate the extended key
|
// Generate the extended key
|
||||||
@@ -41,20 +42,17 @@ pub fn create_wallet(mnemonic_words: String) -> anyhow::Result<Wallet<MemoryData
|
|||||||
// Get private key from the extended key
|
// Get private key from the extended key
|
||||||
let xprv = xkey.into_xprv(Network::Signet).unwrap();
|
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 external_descriptor = Bip84(xprv, KeychainKind::External);
|
||||||
let wallet = Wallet::new(
|
let internal_descriptor = Some(Bip84(xprv, KeychainKind::Internal));
|
||||||
Bip84(xprv, KeychainKind::External),
|
|
||||||
Some(Bip84(xprv, KeychainKind::Internal)),
|
|
||||||
Network::Testnet,
|
|
||||||
MemoryDatabase::default(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(wallet)
|
Ok((external_descriptor, internal_descriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn load_from_file(side_dir: &PathBuf) -> anyhow::Result<Wallet<MemoryDatabase>> {
|
pub(crate) fn load_from_file(
|
||||||
|
side_dir: &PathBuf,
|
||||||
|
) -> anyhow::Result<(Bip84<ExtendedPrivKey>, Option<Bip84<ExtendedPrivKey>>)> {
|
||||||
let mnemonic_path = crate::utils::side_paths(side_dir.clone()).1; // TODO: this tuple stinks
|
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");
|
let mnemonic_words = fs::read_to_string(mnemonic_path).expect("couldn't read bitcoin key file");
|
||||||
println!("Creating wallet from mnemonic: {mnemonic_words}");
|
println!("Creating wallet from mnemonic: {mnemonic_words}");
|
||||||
create_wallet(mnemonic_words)
|
get(mnemonic_words)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ async fn setup(name: &String) -> SideNode {
|
|||||||
// First, load up the keys and create a bft-crdt
|
// First, load up the keys and create a bft-crdt
|
||||||
let side_dir = utils::home(name);
|
let side_dir = utils::home(name);
|
||||||
let bft_crdt_keys = keys::bft_crdt::load_from_file(&side_dir);
|
let bft_crdt_keys = keys::bft_crdt::load_from_file(&side_dir);
|
||||||
let bitcoin_wallet = keys::bitcoin::load_from_file(&side_dir).unwrap();
|
let bitcoin_keys = keys::bitcoin::load_from_file(&side_dir).unwrap();
|
||||||
|
let bitcoin_wallet = clients::btc_electrum_client::create_wallet(bitcoin_keys).unwrap();
|
||||||
let crdt = BaseCrdt::<TransactionList>::new(&bft_crdt_keys);
|
let crdt = BaseCrdt::<TransactionList>::new(&bft_crdt_keys);
|
||||||
|
|
||||||
// Channels for internal communication, and a tokio task for stdin input
|
// Channels for internal communication, and a tokio task for stdin input
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ use bft_json_crdt::{
|
|||||||
json_crdt::{BaseCrdt, SignedOp},
|
json_crdt::{BaseCrdt, SignedOp},
|
||||||
keypair::make_keypair,
|
keypair::make_keypair,
|
||||||
};
|
};
|
||||||
use side_node::{clients::websocket::Client, crdt::TransactionList, keys, node::SideNode, utils};
|
use side_node::{
|
||||||
|
clients::{btc_electrum_client, websocket::Client},
|
||||||
|
crdt::TransactionList,
|
||||||
|
keys,
|
||||||
|
node::SideNode,
|
||||||
|
utils,
|
||||||
|
};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -36,7 +42,8 @@ async fn setup(_: &str) -> SideNode {
|
|||||||
// First, load up the keys and create a bft-crdt
|
// First, load up the keys and create a bft-crdt
|
||||||
let bft_crdt_keys = make_keypair();
|
let bft_crdt_keys = make_keypair();
|
||||||
let mnemonic_words = keys::bitcoin::make_mnemonic();
|
let mnemonic_words = keys::bitcoin::make_mnemonic();
|
||||||
let bitcoin_wallet = keys::bitcoin::create_wallet(mnemonic_words).unwrap();
|
let bitcoin_keys = keys::bitcoin::get(mnemonic_words).unwrap();
|
||||||
|
let bitcoin_wallet = btc_electrum_client::create_wallet(bitcoin_keys).unwrap();
|
||||||
let crdt = BaseCrdt::<TransactionList>::new(&bft_crdt_keys);
|
let crdt = BaseCrdt::<TransactionList>::new(&bft_crdt_keys);
|
||||||
|
|
||||||
// Channels for internal communication, and a tokio task for stdin input
|
// Channels for internal communication, and a tokio task for stdin input
|
||||||
|
|||||||
Reference in New Issue
Block a user