]> Untitled Git - bdk-cli/commitdiff
Add auto backend deployment
authorrajarshimaitra <rajarshi149@gmail.com>
Sun, 9 Jan 2022 17:29:46 +0000 (22:59 +0530)
committerrajarshimaitra <rajarshi149@gmail.com>
Tue, 26 Apr 2022 17:54:12 +0000 (23:24 +0530)
This adds bitcoind and electrsd deployment and management for each kind
of feature flags. The wallet then gets connected to the backend. All the
backend related args for bdk-cli can be omitted in regtest-* mode.

Cargo.lock
Cargo.toml
src/bdk_cli.rs

index aff727e237c86bcf0c419cc53c02341def1eeaf6..a231031d01d526c36b8c24b96dda4c0719ba8093 100644 (file)
@@ -2,6 +2,12 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
 [[package]]
 name = "aho-corasick"
 version = "0.7.18"
@@ -48,6 +54,12 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
+[[package]]
+name = "base-x"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
+
 [[package]]
 name = "base64"
 version = "0.10.1"
@@ -105,7 +117,7 @@ dependencies = [
  "sled",
  "socks",
  "tokio",
- "ureq",
+ "ureq 2.2.0",
 ]
 
 [[package]]
@@ -118,6 +130,7 @@ dependencies = [
  "bdk-reserves",
  "clap",
  "dirs-next",
+ "electrsd",
  "env_logger",
  "fd-lock",
  "log",
@@ -250,6 +263,22 @@ dependencies = [
  "serde_json",
 ]
 
+[[package]]
+name = "bitcoind"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65ddc41af9556a341c909bc71de33e16da52bf5f8dbda6b7a402054c60bdb722"
+dependencies = [
+ "bitcoin_hashes 0.10.0",
+ "bitcoincore-rpc",
+ "flate2",
+ "home",
+ "log",
+ "tar",
+ "tempfile",
+ "ureq 1.5.5",
+]
+
 [[package]]
 name = "bitflags"
 version = "1.3.2"
@@ -274,6 +303,27 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
 
+[[package]]
+name = "bzip2"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0"
+dependencies = [
+ "bzip2-sys",
+ "libc",
+]
+
+[[package]]
+name = "bzip2-sys"
+version = "0.1.11+1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
 [[package]]
 name = "cc"
 version = "1.0.73"
@@ -341,6 +391,39 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "const_fn"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935"
+
+[[package]]
+name = "cookie"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951"
+dependencies = [
+ "percent-encoding",
+ "time",
+ "version_check",
+]
+
+[[package]]
+name = "cookie_store"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3818dfca4b0cb5211a659bbcbb94225b7127407b2b135e650d717bfb78ab10d3"
+dependencies = [
+ "cookie",
+ "idna",
+ "log",
+ "publicsuffix",
+ "serde",
+ "serde_json",
+ "time",
+ "url",
+]
+
 [[package]]
 name = "crc32fast"
 version = "1.3.2"
@@ -395,12 +478,33 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "discard"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
+
 [[package]]
 name = "either"
 version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
+[[package]]
+name = "electrsd"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "334abee7787b76757ac34b13a9a1cbf1ef0f2da35162d3ceb95a5b0bc34df80f"
+dependencies = [
+ "bitcoin_hashes 0.10.0",
+ "bitcoind",
+ "electrum-client",
+ "log",
+ "nix",
+ "ureq 2.2.0",
+ "zip",
+]
+
 [[package]]
 name = "electrum-client"
 version = "0.8.0"
@@ -445,6 +549,15 @@ dependencies = [
  "termcolor",
 ]
 
+[[package]]
+name = "error-chain"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
+dependencies = [
+ "version_check",
+]
+
 [[package]]
 name = "error-code"
 version = "2.3.1"
@@ -455,6 +568,15 @@ dependencies = [
  "str-buf",
 ]
 
+[[package]]
+name = "fastrand"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
+dependencies = [
+ "instant",
+]
+
 [[package]]
 name = "fd-lock"
 version = "3.0.2"
@@ -466,6 +588,30 @@ dependencies = [
  "windows-sys",
 ]
 
+[[package]]
+name = "filetime"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "winapi",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
+dependencies = [
+ "cfg-if",
+ "crc32fast",
+ "libc",
+ "miniz_oxide",
+]
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -663,6 +809,15 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "home"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
+dependencies = [
+ "winapi",
+]
+
 [[package]]
 name = "http"
 version = "0.2.6"
@@ -910,6 +1065,16 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "miniz_oxide"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
+dependencies = [
+ "adler",
+ "autocfg",
+]
+
 [[package]]
 name = "mio"
 version = "0.7.14"
@@ -1028,6 +1193,12 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
+[[package]]
+name = "pkg-config"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.16"
@@ -1058,6 +1229,12 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
+
 [[package]]
 name = "proc-macro2"
 version = "1.0.36"
@@ -1067,6 +1244,28 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "publicsuffix"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3bbaa49075179162b49acac1c6aa45fb4dafb5f13cf6794276d77bc7fd95757b"
+dependencies = [
+ "error-chain",
+ "idna",
+ "lazy_static",
+ "regex",
+ "url",
+]
+
+[[package]]
+name = "qstring"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e"
+dependencies = [
+ "percent-encoding",
+]
+
 [[package]]
 name = "quick-error"
 version = "1.2.3"
@@ -1176,6 +1375,15 @@ version = "0.6.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
 
+[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi",
+]
+
 [[package]]
 name = "reqwest"
 version = "0.11.10"
@@ -1241,6 +1449,15 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+dependencies = [
+ "semver",
+]
+
 [[package]]
 name = "rustls"
 version = "0.16.0"
@@ -1332,6 +1549,21 @@ dependencies = [
  "cc",
 ]
 
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
 [[package]]
 name = "serde"
 version = "1.0.136"
@@ -1375,6 +1607,21 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "sha1"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
+dependencies = [
+ "sha1_smol",
+]
+
+[[package]]
+name = "sha1_smol"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
+
 [[package]]
 name = "shlex"
 version = "1.1.0"
@@ -1445,6 +1692,64 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
+[[package]]
+name = "standback"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "stdweb"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
+dependencies = [
+ "discard",
+ "rustc_version",
+ "stdweb-derive",
+ "stdweb-internal-macros",
+ "stdweb-internal-runtime",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "stdweb-derive"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_derive",
+ "syn",
+]
+
+[[package]]
+name = "stdweb-internal-macros"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
+dependencies = [
+ "base-x",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sha1",
+ "syn",
+]
+
+[[package]]
+name = "stdweb-internal-runtime"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
+
 [[package]]
 name = "str-buf"
 version = "1.0.5"
@@ -1492,6 +1797,31 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "tar"
+version = "0.4.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
+dependencies = [
+ "filetime",
+ "libc",
+ "xattr",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "libc",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi",
+]
+
 [[package]]
 name = "termcolor"
 version = "1.1.3"
@@ -1530,6 +1860,44 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "time"
+version = "0.2.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242"
+dependencies = [
+ "const_fn",
+ "libc",
+ "standback",
+ "stdweb",
+ "time-macros",
+ "version_check",
+ "winapi",
+]
+
+[[package]]
+name = "time-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
+dependencies = [
+ "proc-macro-hack",
+ "time-macros-impl",
+]
+
+[[package]]
+name = "time-macros-impl"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f"
+dependencies = [
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "standback",
+ "syn",
+]
+
 [[package]]
 name = "tokio"
 version = "1.14.1"
@@ -1654,6 +2022,25 @@ version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
 
+[[package]]
+name = "ureq"
+version = "1.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b8b063c2d59218ae09f22b53c42eaad0d53516457905f5235ca4bc9e99daa71"
+dependencies = [
+ "base64 0.13.0",
+ "chunked_transfer",
+ "cookie",
+ "cookie_store",
+ "log",
+ "once_cell",
+ "qstring",
+ "rustls 0.19.1",
+ "url",
+ "webpki",
+ "webpki-roots 0.21.1",
+]
+
 [[package]]
 name = "ureq"
 version = "2.2.0"
@@ -1912,8 +2299,30 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "xattr"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "zeroize"
 version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
+
+[[package]]
+name = "zip"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815"
+dependencies = [
+ "byteorder",
+ "bzip2",
+ "crc32fast",
+ "flate2",
+ "thiserror",
+]
index 0ed9caa22c6943c6944ef2b43bb97de651836b89..af87bad765c6a7ebd367c53c16e244fff111e0c9 100644 (file)
@@ -28,6 +28,7 @@ env_logger = { version = "0.7", optional = true }
 clap = { version = "2.33", optional = true }
 regex = { version = "1", optional = true }
 bdk-reserves = { version = "0.17", optional = true}
+electrsd = { version= "0.12", features = ["trigger", "bitcoind_22_0"], optional = true}
 
 [features]
 default = ["cli", "repl"]
@@ -42,6 +43,11 @@ compact_filters = ["bdk/compact_filters"]
 rpc = ["bdk/rpc"]
 reserves = ["bdk-reserves"]
 verify = ["bdk/verify"]
+regtest-node = []
+regtest-bitcoin = ["regtest-node" , "rpc", "electrsd"]
+regtest-electrum = ["regtest-node", "electrum", "electrsd/electrs_0_8_10"]
+regtest-esplora-ureq = ["regtest-node", "esplora-ureq", "electrsd/esplora_a33e97e1"]
+regtest-esplora-reqwest = ["regtest-node", "esplora-reqwest", "electrsd/esplora_a33e97e1"]
 
 [[bin]]
 name = "bdk-cli"
index 93b9fd9208ef1ae994070f1ab76ff7775b508701..24ee81bc787490947ad9d340ba351ac74f0ad8e8 100644 (file)
@@ -121,21 +121,42 @@ fn open_database(wallet_opts: &WalletOpts) -> Result<Tree, Error> {
     Ok(tree)
 }
 
+#[allow(dead_code)]
+// Different Backend types activated with `regtest-*` mode.
+// If `regtest-*` feature not activated, then default is `None`.
+enum Backend {
+    None,
+    Bitcoin { rpc_url: String, rpc_auth: String },
+    Electrum { electrum_url: String },
+    Esplora { esplora_url: String },
+}
+
 #[cfg(any(
     feature = "electrum",
     feature = "esplora",
     feature = "compact_filters",
     feature = "rpc"
 ))]
