diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 348df920..d63506ba 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -363,9 +363,9 @@ dependencies = [ [[package]] name = "async-wsocket" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eee6fcc818b89848df37050215603de0e2e072734e4730c03060feb2d0abebb" +checksum = "c917625d498803b60135e0b409c3635b4bafc659da5c55a362d93f68412d1ebe" dependencies = [ "async-utility", "futures", @@ -1109,6 +1109,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -1354,6 +1363,15 @@ dependencies = [ "syn 2.0.76", ] +[[package]] +name = "doxygen-rs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9" +dependencies = [ + "phf 0.11.2", +] + [[package]] name = "dpi" version = "0.1.1" @@ -1534,18 +1552,6 @@ dependencies = [ "zune-inflate", ] -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - [[package]] name = "fastrand" version = "2.1.1" @@ -2176,15 +2182,6 @@ dependencies = [ "allocator-api2", ] -[[package]] -name = "hashlink" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" -dependencies = [ - "hashbrown 0.14.5", -] - [[package]] name = "heck" version = "0.4.1" @@ -2197,6 +2194,40 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "heed" +version = "0.20.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d4f449bab7320c56003d37732a917e18798e2f1709d80263face2b4f9436ddb" +dependencies = [ + "bitflags 2.6.0", + "byteorder", + "heed-traits", + "heed-types", + "libc", + "lmdb-master-sys", + "once_cell", + "page_size", + "synchronoise", + "url", +] + +[[package]] +name = "heed-traits" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3130048d404c57ce5a1ac61a903696e8fcde7e8c2991e9fcfc1f27c3ef74ff" + +[[package]] +name = "heed-types" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d3f528b053a6d700b2734eabcd0fd49cb8230647aa72958467527b0b7917114" +dependencies = [ + "byteorder", + "heed-traits", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -2770,17 +2801,6 @@ dependencies = [ "redox_syscall", ] -[[package]] -name = "libsqlite3-sys" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - [[package]] name = "linkify" version = "0.10.0" @@ -2806,6 +2826,17 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "lmdb-master-sys" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "472c3760e2a8d0f61f322fb36788021bb36d573c502b50fa3e2bcaac3ec326c9" +dependencies = [ + "cc", + "doxygen-rs", + "libc", +] + [[package]] name = "lnurl-pay" version = "0.6.0" @@ -3086,7 +3117,7 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nostr" version = "0.34.0" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" dependencies = [ "aes", "base64 0.22.1", @@ -3105,7 +3136,6 @@ dependencies = [ "scrypt", "serde", "serde_json", - "tracing", "unicode-normalization", "url", "wasm-bindgen", @@ -3116,7 +3146,7 @@ dependencies = [ [[package]] name = "nostr-database" version = "0.34.0" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" dependencies = [ "async-trait", "flatbuffers", @@ -3127,10 +3157,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "nostr-lmdb" +version = "0.34.0" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" +dependencies = [ + "heed", + "nostr", + "nostr-database", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "nostr-relay-pool" version = "0.34.0" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" dependencies = [ "async-utility", "async-wsocket", @@ -3146,16 +3189,16 @@ dependencies = [ [[package]] name = "nostr-sdk" version = "0.34.0" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" dependencies = [ "async-utility", "atomic-destructor", "lnurl-pay", "nostr", "nostr-database", + "nostr-lmdb", "nostr-relay-pool", "nostr-signer", - "nostr-sqlite", "nostr-zapper", "nwc", "thiserror", @@ -3166,7 +3209,7 @@ dependencies = [ [[package]] name = "nostr-signer" version = "0.34.0" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" dependencies = [ "async-utility", "nostr", @@ -3176,24 +3219,10 @@ dependencies = [ "tracing", ] -[[package]] -name = "nostr-sqlite" -version = "0.34.0" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" -dependencies = [ - "async-trait", - "nostr", - "nostr-database", - "rusqlite", - "thiserror", - "tokio", - "tracing", -] - [[package]] name = "nostr-zapper" version = "0.34.0" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" dependencies = [ "async-trait", "nostr", @@ -3326,7 +3355,7 @@ dependencies = [ [[package]] name = "nwc" version = "0.34.1" -source = "git+https://github.com/rust-nostr/nostr#2a429da9131fec7d61b5518596b432b06e16facd" +source = "git+https://github.com/rust-nostr/nostr#d7038bc167d4aed57e9153f4224cfca349613a61" dependencies = [ "async-utility", "nostr", @@ -3594,6 +3623,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "pango" version = "0.18.3" @@ -4376,20 +4415,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rusqlite" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" -dependencies = [ - "bitflags 2.6.0", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -5113,6 +5138,15 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synchronoise" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dbc01390fc626ce8d1cffe3376ded2b72a11bb70e1c75f404a210e4daa4def2" +dependencies = [ + "crossbeam-queue", +] + [[package]] name = "sys-locale" version = "0.3.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 2478aee0..290e17eb 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -11,12 +11,6 @@ rust-version = "1.70" tauri-build = { version = "2.0.0-rc", features = [] } [dependencies] -nostr-sdk = { git = "https://github.com/rust-nostr/nostr", features = [ - "sqlite", -] } -tokio = { version = "1", features = ["full"] } -serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } tauri = { version = "2.0.0-rc", features = [ "unstable", "tray-icon", @@ -38,8 +32,14 @@ tauri-plugin-store = "2.0.0-rc" tauri-plugin-decorum = "1.0.0" tauri-plugin-prevent-default = "0.4" tauri-specta = { version = "2.0.0-rc.15", features = ["derive", "typescript"] } + +nostr-sdk = { git = "https://github.com/rust-nostr/nostr", features = ["lmdb"] } + specta = "^2.0.0-rc.20" specta-typescript = "0.0.7" +tokio = { version = "1", features = ["full"] } +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } reqwest = "0.12.4" url = "2.5.0" futures = "0.3.30" diff --git a/src-tauri/resources/relays.txt b/src-tauri/resources/relays.txt index 103a70b0..07914bf8 100644 --- a/src-tauri/resources/relays.txt +++ b/src-tauri/resources/relays.txt @@ -1,4 +1,2 @@ wss://relay.damus.io, wss://relay.nostr.net, -wss://purplepag.es/, -wss://directory.yabu.me/, diff --git a/src-tauri/src/commands/account.rs b/src-tauri/src/commands/account.rs index d317f374..2ed54b06 100644 --- a/src-tauri/src/commands/account.rs +++ b/src-tauri/src/commands/account.rs @@ -127,7 +127,7 @@ pub async fn connect_account(uri: String, state: State<'_, Nostr>) -> Result { // Local user let app_keys = Keys::generate(); - let app_secret = app_keys.secret_key().to_string(); + let app_secret = app_keys.secret_key().to_secret_hex(); // Get remote user let remote_user = bunker_uri.signer_public_key().unwrap(); diff --git a/src-tauri/src/commands/event.rs b/src-tauri/src/commands/event.rs index 826fb82a..61689731 100644 --- a/src-tauri/src/commands/event.rs +++ b/src-tauri/src/commands/event.rs @@ -247,7 +247,7 @@ pub async fn get_events_from_contacts( .until(as_of) .authors(authors); - match client.database().query(vec![filter], Order::Desc).await { + match client.database().query(vec![filter]).await { Ok(events) => { let fils = filter_converstation(events); let futures = fils.iter().map(|ev| async move { @@ -449,7 +449,9 @@ pub async fn publish( // Create unsigned event let unsigned_event = match difficulty { - Some(num) => EventBuilder::text_note(content, tags).to_unsigned_pow_event(public_key, num), + Some(num) => EventBuilder::text_note(content, tags) + .pow(num) + .to_unsigned_event(public_key), None => EventBuilder::text_note(content, tags).to_unsigned_event(public_key), }; @@ -479,14 +481,11 @@ pub async fn reply( let reply_id = EventId::parse(&to).map_err(|err| err.to_string())?; - match database - .query(vec![Filter::new().id(reply_id)], Order::Desc) - .await - { + match database.query(vec![Filter::new().id(reply_id)]).await { Ok(events) => { if let Some(event) = events.first() { let relay_hint = if let Some(relays) = database - .event_seen_on_relays(event.id) + .event_seen_on_relays(&event.id) .await .map_err(|err| err.to_string())? { @@ -515,13 +514,10 @@ pub async fn reply( Err(_) => return Err("Event is not valid.".into()), }; - if let Ok(events) = database - .query(vec![Filter::new().id(root_id)], Order::Desc) - .await - { + if let Ok(events) = database.query(vec![Filter::new().id(root_id)]).await { if let Some(event) = events.first() { let relay_hint = if let Some(relays) = database - .event_seen_on_relays(event.id) + .event_seen_on_relays(&event.id) .await .map_err(|err| err.to_string())? { @@ -579,7 +575,7 @@ pub async fn event_to_bech32(id: String, state: State<'_, Nostr>) -> Result) -> Result) -> Result, - public_key: &str, -) -> Result, String> { - let client = &state.client; - let public_key = PublicKey::parse(public_key).map_err(|e| e.to_string())?; - - let filter = Filter::new().kind(Kind::ContactList).author(public_key); - let events = match client - .get_events_of( - vec![filter], - EventSource::both(Some(Duration::from_secs(5))), - ) - .await - { - Ok(events) => events, - Err(err) => return Err(err.to_string()), - }; - - let mut ret: Vec = vec![]; - if let Some(latest_event) = events.iter().max_by_key(|event| event.created_at()) { - ret.extend(latest_event.tags().iter().filter_map(|tag| { - if let Some(TagStandard::PublicKey { - uppercase: false, .. - }) = ::clone(tag).to_standardized() - { - tag.content().map(String::from) - } else { - None - } - })); - } - - Ok(ret) -} - -pub async fn get_followers( - state: State<'_, Nostr>, - public_key: &str, -) -> Result, String> { - let client = &state.client; - let public_key = PublicKey::parse(public_key).map_err(|e| e.to_string())?; - - let filter = Filter::new().kind(Kind::ContactList).custom_tag( - SingleLetterTag::lowercase(Alphabet::P), - vec![public_key.to_hex()], - ); - - let events = match client - .get_events_of( - vec![filter], - EventSource::both(Some(Duration::from_secs(5))), - ) - .await - { - Ok(events) => events, - Err(err) => return Err(err.to_string()), - }; - - let ret: Vec = events - .into_iter() - .map(|event| event.author().to_hex()) - .collect(); - - Ok(ret) - // TODO: get more than 500 events -} - #[tauri::command] #[specta::specta] pub async fn get_notifications(state: State<'_, Nostr>) -> Result, String> { @@ -491,11 +423,7 @@ pub async fn get_notifications(state: State<'_, Nostr>) -> Result, S ]) .limit(200); - match client - .database() - .query(vec![filter], Order::default()) - .await - { + match client.database().query(vec![filter]).await { Ok(events) => Ok(events.into_iter().map(|ev| ev.as_json()).collect()), Err(err) => Err(err.to_string()), } diff --git a/src-tauri/src/common.rs b/src-tauri/src/common.rs index 7db9feeb..f5f19c54 100644 --- a/src-tauri/src/common.rs +++ b/src-tauri/src/common.rs @@ -288,7 +288,7 @@ pub async fn init_nip65(client: &Client) { Some(_) => RelayOptions::new().write(true).read(false), None => RelayOptions::default(), }; - if let Err(e) = client.add_relay_with_opts(&url.to_string(), opts).await { + if let Err(e) = client.pool().add_relay(&url.to_string(), opts).await { eprintln!("Failed to add relay {}: {:?}", url, e); } if let Err(e) = client.connect_relay(url.to_string()).await { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 71909fa4..cbf4c371 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -193,16 +193,16 @@ fn main() { let dir = handle .path() .app_config_dir() - .expect("App config directory not found."); - let _ = fs::create_dir_all(dir.clone()); + .expect("Error: app config directory not found."); + let _ = fs::create_dir_all(&dir); // Setup database - let database = SQLiteDatabase::open(dir.join("nostr.db")) - .await - .expect("Database error."); + let database = NostrLMDB::open(dir.join("nostr-lmdb")) + .expect("Error: cannot create database."); // Config let opts = Options::new() + .gossip(true) .max_avg_latency(Duration::from_millis(500)) .automatic_authentication(true) .connection_timeout(Some(Duration::from_secs(5))) @@ -232,7 +232,7 @@ fn main() { } else { RelayOptions::new().write(true).read(false) }; - let _ = client.add_relay_with_opts(relay, opts).await; + let _ = client.pool().add_relay(relay, opts).await; } Err(_) => { let _ = client.add_relay(relay).await; @@ -242,6 +242,14 @@ fn main() { } } + if let Err(e) = client.add_discovery_relay("wss://purplepag.es/").await { + println!("Add discovery relay failed: {}", e) + } + + if let Err(e) = client.add_discovery_relay("wss://directory.yabu.me/").await { + println!("Add discovery relay failed: {}", e) + } + // Connect client.connect().await; @@ -327,7 +335,10 @@ fn main() { // Send native notification if allow_notification { let author = client - .metadata(event.pubkey) + .fetch_metadata( + event.pubkey, + Some(Duration::from_secs(5)), + ) .await .unwrap_or_else(|_| Metadata::new()); @@ -393,7 +404,7 @@ fn prevent_default() -> tauri::plugin::TauriPlugin { } fn send_notification(event: &Event, author: Metadata, handle: &tauri::AppHandle) { - match event.kind() { + match event.kind { Kind::TextNote => { if let Err(e) = handle .notification() diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 9915fd0d..7cfe774e 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -17,6 +17,6 @@ export const Route = createFileRoute("/")({ }); } - return { accounts }; + return { accounts: accounts.filter((account) => !account.endsWith("Lume")) }; }, });