diff --git a/Cargo.lock b/Cargo.lock index f95781f..8ec9f56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,7 +130,7 @@ version = "1.0.0-alpha.1" source = "git+https://github.com/bitcoindevkit/bdk?rev=8f38e96e4542db2378e2e64cd9289638ee86ba1a#8f38e96e4542db2378e2e64cd9289638ee86ba1a" dependencies = [ "bdk_chain", - "bitcoin", + "bitcoin 0.29.2", "getrandom", "js-sys", "log", @@ -145,7 +145,7 @@ name = "bdk_chain" version = "0.5.0" source = "git+https://github.com/bitcoindevkit/bdk?rev=8f38e96e4542db2378e2e64cd9289638ee86ba1a#8f38e96e4542db2378e2e64cd9289638ee86ba1a" dependencies = [ - "bitcoin", + "bitcoin 0.29.2", "miniscript", "serde", ] @@ -194,11 +194,31 @@ checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" dependencies = [ "base64 0.13.1", "bech32", - "bitcoin_hashes", - "secp256k1", + "bitcoin_hashes 0.11.0", + "secp256k1 0.24.3", "serde", ] +[[package]] +name = "bitcoin" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e99ff7289b20a7385f66a0feda78af2fc119d28fb56aea8886a9cd0a4abdd75" +dependencies = [ + "bech32", + "bitcoin-private", + "bitcoin_hashes 0.12.0", + "hex_lit", + "secp256k1 0.27.0", + "serde", +] + +[[package]] +name = "bitcoin-private" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" + [[package]] name = "bitcoin_hashes" version = "0.11.0" @@ -208,6 +228,38 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin_hashes" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" +dependencies = [ + "bitcoin-private", + "serde", +] + +[[package]] +name = "bitcoincore-rpc" +version = "0.17.0" +dependencies = [ + "bitcoin-private", + "bitcoincore-rpc-json", + "jsonrpc", + "log", + "serde", + "serde_json", +] + +[[package]] +name = "bitcoincore-rpc-json" +version = "0.17.0" +dependencies = [ + "bitcoin 0.30.1", + "bitcoin-private", + "serde", + "serde_json", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -318,7 +370,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da3b630e345cdfc6f64315414b50815a9eeabbf12438413798bf09e9e79be8b8" dependencies = [ "anyhow", - "bitcoin", + "bitcoin 0.29.2", "bytes", "futures-util", "hex", @@ -415,7 +467,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e11244e7fd8b0beee0a3c62137c4bd9f756fe2c492ccf93171f81467b59200" dependencies = [ - "bitcoin", + "bitcoin 0.29.2", "log", "reqwest", "serde", @@ -617,6 +669,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex_lit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" + [[package]] name = "home" version = "0.5.5" @@ -755,6 +813,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpc" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8128f36b47411cd3f044be8c1f5cc0c9e24d1d1bfdc45f0a57897b32513053f2" +dependencies = [ + "base64 0.13.1", + "serde", + "serde_json", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -797,7 +866,7 @@ version = "9.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5b106477a0709e2da253e5559ba4ab20a272f8577f1eefff72f3a905b5d35f5" dependencies = [ - "bitcoin", + "bitcoin 0.29.2", "serde", ] @@ -1159,9 +1228,21 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "rand", - "secp256k1-sys", + "secp256k1-sys 0.6.1", + "serde", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "bitcoin_hashes 0.12.0", + "rand", + "secp256k1-sys 0.8.1", "serde", ] @@ -1174,6 +1255,15 @@ dependencies = [ "cc", ] +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -1258,6 +1348,7 @@ dependencies = [ "bdk", "bdk_esplora", "bdk_file_store", + "bitcoincore-rpc", "clap", "cln-plugin", "cln-rpc", diff --git a/Cargo.toml b/Cargo.toml index 1ddcaf6..6667f78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,8 @@ bdk = { git = "https://github.com/bitcoindevkit/bdk", version = "1.0.0-alpha.1", bdk_esplora = { git = "https://github.com/bitcoindevkit/bdk", rev = "8f38e96e4542db2378e2e64cd9289638ee86ba1a" } # bdk_file_store = { version = "0.2.0" } # bdk_file_store = { path = "../bdk/crates/file_store" } -bdk_file_store ={ git = "https://github.com/bitcoindevkit/bdk", rev = "8f38e96e4542db2378e2e64cd9289638ee86ba1a" } +bdk_file_store = { git = "https://github.com/bitcoindevkit/bdk", rev = "8f38e96e4542db2378e2e64cd9289638ee86ba1a" } +bitcoincore-rpc = { path = "../rust-bitcoincore-rpc/client" } clap = { version = "4.4.0", features = ["derive"] } cln-plugin = { git = "https://github.com/elementsproject/lightning", version = "0.1.4" } # cln-plugin = { path = "../../lightning/plugins" } diff --git a/src/main.rs b/src/main.rs index b485e61..845c832 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ #[macro_use] extern crate serde_json; +use bitcoincore_rpc::bitcoincore_rpc_json::ScanBlocksRequest; use clap::error::ErrorKind; use clap::{CommandFactory, Parser, Subcommand}; use cln_rpc::model::DatastoreMode; @@ -27,18 +28,57 @@ use smaug::wallet::{AddArgs, DescriptorWallet, SMAUG_DATADIR, UTXO_DEPOSIT_TAG, use cln_plugin::{anyhow, messages, options, Builder, Error, Plugin}; use tokio; -use bdk::TransactionDetails; +use bdk::{TransactionDetails, descriptor}; use smaug::state::{Smaug, State}; + +fn scanblocks<'a>( + brpc_user: String, + brpc_pass: String, +) -> Result<(), Error> +{ + // let external_descriptor = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/0'/0'/0/*)"; + // mutinynet_descriptor = "wpkh(tprv8ZgxMBicQKsPdSAgthqLZ5ZWQkm5As4V3qNA5G8KKxGuqdaVVtBhytrUqRGPm4RxTktSdvch8JyUdfWR8g3ddrC49WfZnj4iGZN8y5L8NPZ/*)" + let _mutinynet_descriptor_ext = "wpkh(tprv8ZgxMBicQKsPdSAgthqLZ5ZWQkm5As4V3qNA5G8KKxGuqdaVVtBhytrUqRGPm4RxTktSdvch8JyUdfWR8g3ddrC49WfZnj4iGZN8y5L8NPZ/84'/0'/0'/0/*)"; + let _mutinynet_descriptor_int = "wpkh(tprv8ZgxMBicQKsPdSAgthqLZ5ZWQkm5As4V3qNA5G8KKxGuqdaVVtBhytrUqRGPm4RxTktSdvch8JyUdfWR8g3ddrC49WfZnj4iGZN8y5L8NPZ/84'/0'/0'/1/*)"; + let _mutinynet_descriptor_ext_2 = "wpkh(tprv8ZgxMBicQKsPeRye8MhHA8hLxMuomycmGYXyRs7zViNck2VJsCJMTPt81Que8qp3PyPgQRnN7Gb1JyBVBKgj8AKEoEmmYxYDwzZJ63q1yjA/84'/0'/0'/0/*)"; + let _mutinynet_descriptor_int_2 = "wpkh(tprv8ZgxMBicQKsPeRye8MhHA8hLxMuomycmGYXyRs7zViNck2VJsCJMTPt81Que8qp3PyPgQRnN7Gb1JyBVBKgj8AKEoEmmYxYDwzZJ63q1yjA/84'/0'/0'/1/*)"; + + extern crate bitcoincore_rpc; + + use bitcoincore_rpc::{Auth, Client, RpcApi}; + + let rpc = Client::new("http://localhost:18443", + Auth::UserPass(brpc_user, brpc_pass) + // Auth::CookieFile(PathBuf::from("/home/cguida/.bitcoin/regtest/.cookie")) + ).unwrap(); + let descriptor = ScanBlocksRequest::Extended { desc:_mutinynet_descriptor_ext.to_string(), range: None }; + let descriptors = &[descriptor]; + let res = rpc.scan_blocks_blocking(descriptors); + log::info!("scanblocks result: {:?}", res.unwrap()); + + return Ok(()); +} + #[tokio::main] // #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), anyhow::Error> { let builder = Builder::new(tokio::io::stdin(), tokio::io::stdout()) .option(options::ConfigOption::new( - "wd_network", + "smaug_network", options::Value::OptString, "Which network to use: [bitcoin, testnet, signet, regtest, mutinynet]", )) + .option(options::ConfigOption::new( + "smaug_brpc_user", + options::Value::OptString, + "Bitcoind RPC user (Required)", + )) + .option(options::ConfigOption::new( + "smaug_brpc_pass", + options::Value::OptString, + "Bitcoind RPC password (Required)", + )) .notification(messages::NotificationTopic::new(UTXO_DEPOSIT_TAG)) .notification(messages::NotificationTopic::new(UTXO_SPENT_TAG)) .rpcmethod( @@ -58,17 +98,31 @@ async fn main() -> Result<(), anyhow::Error> { configured_plugin.configuration() ); log::debug!( - "wd_network = {:?}, cln_network = {}", - configured_plugin.option("wd_network"), + "smaug_network = {:?}, cln_network = {}", + configured_plugin.option("smaug_network"), configured_plugin.configuration().network ); - let network = match configured_plugin.option("wd_network") { - Some(wd_network) => match wd_network.as_str() { + let network = match configured_plugin.option("smaug_network") { + Some(smaug_network) => match smaug_network.as_str() { Some(wdn) => wdn.to_owned(), None => configured_plugin.configuration().network, }, None => configured_plugin.configuration().network, }; + let brpc_user = match configured_plugin.option("smaug_brpc_user") { + Some(smaug_brpc_user) => match smaug_brpc_user.as_str() { + Some(wdn) => wdn.to_owned(), + None => {return Err(anyhow!("must specify smaug_brpc_user"))}, + }, + None => {return Err(anyhow!("must specify smaug_brpc_user (your bitcoind instance rpcuser)"))}, + }; + let brpc_pass = match configured_plugin.option("smaug_brpc_pass") { + Some(smaug_brpc_pass) => match smaug_brpc_pass.as_str() { + Some(wdn) => wdn.to_owned(), + None => {return Err(anyhow!("must specify smaug_brpc_pass (your bitcoind instance rpcpassword)"))}, + }, + None => {return Err(anyhow!("must specify smaug_brpc_user"))}, + }; let ln_dir: PathBuf = configured_plugin.configuration().lightning_dir.into(); // Create data dir if it does not exist fs::create_dir_all(ln_dir.join(SMAUG_DATADIR)).unwrap_or_else(|e| { @@ -105,6 +159,8 @@ async fn main() -> Result<(), anyhow::Error> { let watch_descriptor = Smaug { wallets, network: network.clone(), + brpc_user: brpc_user.clone(), + brpc_pass: brpc_pass.clone(), db_dir: ln_dir.join(SMAUG_DATADIR), }; let plugin_state = Arc::new(Mutex::new(watch_descriptor.clone())); @@ -276,7 +332,11 @@ async fn list( plugin: Plugin, // _v: serde_json::Value, ) -> Result { - let wallets = &plugin.state().lock().await.wallets; + let state = &plugin.state().lock().await; + let brpc_user = state.brpc_user.clone(); + let brpc_pass = state.brpc_pass.clone(); + let wallets = state.wallets.clone(); + scanblocks(brpc_user, brpc_pass)?; let mut result = BTreeMap::::new(); for (wallet_name, wallet) in wallets { result.insert( diff --git a/src/state.rs b/src/state.rs index da72fe1..6da9880 100644 --- a/src/state.rs +++ b/src/state.rs @@ -13,6 +13,10 @@ pub struct Smaug { pub wallets: BTreeMap, // The network relevant to our wallets pub network: String, + // Bitcoind RPC user + pub brpc_user: String, + // Bitcoind RPC password + pub brpc_pass: String, // The db path relevant to our wallets pub db_dir: PathBuf, } @@ -22,6 +26,8 @@ impl Smaug { Self { wallets: BTreeMap::new(), network: bitcoin::Network::Bitcoin.to_string(), + brpc_user: String::from("bitcoin"), + brpc_pass: String::from("password"), db_dir: PathBuf::new(), } }