-fn new_blockchain(_network: Network, wallet_opts: &WalletOpts) -> Result<AnyBlockchain, Error> {
+fn new_blockchain(
+    _network: Network,
+    wallet_opts: &WalletOpts,
+    _backend: &Backend,
+) -> Result<AnyBlockchain, Error> {
     #[cfg(feature = "electrum")]
-    let config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
-        url: wallet_opts.electrum_opts.server.clone(),
-        socks5: wallet_opts.proxy_opts.proxy.clone(),
-        retry: wallet_opts.proxy_opts.retries,
-        timeout: wallet_opts.electrum_opts.timeout,
-        stop_gap: wallet_opts.electrum_opts.stop_gap,
-    });
+    let config = {
+        let url = match _backend {
+            Backend::Electrum { electrum_url } => electrum_url.to_owned(),
+            _ => wallet_opts.electrum_opts.server.clone(),
+        };
+
+        AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
+            url,
+            socks5: wallet_opts.proxy_opts.proxy.clone(),
+            retry: wallet_opts.proxy_opts.retries,
+            timeout: wallet_opts.electrum_opts.timeout,
+            stop_gap: wallet_opts.electrum_opts.stop_gap,
+        })
+    };
 
     #[cfg(feature = "esplora")]
     let config = AnyBlockchainConfig::Esplora(EsploraBlockchainConfig {
@@ -172,17 +193,27 @@ fn new_blockchain(_network: Network, wallet_opts: &WalletOpts) -> Result<AnyBloc
 
     #[cfg(feature = "rpc")]
     let config: AnyBlockchainConfig = {
-        let auth = if let Some(cookie) = &wallet_opts.rpc_opts.cookie {
-            Auth::Cookie {
-                file: cookie.into(),
-            }
-        } else {
-            Auth::UserPass {
-                username: wallet_opts.rpc_opts.basic_auth.0.clone(),
-                password: wallet_opts.rpc_opts.basic_auth.1.clone(),
+        let (url, auth) = match _backend {
+            Backend::Bitcoin { rpc_url, rpc_auth } => (
+                rpc_url,
+                Auth::Cookie {
+                    file: rpc_auth.into(),
+                },
+            ),
+            _ => {
+                let auth = if let Some(cookie) = &wallet_opts.rpc_opts.cookie {
+                    Auth::Cookie {
+                        file: cookie.into(),
+                    }
+                } else {
+                    Auth::UserPass {
+                        username: wallet_opts.rpc_opts.basic_auth.0.clone(),
+                        password: wallet_opts.rpc_opts.basic_auth.1.clone(),
+                    }
+                };
+                (&wallet_opts.rpc_opts.address, auth)
             }
         };
-
         // Use deterministic wallet name derived from descriptor
         let wallet_name = wallet_name_from_descriptor(
             &wallet_opts.descriptor[..],
@@ -191,8 +222,7 @@ fn new_blockchain(_network: Network, wallet_opts: &WalletOpts) -> Result<AnyBloc
             &Secp256k1::new(),
         )?;
 
-        let mut rpc_url = "http://".to_string();
-        rpc_url.push_str(&wallet_opts.rpc_opts.address[..]);
+        let rpc_url = "http://".to_string() + &url;
 
         let rpc_config = RpcConfig {
             url: rpc_url,
@@ -233,7 +263,63 @@ fn main() {
         warn!("This is experimental software and not currently recommended for use on Bitcoin mainnet, proceed with caution.")
     }
 
-    match handle_command(cli_opts, network) {
+    #[cfg(feature = "regtest-node")]
+    let bitcoind = {
+        if network != Network::Regtest {
+            error!("Do not override default network value for `regtest-node` features");
+        }
+        let bitcoind_conf = electrsd::bitcoind::Conf::default();
+        let bitcoind_exe = electrsd::bitcoind::downloaded_exe_path()
+            .expect("We should always have downloaded path");
+        electrsd::bitcoind::BitcoinD::with_conf(bitcoind_exe, &bitcoind_conf).unwrap()
+    };
+
+    #[cfg(feature = "regtest-bitcoin")]
+    let backend = {
+        Backend::Bitcoin {
+            rpc_url: bitcoind.params.rpc_socket.to_string(),
+            rpc_auth: bitcoind
+                .params
+                .cookie_file
+                .clone()
+                .into_os_string()
+                .into_string()
+                .unwrap(),
+        }
+    };
+
+    #[cfg(feature = "regtest-electrum")]
+    let (_electrsd, backend) = {
+        let elect_conf = electrsd::Conf::default();
+        let elect_exe =
+            electrsd::downloaded_exe_path().expect("We should always have downloaded path");
+        let electrsd = electrsd::ElectrsD::with_conf(elect_exe, &bitcoind, &elect_conf).unwrap();
+        let backend = Backend::Electrum {
+            electrum_url: electrsd.electrum_url.clone(),
+        };
+        (electrsd, backend)
+    };
+
+    #[cfg(any(feature = "regtest-esplora-ureq", feature = "regtest-esplora-reqwest"))]
+    let (_electrsd, backend) = {
+        let mut elect_conf = electrsd::Conf::default();
+        elect_conf.http_enabled = true;
+        let elect_exe =
+            electrsd::downloaded_exe_path().expect("Electrsd downloaded binaries not found");
+        let electrsd = electrsd::ElectrsD::with_conf(elect_exe, &bitcoind, &elect_conf).unwrap();
+        let backend = Backend::Esplora {
+            esplora_url: electrsd
+                .esplora_url
+                .clone()
+                .expect("Esplora port not open in electrum"),
+        };
+        (electrsd, backend)
+    };
+
+    #[cfg(not(feature = "regtest-node"))]
+    let backend = Backend::None;
+
+    match handle_command(cli_opts, network, backend) {
         Ok(result) => println!("{}", result),
         Err(e) => {
             match e {
@@ -264,7 +350,7 @@ fn maybe_descriptor_wallet_name(
     Ok(wallet_opts)
 }
 
-fn handle_command(cli_opts: CliOpts, network: Network) -> Result<String, Error> {
+fn handle_command(cli_opts: CliOpts, network: Network, _backend: Backend) -> Result<String, Error> {
     let result = match cli_opts.subcommand {
         #[cfg(any(
             feature = "electrum",
@@ -278,7 +364,7 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result<String, Error>
         } => {
             let wallet_opts = maybe_descriptor_wallet_name(wallet_opts, network)?;
             let database = open_database(&wallet_opts)?;
-            let blockchain = new_blockchain(network, &wallet_opts)?;
+            let blockchain = new_blockchain(network, &wallet_opts, &_backend)?;
             let wallet = new_wallet(network, &wallet_opts, database)?;
             let result =
                 bdk_cli::handle_online_wallet_subcommand(&wallet, &blockchain, online_subcommand)?;
@@ -317,20 +403,6 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result<String, Error>
             let wallet_opts = maybe_descriptor_wallet_name(wallet_opts, network)?;
             let database = open_database(&wallet_opts)?;
 
-            #[cfg(any(
-                feature = "electrum",
-                feature = "esplora",
-                feature = "compact_filters",
-                feature = "rpc"
-            ))]
-            let wallet = new_wallet(network, &wallet_opts, database)?;
-
-            #[cfg(not(any(
-                feature = "electrum",
-                feature = "esplora",
-                feature = "compact_filters",
-                feature = "rpc"
-            )))]
             let wallet = new_wallet(network, &wallet_opts, database)?;
 
             let mut rl = Editor::<()>::new();
@@ -377,7 +449,7 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result<String, Error>
                                 feature = "rpc"
                             ))]
                             ReplSubCommand::OnlineWalletSubCommand(online_subcommand) => {
-                                let blockchain = new_blockchain(network, &wallet_opts)?;
+                                let blockchain = new_blockchain(network, &wallet_opts, &_backend)?;
                                 bdk_cli::handle_online_wallet_subcommand(
                                     &wallet,
                                     &blockchain,