From 959589e8bc9850d3a7957dbbcde5b765ebb354dd Mon Sep 17 00:00:00 2001 From: "kody.low" Date: Sun, 2 Jun 2024 15:32:10 -0700 Subject: [PATCH 1/2] fix: sent info and writing keys correctly --- fedimint-nwc/src/main.rs | 3 +- fedimint-nwc/src/services/nostr.rs | 74 +++++++++++++++++++----------- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/fedimint-nwc/src/main.rs b/fedimint-nwc/src/main.rs index 0db801a..0eec08a 100644 --- a/fedimint-nwc/src/main.rs +++ b/fedimint-nwc/src/main.rs @@ -18,10 +18,11 @@ use crate::state::AppState; async fn main() -> Result<()> { init_logging_and_env()?; let cli = Cli::parse(); - let state = AppState::new(cli).await?; + let mut state = AppState::new(cli).await?; state.nostr_service.connect().await; state.nostr_service.broadcast_info_event().await?; + state.nostr_service.subscribe_nwc().await; let server_handle = tokio::spawn(async { match run_server().await { diff --git a/fedimint-nwc/src/services/nostr.rs b/fedimint-nwc/src/services/nostr.rs index 806e300..23bb1c8 100644 --- a/fedimint-nwc/src/services/nostr.rs +++ b/fedimint-nwc/src/services/nostr.rs @@ -7,7 +7,8 @@ use nostr::nips::nip04; use nostr::nips::nip47::Response; use nostr_sdk::secp256k1::SecretKey; use nostr_sdk::{ - Client, Event, EventBuilder, EventId, JsonUtil, Keys, Kind, RelayPoolNotification, Tag, + Client, Event, EventBuilder, EventId, Filter, JsonUtil, Keys, Kind, RelayPoolNotification, Tag, + Timestamp, }; use serde::{Deserialize, Serialize}; use tokio::sync::broadcast::Receiver; @@ -23,31 +24,43 @@ pub struct NostrService { user_key: SecretKey, #[serde(default)] pub sent_info: bool, + pub keys_file_path: PathBuf, } impl NostrService { pub async fn new(keys_file_path: &PathBuf, relays: &str) -> Result { - let (server_key, user_key) = match File::open(keys_file_path) { + let (server_key, user_key, sent_info) = match File::open(keys_file_path) { Ok(file) => { let reader = BufReader::new(file); let keys: Self = serde_json::from_reader(reader).context("Failed to parse JSON")?; - (keys.server_key, keys.user_key) + (keys.server_key, keys.user_key, keys.sent_info) } Err(_) => { let (server_key, user_key) = Self::generate_keys()?; - Self::write_keys(server_key, user_key, keys_file_path)?; - (server_key, user_key) + (server_key, user_key, false) } }; let client = Client::new(&Keys::new(server_key.into())); - Self::add_relays(&client, relays).await?; - Ok(Self { + let service = Self { client, server_key, user_key, - sent_info: false, - }) + sent_info, + keys_file_path: keys_file_path.clone(), + }; + + service.add_relays(relays).await?; + + if !sent_info { + service.write_keys().context("Failed to write keys")?; + } + + Ok(service) + } + + pub fn set_sent_info(&mut self, sent_info: bool) { + self.sent_info = sent_info; } fn generate_keys() -> Result<(SecretKey, SecretKey)> { @@ -58,20 +71,10 @@ impl NostrService { Ok((**server_key, **user_key)) } - fn write_keys( - server_key: SecretKey, - user_key: SecretKey, - keys_file_path: &PathBuf, - ) -> Result<()> { - let keys = Self { - server_key, - user_key, - sent_info: false, - client: Client::new(&Keys::new(server_key.into())), /* Dummy client for struct - * initialization */ - }; - let json_str = serde_json::to_string(&keys).context("Failed to serialize data")?; - let mut file = File::create(keys_file_path).context("Failed to create file")?; + fn write_keys(&self) -> Result<()> { + let json_str = serde_json::to_string(&self).context("Failed to serialize data")?; + let mut file = + File::create(self.keys_file_path.clone()).context("Failed to create file")?; file.write_all(json_str.as_bytes()) .context("Failed to write to file")?; Ok(()) @@ -85,7 +88,7 @@ impl NostrService { Keys::new(self.user_key.into()) } - async fn add_relays(client: &Client, relays: &str) -> Result<()> { + async fn add_relays(&self, relays: &str) -> Result<()> { let lines = relays.split(',').collect::>(); let relays = lines .iter() @@ -94,7 +97,7 @@ impl NostrService { .map(|line| line.to_string()) .collect::>(); for relay in relays { - client.add_relay(relay).await?; + self.client.add_relay(relay).await?; } Ok(()) } @@ -130,7 +133,10 @@ impl NostrService { Ok(()) } - pub async fn broadcast_info_event(&self) -> Result<(), anyhow::Error> { + pub async fn broadcast_info_event(&mut self) -> Result<(), anyhow::Error> { + if self.sent_info { + return Ok(()); + } let content = METHODS .iter() .map(ToString::to_string) @@ -139,8 +145,10 @@ impl NostrService { let info = EventBuilder::new(Kind::WalletConnectInfo, content, []) .to_event(&self.server_keys())?; info!("Broadcasting info event: {}", info.as_json()); - let event_id = self.client.send_event(info).await?; + let event_id = self.send_event(info).await?; info!("Broadcasted info event: {}", event_id); + self.sent_info = true; + self.write_keys()?; Ok(()) } @@ -164,4 +172,16 @@ impl NostrService { && event.verify().is_ok() && event.pubkey == self.user_keys().public_key() } + + pub async fn subscribe_nwc(&self) { + let subscription = Filter::new() + .kinds(vec![Kind::WalletConnectRequest]) + .author(self.user_keys().public_key()) + .pubkey(self.server_keys().public_key()) + .since(Timestamp::now()); + + self.client.subscribe(vec![subscription], None).await; + + info!("Listening for nip 47 requests..."); + } } From c58b6162725f4d52dabb8788bada52fb3e2b99fd Mon Sep 17 00:00:00 2001 From: "kody.low" Date: Sun, 2 Jun 2024 15:51:06 -0700 Subject: [PATCH 2/2] feat: simple nwc --- Cargo.lock | 635 ++++++++++++++++++++++++++++- fedimint-nwc/Cargo.toml | 2 + fedimint-nwc/src/main.rs | 9 + fedimint-nwc/src/services/nostr.rs | 43 +- fedimint-nwc/src/utils.rs | 14 + 5 files changed, 690 insertions(+), 13 deletions(-) create mode 100644 fedimint-nwc/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index fb866cf..aa2e974 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "allocator-api2" version = "0.2.18" @@ -155,6 +161,23 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "arbitrary" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "argon2" version = "0.5.3" @@ -172,6 +195,9 @@ name = "arrayvec" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +dependencies = [ + "serde", +] [[package]] name = "async-lock" @@ -295,6 +321,30 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "serde", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + [[package]] name = "axum" version = "0.7.5" @@ -505,6 +555,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitcoin" version = "0.29.2" @@ -636,6 +692,12 @@ version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" +[[package]] +name = "bitstream-io" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e445576659fd04a57b44cbd00aa37aaa815ebefa0aa3cb677a6b5e63d883074f" + [[package]] name = "bitvec" version = "1.0.1" @@ -698,6 +760,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "built" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9c056b9ed43aee5e064b683aa1ec783e19c6acec7559e3ae931b7490472fbe" +dependencies = [ + "cargo-lock", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -710,12 +781,24 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "bytemuck" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" + [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.6.0" @@ -733,6 +816,18 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "cargo-lock" +version = "8.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031718ddb8f78aa5def78a09e90defe30151d1f6c672f937af4dd916429ed996" +dependencies = [ + "semver", + "serde", + "toml 0.5.11", + "url", +] + [[package]] name = "cbc" version = "0.1.2" @@ -762,6 +857,16 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-expr" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -907,6 +1012,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.1" @@ -956,6 +1067,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.12" @@ -965,6 +1085,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -1136,12 +1275,37 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + [[package]] name = "fedimint" version = "0.0.1" @@ -1497,11 +1661,13 @@ dependencies = [ "clap 4.5.4", "dotenv", "futures-util", + "image", "itertools 0.13.0", "lightning-invoice", "multimint 0.3.7", "nostr", "nostr-sdk", + "qrcode", "redb", "serde", "serde_json", @@ -1633,6 +1799,25 @@ dependencies = [ "subtle", ] +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1776,6 +1961,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.28.1" @@ -1876,6 +2071,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.8.2" @@ -2173,6 +2378,39 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +dependencies = [ + "byteorder-lite", + "thiserror", +] + [[package]] name = "imbl" version = "2.0.3" @@ -2195,6 +2433,12 @@ dependencies = [ "bitmaps", ] +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + [[package]] name = "impl-tools" version = "0.10.0" @@ -2291,6 +2535,17 @@ dependencies = [ "web-sys", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -2345,6 +2600,12 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.69" @@ -2470,12 +2731,28 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libfuzzer-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf184a4b6b274f82a5df6b357da6055d3e82272327bba281c28bbba6f1664ef" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libloading" version = "0.8.3" @@ -2586,6 +2863,15 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "lru" version = "0.12.3" @@ -2636,6 +2922,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.7.2" @@ -2691,6 +2987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", + "simd-adler32", ] [[package]] @@ -2753,6 +3050,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e664971378a3987224f7a0e10059782035e89899ae403718ee07de85bec42afe" +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nom" version = "7.1.3" @@ -2763,6 +3066,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "nostr" version = "0.31.2" @@ -2877,12 +3186,53 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -3159,6 +3509,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "poly1305" version = "0.8.0" @@ -3189,7 +3552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" dependencies = [ "toml_datetime", - "toml_edit", + "toml_edit 0.20.2", ] [[package]] @@ -3246,6 +3609,30 @@ version = "2.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "qrcode" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e719ca51966ff9f5a8436edb00d6115b3c606a0bb27c8f8ca74a38ff2b036d" +dependencies = [ + "image", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quote" version = "1.0.36" @@ -3300,6 +3687,77 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rav1e" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c383692a5e7abd9f6d1eddb1a5e0269f859392387883361bb09e5555852ec1" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.10.5", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "rand", + "rand_chacha", + "rust_hawktracer", + "rustc_version", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badc69028460108fa7e32d4aec2b0c980710d7a31a896864002c8c1fc61516ee" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redb" version = "2.1.0" @@ -3446,6 +3904,15 @@ dependencies = [ "winreg 0.52.0", ] +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + [[package]] name = "ring" version = "0.16.20" @@ -3486,6 +3953,28 @@ dependencies = [ "librocksdb-sys", ] +[[package]] +name = "rust_hawktracer" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3480a29b927f66c6e06527be7f49ef4d291a01d694ec1fe85b0de71d6b02ac1" +dependencies = [ + "rust_hawktracer_normal_macro", + "rust_hawktracer_proc_macro", +] + +[[package]] +name = "rust_hawktracer_normal_macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a570059949e1dcdc6f35228fa389f54c2c84dfe0c94c05022baacd56eacd2e9" + +[[package]] +name = "rust_hawktracer_proc_macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb626abdbed5e93f031baae60d72032f56bc964e11ac2ff65f2ba3ed98d6d3e1" + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -3730,6 +4219,9 @@ name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] [[package]] name = "send_wrapper" @@ -3794,6 +4286,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3875,6 +4376,21 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "slab" version = "0.4.9" @@ -3926,6 +4442,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "strsim" @@ -4019,12 +4538,31 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" +dependencies = [ + "cfg-expr", + "heck 0.4.1", + "pkg-config", + "toml 0.7.8", + "version-compare", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + [[package]] name = "termcolor" version = "1.4.1" @@ -4070,6 +4608,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.36" @@ -4243,11 +4792,48 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + [[package]] name = "toml_datetime" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] [[package]] name = "toml_edit" @@ -4491,6 +5077,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "validator" version = "0.17.0" @@ -4533,6 +5130,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + [[package]] name = "version_check" version = "0.9.4" @@ -4672,6 +5275,12 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "winapi" version = "0.3.9" @@ -4924,3 +5533,27 @@ dependencies = [ "cc", "pkg-config", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +dependencies = [ + "zune-core", +] diff --git a/fedimint-nwc/Cargo.toml b/fedimint-nwc/Cargo.toml index 2e1c779..b5963aa 100644 --- a/fedimint-nwc/Cargo.toml +++ b/fedimint-nwc/Cargo.toml @@ -16,12 +16,14 @@ bincode = "1.3.3" clap = { version = "4.5.4", features = ["derive", "env"] } dotenv = "0.15.0" futures-util = "0.3.30" +image = "0.25.1" itertools = "0.13.0" lightning-invoice = { version = "0.26.0", features = ["serde"] } # multimint = { version = "0.3.6" } multimint = { path = "../multimint" } nostr = { version = "0.31.2", features = ["nip47"] } nostr-sdk = { version = "0.31.0", features = ["nip47"] } +qrcode = "0.14.0" redb = "2.1.0" serde = "1.0.193" serde_json = "1.0.108" diff --git a/fedimint-nwc/src/main.rs b/fedimint-nwc/src/main.rs index 0eec08a..2375a74 100644 --- a/fedimint-nwc/src/main.rs +++ b/fedimint-nwc/src/main.rs @@ -9,6 +9,7 @@ pub mod nwc; pub mod server; pub mod services; pub mod state; +pub mod utils; use crate::config::Cli; use crate::server::run_server; @@ -24,6 +25,10 @@ async fn main() -> Result<()> { state.nostr_service.broadcast_info_event().await?; state.nostr_service.subscribe_nwc().await; + let uri = state.nostr_service.new_nwc_uri().await?; + info!("\nUri: {uri}\n"); + utils::print_as_qr_code(&uri.to_string()).await?; + let server_handle = tokio::spawn(async { match run_server().await { Ok(_) => info!("Server ran successfully."), @@ -80,6 +85,10 @@ async fn handle_notification(notification: RelayPoolNotification, state: &AppSta } Ok(()) } + RelayPoolNotification::RelayStatus { relay_url, status } => { + info!("Relay status: {relay_url:?} {status:?}"); + Ok(()) + } RelayPoolNotification::Shutdown => { info!("Relay pool shutdown"); Err(anyhow::anyhow!("Relay pool shutdown")) diff --git a/fedimint-nwc/src/services/nostr.rs b/fedimint-nwc/src/services/nostr.rs index 23bb1c8..d924c38 100644 --- a/fedimint-nwc/src/services/nostr.rs +++ b/fedimint-nwc/src/services/nostr.rs @@ -1,14 +1,15 @@ use std::fs::File; use std::io::{BufReader, Write}; use std::path::PathBuf; +use std::str::FromStr; use anyhow::{anyhow, Context, Result}; use nostr::nips::nip04; -use nostr::nips::nip47::Response; +use nostr::nips::nip47::{NostrWalletConnectURI, Response}; use nostr_sdk::secp256k1::SecretKey; use nostr_sdk::{ Client, Event, EventBuilder, EventId, Filter, JsonUtil, Keys, Kind, RelayPoolNotification, Tag, - Timestamp, + Timestamp, Url, }; use serde::{Deserialize, Serialize}; use tokio::sync::broadcast::Receiver; @@ -25,6 +26,7 @@ pub struct NostrService { #[serde(default)] pub sent_info: bool, pub keys_file_path: PathBuf, + pub relays: Vec, } impl NostrService { @@ -41,6 +43,14 @@ impl NostrService { } }; + let lines = relays.split(',').collect::>(); + let relays = lines + .iter() + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .map(|line| line.to_string()) + .collect::>(); + let client = Client::new(&Keys::new(server_key.into())); let service = Self { client, @@ -48,9 +58,10 @@ impl NostrService { user_key, sent_info, keys_file_path: keys_file_path.clone(), + relays, }; - service.add_relays(relays).await?; + service.add_relays().await?; if !sent_info { service.write_keys().context("Failed to write keys")?; @@ -88,15 +99,8 @@ impl NostrService { Keys::new(self.user_key.into()) } - async fn add_relays(&self, relays: &str) -> Result<()> { - let lines = relays.split(',').collect::>(); - let relays = lines - .iter() - .map(|line| line.trim()) - .filter(|line| !line.is_empty()) - .map(|line| line.to_string()) - .collect::>(); - for relay in relays { + async fn add_relays(&self) -> Result<()> { + for relay in self.relays.iter() { self.client.add_relay(relay).await?; } Ok(()) @@ -135,6 +139,7 @@ impl NostrService { pub async fn broadcast_info_event(&mut self) -> Result<(), anyhow::Error> { if self.sent_info { + info!("Already sent info event"); return Ok(()); } let content = METHODS @@ -184,4 +189,18 @@ impl NostrService { info!("Listening for nip 47 requests..."); } + + pub async fn new_nwc_uri(&self) -> Result { + let relay = self + .relays + .first() + .ok_or_else(|| anyhow::anyhow!("No relays provided, cannot generate URI"))?; + let uri = NostrWalletConnectURI::new( + self.server_keys().public_key(), + Url::from_str(relay)?, + self.user_keys().secret_key()?.clone(), + None, + ); + Ok(uri) + } } diff --git a/fedimint-nwc/src/utils.rs b/fedimint-nwc/src/utils.rs new file mode 100644 index 0000000..72cd49f --- /dev/null +++ b/fedimint-nwc/src/utils.rs @@ -0,0 +1,14 @@ +use anyhow::Result; +use qrcode::render::unicode; +use qrcode::QrCode; + +pub async fn print_as_qr_code(data: &str) -> Result<()> { + let code = QrCode::new(data)?; + let image = code + .render::() + .dark_color(unicode::Dense1x2::Dark) + .light_color(unicode::Dense1x2::Light) + .build(); + println!("{}", image); + Ok(()) +}