Skip to content

Commit fe89838

Browse files
committed
Merge #346: refactor(compile): use ValueEnum for script type
79b2b83 test(compile): cover sh and sh-wsh script types (Ikeh Celestine Chukwudi) 36e41a3 refactor(compile): use ValueEnum for script type (Ikeh Celestine Chukwudi) Pull request description: ### Description This PR replaces the `String` `script_type` in `CompileCommand` with a `ScriptType` enum deriving `clap::ValueEnum`. The goal is to make the `match` in `execute` exhaustive and keep the list of accepted script types in one place, instead of repeating it in the argument definition and in the match. Fixes #345 ### Notes to the reviewers The change is limited to `src/handlers/descriptor.rs` and follows the existing `DatabaseType` enum in `src/persister.rs`. * Added the `ScriptType` enum with the variants `Sh`, `Wsh`, `ShWsh` and `Tr`, gated behind the `compiler` feature like the rest of the `compile` command. * Changed `script_type` from `String` to `ScriptType`, replacing the hand-written `value_parser` list with `value_enum`. * The `match` in `execute` now matches on the enum variants. * Removed the `_ =>` arm returning "Invalid script type", which was unreachable because clap already rejects any other value. There is no CLI behavior change. clap renders the variants in kebab-case, so `--type` still accepts `sh`, `wsh`, `sh-wsh` and `tr`, the default is still `wsh`, and the `TYPE` env var still works. I checked manually that `compile --type sh-wsh` produces the same descriptor before and after the change, and the existing `compile` tests pass. ### Changelog notice None. This is an internal refactor with no user-facing change. ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk-cli/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing ACKs for top commit: tvpeter: ACK 79b2b83 Tree-SHA512: cb8ab8fef5d109149740f22c20d6bee768079d082f3f84b7cb80541b605b66f2235d386ff080d4e31b24285a8e7935ab87deeae500abf9895f91d766226ba500
2 parents 4f4d8ca + 79b2b83 commit fe89838

2 files changed

Lines changed: 45 additions & 13 deletions

File tree

‎src/handlers/descriptor.rs‎

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use crate::{
1313
};
1414
use clap::Parser;
1515
#[cfg(feature = "compiler")]
16+
use clap::ValueEnum;
17+
#[cfg(feature = "compiler")]
1618
use {
1719
bdk_wallet::{
1820
bitcoin::{
@@ -70,9 +72,24 @@ pub struct CompileCommand {
7072
#[arg(env = "POLICY", required = true, index = 1)]
7173
policy: String,
7274
/// Sets the script type used to embed the compiled policy.
73-
#[arg(env = "TYPE", short = 't', long = "type", default_value = "wsh", value_parser = ["sh","wsh", "sh-wsh", "tr"]
74-
)]
75-
script_type: String,
75+
#[arg(
76+
env = "TYPE",
77+
short = 't',
78+
long = "type",
79+
value_enum,
80+
default_value_t = ScriptType::Wsh
81+
)]
82+
script_type: ScriptType,
83+
}
84+
85+
/// Script types the compiled policy can be embedded in.
86+
#[cfg(feature = "compiler")]
87+
#[derive(Clone, Copy, ValueEnum, Debug, Eq, PartialEq)]
88+
pub enum ScriptType {
89+
Sh,
90+
Wsh,
91+
ShWsh,
92+
Tr,
7693
}
7794

7895
#[cfg(feature = "compiler")]
@@ -87,11 +104,11 @@ impl AppCommand<AppContext<Init>> for CompileCommand {
87104

88105
// Compile per branch, not once up front: the contexts have different script
89106
// limits, and the narrowest one would reject policies valid for the requested type.
90-
let descriptor = match self.script_type.as_str() {
91-
"sh" => Descriptor::new_sh(policy.compile()?),
92-
"wsh" => Descriptor::new_wsh(policy.compile()?),
93-
"sh-wsh" => Descriptor::new_sh_wsh(policy.compile()?),
94-
"tr" => {
107+
let descriptor = match self.script_type {
108+
ScriptType::Sh => Descriptor::new_sh(policy.compile()?),
109+
ScriptType::Wsh => Descriptor::new_wsh(policy.compile()?),
110+
ScriptType::ShWsh => Descriptor::new_sh_wsh(policy.compile()?),
111+
ScriptType::Tr => {
95112
// Use a randomized unspendable internal key (H + rG) instead of a fixed NUMS
96113
// point. This improves privacy by preventing observers from determining whether
97114
// key-path spending is disabled. `r` is returned so the user can verify the key
@@ -113,11 +130,6 @@ impl AppCommand<AppContext<Init>> for CompileCommand {
113130
let tree = TapTree::Leaf(Arc::new(policy.compile()?));
114131
Descriptor::new_tr(xonly_internal_key.to_string(), Some(tree))
115132
}
116-
_ => {
117-
return Err(Error::Generic(
118-
"Invalid script type. Supported: sh, wsh, sh-wsh, tr".into(),
119-
));
120-
}
121133
}?;
122134

123135
Ok(DescriptorResult {

‎tests/integration/init.rs‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,26 @@ mod test_compile {
223223
.stdout(predicate::str::contains("wsh("));
224224
}
225225

226+
#[test]
227+
fn test_compile_sh_and_sh_wsh() {
228+
let temp_dir = TempDir::new().unwrap();
229+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
230+
231+
let policy = "pk(02e5b88fdb71c696e1a473f309a47535b7190e21a22bd25e7fc8bd055db3bba12f)";
232+
233+
// compile sh
234+
cli.cmd("compile", &[policy, "--type", "sh"])
235+
.assert()
236+
.success()
237+
.stdout(predicate::str::contains("\"descriptor\": \"sh(pk("));
238+
239+
// compile sh-wsh
240+
cli.cmd("compile", &[policy, "--type", "sh-wsh"])
241+
.assert()
242+
.success()
243+
.stdout(predicate::str::contains("\"descriptor\": \"sh(wsh(pk("));
244+
}
245+
226246
#[test]
227247
fn test_compile_invalid_policy() {
228248
let temp_dir = TempDir::new().unwrap();

0 commit comments

Comments
 (0)