Skip to content

Commit 618bf39

Browse files
committed
fix descriptors generation
1 parent 193b9cd commit 618bf39

File tree

4 files changed

+127
-391
lines changed

4 files changed

+127
-391
lines changed

src/commands.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ use bdk_wallet::bitcoin::{
1717
Address, Network, OutPoint, ScriptBuf,
1818
bip32::{DerivationPath, Xpriv},
1919
};
20-
use clap::{Args, Parser, Subcommand, ValueEnum, builder::TypedValueParser, value_parser};
20+
use clap::{
21+
Args, Parser, Subcommand, ValueEnum,
22+
builder::{PossibleValuesParser, TypedValueParser},
23+
value_parser,
24+
};
2125

2226
#[cfg(any(feature = "electrum", feature = "esplora", feature = "rpc"))]
2327
use crate::utils::parse_proxy_auth;
@@ -492,7 +496,7 @@ pub enum DescriptorSubCommand {
492496
#[arg(
493497
long = "type",
494498
short = 't',
495-
value_parser = clap::builder::PossibleValuesParser::new(["44", "49", "84", "86"])
499+
value_parser = PossibleValuesParser::new(["44", "49", "84", "86"])
496500
.map(|s| s.parse::<u8>().unwrap()),
497501
default_value = "84"
498502
)]
@@ -503,7 +507,4 @@ pub enum DescriptorSubCommand {
503507
/// Optional key input
504508
key: Option<String>,
505509
},
506-
507-
/// Show info about a given descriptor
508-
Info { descriptor: String },
509510
}

src/error.rs

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use thiserror::Error;
55

