]> Untitled Git - bdk-cli/commitdiff
test: add test for multiple recipients and sp code
authorVihiga Tyonum <withtvpeter@gmail.com>
Tue, 7 Jul 2026 08:21:50 +0000 (09:21 +0100)
committerVihiga Tyonum <withtvpeter@gmail.com>
Wed, 8 Jul 2026 21:49:32 +0000 (22:49 +0100)
tests/integration/init.rs
tests/integration/online.rs

index 7b40614031859b0b064e2681ece1c9bd3a536279..ad1e12c87aaf3b5ea004fd87c9873e0d5d2b676f 100644 (file)
@@ -292,3 +292,37 @@ mod test_config {
         assert_eq!(config["int_descriptor"].as_str().unwrap(), int_desc);
     }
 }
+
+
+//  SILENT PAYMENTS 
+#[cfg(feature = "silent-payments")]
+mod test_silent_payments {
+    use super::*;
+
+    const SCAN: &str = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798";
+    const SPEND: &str = "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5";
+
+    #[test]
+    fn test_silent_payment_code_network_hrp() {
+        BdkCli::new("regtest", None)
+            .cmd("silent_payment_code", &["--scan_key", SCAN, "--spend_key", SPEND])
+            .assert()
+            .success()
+            .stdout(predicate::str::contains("sprt1"));
+
+        BdkCli::new("testnet", None)
+            .cmd("silent_payment_code", &["--scan_key", SCAN, "--spend_key", SPEND])
+            .assert()
+            .success()
+            .stdout(predicate::str::contains("tsp1"));
+    }
+
+    #[test]
+    fn test_silent_payment_code_rejects_invalid_pubkey() {
+        BdkCli::new("regtest", None)
+            .cmd("silent_payment_code", &["--scan_key", "deadbeef", "--spend_key", SPEND])
+            .assert()
+            .failure()
+            .stderr(predicate::str::contains("malformed public key"));
+    }
+}
index bdeb39fceebd4c706eb5ee606b92092b4db18fdc..1defa06aa4d8bca7fc5849c1e3e2d5884b681d5e 100644 (file)
@@ -433,4 +433,141 @@ mod test_online {
             "balance should reflect exactly one confirmed spend after RBF, got {final_balance}"
         );
     }
+
+    #[test]
+    fn test_create_tx_multiple_recipients() {
+        use bdk_wallet::bitcoin::Psbt;
+
+        let (cli, mut cmd_init, env) = setup_online_wallet();
+        cmd_init.assert().success();
+        fund_and_sync_wallet(&cli, &env);
+
+        let second = cli_new_address(&cli);
+
+        let psbt_b64 = run_wallet_json(
+            &cli,
+            &[
+                "create_tx",
+                "--to",
+                &format!("{RECIPIENT}:20000"),
+                "--to",
+                &format!("{second}:30000"),
+            ],
+        )["psbt"]
+            .as_str()
+            .expect("create_tx: missing 'psbt' field")
+            .to_string();
+
+        let psbt: Psbt = psbt_b64
+            .parse()
+            .expect("create_tx returned an invalid PSBT");
+        let values: Vec<u64> = psbt
+            .unsigned_tx
+            .output
+            .iter()
+            .map(|o| o.value.to_sat())
+            .collect();
+
+        assert!(
+            values.contains(&20_000),
+            "first recipient (20_000) output missing: {values:?}"
+        );
+        assert!(
+            values.contains(&30_000),
+            "second recipient (30_000) output missing: {values:?}"
+        );
+        assert!(
+            psbt.unsigned_tx.output.len() >= 2,
+            "expected at least the two recipient outputs, got {}",
+            psbt.unsigned_tx.output.len()
+        );
+    }
+
+    #[cfg(feature = "rpc")]
+    mod test_online_rpc {
+        use crate::common::BdkCli;
+        use bdk_testenv::{TestEnv, bitcoincore_rpc::RpcApi};
+        use bdk_wallet::bitcoin::{Address, Amount, Network};
+        use serde_json::Value;
+        use std::str::FromStr;
+        use tempfile::TempDir;
+
+        static WALLET_NAME: &str = "test_rpc_wallet";
+
+    
+        #[test]
+        fn test_rpc_full_scan_reflects_funding() {
+            let env = TestEnv::new().expect("start testenv");
+            let rpc_url = env.bitcoind.rpc_url();
+            let cookie = env
+                .bitcoind
+                .params
+                .cookie_file
+                .to_str()
+                .unwrap()
+                .to_string();
+
+            let temp_dir = TempDir::new().unwrap();
+            let cli = BdkCli::new("regtest", Some(temp_dir.path().to_path_buf()));
+
+            // descriptors
+            let desc = cli.cmd("descriptor", &["--type", "tr"]).output().unwrap();
+            let dv: Value = serde_json::from_slice(&desc.stdout).unwrap();
+            let ext = dv["private_descriptors"]["external"].as_str().unwrap();
+            let int = dv["private_descriptors"]["internal"].as_str().unwrap();
+
+            // config: rpc client-type, --url flag, cookie as a POSITIONAL arg
+            cli.build_base_cmd()
+                .args(["wallet", "--wallet", WALLET_NAME, "config"])
+                .args(["--ext-descriptor", ext, "--int-descriptor", int])
+                .args(["--client-type", "rpc", "--database-type", "sqlite"])
+                .args(["--url", &rpc_url])
+                .arg(&cookie)
+                .assert()
+                .success();
+
+            // wallet address to fund
+            let out = cli
+                .wallet_cmd(&["--wallet", WALLET_NAME, "new_address"])
+                .output()
+                .unwrap();
+            let addr_json: Value = serde_json::from_slice(&out.stdout).unwrap();
+            let address = Address::from_str(addr_json["address"].as_str().unwrap())
+                .unwrap()
+                .require_network(Network::Regtest)
+                .unwrap();
+
+            // fund + confirm 
+            let node_addr = env
+                .rpc_client()
+                .get_new_address(None, None)
+                .unwrap()
+                .assume_checked();
+            env.mine_blocks(101, Some(node_addr)).unwrap();
+            env.send(&address, Amount::from_btc(0.5).unwrap()).unwrap();
+            env.mine_blocks(3, None).unwrap();
+
+            // full_scan + balance via rpc
+            let scan = cli
+                .wallet_cmd(&["--wallet", WALLET_NAME, "full_scan"])
+                .output()
+                .unwrap();
+            assert!(
+                scan.status.success(),
+                "rpc full_scan failed: {}",
+                String::from_utf8_lossy(&scan.stderr)
+            );
+
+            let bal = cli
+                .wallet_cmd(&["--wallet", WALLET_NAME, "balance"])
+                .output()
+                .unwrap();
+            let bj: Value = serde_json::from_slice(&bal.stdout).unwrap();
+            assert_eq!(
+                bj["confirmed"].as_u64(),
+                Some(50_000_000),
+                "rpc-synced confirmed balance mismatch: {bj}"
+            );
+        }
+    }
 }