Skip to content

Commit 3ba1dc0

Browse files
committed
fix descriptors generation
1 parent dd58621 commit 3ba1dc0

4 files changed

Lines changed: 110 additions & 374 deletions

File tree

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: 20 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,6 @@ use bdk_wallet::keys::{
3535
bip39::WordCount,
3636
};
3737
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;
4638
#[cfg(feature = "sqlite")]
4739
use bdk_wallet::rusqlite::Connection;
4840
use bdk_wallet::{KeychainKind, SignOptions, Wallet};
@@ -55,7 +47,6 @@ use bdk_wallet::{
5547
};
5648
use cli_table::{Cell, CellStruct, Style, Table, format::Justify};
5749
use serde_json::json;
58-
use bdk_wallet::{KeychainKind, SignOptions, Wallet};
5950

6051
#[cfg(feature = "electrum")]
6152
use crate::utils::BlockchainClient::Electrum;
@@ -64,18 +55,11 @@ use bdk_kyoto::{Info, LightClient};
6455
#[cfg(feature = "compiler")]
6556
use bdk_wallet::bitcoin::XOnlyPublicKey;
6657
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};
58+
use serde_json::Value;
7459
use std::collections::BTreeMap;
7560
#[cfg(any(feature = "electrum", feature = "esplora"))]
7661
use std::collections::HashSet;
7762
use std::convert::TryFrom;
78-
use std::fmt;
7963
#[cfg(any(feature = "repl", feature = "electrum", feature = "esplora"))]
8064
use std::io::Write;
8165
use std::str::FromStr;
@@ -84,7 +68,6 @@ use std::str::FromStr;
8468
use crate::utils::BlockchainClient::Electrum;
8569
#[cfg(feature = "cbf")]
8670
use bdk_kyoto::{Info, LightClient};
87-
use bdk_wallet::bitcoin::base64::prelude::*;
8871
#[cfg(feature = "cbf")]
8972
use tokio::select;
9073
#[cfg(any(
@@ -1307,8 +1290,7 @@ pub(crate) async fn handle_command(cli_opts: CliOpts) -> Result<String, Error> {
13071290
subcommand: descriptor_subcommand,
13081291
} => {
13091292
let network = cli_opts.network;
1310-
let descriptor = handle_descriptor_subcommand(network, descriptor_subcommand)
1311-
.map_err(|e| Error::Generic(e.to_string()))?;
1293+
let descriptor = handle_descriptor_subcommand(network, descriptor_subcommand)?;
13121294
let json = serde_json::to_string_pretty(&descriptor)?;
13131295
Ok(json)
13141296
}
@@ -1395,84 +1377,35 @@ pub fn handle_descriptor_subcommand(
13951377
multipath,
13961378
key,
13971379
} => {
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)),
1380+
let descriptor_type = match r#type {
1381+
44 => DescriptorType::Bip44,
1382+
49 => DescriptorType::Bip49,
1383+
84 => DescriptorType::Bip84,
1384+
86 => DescriptorType::Bip86,
1385+
_ => {
1386+
return Err(Error::Generic(
1387+
"Unsupported script type: {r#type}".to_string(),
1388+
));
1389+
}
14041390
};
14051391

14061392
match (multipath, key.as_ref()) {
1407-
(true, Some(k)) => generate_multipath_descriptor(&network, r#type, k),
1393+
// generate multipath descriptors
1394+
(true, Some(k)) => generate_descriptors(&network, descriptor_type, k, true),
14081395
(false, Some(k)) => {
14091396
if is_mnemonic(k) {
1410-
generate_descriptor_from_mnemonic_string(
1411-
k,
1412-
network,
1413-
derivation_path_str,
1414-
descriptor_type,
1415-
)
1397+
// generate descriptors from given mnemonic string
1398+
generate_descriptor_from_mnemonic_string(k, network, descriptor_type)
14161399
} else {
1417-
generate_standard_descriptor(&network, r#type, k)
1400+
// generate descriptors from key
1401+
generate_descriptors(&network, descriptor_type, k, false)
14181402
}
14191403
}
1404+
// generate mnemonic and descriptors
14201405
(false, None) => generate_new_descriptor_with_mnemonic(network, descriptor_type),
1421-
_ => Err(Error::InvalidArguments(
1422-
"Provide a key or weak string".to_string(),
1423-
)),
1406+
_ => Err(Error::Generic("Provide a key or string".to_string())),
14241407
}
14251408
}
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)
14761409
}
14771410
}
14781411

0 commit comments

Comments
 (0)