mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-08-07 05:52:31 -04:00
Derive bitcoin private key from seed
This commit is contained in:
parent
181e7c5096
commit
23cbee842f
3 changed files with 37 additions and 3 deletions
|
@ -13,7 +13,6 @@ use backoff::{backoff::Constant as ConstantBackoff, tokio::retry};
|
||||||
use bdk::{
|
use bdk::{
|
||||||
blockchain::{noop_progress, Blockchain, ElectrumBlockchain},
|
blockchain::{noop_progress, Blockchain, ElectrumBlockchain},
|
||||||
electrum_client::{Client, ElectrumApi},
|
electrum_client::{Client, ElectrumApi},
|
||||||
keys::GeneratableDefaultOptions,
|
|
||||||
FeeRate,
|
FeeRate,
|
||||||
};
|
};
|
||||||
use reqwest::{Method, Url};
|
use reqwest::{Method, Url};
|
||||||
|
@ -36,6 +35,7 @@ impl Wallet {
|
||||||
electrum_http_url: Url,
|
electrum_http_url: Url,
|
||||||
network: bitcoin::Network,
|
network: bitcoin::Network,
|
||||||
datadir: &Path,
|
datadir: &Path,
|
||||||
|
p_key: bitcoin::PrivateKey,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
// todo: Implement conversion to anyhow::error so we can use ?
|
// todo: Implement conversion to anyhow::error so we can use ?
|
||||||
let client =
|
let client =
|
||||||
|
@ -43,8 +43,6 @@ impl Wallet {
|
||||||
|
|
||||||
let db = bdk::sled::open(datadir)?.open_tree(SLED_TREE_NAME)?;
|
let db = bdk::sled::open(datadir)?.open_tree(SLED_TREE_NAME)?;
|
||||||
|
|
||||||
// todo: make key generation configurable using a descriptor
|
|
||||||
let p_key = ::bitcoin::PrivateKey::generate_default()?;
|
|
||||||
let bdk_wallet = bdk::Wallet::new(
|
let bdk_wallet = bdk::Wallet::new(
|
||||||
bdk::template::P2WPKH(p_key),
|
bdk::template::P2WPKH(p_key),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -19,6 +19,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
execution_params::GetExecutionParams,
|
execution_params::GetExecutionParams,
|
||||||
protocol::bob::cancel::CancelError,
|
protocol::bob::cancel::CancelError,
|
||||||
|
seed::Seed,
|
||||||
};
|
};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use database::Database;
|
use database::Database;
|
||||||
|
@ -97,6 +98,7 @@ async fn main() -> Result<()> {
|
||||||
bitcoin_network,
|
bitcoin_network,
|
||||||
&wallet_data_dir,
|
&wallet_data_dir,
|
||||||
monero_network,
|
monero_network,
|
||||||
|
seed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -139,6 +141,7 @@ async fn main() -> Result<()> {
|
||||||
bitcoin_network,
|
bitcoin_network,
|
||||||
&wallet_data_dir,
|
&wallet_data_dir,
|
||||||
monero_network,
|
monero_network,
|
||||||
|
seed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -188,6 +191,7 @@ async fn main() -> Result<()> {
|
||||||
bitcoin_network,
|
bitcoin_network,
|
||||||
&wallet_data_dir,
|
&wallet_data_dir,
|
||||||
monero_network,
|
monero_network,
|
||||||
|
seed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -216,6 +220,7 @@ async fn main() -> Result<()> {
|
||||||
bitcoin_network,
|
bitcoin_network,
|
||||||
&wallet_data_dir,
|
&wallet_data_dir,
|
||||||
monero_network,
|
monero_network,
|
||||||
|
seed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -247,6 +252,7 @@ async fn main() -> Result<()> {
|
||||||
bitcoin_network,
|
bitcoin_network,
|
||||||
&wallet_data_dir,
|
&wallet_data_dir,
|
||||||
monero_network,
|
monero_network,
|
||||||
|
seed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -297,6 +303,7 @@ async fn main() -> Result<()> {
|
||||||
bitcoin_network,
|
bitcoin_network,
|
||||||
&wallet_data_dir,
|
&wallet_data_dir,
|
||||||
monero_network,
|
monero_network,
|
||||||
|
seed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -334,6 +341,7 @@ async fn init_wallets(
|
||||||
bitcoin_network: bitcoin::Network,
|
bitcoin_network: bitcoin::Network,
|
||||||
bitcoin_wallet_data_dir: &Path,
|
bitcoin_wallet_data_dir: &Path,
|
||||||
monero_network: monero::Network,
|
monero_network: monero::Network,
|
||||||
|
seed: Seed,
|
||||||
) -> Result<(bitcoin::Wallet, monero::Wallet)> {
|
) -> Result<(bitcoin::Wallet, monero::Wallet)> {
|
||||||
let config_path = if let Some(config_path) = config_path {
|
let config_path = if let Some(config_path) = config_path {
|
||||||
config_path
|
config_path
|
||||||
|
@ -354,6 +362,7 @@ async fn init_wallets(
|
||||||
config.bitcoin.electrum_http_url,
|
config.bitcoin.electrum_http_url,
|
||||||
bitcoin_network,
|
bitcoin_network,
|
||||||
bitcoin_wallet_data_dir,
|
bitcoin_wallet_data_dir,
|
||||||
|
seed.root_private_key(bitcoin_network),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use ::bitcoin::secp256k1::{self, constants::SECRET_KEY_SIZE, SecretKey};
|
use ::bitcoin::secp256k1::{self, constants::SECRET_KEY_SIZE, SecretKey};
|
||||||
|
use bitcoin::{
|
||||||
|
hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine},
|
||||||
|
PrivateKey,
|
||||||
|
};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
@ -18,6 +22,29 @@ impl Seed {
|
||||||
Ok(Seed(bytes))
|
Ok(Seed(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the private key and chain code to be used as root extended
|
||||||
|
/// private key for a BIP32 wallet.
|
||||||
|
pub fn root_private_key(&self, network: bitcoin::Network) -> PrivateKey {
|
||||||
|
let bytes = self.bytes();
|
||||||
|
|
||||||
|
// Yes, this is as per BIP32 and used in both Bitcoin and Ethereum ecosystems
|
||||||
|
let hash_key = b"Bitcoin seed";
|
||||||
|
|
||||||
|
let mut engine = HmacEngine::<sha512::Hash>::new(hash_key);
|
||||||
|
engine.input(&bytes);
|
||||||
|
let hash = Hmac::<sha512::Hash>::from_engine(engine);
|
||||||
|
let output = &hash.into_inner()[..];
|
||||||
|
let key = &output[..32];
|
||||||
|
|
||||||
|
let secret_key = SecretKey::from_slice(key).expect("32 bytes array should be fine");
|
||||||
|
|
||||||
|
PrivateKey {
|
||||||
|
compressed: true,
|
||||||
|
network,
|
||||||
|
key: secret_key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn bytes(&self) -> [u8; SEED_LENGTH] {
|
pub fn bytes(&self) -> [u8; SEED_LENGTH] {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue