assert_eq!(config["int_descriptor"].as_str().unwrap(), int_desc);
}
}
+
+#[cfg(feature = "rpc")]
+mod test_offline {
+ use super::*;
+ use assert_cmd::Command;
+ use serde_json::Value;
+
+ static WALLET_NAME: &str = "test_config_wallet";
+
+ /// Helper to spin up a sandboxed CLI with the generated descriptors
+ fn setup_wallet_config() -> (BdkCli, Command) {
+ let temp_dir = TempDir::new().unwrap();
+ let cli = BdkCli::new("regtest", Some(temp_dir.path().to_path_buf()));
+
+ // generate descriptors
+ let desc = cli
+ .cmd("descriptor", &["--type", "tr"])
+ .output()
+ .expect("Command to generate descriptors failed");
+
+ let desc_values: Value =
+ serde_json::from_slice(&desc.stdout).expect("Invalid JSON from output descriptor");
+
+ let pub_desc = &desc_values["public_descriptors"];
+
+ let ext_desc = pub_desc["external"].as_str().unwrap();
+ let int_desc = pub_desc["internal"].as_str().unwrap();
+ let client_type = "rpc";
+ let db: &str = "sqlite";
+ let url = "http://localhost:18443";
+
+ let mut cmd_init = cli.build_base_cmd();
+ cmd_init
+ .arg("wallet")
+ .arg("--wallet")
+ .arg(WALLET_NAME)
+ .arg("config")
+ .arg("--ext-descriptor")
+ .arg(ext_desc)
+ .arg("--int-descriptor")
+ .arg(int_desc)
+ .arg("--client-type")
+ .arg(client_type)
+ .arg("--database-type")
+ .arg(db)
+ .arg("--url")
+ .arg(url);
+ (cli, cmd_init)
+ }
+
+ #[test]
+ fn test_new_and_unused_address() {
+ let (cli, mut cmd_init) = setup_wallet_config();
+ cmd_init.assert().success();
+
+ // new address
+ cli.wallet_cmd(&["--wallet", WALLET_NAME, "new_address"])
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("\"address\":"));
+
+ // `unused-address`
+ cli.wallet_cmd(&["--wallet", WALLET_NAME, "unused_address"])
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("\"address\":"));
+ }
+
+ #[test]
+ fn test_empty_wallet_balances_and_lists() {
+ let (cli, mut cmd_init) = setup_wallet_config();
+ cmd_init.assert().success();
+
+ // balance
+ cli.wallet_cmd(&["--wallet", WALLET_NAME, "balance"])
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("\"total\":"))
+ .stdout(predicate::str::contains("\"trusted_pending\":"))
+ .stdout(predicate::str::contains("\"untrusted_pending\":"))
+ .stdout(predicate::str::contains("\"immature\":"))
+ .stdout(predicate::str::contains("\"confirmed\":"));
+
+ // Unspent UTXOs
+ cli.wallet_cmd(&["--wallet", WALLET_NAME, "unspent"])
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("[]"));
+
+ // Transactions
+ cli.wallet_cmd(&["--wallet", WALLET_NAME, "transactions"])
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("[]"));
+ }
+
+ #[test]
+ fn test_policies_and_public_descriptor() {
+ let (cli, mut cmd_init) = setup_wallet_config();
+ cmd_init.assert().success();
+
+ // Policies
+ cli.wallet_cmd(&["--wallet", WALLET_NAME, "policies"])
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("\"external\":"))
+ .stdout(predicate::str::contains("\"internal\":"));
+
+ // Public Descriptor
+ cli.wallet_cmd(&["--wallet", WALLET_NAME, "public_descriptor"])
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("external"))
+ .stdout(predicate::str::contains("internal"));
+ }
+
+ #[test]
+ fn test_create_tx_insufficient_funds() {
+ let (cli, mut cmd_init) = setup_wallet_config();
+ cmd_init.assert().success();
+
+ // create transaction
+ cli.wallet_cmd(&[
+ "--wallet",
+ WALLET_NAME,
+ "create_tx",
+ "--to",
+ "tb1p4tp4l6glyr2gs94neqcpr5gha7344nfyznfkc8szkreflscsdkgqsdent4:1000",
+ ])
+ .assert()
+ .failure()
+ .stderr(predicate::str::contains("Insufficient"));
+ }
+
+ #[test]
+ fn test_combine_psbt_invalid_input() {
+ let (cli, mut cmd_init) = setup_wallet_config();
+ cmd_init.assert().success();
+
+ // Invalid create-tx.
+ cli.wallet_cmd(&[
+ "--wallet",
+ WALLET_NAME,
+ "combine_psbt",
+ "invalid_psbt",
+ "another_invalid_psbt",
+ ])
+ .assert()
+ .failure()
+ .stderr(predicate::str::contains("Invalid"));
+ }
+}