66
#[derive(Debug, Error)]
77
pub enum BDKCliError {
8-
#[error("BIP39 error: {0}")]
9-
BIP39Error(#[from] bdk_wallet::bip39::Error),
8+
#[error("BIP39 error: {0:?}")]
9+
BIP39Error(#[from] Option<bdk_wallet::bip39::Error>),
1010

1111
#[error("BIP32 error: {0}")]
1212
BIP32Error(#[from] bdk_wallet::bitcoin::bip32::Error),
@@ -103,30 +103,6 @@ pub enum BDKCliError {
103103
#[cfg(feature = "cbf")]
104104
#[error("BDK-Kyoto update error: {0}")]
105105
KyotoUpdateError(#[from] bdk_kyoto::UpdateError),
106-
107-
#[error("Mnemonic generation failed: {0}")]
108-
MnemonicGenerationError(String),
109-
110-
#[error("Xpriv creation failed: {0}")]
111-
XprivCreationError(String),
112-
113-
#[error("Descriptor parsing failed: {0}")]
114-
DescriptorParsingError(String),
115-
116-
#[error("Invalid extended key (xpub): {0}")]
117-
InvalidKey(String),
118-
119-
#[error("Invalid derivation path: {0}")]
120-
InvalidDerivationPath(String),
121-
122-
#[error("Unsupported script type: {0}")]
123-
UnsupportedScriptType(u8),
124-
125-
#[error("Descriptor key conversion failed: {0}")]
126-
DescriptorKeyError(String),
127-
128-
#[error("Invalid arguments: {0}")]
129-
InvalidArguments(String),
130106
}
131107

132108
impl From<ExtractTxError> for BDKCliError {

src/handlers.rs

Lines changed: 33 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ use crate::commands::*;
1515
use crate::error::BDKCliError as Error;
1616
#[cfg(any(feature = "sqlite", feature = "redb"))]
1717
use crate::persister::Persister;
18-
#[cfg(feature = "cbf")]
19-
use crate::utils::BlockchainClient::KyotoClient;
2018
use crate::utils::*;
2119
#[cfg(feature = "redb")]
2220
use bdk_redb::Store as RedbStore;
@@ -35,58 +33,41 @@ use bdk_wallet::keys::{
3533
bip39::WordCount,
3634
};
3735
use bdk_wallet::miniscript::miniscript;
38-
use bdk_wallet::bitcoin::bip32::{DerivationPath, KeySource};
39-
use bdk_wallet::bitcoin::consensus::encode::serialize_hex;
40-
use bdk_wallet::bitcoin::script::PushBytesBuf;
41-
use bdk_wallet::bitcoin::Network;
42-
use bdk_wallet::bitcoin::{secp256k1::Secp256k1, Txid};
43-
use bdk_wallet::bitcoin::{Amount, FeeRate, Psbt, Sequence};
44-
use bdk_wallet::descriptor::{Descriptor, Segwitv0};
45-
use bdk_wallet::keys::bip39::WordCount;
4636
#[cfg(feature = "sqlite")]
4737
use bdk_wallet::rusqlite::Connection;
4838
use bdk_wallet::{KeychainKind, SignOptions, Wallet};
4939
#[cfg(feature = "compiler")]
5040
use bdk_wallet::{
41+
bitcoin::XOnlyPublicKey,
5142
descriptor::{Descriptor, Legacy, Miniscript},
52-
miniscript::{Tap, descriptor::TapTree, policy::Concrete},
5343
descriptor::{Legacy, Miniscript},
5444
miniscript::policy::Concrete,
45+
miniscript::{Tap, descriptor::TapTree, policy::Concrete},
5546
};
5647
use cli_table::{Cell, CellStruct, Style, Table, format::Justify};
5748
use serde_json::json;
58-
use bdk_wallet::{KeychainKind, SignOptions, Wallet};
49+
#[cfg(feature = "cbf")]
50+
use {
51+
crate::utils::BlockchainClient::KyotoClient,
52+
bdk_kyoto::{Info, LightClient},
53+
tokio::select,
54+
};
5955

6056
#[cfg(feature = "electrum")]
6157
use crate::utils::BlockchainClient::Electrum;
62-
#[cfg(feature = "cbf")]
63-
use bdk_kyoto::{Info, LightClient};
64-
#[cfg(feature = "compiler")]
65-
use bdk_wallet::bitcoin::XOnlyPublicKey;
58+
#[cfg(feature = "electrum")]
59+
use crate::utils::BlockchainClient::Electrum;
6660
use bdk_wallet::bitcoin::base64::prelude::*;
67-
use bdk_wallet::keys::DescriptorKey::Secret;
68-
use bdk_wallet::keys::{
69-
DerivableKey, DescriptorKey, DescriptorKey::Secret, DescriptorPublicKey, ExtendedKey,
70-
GeneratableKey, GeneratedKey, bip39::WordCount,
71-
};
72-
use bdk_wallet::miniscript::miniscript;
73-
use serde_json::{Value, json};
61+
use serde_json::Value;
7462
use std::collections::BTreeMap;
7563
#[cfg(any(feature = "electrum", feature = "esplora"))]
7664
use std::collections::HashSet;
7765
use std::convert::TryFrom;
78-
use std::fmt;
7966
#[cfg(any(feature = "repl", feature = "electrum", feature = "esplora"))]
8067
use std::io::Write;
8168
use std::str::FromStr;
82-
83-
#[cfg(feature = "electrum")]
84-
use crate::utils::BlockchainClient::Electrum;
85-
#[cfg(feature = "cbf")]
86-
use bdk_kyoto::{Info, LightClient};
87-
use bdk_wallet::bitcoin::base64::prelude::*;
88-
#[cfg(feature = "cbf")]
89-
use tokio::select;
69+
#[cfg(any(feature = "redb", feature = "compiler"))]
70+
use std::sync::Arc;
9071
#[cfg(any(
9172
feature = "electrum",
9273
feature = "esplora",
@@ -95,7 +76,7 @@ use tokio::select;
9576
))]
9677
use {
9778
crate::commands::OnlineWalletSubCommand::*,
98-
bdk_wallet::bitcoin::{consensus::Decodable, hex::FromHex, Transaction},
79+
bdk_wallet::bitcoin::{Transaction, consensus::Decodable, hex::FromHex},
9980
};
10081
#[cfg(feature = "esplora")]
10182
use {crate::utils::BlockchainClient::Esplora, bdk_esplora::EsploraAsyncExt};
@@ -1307,8 +1288,7 @@ pub(crate) async fn handle_command(cli_opts: CliOpts) -> Result<String, Error> {
13071288
subcommand: descriptor_subcommand,
13081289
} => {
13091290
let network = cli_opts.network;
1310-
let descriptor = handle_descriptor_subcommand(network, descriptor_subcommand)
1311-
.map_err(|e| Error::Generic(e.to_string()))?;
1291+
let descriptor = handle_descriptor_subcommand(network, descriptor_subcommand)?;
13121292
let json = serde_json::to_string_pretty(&descriptor)?;
13131293
Ok(json)
13141294
}
@@ -1395,84 +1375,35 @@ pub fn handle_descriptor_subcommand(
13951375
multipath,
13961376
key,
13971377
} => {
1398-
let (descriptor_type, derivation_path_str) = match r#type {
1399-
44 => (DescriptorType::Bip44, "m/44h/1h/0h"),
1400-
49 => (DescriptorType::Bip49, "m/49h/1h/0h"),
1401-
84 => (DescriptorType::Bip84, "m/84h/1h/0h"),
1402-
86 => (DescriptorType::Bip86, "m/86h/1h/0h"),
1403-
_ => return Err(Error::UnsupportedScriptType(r#type)),
1378+
let descriptor_type = match r#type {
1379+
44 => DescriptorType::Bip44,
1380+
49 => DescriptorType::Bip49,
1381+
84 => DescriptorType::Bip84,
1382+
86 => DescriptorType::Bip86,
1383+
_ => {
1384+
return Err(Error::Generic(
1385+
"Unsupported script type: {r#type}".to_string(),
1386+
));
1387+
}
14041388
};
14051389

14061390
match (multipath, key.as_ref()) {
1407-
(true, Some(k)) => generate_multipath_descriptor(&network, r#type, k),
1391+
// generate multipath descriptors
1392+
(true, Some(k)) => generate_descriptors(&network, descriptor_type, k, true),
14081393
(false, Some(k)) => {
14091394
if is_mnemonic(k) {
1410-
generate_descriptor_from_mnemonic_string(
1411-
k,
1412-
network,
1413-
derivation_path_str,
1414-
descriptor_type,
1415-
)
1395+
// generate descriptors from given mnemonic string
1396+
generate_descriptor_from_mnemonic_string(k, network, descriptor_type)
14161397
} else {
1417-
generate_standard_descriptor(&network, r#type, k)
1398+
// generate descriptors from key
1399+
generate_descriptors(&network, descriptor_type, k, false)
14181400
}
14191401
}
1402+
// generate mnemonic and descriptors
14201403
(false, None) => generate_new_descriptor_with_mnemonic(network, descriptor_type),
1421-
_ => Err(Error::InvalidArguments(
1422-
"Provide a key or weak string".to_string(),
1423-
)),
1404+
_ => Err(Error::Generic("Provide a key or string".to_string())),
14241405
}
14251406
}
1426-
DescriptorSubCommand::Info { descriptor } => {
1427-
let parsed: Descriptor<DescriptorPublicKey> = descriptor
1428-
.parse()
1429-
.map_err(|e| Error::Generic(format!("Failed to parse descriptor: {}", e)))?;
1430-
1431-
let checksum = parsed.to_string();
1432-
let script_type = match parsed {
1433-
Descriptor::Wpkh(_) => "wpkh",
1434-
Descriptor::Pkh(_) => "pkh",
1435-
Descriptor::Sh(_) => "sh",
1436-
Descriptor::Tr(_) => "tr",
1437-
_ => "other",
1438-
};
1439-
1440-
let json = json!({
1441-
"descriptor": checksum,
1442-
"type": script_type,
1443-
"is_multipath": descriptor.contains("/*"),
1444-
});
1445-
1446-
Ok(json)
1447-
}
1448-
}
1449-
}
1450-
1451-
pub fn generate_standard_descriptor(
1452-
network: &Network,
1453-
script_type: u8,
1454-
key: &str,
1455-
) -> Result<Value, Error> {
1456-
let descriptor_type = match script_type {
1457-
44 => DescriptorType::Bip44,
1458-
49 => DescriptorType::Bip49,
1459-
84 => DescriptorType::Bip84,
1460-
86 => DescriptorType::Bip86,
1461-
_ => return Err(Error::UnsupportedScriptType(script_type)),
1462-
};
1463-
1464-
generate_descriptor_from_key_by_type(network, key, descriptor_type)
1465-
}
1466-
1467-
impl fmt::Display for DescriptorType {
1468-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1469-
let s = match self {
1470-
DescriptorType::Bip44 => "bip44",
1471-
DescriptorType::Bip49 => "bip49",
1472-
DescriptorType::Bip84 => "bip84",
1473-
DescriptorType::Bip86 => "bip86",
1474-
};
1475-
write!(f, "{}", s)
14761407
}
14771408
}
14781409

0 commit comments

Comments
 (0)