Derive bitcoin private key from seed

This commit is contained in:
rishflab 2021-02-09 17:23:13 +11:00
parent a51194b9fa
commit 4768c79070
5 changed files with 64 additions and 15 deletions

View File

@ -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?;

View File

@ -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?;

View File

@ -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<Self> {
// 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,

View File

@ -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<ExtendedPrivKey> {
let private_key = ExtendedPrivKey::new_master(network, &self.bytes())?;
Ok(private_key)
}
pub fn bytes(&self) -> [u8; SEED_LENGTH] {
self.0
}

View File

@ -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<bitcoin::Wallet>, Arc<monero::Wallet>) {
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");