]> Untitled Git - bdk-cli/commitdiff
refactor(compile): lazy compilation and use pipe for readability
authorVadim Anufriev <mailbox@vaan.io>
Tue, 24 Mar 2026 20:12:30 +0000 (00:12 +0400)
committerVadim Anufriev <m@vaan.io>
Wed, 27 May 2026 08:35:23 +0000 (12:35 +0400)
Move miniscript compilation inside match arms to avoid compiling
for all script contexts when only one is needed. Use `tap::Pipe`
for concise method chaining in sh/wsh/sh-wsh branches.

Cargo.lock
Cargo.toml
src/handlers.rs

index f40db91ebc05a007ebe0b97054ef11bdba8fe07a..d984ac41a0f535cddaafbb1326a3291b21657263 100644 (file)
@@ -216,6 +216,7 @@ dependencies = [
  "serde",
  "serde_json",
  "shlex",
+ "tap",
  "thiserror 2.0.18",
  "tokio",
  "toml 1.1.0+spec-1.1.0",
@@ -2635,6 +2636,12 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
 [[package]]
 name = "tempfile"
 version = "3.24.0"
index 3b4ffc6170ecddd29d3adf31505ec70f7c7613e8..460366214c558a1b4f00614e58adaf86e6682319 100644 (file)
@@ -27,6 +27,7 @@ tracing-subscriber = "0.3.20"
 toml = "1.1.0"
 serde= {version = "1.0", features = ["derive"]}
 shlex = "1.3.0"
+tap = "1.0.1"
 
 # Optional dependencies
 bdk_bitcoind_rpc = { version = "0.21.0", features = ["std"], optional = true }
index 6c5647bcb9eb8d6ef1f232fc0ce065f1928f6e9c..8d893b7fb2332946f130d0209f3ed3b2158c9059 100644 (file)
@@ -48,13 +48,15 @@ use bdk_wallet::{
         key::{Parity, rand},
         secp256k1::{Scalar, SecretKey},
     },
-    descriptor::{Descriptor, Legacy, Miniscript},
+    descriptor::{Descriptor, Legacy},
     miniscript::{Tap, descriptor::TapTree, policy::Concrete},
 };
 
 use clap::CommandFactory;
 use cli_table::{Cell, CellStruct, Style, Table, format::Justify};
 use serde_json::json;
+#[cfg(feature = "compiler")]
+use tap::Pipe;
 #[cfg(feature = "silent-payments")]
 use {
     bdk_sp::{
@@ -1286,16 +1288,12 @@ pub(crate) fn handle_compile_subcommand(
 ) -> Result<String, Error> {
     let policy = Concrete::<String>::from_str(policy.as_str())?;
 
-    let legacy_policy: Miniscript<String, Legacy> = policy.compile()?;
-    let segwit_policy: Miniscript<String, Segwitv0> = policy.compile()?;
-    let taproot_policy: Miniscript<String, Tap> = policy.compile()?;
-
     let mut r = None;
 
     let descriptor = match script_type.as_str() {
-        "sh" => Descriptor::new_sh(legacy_policy),
-        "wsh" => Descriptor::new_wsh(segwit_policy),
-        "sh-wsh" => Descriptor::new_sh_wsh(segwit_policy),
+        "sh" => policy.compile::<Legacy>()?.pipe(Descriptor::new_sh),
+        "wsh" => policy.compile::<Segwitv0>()?.pipe(Descriptor::new_wsh),
+        "sh-wsh" => policy.compile::<Segwitv0>()?.pipe(Descriptor::new_sh_wsh),
         "tr" => {
             // For tr descriptors, we use a randomized unspendable key (H + rG).
             // This improves privacy by preventing observers from determining if key path spending is disabled.
@@ -1314,7 +1312,7 @@ pub(crate) fn handle_compile_subcommand(
             let internal_key_point = nums_point.add_exp_tweak(&secp, &Scalar::from(r_secret))?;
             let (xonly_internal_key, _) = internal_key_point.x_only_public_key();
 
-            let tree = TapTree::Leaf(Arc::new(taproot_policy));
+            let tree = TapTree::Leaf(Arc::new(policy.compile::<Tap>()?));
 
             Descriptor::new_tr(xonly_internal_key.to_string(), Some(tree))
         }