]> Untitled Git - bdk-cli/commitdiff
feat(multipath): Add tests for multipath desc
authorVihiga Tyonum <withtvpeter@gmail.com>
Wed, 29 Jul 2026 22:34:04 +0000 (23:34 +0100)
committerVihiga Tyonum <withtvpeter@gmail.com>
Wed, 29 Jul 2026 22:35:58 +0000 (23:35 +0100)
-Add tests for multipath descriptors.
- Update CHANGELOG

CHANGELOG.md
tests/integration/offline.rs

index 79da994df963ba1ce75c776fa4f983627bdad1b2..098eee19586bbe4c6f4b4583ba087399fa34fa57 100644 (file)
@@ -5,6 +5,9 @@ page. See [DEVELOPMENT_CYCLE.md](DEVELOPMENT_CYCLE.md) for more details.
 
 ## [Unreleased]
 
+- Added support for Multipath (two-paths) descriptors.
+
+
 ## [4.0.0]
 
 - Added persistance to existing async payjoin integration
index 780761a01396eeb79e65e4c01e6f18b9c8f8ced6..2fceefc30e9088e231f68bd3c1f890b2f6937171 100644 (file)
@@ -349,3 +349,86 @@ mod repl_tests {
         );
     }
 }
+
+#[cfg(all(
+    feature = "sqlite",
+    not(any(
+        feature = "electrum",
+        feature = "esplora",
+        feature = "rpc",
+        feature = "cbf"
+    ))
+))]
+mod multipath_tests {
+    use crate::common::BdkCli;
+    use assert_cmd::Command;
+    use predicates::prelude::*;
+    use tempfile::TempDir;
+
+    // A public BIP-389 two-path (multipath) descriptor
+    const MULTIPATH_DESC: &str = "wpkh([9a6a2580/84'/1'/0']tpubDDnGNapGEY6AZAdQbfRJgMg9fvz8pUBrLwvyvUqEgcUfgzM6zc2eVK4vY9x9L5FJWdX8WumXuLEDV5zDZnTfbn87vLe9XceCFwTu9so9Kks/<0;1>/*)";
+    const INT_DESC: &str = "wpkh([07234a14/84'/1'/0']tpubDCSgT6PaVLQH9h2TAxKryhvkEurUBcYRJc9dhTcMDyahhWiMWfEWvQQX89yaw7w7XU8bcVujoALfxq59VkFATri3Cxm5mkp9kfHfRFDckEh/1/*)";
+
+    fn save_config(cli: &BdkCli, wallet: &str, ext: &str, int: Option<&str>) -> Command {
+        let mut cmd = cli.build_base_cmd();
+        cmd.arg("wallet")
+            .arg("--wallet")
+            .arg(wallet)
+            .arg("config")
+            .arg("--ext-descriptor")
+            .arg(ext)
+            .arg("--database-type")
+            .arg("sqlite");
+        if let Some(int) = int {
+            cmd.arg("--int-descriptor").arg(int);
+        }
+        cmd
+    }
+
+    #[test]
+    fn multipath_descriptor_creates_split_keychains() {
+        let tmp = TempDir::new().unwrap();
+        let cli = BdkCli::new("testnet", Some(tmp.path().to_path_buf()));
+        save_config(&cli, "multipath_wallet", MULTIPATH_DESC, None)
+            .assert()
+            .success();
+
+        cli.wallet_cmd(&["--wallet", "multipath_wallet", "public_descriptor"])
+            .assert()
+            .success()
+            .stdout(predicate::str::contains("/0/*"))
+            .stdout(predicate::str::contains("/1/*"));
+    }
+
+    #[test]
+    fn multipath_wallet_reloads() {
+        let tmp = TempDir::new().unwrap();
+        let cli = BdkCli::new("testnet", Some(tmp.path().to_path_buf()));
+        save_config(&cli, "multipath_wallet", MULTIPATH_DESC, None)
+            .assert()
+            .success();
+
+        cli.wallet_cmd(&["--wallet", "multipath_wallet", "new_address"])
+            .assert()
+            .success();
+        cli.wallet_cmd(&["--wallet", "multipath_wallet", "new_address"])
+            .assert()
+            .success();
+    }
+
+    #[test]
+    fn multipath_with_internal_is_ambiguous() {
+        let tmp = TempDir::new().unwrap();
+        let cli = BdkCli::new("testnet", Some(tmp.path().to_path_buf()));
+        save_config(&cli, "multipath_wallet", MULTIPATH_DESC, Some(INT_DESC))
+            .assert()
+            .success();
+
+        cli.wallet_cmd(&["--wallet", "multipath_wallet", "new_address"])
+            .assert()
+            .failure()
+            .stderr(predicate::str::contains(
+                "multipath descriptor and a separate internal descriptor",
+            ));
+    }
+}