Skip to content

Commit 38d4ca1

Browse files
committed
feat(multipath): Update wallet init for multipath
- Update wallet initialization/creation to check if external descriptor is multipath for both persisted and non persisted wallets - add error variant for when both multipath and internal descriptors are provided
1 parent 15b6f5b commit 38d4ca1

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

src/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ use thiserror::Error;
55

66
#[derive(Debug, Error)]
77
pub enum BDKCliError {
8+
#[error(
9+
"Ambiguous descriptors: cannot provide both a multipath descriptor and a separate internal descriptor."
10+
)]
11+
AmbiguousDescriptors,
12+
813
#[error("BIP39 error: {0:?}")]
914
BIP39Error(#[from] Option<bdk_wallet::bip39::Error>),
1015

src/utils.rs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ where
268268
let ext_descriptor = wallet_opts.ext_descriptor.clone();
269269
let int_descriptor = wallet_opts.int_descriptor.clone();
270270

271+
let is_multipath = ext_descriptor.contains('<') && ext_descriptor.contains(';');
272+
if is_multipath && int_descriptor.is_some() {
273+
return Err(Error::AmbiguousDescriptors);
274+
}
275+
271276
let mut wallet_load_params = Wallet::load();
272277
wallet_load_params =
273278
wallet_load_params.descriptor(KeychainKind::External, Some(ext_descriptor.clone()));
@@ -285,16 +290,20 @@ where
285290

286291
let wallet = match wallet_opt {
287292
Some(wallet) => wallet,
288-
None => match int_descriptor {
289-
Some(int_descriptor) => Wallet::create(ext_descriptor, int_descriptor)
290-
.network(network)
291-
.create_wallet(persister)
292-
.map_err(|e| Error::Generic(e.to_string()))?,
293-
None => Wallet::create_single(ext_descriptor)
293+
None => {
294+
let builder = if let Some(int_descriptor) = int_descriptor {
295+
Wallet::create(ext_descriptor, int_descriptor)
296+
} else if ext_descriptor.contains('<') && ext_descriptor.contains(';') {
297+
Wallet::create_from_two_path_descriptor(ext_descriptor)
298+
} else {
299+
Wallet::create_single(ext_descriptor)
300+
};
301+
302+
builder
294303
.network(network)
295304
.create_wallet(persister)
296-
.map_err(|e| Error::Generic(e.to_string()))?,
297-
},
305+
.map_err(|e| Error::Generic(e.to_string()))?
306+
}
298307
};
299308

300309
Ok(wallet)
@@ -306,20 +315,21 @@ pub(crate) fn new_wallet(network: Network, wallet_opts: &WalletOpts) -> Result<W
306315
let ext_descriptor = wallet_opts.ext_descriptor.clone();
307316
let int_descriptor = wallet_opts.int_descriptor.clone();
308317

309-
match int_descriptor {
310-
Some(int_descriptor) => {
311-
let wallet = Wallet::create(ext_descriptor, int_descriptor)
312-
.network(network)
313-
.create_wallet_no_persist()?;
314-
Ok(wallet)
315-
}
316-
None => {
317-
let wallet = Wallet::create_single(ext_descriptor)
318-
.network(network)
319-
.create_wallet_no_persist()?;
320-
Ok(wallet)
321-
}
318+
let is_multipath = ext_descriptor.contains('<') && ext_descriptor.contains(';');
319+
if is_multipath && int_descriptor.is_some() {
320+
return Err(Error::AmbiguousDescriptors);
322321
}
322+
323+
let builder = if let Some(int_descriptor) = int_descriptor {
324+
Wallet::create(ext_descriptor, int_descriptor)
325+
} else if ext_descriptor.contains('<') && ext_descriptor.contains(';') {
326+
Wallet::create_from_two_path_descriptor(ext_descriptor)
327+
} else {
328+
Wallet::create_single(ext_descriptor)
329+
};
330+
331+
let wallet = builder.network(network).create_wallet_no_persist()?;
332+
Ok(wallet)
323333
}
324334

325335
#[cfg(feature = "cbf")]

0 commit comments

Comments
 (0)