Skip to content

Commit cb49166

Browse files
committed
feat: descriptor wallet support
1 parent cc8ed9c commit cb49166

2 files changed

Lines changed: 42 additions & 8 deletions

File tree

bitcoin/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ pub enum Error {
7979
AddressError(#[from] AddressError),
8080
#[error("Failed to fetch coinbase tx")]
8181
CoinbaseFetchingFailure,
82+
#[error("InvalidDescriptor")]
83+
InvalidDescriptor,
8284
}
8385

8486
impl Error {

bitcoin/src/lib.rs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ mod iter;
1313

1414
use async_trait::async_trait;
1515
use backoff::{backoff::Backoff, future::retry, ExponentialBackoff};
16+
use bitcoincore_rpc::{
17+
bitcoin::consensus::encode::serialize_hex,
18+
bitcoincore_rpc_json::{GetDescriptorInfoResult, ImportDescriptors, ScanningDetails, Timestamp},
19+
};
1620
pub use bitcoincore_rpc::{
1721
bitcoin as bitcoin_primitives,
1822
bitcoin::{
@@ -74,7 +78,7 @@ pub const DEFAULT_MAX_TX_COUNT: usize = 100_000_000;
7478
/// the bitcoin core version.
7579
/// See https://github.com/bitcoin/bitcoin/blob/833add0f48b0fad84d7b8cf9373a349e7aef20b4/src/rpc/net.cpp#L627
7680
/// and https://github.com/bitcoin/bitcoin/blob/833add0f48b0fad84d7b8cf9373a349e7aef20b4/src/clientversion.h#L33-L37
77-
pub const BITCOIN_CORE_VERSION_23: usize = 230_000;
81+
pub const BITCOIN_CORE_VERSION_26: usize = 260_000;
7882
const NOT_IN_MEMPOOL_ERROR_CODE: i32 = BitcoinRpcError::RpcInvalidAddressOrKey as i32;
7983

8084
// Time to sleep before retry on startup.
@@ -283,7 +287,7 @@ async fn connect(rpc: &Client, connection_timeout: Duration) -> Result<Network,
283287
info!("Connected to {}", chain);
284288
info!("Bitcoin version {}", version);
285289

286-
if version >= BITCOIN_CORE_VERSION_23 {
290+
if version >= BITCOIN_CORE_VERSION_26 {
287291
return Err(Error::IncompatibleVersion(version))
288292
}
289293

@@ -623,9 +627,38 @@ impl BitcoinCore {
623627
.await
624628
}
625629

626-
pub async fn import_private_key(&self, privkey: PrivateKey) -> Result<(), Error> {
627-
self.with_wallet(|| async { Ok(self.rpc.import_private_key(&privkey, None, None)?) })
628-
.await
630+
pub fn import_private_key(&self, privkey: &PrivateKey, label: Option<&str>) -> Result<(), Error> {
631+
let wallet_info = self.rpc.get_wallet_info()?;
632+
let using_descriptor_wallet = true;
633+
if using_descriptor_wallet {
634+
let bare_descriptor = format!("wpkh({})", privkey.to_string());
635+
636+
let descriptor = match self.rpc.get_descriptor_info(&bare_descriptor)? {
637+
GetDescriptorInfoResult {
638+
has_private_keys: true,
639+
is_solvable: true,
640+
checksum: Some(checksum),
641+
..
642+
} => {
643+
format!("{bare_descriptor}#{checksum}")
644+
}
645+
_ => {
646+
return Err(Error::InvalidDescriptor);
647+
}
648+
};
649+
let desc = ImportDescriptors {
650+
descriptor,
651+
timestamp: Timestamp::Now,
652+
label: label.map(|x| x.to_string()),
653+
..Default::default()
654+
};
655+
656+
self.rpc.import_descriptors(desc)?;
657+
} else {
658+
self.rpc.import_private_key(&privkey, label, Some(false))?;
659+
}
660+
661+
Ok(())
629662
}
630663

631664
pub async fn wait_for_rescan(&self) -> Result<(), Error> {
@@ -794,6 +827,7 @@ impl BitcoinCoreApi for BitcoinCore {
794827
.require_network(self.network)?;
795828
let address_info = self.rpc.get_address_info(&address)?;
796829
let public_key = address_info.pubkey.ok_or(Error::MissingPublicKey)?;
830+
warn!("public key: {}", public_key.to_string());
797831
Ok(public_key)
798832
}
799833

@@ -815,15 +849,13 @@ impl BitcoinCoreApi for BitcoinCore {
815849
let private_key = self.rpc.dump_private_key(&address)?;
816850
let deposit_secret_key =
817851
addr::calculate_deposit_secret_key(private_key.inner, SecretKey::from_slice(&secret_key)?)?;
818-
self.rpc.import_private_key(
852+
self.import_private_key(
819853
&PrivateKey {
820854
compressed: private_key.compressed,
821855
network: self.network,
822856
inner: deposit_secret_key,
823857
},
824858
Some(DEPOSIT_LABEL),
825-
// rescan true by default
826-
Some(false),
827859
)?;
828860
Ok(())
829861
}

0 commit comments

Comments
 (0)