From 263f63e1815bb0083702a086854a1b3258180add Mon Sep 17 00:00:00 2001 From: stringhandler Date: Mon, 19 Oct 2026 15:34:20 +0200 Subject: [PATCH] Remove the daemon module and hal-simplicity-daemon binary The JSON-RPC daemon was an optional, off-by-default feature that was not built or tested in CI and is not documented. It exposes key generation and program execution over unauthenticated plain HTTP with no request size or resource limits, so it is not suitable for production use and keeps attracting security reports. All of its functionality is a thin wrapper around the `actions` module, which remains available to library users. This removes the `daemon` feature, the `hal_simplicity::daemon` module, the `hal-simplicity-daemon` binary, and the daemon-only dependencies (chrono, hyper, hyper-util, http-body-util, tokio). Assisted-by: Claude Code (Claude Opus 5.5) --- Cargo.lock | 360 +------------------------ Cargo.toml | 21 -- src/bin/hal-simplicity-daemon/main.rs | 77 ------ src/daemon/handler.rs | 260 ------------------ src/daemon/jsonrpc/mod.rs | 373 -------------------------- src/daemon/mod.rs | 178 ------------ src/daemon/types.rs | 231 ---------------- src/lib.rs | 3 - 8 files changed, 6 insertions(+), 1497 deletions(-) delete mode 100644 src/bin/hal-simplicity-daemon/main.rs delete mode 100644 src/daemon/handler.rs delete mode 100644 src/daemon/jsonrpc/mod.rs delete mode 100644 src/daemon/mod.rs delete mode 100644 src/daemon/types.rs diff --git a/Cargo.lock b/Cargo.lock index e71a00f..70d7b95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,12 +17,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "atty" version = "0.2.11" @@ -177,12 +171,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - [[package]] name = "bumpalo" version = "3.17.0" @@ -195,12 +183,6 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" -[[package]] -name = "bytes" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" - [[package]] name = "cc" version = "1.2.25" @@ -242,7 +224,7 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags 1.0.4", + "bitflags", "strsim", "textwrap", "unicode-width", @@ -255,7 +237,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.0.4", + "bitflags", ] [[package]] @@ -277,16 +259,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - [[package]] name = "fern" version = "0.5.7" @@ -302,21 +274,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - [[package]] name = "getrandom" version = "0.2.8" @@ -366,22 +323,17 @@ dependencies = [ name = "hal-simplicity" version = "0.2.0" dependencies = [ - "chrono", "clap", "elements", "fern", "hal", "hex", - "http-body-util", - "hyper", - "hyper-util", "log", "serde", "serde_json", "serde_yaml", "simplicity-lang", "thiserror", - "tokio", ] [[package]] @@ -411,99 +363,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" -[[package]] -name = "http" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" -dependencies = [ - "bytes", - "itoa 1.0.17", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "httpdate", - "itoa 1.0.17", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", -] - -[[package]] -name = "hyper-util" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "hyper", - "pin-project-lite", - "tokio", -] - [[package]] name = "itoa" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -[[package]] -name = "itoa" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" - [[package]] name = "jobserver" version = "0.1.12" @@ -565,15 +430,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - [[package]] name = "log" version = "0.4.6" @@ -593,17 +449,6 @@ dependencies = [ "bitcoin", ] -[[package]] -name = "mio" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - [[package]] name = "num-integer" version = "0.1.39" @@ -628,41 +473,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.5.18", - "smallvec", - "windows-link", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -838,22 +648,13 @@ version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags 2.10.0", -] - [[package]] name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" dependencies = [ - "redox_syscall 0.1.51", + "redox_syscall", ] [[package]] @@ -862,12 +663,6 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "secp256k1" version = "0.29.1" @@ -938,7 +733,7 @@ version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" dependencies = [ - "itoa 0.4.3", + "itoa", "ryu", "serde", ] @@ -967,16 +762,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - [[package]] name = "simplicity-lang" version = "0.8.0" @@ -1005,22 +790,6 @@ dependencies = [ "cc", ] -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - [[package]] name = "strsim" version = "0.8.0" @@ -1056,7 +825,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" dependencies = [ "libc", - "redox_syscall 0.1.51", + "redox_syscall", "redox_termios", ] @@ -1096,7 +865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" dependencies = [ "libc", - "redox_syscall 0.1.51", + "redox_syscall", "winapi", ] @@ -1115,34 +884,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "1.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" -dependencies = [ - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "unicode-ident" version = "1.0.8" @@ -1255,95 +996,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "yaml-rust" version = "0.4.3" diff --git a/Cargo.toml b/Cargo.toml index 8c0af83..e318c9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,20 +19,6 @@ path = "src/lib.rs" name = "hal-simplicity" path = "src/bin/hal-simplicity/main.rs" -[[bin]] -name = "hal-simplicity-daemon" -path = "src/bin/hal-simplicity-daemon/main.rs" - -[features] -default = [] -daemon = [ - "dep:chrono", - "dep:hyper", - "dep:hyper-util", - "dep:http-body-util", - "dep:tokio", -] - [dependencies] hal = "0.10.0" clap = "2.32" @@ -48,13 +34,6 @@ elements = { version = "0.25.3", features = [ "serde", "base64" ] } simplicity = { package = "simplicity-lang", version = "0.8.0", features = [ "base64", "serde" ] } thiserror = "2.0.17" -# Daemon-only dependencies -chrono = { version = "0.4", optional = true } -hyper = { version = "1.8.1", features = ["server", "http1"], optional = true } -hyper-util = { version = "0.1", features = ["tokio"], optional = true } -http-body-util = { version = "0.1", optional = true } -tokio = { version = "1.48.0", features = ["full"], optional = true } - [lints.clippy] # Exclude lints we don't think are valuable. needless_question_mark = "allow" # https://github.com/rust-bitcoin/rust-bitcoin/pull/2134 diff --git a/src/bin/hal-simplicity-daemon/main.rs b/src/bin/hal-simplicity-daemon/main.rs deleted file mode 100644 index da281a8..0000000 --- a/src/bin/hal-simplicity-daemon/main.rs +++ /dev/null @@ -1,77 +0,0 @@ -#[cfg(not(feature = "daemon"))] -fn main() { - eprintln!("hal-simplicity-daemon can only be built with the 'daemon' feature enabled"); - std::process::exit(1); -} - -#[cfg(feature = "daemon")] -fn main() { - use hal_simplicity::daemon::HalSimplicityDaemon; - - /// Default address for the TCP listener - const DEFAULT_ADDRESS: &str = "127.0.0.1:28579"; - - /// Setup logging with the given log level. - fn setup_logger(lvl: log::LevelFilter) { - fern::Dispatch::new() - .format(|out, message, _record| out.finish(format_args!("{}", message))) - .level(lvl) - .chain(std::io::stderr()) - .apply() - .expect("error setting up logger"); - } - - /// Create the main app object. - fn init_app<'a, 'b>() -> clap::App<'a, 'b> { - clap::App::new("hal-simplicity-daemon") - .bin_name("hal-simplicity-daemon") - .version(clap::crate_version!()) - .about("hal-simplicity-daemon -- JSON-RPC daemon for Simplicity operations") - .arg( - clap::Arg::with_name("address") - .short("a") - .long("address") - .value_name("ADDRESS") - .help("TCP address to bind to (default: 127.0.0.1:28579)") - .takes_value(true), - ) - .arg( - clap::Arg::with_name("verbose") - .short("v") - .long("verbose") - .help("Enable verbose logging output to stderr") - .takes_value(false), - ) - } - - let app = init_app(); - let matches = app.get_matches(); - - // Enable logging in verbose mode. - match matches.is_present("verbose") { - true => setup_logger(log::LevelFilter::Debug), - false => setup_logger(log::LevelFilter::Info), - } - - // Get the address from command line or use default - let address = matches.value_of("address").unwrap_or(DEFAULT_ADDRESS); - - log::info!("Starting hal-simplicity-daemon on {}...", address); - - // Create the daemon - let daemon = match HalSimplicityDaemon::new(address) { - Ok(d) => d, - Err(e) => { - log::error!("Failed to create daemon: {}", e); - - std::process::exit(1); - } - }; - - // Start the daemon and block - if let Err(e) = daemon.listen_blocking() { - log::error!("Daemon error: {}", e); - - std::process::exit(1); - } -} diff --git a/src/daemon/handler.rs b/src/daemon/handler.rs deleted file mode 100644 index 2298b8d..0000000 --- a/src/daemon/handler.rs +++ /dev/null @@ -1,260 +0,0 @@ -use std::str::FromStr; - -use super::jsonrpc::{ErrorCode, JsonRpcService, RpcError, RpcHandler}; -use serde_json::Value; - -use super::types::*; -use crate::actions; - -use crate::Network; - -/// RPC method names -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum RpcMethod { - AddressCreate, - AddressInspect, - BlockCreate, - BlockDecode, - TxCreate, - TxDecode, - KeypairGenerate, - SimplicityInfo, - SimplicitySighash, - PsetCreate, - PsetExtract, - PsetFinalize, - PsetRun, - PsetUpdateInput, -} - -impl FromStr for RpcMethod { - type Err = RpcError; - - fn from_str(s: &str) -> Result { - let method = match s { - "address_create" => Self::AddressCreate, - "address_inspect" => Self::AddressInspect, - "block_create" => Self::BlockCreate, - "block_decode" => Self::BlockDecode, - "tx_create" => Self::TxCreate, - "tx_decode" => Self::TxDecode, - "keypair_generate" => Self::KeypairGenerate, - "simplicity_info" => Self::SimplicityInfo, - "simplicity_sighash" => Self::SimplicitySighash, - "pset_create" => Self::PsetCreate, - "pset_extract" => Self::PsetExtract, - "pset_finalize" => Self::PsetFinalize, - "pset_run" => Self::PsetRun, - "pset_update_input" => Self::PsetUpdateInput, - _ => return Err(RpcError::new(ErrorCode::MethodNotFound)), - }; - - Ok(method) - } -} - -/// Default RPC handler that provides basic methods -#[derive(Default)] -pub struct DefaultRpcHandler; - -impl RpcHandler for DefaultRpcHandler { - fn handle(&self, method: &str, params: Option) -> Result { - let rpc_method = RpcMethod::from_str(method)?; - - match rpc_method { - RpcMethod::AddressCreate => { - let req: AddressCreateRequest = parse_params(params)?; - let result = actions::address::address_create( - req.pubkey.as_deref(), - req.script.as_deref(), - req.blinder.as_deref(), - req.network.unwrap_or(Network::Liquid), - ) - .map_err(|e| RpcError::custom(ErrorCode::InternalError.code(), e.to_string()))?; - - serialize_result(result) - } - RpcMethod::AddressInspect => { - let req: AddressInspectRequest = parse_params(params)?; - let result = actions::address::address_inspect(&req.address).map_err(|e| { - RpcError::custom(ErrorCode::InternalError.code(), e.to_string()) - })?; - - serialize_result(result) - } - RpcMethod::BlockCreate => { - let req: BlockCreateRequest = parse_params(params)?; - - let block = actions::block::block_create(req.block_info).map_err(|e| { - RpcError::custom(ErrorCode::InternalError.code(), e.to_string()) - })?; - - let raw_block = hex::encode(elements::encode::serialize(&block)); - serialize_result(BlockCreateResponse { - raw_block, - }) - } - RpcMethod::BlockDecode => { - let req: BlockDecodeRequest = parse_params(params)?; - let result = actions::block::block_decode( - &req.raw_block, - req.network.unwrap_or(Network::Liquid), - req.txids.unwrap_or(false), - ) - .map_err(|e| RpcError::custom(ErrorCode::InternalError.code(), e.to_string()))?; - - serialize_result(result) - } - RpcMethod::TxCreate => { - let req: TxCreateRequest = parse_params(params)?; - let tx = actions::tx::tx_create(req.tx_info).map_err(|e| { - RpcError::custom(ErrorCode::InternalError.code(), e.to_string()) - })?; - - let raw_tx = hex::encode(elements::encode::serialize(&tx)); - serialize_result(TxCreateResponse { - raw_tx, - }) - } - RpcMethod::TxDecode => { - let req: TxDecodeRequest = parse_params(params)?; - let result = - actions::tx::tx_decode(&req.raw_tx, req.network.unwrap_or(Network::Liquid)) - .map_err(|e| { - RpcError::custom(ErrorCode::InternalError.code(), e.to_string()) - })?; - - serialize_result(result) - } - RpcMethod::KeypairGenerate => { - let result = actions::keypair::keypair_generate(); - - serialize_result(result) - } - RpcMethod::SimplicityInfo => { - let req: SimplicityInfoRequest = parse_params(params)?; - let result = actions::simplicity::simplicity_info( - &req.program, - req.witness.as_deref(), - req.state.as_deref(), - ) - .map_err(|e| RpcError::custom(ErrorCode::InternalError.code(), e.to_string()))?; - - serialize_result(result) - } - RpcMethod::SimplicitySighash => { - let req: SimplicitySighashRequest = parse_params(params)?; - // TODO(ivanlele): I don't like this flip flop conversion, maybe there is a better API - let input_utxos = req - .input_utxos - .as_ref() - .map(|v| v.iter().map(String::as_str).collect::>()); - - let result = actions::simplicity::simplicity_sighash( - &req.tx, - &req.input_index.to_string(), - &req.cmr, - req.control_block.as_deref(), - req.genesis_hash.as_deref(), - req.secret_key.as_deref(), - req.public_key.as_deref(), - req.signature.as_deref(), - input_utxos.as_deref(), - ) - .map_err(|e| RpcError::custom(ErrorCode::InternalError.code(), e.to_string()))?; - serialize_result(result) - } - RpcMethod::PsetCreate => { - let req: PsetCreateRequest = parse_params(params)?; - let result = actions::simplicity::pset::pset_create(&req.inputs, &req.outputs) - .map_err(|e| { - RpcError::custom(ErrorCode::InternalError.code(), e.to_string()) - })?; - - serialize_result(result) - } - RpcMethod::PsetExtract => { - let req: PsetExtractRequest = parse_params(params)?; - let raw_tx = actions::simplicity::pset::pset_extract(&req.pset).map_err(|e| { - RpcError::custom(ErrorCode::InternalError.code(), e.to_string()) - })?; - - serialize_result(PsetExtractResponse { - raw_tx, - }) - } - RpcMethod::PsetFinalize => { - let req: PsetFinalizeRequest = parse_params(params)?; - let result = actions::simplicity::pset::pset_finalize( - &req.pset, - &req.input_index.to_string(), - &req.program, - &req.witness, - req.genesis_hash.as_deref(), - ) - .map_err(|e| RpcError::custom(ErrorCode::InternalError.code(), e.to_string()))?; - - serialize_result(result) - } - RpcMethod::PsetRun => { - let req: PsetRunRequest = parse_params(params)?; - let result = actions::simplicity::pset::pset_run( - &req.pset, - &req.input_index.to_string(), - &req.program, - &req.witness, - req.genesis_hash.as_deref(), - ) - .map_err(|e| RpcError::custom(ErrorCode::InternalError.code(), e.to_string()))?; - - serialize_result(result) - } - RpcMethod::PsetUpdateInput => { - let req: PsetUpdateInputRequest = parse_params(params)?; - let result = actions::simplicity::pset::pset_update_input( - &req.pset, - &req.input_index.to_string(), - &req.input_utxo, - req.internal_key.as_deref(), - req.cmr.as_deref(), - req.state.as_deref(), - ) - .map_err(|e| RpcError::custom(ErrorCode::InternalError.code(), e.to_string()))?; - - serialize_result(result) - } - } - } -} - -impl DefaultRpcHandler { - fn new() -> Self { - Self - } -} - -/// Parse parameters from JSON value -fn parse_params(params: Option) -> Result { - let params = params.ok_or_else(|| { - RpcError::custom(ErrorCode::InvalidParams.code(), "Missing parameters".to_string()) - })?; - - serde_json::from_value(params).map_err(|e| { - RpcError::custom(ErrorCode::InvalidParams.code(), format!("Invalid parameters: {}", e)) - }) -} - -/// Serialize result to JSON value -fn serialize_result(result: T) -> Result { - serde_json::to_value(result).map_err(|e| { - RpcError::custom( - ErrorCode::InternalError.code(), - format!("Failed to serialize result: {}", e), - ) - }) -} - -/// Create a JSONRPC service with the default handler -pub fn create_service() -> JsonRpcService { - JsonRpcService::new(DefaultRpcHandler::new()) -} diff --git a/src/daemon/jsonrpc/mod.rs b/src/daemon/jsonrpc/mod.rs deleted file mode 100644 index c4f15e1..0000000 --- a/src/daemon/jsonrpc/mod.rs +++ /dev/null @@ -1,373 +0,0 @@ -//! Simple JSONRPC 2.0 implementation -//! -//! - -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use std::fmt; - -/// JSONRPC 2.0 Error codes as defined in the specification -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ErrorCode { - ParseError = -32700, - InvalidRequest = -32600, - MethodNotFound = -32601, - InvalidParams = -32602, - InternalError = -32603, -} - -impl ErrorCode { - pub fn code(&self) -> i64 { - *self as i64 - } - - pub fn message(&self) -> &str { - match self { - ErrorCode::ParseError => "Parse error", - ErrorCode::InvalidRequest => "Invalid Request", - ErrorCode::MethodNotFound => "Method not found", - ErrorCode::InvalidParams => "Invalid params", - ErrorCode::InternalError => "Internal error", - } - } -} - -/// JSONRPC 2.0 Error object -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RpcError { - pub code: i64, - pub message: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub data: Option, -} - -impl RpcError { - pub fn new(error_code: ErrorCode) -> Self { - Self { - code: error_code.code(), - message: error_code.message().to_string(), - data: None, - } - } - - pub fn with_data(mut self, data: Value) -> Self { - self.data = Some(data); - self - } - - pub fn custom(code: i64, message: String) -> Self { - Self { - code, - message, - data: None, - } - } -} - -impl fmt::Display for RpcError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "RPC Error {}: {}", self.code, self.message) - } -} - -impl std::error::Error for RpcError {} - -/// JSONRPC 2.0 Request object -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RpcRequest { - pub jsonrpc: String, - pub method: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub params: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub id: Option, -} - -impl RpcRequest { - pub fn new(method: String, params: Option, id: Option) -> Self { - Self { - jsonrpc: "2.0".to_string(), - method, - params, - id, - } - } - - /// Check if this is a notification (no id field) - pub fn is_notification(&self) -> bool { - self.id.is_none() - } - - /// Validate the request according to JSONRPC 2.0 spec - pub fn validate(&self) -> Result<(), RpcError> { - if self.jsonrpc != "2.0" { - return Err(RpcError::new(ErrorCode::InvalidRequest) - .with_data(Value::String("jsonrpc field must be '2.0'".to_string()))); - } - - if self.method.is_empty() { - return Err(RpcError::new(ErrorCode::InvalidRequest) - .with_data(Value::String("method field cannot be empty".to_string()))); - } - - Ok(()) - } -} - -/// JSONRPC 2.0 Response object -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RpcResponse { - pub jsonrpc: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub result: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub error: Option, - pub id: Value, -} - -impl RpcResponse { - pub fn success(result: Value, id: Value) -> Self { - Self { - jsonrpc: "2.0".to_string(), - result: Some(result), - error: None, - id, - } - } - - pub fn error(error: RpcError, id: Value) -> Self { - Self { - jsonrpc: "2.0".to_string(), - result: None, - error: Some(error), - id, - } - } -} - -/// Represents either a single request or batch requests -#[derive(Debug)] -pub enum RpcCall { - Single(RpcRequest), - Batch(Vec), -} - -impl RpcCall { - /// Parse a JSON string into an RPC call - pub fn from_json(json: &str) -> Result { - // Try parsing as a single request first - if let Ok(request) = serde_json::from_str::(json) { - request.validate()?; - return Ok(RpcCall::Single(request)); - } - - // Try psrsing as a batch request - match serde_json::from_str::>(json) { - Ok(requests) => { - if requests.is_empty() { - return Err(RpcError::new(ErrorCode::InvalidRequest) - .with_data(Value::String("batch request cannot be empty".to_string()))); - } - - for request in &requests { - request.validate()?; - } - - Ok(RpcCall::Batch(requests)) - } - Err(_) => Err(RpcError::new(ErrorCode::ParseError)), - } - } -} - -/// Represents either a single response or batch responses -#[derive(Debug, Serialize)] -#[serde(untagged)] -pub enum RpcOutput { - Single(RpcResponse), - Batch(Vec), -} - -impl RpcOutput { - pub fn to_json(&self) -> Result { - serde_json::to_string(self) - } -} - -/// Handler trait for RPC methods -pub trait RpcHandler: Send + Sync { - fn handle(&self, method: &str, params: Option) -> Result; -} - -/// Main JSONRPC service -pub struct JsonRpcService { - handler: H, -} - -impl JsonRpcService { - pub fn new(handler: H) -> Self { - Self { - handler, - } - } - - /// Process a raw JSON string and return a JSON response - pub fn handle_raw(&self, json: &str) -> String { - match RpcCall::from_json(json) { - Ok(call) => match call { - RpcCall::Single(request) => { - let response = self.handle_single(request); - if let Some(resp) = response { - serde_json::to_string(&resp).unwrap_or_else(|_| { - serde_json::to_string(&RpcResponse::error( - RpcError::new(ErrorCode::InternalError), - Value::Null, - )) - .unwrap() - }) - } else { - // Notification - no response - String::new() - } - } - RpcCall::Batch(requests) => { - let responses = self.handle_batch(requests); - if responses.is_empty() { - // All notifications - no response - String::new() - } else { - RpcOutput::Batch(responses).to_json().unwrap_or_else(|_| { - serde_json::to_string(&RpcResponse::error( - RpcError::new(ErrorCode::InternalError), - Value::Null, - )) - .unwrap() - }) - } - } - }, - Err(error) => { - serde_json::to_string(&RpcResponse::error(error, Value::Null)).expect("should ") - } - } - } - - /// Handle a single RPC request - fn handle_single(&self, request: RpcRequest) -> Option { - // Notifications don't get responses - if request.is_notification() { - let _ = self.handler.handle(&request.method, request.params); - return None; - } - - let id = request.id.clone().unwrap_or(Value::Null); - - let response = match self.handler.handle(&request.method, request.params) { - Ok(result) => RpcResponse::success(result, id), - Err(error) => RpcResponse::error(error, id), - }; - - Some(response) - } - - /// Handle a batch of RPC requests - fn handle_batch(&self, requests: Vec) -> Vec { - requests.into_iter().filter_map(|request| self.handle_single(request)).collect() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - struct TestHandler; - - impl RpcHandler for TestHandler { - fn handle(&self, method: &str, params: Option) -> Result { - match method { - "echo" => Ok(params.unwrap_or(Value::Null)), - "add" => { - let params = params.ok_or_else(|| RpcError::new(ErrorCode::InvalidParams))?; - let array = - params.as_array().ok_or_else(|| RpcError::new(ErrorCode::InvalidParams))?; - if array.len() != 2 { - return Err(RpcError::new(ErrorCode::InvalidParams)); - } - let a = - array[0].as_i64().ok_or_else(|| RpcError::new(ErrorCode::InvalidParams))?; - let b = - array[1].as_i64().ok_or_else(|| RpcError::new(ErrorCode::InvalidParams))?; - Ok(Value::Number((a + b).into())) - } - _ => Err(RpcError::new(ErrorCode::MethodNotFound)), - } - } - } - - #[test] - fn test_single_request() { - let service = JsonRpcService::new(TestHandler); - let request = r#"{"jsonrpc":"2.0","method":"echo","params":"hello","id":1}"#; - let response = service.handle_raw(request); - assert!(response.contains(r#""result":"hello""#)); - assert!(response.contains(r#""id":1"#)); - } - - #[test] - fn test_notification() { - let service = JsonRpcService::new(TestHandler); - let request = r#"{"jsonrpc":"2.0","method":"echo","params":"hello"}"#; - let response = service.handle_raw(request); - assert_eq!(response, ""); - } - - #[test] - fn test_batch_request() { - let service = JsonRpcService::new(TestHandler); - let request = r#"[ - {"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}, - {"jsonrpc":"2.0","method":"add","params":[3,4],"id":2} - ]"#; - let response = service.handle_raw(request); - assert!(response.contains(r#""result":3"#)); - assert!(response.contains(r#""result":7"#)); - } - - #[test] - fn test_method_not_found() { - let service = JsonRpcService::new(TestHandler); - let request = r#"{"jsonrpc":"2.0","method":"unknown","id":1}"#; - let response = service.handle_raw(request); - assert!(response.contains(r#""code":-32601"#)); - assert!(response.contains("Method not found")); - } - - #[test] - fn test_invalid_json() { - let service = JsonRpcService::new(TestHandler); - let request = r#"{"jsonrpc":"2.0","method":"#; - let response = service.handle_raw(request); - assert!(response.contains(r#""code":-32700"#)); - } - - #[test] - fn test_invalid_request() { - let service = JsonRpcService::new(TestHandler); - let request = r#"{"jsonrpc":"1.0","method":"echo","id":1}"#; - let response = service.handle_raw(request); - assert!(response.contains(r#""code":-32600"#)); - } - - #[test] - fn test_batch_with_notifications() { - let service = JsonRpcService::new(TestHandler); - let request = r#"[ - {"jsonrpc":"2.0","method":"echo","params":"notify"}, - {"jsonrpc":"2.0","method":"add","params":[1,2],"id":1} - ]"#; - let response = service.handle_raw(request); - // Should only have one response (the non-notification) - assert!(response.contains(r#""result":3"#)); - assert!(response.contains(r#""id":1"#)); - } -} diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs deleted file mode 100644 index fee6436..0000000 --- a/src/daemon/mod.rs +++ /dev/null @@ -1,178 +0,0 @@ -pub mod handler; -pub mod types; - -pub mod jsonrpc; - -use std::net::SocketAddr; -use std::sync::Arc; - -use http_body_util::{BodyExt, Full}; -use hyper::body::Bytes; -use hyper::server::conn::http1; -use hyper::service::service_fn; -use hyper::{body::Incoming, Method, Request, Response, StatusCode}; -use hyper_util::rt::TokioIo; -use tokio::net::TcpListener; -use tokio::sync::broadcast; - -use thiserror::Error; - -use handler::DefaultRpcHandler; -use jsonrpc::JsonRpcService; - -/// Errors that can occur in the daemon, usually on startup. -#[derive(Error, Debug)] -pub enum DaemonError { - #[error("IO error: {0}")] - Io(#[from] std::io::Error), - #[error("Address parse error: {0}")] - AddrParse(#[from] std::net::AddrParseError), -} - -/// The HAL Simplicity Daemon -/// -/// It listens for JSON-RPC requests over HTTP and handles them. -/// Does not block the current thread when started. Instead, it spawns a new thread. -pub struct HalSimplicityDaemon { - address: SocketAddr, - shutdown_tx: broadcast::Sender<()>, - rpc_service: Arc>, -} - -impl HalSimplicityDaemon { - pub fn new(address: &str) -> Result { - let address: SocketAddr = address.parse()?; - let (shutdown_tx, _) = broadcast::channel(1); - let rpc_service = Arc::new(handler::create_service()); - - Ok(Self { - address, - shutdown_tx, - rpc_service, - }) - } - - /// Core event loop that accepts connections and handles them - async fn run_event_loop( - listener: TcpListener, - rpc_service: Arc>, - mut shutdown_rx: broadcast::Receiver<()>, - ) -> Result<(), DaemonError> { - loop { - tokio::select! { - Ok((stream, _)) = listener.accept() => { - let io = TokioIo::new(stream); - let rpc_service_clone = rpc_service.clone(); - tokio::task::spawn(async move { - http1::Builder::new() - .serve_connection(io, service_fn(move |req| { - handle_request(req, rpc_service_clone.clone()) - })) - .await - }); - } - _ = shutdown_rx.recv() => { - break; - } - } - } - - Ok(()) - } - - /// Start the daemon on a new thread. - /// Useful when you need just to spawn the daemon and continue doing other things in the main thread. - pub fn start(&mut self) -> Result<(), DaemonError> { - let address = self.address; - let shutdown_tx = self.shutdown_tx.clone(); - let rpc_service = self.rpc_service.clone(); - - let runtime = tokio::runtime::Runtime::new()?; - let listener = runtime.block_on(async { TcpListener::bind(&address).await })?; - - std::thread::spawn(move || { - runtime.block_on(async move { - let shutdown_rx = shutdown_tx.subscribe(); - let _ = Self::run_event_loop(listener, rpc_service, shutdown_rx).await; - }); - }); - - Ok(()) - } - - /// Start the daemon and block the current thread, - /// Useful for CLI applications. - pub fn listen_blocking(self) -> Result<(), DaemonError> { - let runtime = tokio::runtime::Runtime::new()?; - - runtime.block_on(async move { - let listener = TcpListener::bind(&self.address).await?; - let shutdown_rx = self.shutdown_tx.subscribe(); - Self::run_event_loop(listener, self.rpc_service, shutdown_rx).await - }) - } - - /// Shutdown the daemon - pub fn shutdown(&self) { - let _ = self.shutdown_tx.send(()); - } -} - -/// Handles an incoming HTTP request and produces a response. -async fn handle_request( - req: Request, - rpc_service: Arc>, -) -> Result>, DaemonError> { - let path = req.uri().path(); - let method = req.method(); - - if method != Method::POST { - return Ok(create_status_response(StatusCode::METHOD_NOT_ALLOWED)); - } - - if path != "/rpc" && path != "/" { - return Ok(create_status_response(StatusCode::NOT_FOUND)); - } - - let body_str = match read_body_as_string(req).await { - Ok(body) => body, - Err(status) => return Ok(create_status_response(status)), - }; - - let response_str = rpc_service.handle_raw(&body_str); - - if response_str.is_empty() { - return Ok(create_status_response(StatusCode::NO_CONTENT)); - } - - Ok(create_json_response(response_str)) -} - -/// Creates an HTTP response with the given status code -fn create_status_response(status: StatusCode) -> Response> { - let body = if status == StatusCode::NO_CONTENT { - Bytes::new() - } else { - Bytes::from(status.canonical_reason().unwrap_or("Unknown Error")) - }; - let mut response = Response::new(Full::new(body)); - *response.status_mut() = status; - response -} - -/// Reads and validates the request body as a UTF-8 string -async fn read_body_as_string(req: Request) -> Result { - let body_bytes = req.collect().await.map_err(|_| StatusCode::BAD_REQUEST)?.to_bytes(); - - String::from_utf8(body_bytes.to_vec()).map_err(|_| StatusCode::BAD_REQUEST) -} - -/// Creates a successful JSON-RPC response -fn create_json_response(body: String) -> Response> { - let mut response = Response::new(Full::new(Bytes::from(body))); - response.headers_mut().insert( - hyper::header::CONTENT_TYPE, - hyper::header::HeaderValue::from_static("application/json"), - ); - response -} diff --git a/src/daemon/types.rs b/src/daemon/types.rs deleted file mode 100644 index cddf6bf..0000000 --- a/src/daemon/types.rs +++ /dev/null @@ -1,231 +0,0 @@ -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -pub use elements::bitcoin::secp256k1; -pub use elements::hashes::sha256; -pub use simplicity::bitcoin::secp256k1::schnorr; -pub use simplicity::{Amr, Cmr, Ihr}; - -use crate::block::BlockInfo; -use crate::tx::TransactionInfo; -use crate::Network; - -// Custom serialization for Parity as 0 or 1 -mod parity_serde { - use super::*; - - pub fn serialize(parity: &secp256k1::Parity, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_u8(parity.to_i32() as u8) - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let value = u8::deserialize(deserializer)?; - secp256k1::Parity::from_i32(value as i32) - .map_err(|_| serde::de::Error::custom(format!("invalid parity value: {}", value))) - } -} - -// Address types -#[derive(Debug, Serialize, Deserialize)] -pub struct AddressCreateRequest { - pub network: Option, - pub pubkey: Option, - pub script: Option, - pub blinder: Option, -} - -pub use crate::address::Addresses as AddressCreateResponse; - -#[derive(Debug, Serialize, Deserialize)] -pub struct AddressInspectRequest { - pub address: String, -} - -pub use crate::address::AddressInfo as AddressInspectResponse; - -// Block types -#[derive(Debug, Serialize, Deserialize)] -pub struct BlockCreateRequest { - pub block_info: BlockInfo, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct BlockCreateResponse { - pub raw_block: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct BlockDecodeRequest { - pub raw_block: String, - pub network: Option, - pub txids: Option, -} - -pub type BlockDecodeResponse = serde_json::Value; - -// Transaction types -#[derive(Debug, Serialize, Deserialize)] -pub struct TxCreateRequest { - pub tx_info: TransactionInfo, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TxCreateResponse { - pub raw_tx: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TxDecodeRequest { - pub raw_tx: String, - pub network: Option, -} - -pub type TxDecodeResponse = serde_json::Value; - -// Keypair types -#[derive(Debug, Serialize, Deserialize)] -pub struct KeypairGenerateRequest {} - -#[derive(Debug, Serialize, Deserialize)] -pub struct KeypairGenerateResponse { - pub secret: secp256k1::SecretKey, - pub x_only: secp256k1::XOnlyPublicKey, - #[serde(with = "parity_serde")] - pub parity: secp256k1::Parity, -} - -// Simplicity types -#[derive(Debug, Serialize, Deserialize)] -pub struct SimplicityInfoRequest { - pub program: String, - pub witness: Option, - pub state: Option, - pub network: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SimplicityInfoResponse { - pub jets: String, - pub commit_base64: String, - pub commit_decode: String, - pub type_arrow: String, - pub cmr: Cmr, - pub liquid_address_unconf: String, - pub liquid_testnet_address_unconf: String, - pub is_redeem: bool, - pub redeem_info: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct RedeemInfo { - pub redeem_base64: String, - pub witness_hex: String, - pub amr: Amr, - pub ihr: Ihr, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SimplicitySighashRequest { - pub tx: String, - pub input_index: u32, - pub cmr: String, - pub control_block: Option, - pub genesis_hash: Option, - pub secret_key: Option, - pub public_key: Option, - pub signature: Option, - pub input_utxos: Option>, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SimplicitySighashResponse { - pub sighash: sha256::Hash, - pub signature: Option, - pub valid_signature: Option, -} - -// PSET types -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetCreateRequest { - pub inputs: String, - pub outputs: String, - pub network: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetCreateResponse { - pub pset: String, - pub updated_values: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetExtractRequest { - pub pset: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetExtractResponse { - pub raw_tx: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetFinalizeRequest { - pub pset: String, - pub input_index: u32, - pub program: String, - pub witness: String, - pub genesis_hash: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetFinalizeResponse { - pub pset: String, - pub updated_values: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetRunRequest { - pub pset: String, - pub input_index: u32, - pub program: String, - pub witness: String, - pub genesis_hash: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetRunResponse { - pub success: bool, - pub jets: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct JetCall { - pub jet: String, - pub source_ty: String, - pub target_ty: String, - pub success: bool, - pub input_hex: String, - pub output_hex: String, - pub equality_check: Option<(String, String)>, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetUpdateInputRequest { - pub pset: String, - pub input_index: u32, - pub input_utxo: String, - pub internal_key: Option, - pub cmr: Option, - pub state: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PsetUpdateInputResponse { - pub pset: String, - pub updated_values: Vec, -} diff --git a/src/lib.rs b/src/lib.rs index 09f4a6d..fbc8341 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,9 +12,6 @@ pub mod confidential; pub use elements::bitcoin; pub use hal::HexBytes; -#[cfg(feature = "daemon")] -pub mod daemon; - use elements::AddressParams; use serde::{Deserialize, Serialize};