diff --git a/swap/src/bin/nectar.rs b/swap/src/bin/nectar.rs index 23af531e..ee3b3bb4 100644 --- a/swap/src/bin/nectar.rs +++ b/swap/src/bin/nectar.rs @@ -84,8 +84,12 @@ async fn main() -> Result<()> { let execution_params = execution_params::Testnet::get_execution_params(); - let (bitcoin_wallet, monero_wallet) = - init_wallets(config.clone(), &wallet_data_dir).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets( + config.clone(), + &wallet_data_dir, + seed.extended_private_key(BITCOIN_NETWORK)?.private_key, + ) + .await?; let (mut event_loop, _) = EventLoop::new( config.network.listen, @@ -121,12 +125,14 @@ async fn main() -> Result<()> { async fn init_wallets( config: Config, bitcoin_wallet_data_dir: &Path, + private_key: ::bitcoin::PrivateKey, ) -> Result<(bitcoin::Wallet, monero::Wallet)> { let bitcoin_wallet = bitcoin::Wallet::new( config.bitcoin.electrum_rpc_url, config.bitcoin.electrum_http_url, BITCOIN_NETWORK, bitcoin_wallet_data_dir, + private_key, ) .await?; let bitcoin_balance = bitcoin_wallet.balance().await?; diff --git a/swap/src/bin/swap_cli.rs b/swap/src/bin/swap_cli.rs index 67072d59..6546accb 100644 --- a/swap/src/bin/swap_cli.rs +++ b/swap/src/bin/swap_cli.rs @@ -90,8 +90,14 @@ async fn main() -> Result<()> { alice_addr, send_bitcoin, } => { - let (bitcoin_wallet, monero_wallet) = - init_wallets(config, bitcoin_network, &wallet_data_dir, monero_network).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets( + config, + bitcoin_network, + &wallet_data_dir, + monero_network, + seed, + ) + .await?; let swap_id = Uuid::new_v4(); @@ -132,8 +138,14 @@ async fn main() -> Result<()> { alice_peer_id, alice_addr, }) => { - let (bitcoin_wallet, monero_wallet) = - init_wallets(config, bitcoin_network, &wallet_data_dir, monero_network).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets( + config, + bitcoin_network, + &wallet_data_dir, + monero_network, + seed, + ) + .await?; let bob_factory = Builder::new( seed, @@ -157,8 +169,14 @@ async fn main() -> Result<()> { force, }) => { // TODO: Optimization: Only init the Bitcoin wallet, Monero wallet unnecessary - let (bitcoin_wallet, monero_wallet) = - init_wallets(config, bitcoin_network, &wallet_data_dir, monero_network).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets( + config, + bitcoin_network, + &wallet_data_dir, + monero_network, + seed, + ) + .await?; let bob_factory = Builder::new( seed, @@ -201,8 +219,14 @@ async fn main() -> Result<()> { alice_addr, force, }) => { - let (bitcoin_wallet, monero_wallet) = - init_wallets(config, bitcoin_network, &wallet_data_dir, monero_network).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets( + config, + bitcoin_network, + &wallet_data_dir, + monero_network, + seed, + ) + .await?; // TODO: Optimize to only use the Bitcoin wallet, Monero wallet is unnecessary let bob_factory = Builder::new( @@ -238,12 +262,14 @@ async fn init_wallets( bitcoin_network: bitcoin::Network, bitcoin_wallet_data_dir: &Path, monero_network: monero::Network, + seed: Seed, ) -> Result<(bitcoin::Wallet, monero::Wallet)> { let bitcoin_wallet = bitcoin::Wallet::new( config.bitcoin.electrum_rpc_url, config.bitcoin.electrum_http_url, bitcoin_network, bitcoin_wallet_data_dir, + seed.extended_private_key(bitcoin_network)?.private_key, ) .await?; diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index fc7448d1..2c5751f1 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -13,7 +13,7 @@ use backoff::{backoff::Constant as ConstantBackoff, tokio::retry}; use bdk::{ blockchain::{noop_progress, Blockchain, ElectrumBlockchain}, electrum_client::{self, Client, ElectrumApi}, - keys::GeneratableDefaultOptions, + miniscript::bitcoin::PrivateKey, FeeRate, }; use reqwest::{Method, Url}; @@ -43,7 +43,8 @@ impl Wallet { electrum_rpc_url: Url, electrum_http_url: Url, network: bitcoin::Network, - waller_dir: &Path, + wallet_dir: &Path, + private_key: PrivateKey, ) -> Result { // Workaround for https://github.com/bitcoindevkit/rust-electrum-client/issues/47. let config = electrum_client::ConfigBuilder::default().retry(2).build(); @@ -51,11 +52,10 @@ impl Wallet { let client = Client::from_config(electrum_rpc_url.as_str(), config) .map_err(|e| anyhow!("Failed to init electrum rpc client: {:?}", e))?; - let db = bdk::sled::open(waller_dir)?.open_tree(SLED_TREE_NAME)?; + let db = bdk::sled::open(wallet_dir)?.open_tree(SLED_TREE_NAME)?; - let p_key = ::bitcoin::PrivateKey::generate_default()?; let bdk_wallet = bdk::Wallet::new( - bdk::template::P2WPKH(p_key), + bdk::template::P2WPKH(private_key), None, network, db, diff --git a/swap/src/seed.rs b/swap/src/seed.rs index 2a0b3836..48c9d039 100644 --- a/swap/src/seed.rs +++ b/swap/src/seed.rs @@ -1,5 +1,7 @@ use crate::fs::ensure_directory_exists; use ::bitcoin::secp256k1::{self, constants::SECRET_KEY_SIZE, SecretKey}; +use anyhow::Result; +use bdk::bitcoin::util::bip32::ExtendedPrivKey; use pem::{encode, Pem}; use rand::prelude::*; use std::{ @@ -26,6 +28,11 @@ impl Seed { Ok(Seed(bytes)) } + pub fn extended_private_key(&self, network: bitcoin::Network) -> Result { + let private_key = ExtendedPrivKey::new_master(network, &self.bytes())?; + Ok(private_key) + } + pub fn bytes(&self) -> [u8; SEED_LENGTH] { self.0 } diff --git a/swap/tests/testutils/mod.rs b/swap/tests/testutils/mod.rs index 96e0589c..3f8fc49e 100644 --- a/swap/tests/testutils/mod.rs +++ b/swap/tests/testutils/mod.rs @@ -346,6 +346,9 @@ where .get_host_port(testutils::electrs::HTTP_PORT) .expect("Could not map electrs http port"); + let alice_seed = Seed::random().unwrap(); + let bob_seed = Seed::random().unwrap(); + let (alice_bitcoin_wallet, alice_monero_wallet) = init_test_wallets( "alice", containers.bitcoind_url.clone(), @@ -354,6 +357,7 @@ where tempdir().unwrap().path(), electrs_rpc_port, electrs_http_port, + alice_seed, ) .await; @@ -375,6 +379,7 @@ where tempdir().unwrap().path(), electrs_rpc_port, electrs_http_port, + bob_seed, ) .await; @@ -570,6 +575,7 @@ async fn init_monero_container( (monero, monerods) } +#[allow(clippy::too_many_arguments)] async fn init_test_wallets( name: &str, bitcoind_url: Url, @@ -578,6 +584,7 @@ async fn init_test_wallets( datadir: &Path, electrum_rpc_port: u16, electrum_http_port: u16, + seed: Seed, ) -> (Arc, Arc) { monero .init(vec![(name, starting_balances.xmr.as_piconero())]) @@ -603,6 +610,9 @@ async fn init_test_wallets( electrum_http_url, bitcoin::Network::Regtest, datadir, + seed.extended_private_key(bitcoin::Network::Regtest) + .expect("Could not create extended private key from seed") + .private_key, ) .await .expect("could not init btc wallet");