Skip to content

Commit 0881d45

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 b9cf2ac commit 0881d45

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
@@ -241,6 +241,11 @@ where
241241
let ext_descriptor = wallet_opts.ext_descriptor.clone();
242242
let int_descriptor = wallet_opts.int_descriptor.clone();
243243

244+
let is_multipath = ext_descriptor.contains('<') && ext_descriptor.contains(';');
245+
if is_multipath && int_descriptor.is_some() {
246+
return Err(Error::AmbiguousDescriptors);
247+
}
248+
244249
let mut wallet_load_params = Wallet::load();
245250
wallet_load_params =
246251
wallet_load_params.descriptor(KeychainKind::External, Some(ext_descriptor.clone()));
@@ -258,16 +263,20 @@ where
258263

259264
let wallet = match wallet_opt {
260265
Some(wallet) => wallet,
261-
None => match int_descriptor {
262-
Some(int_descriptor) => Wallet::create(ext_descriptor, int_descriptor)
263-
.network(network)
264-
.create_wallet(persister)
265-
.map_err(|e| Error::Generic(e.to_string()))?,
266-
None => Wallet::create_single(ext_descriptor)
266+
None => {
267+
let builder = if let Some(int_descriptor) = int_descriptor {
268+
Wallet::create(ext_descriptor, int_descriptor)
269+
} else if ext_descriptor.contains('<') && ext_descriptor.contains(';') {
270+
Wallet::create_from_two_path_descriptor(ext_descriptor)
271+
} else {
272+
Wallet::create_single(ext_descriptor)
273+
};
274+
275+
builder
267276
.network(network)
268277
.create_wallet(persister)
269-
.map_err(|e| Error::Generic(e.to_string()))?,
270-
},
278+
.map_err(|e| Error::Generic(e.to_string()))?
279+
}
271280
};
272281

273282
Ok(wallet)
@@ -279,20 +288,21 @@ pub(crate) fn new_wallet(network: Network, wallet_opts: &WalletOpts) -> Result<W
279288
let ext_descriptor = wallet_opts.ext_descriptor.clone();
280289
let int_descriptor = wallet_opts.int_descriptor.clone();
281290

282-
match int_descriptor {
283-
Some(int_descriptor) => {
284-
let wallet = Wallet::create(ext_descriptor, int_descriptor)
285-
.network(network)
286-
.create_wallet_no_persist()?;
287-
Ok(wallet)
288-
}
289-
None => {
290-
let wallet = Wallet::create_single(ext_descriptor)
291-
.network(network)
292-
.create_wallet_no_persist()?;
293-
Ok(wallet)
294-
}
291+
let is_multipath = ext_descriptor.contains('<') && ext_descriptor.contains(';');
292+
if is_multipath && int_descriptor.is_some() {
293+
return Err(Error::AmbiguousDescriptors);
295294
}
295+
296+
let builder = if let Some(int_descriptor) = int_descriptor {
297+
Wallet::create(ext_descriptor, int_descriptor)
298+
} else if ext_descriptor.contains('<') && ext_descriptor.contains(';') {
299+
Wallet::create_from_two_path_descriptor(ext_descriptor)
300+
} else {
301+
Wallet::create_single(ext_descriptor)
302+
};
303+
304+
let wallet = builder.network(network).create_wallet_no_persist()?;
305+
Ok(wallet)
296306
}
297307

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

0 commit comments

Comments
 (0)