feat: use latest nostr sdk

This commit is contained in:
2024-10-23 10:16:56 +07:00
parent cc7de41bfd
commit 172566028b
21 changed files with 596 additions and 240 deletions

View File

@@ -28,6 +28,9 @@ pub async fn watch_account(key: String, state: State<'_, Nostr>) -> Result<Strin
keyring.set_password("").map_err(|e| e.to_string())?;
// Run sync for this account
// run_sync_for(public_key, app_handle);
// Update state
state.accounts.lock().unwrap().push(bech32.clone());
@@ -41,27 +44,32 @@ pub async fn import_account(
password: String,
state: State<'_, Nostr>,
) -> Result<String, String> {
let (npub, enc_bech32) = match key.starts_with("ncryptsec") {
let client = &state.client;
let (npub, enc_bech32, signer) = match key.starts_with("ncryptsec") {
true => {
let enc = EncryptedSecretKey::from_bech32(key).map_err(|err| err.to_string())?;
let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?;
let secret_key = enc.to_secret_key(password).map_err(|err| err.to_string())?;
let keys = Keys::new(secret_key);
let npub = keys.public_key().to_bech32().unwrap();
let npub = keys
.public_key()
.to_bech32()
.map_err(|err| err.to_string())?;
let signer = NostrSigner::Keys(keys);
(npub, enc_bech32)
(npub, enc_bech32, signer)
}
false => {
let secret_key = SecretKey::from_bech32(key).map_err(|err| err.to_string())?;
let keys = Keys::new(secret_key.clone());
let npub = keys.public_key().to_bech32().unwrap();
let signer = NostrSigner::Keys(keys);
let enc = EncryptedSecretKey::new(&secret_key, password, 16, KeySecurity::Medium)
.map_err(|err| err.to_string())?;
let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?;
(npub, enc_bech32)
(npub, enc_bech32, signer)
}
};
@@ -75,6 +83,12 @@ pub async fn import_account(
let pwd = serde_json::to_string(&account).map_err(|e| e.to_string())?;
keyring.set_password(&pwd).map_err(|e| e.to_string())?;
// Run sync for this account
// run_sync_for(public_key, app_handle);
// Update signer
client.set_signer(Some(signer)).await;
// Update state
state.accounts.lock().unwrap().push(npub.clone());
@@ -115,6 +129,9 @@ pub async fn connect_account(uri: String, state: State<'_, Nostr>) -> Result<Str
let j = serde_json::to_string(&account).map_err(|e| e.to_string())?;
let _ = keyring.set_password(&j);
// Run sync for this account
// run_sync_for(public_key, app_handle);
// Update signer
let _ = client.set_signer(Some(signer.into())).await;

View File

@@ -313,8 +313,14 @@ pub async fn publish(
let builder =
EventBuilder::text_note(content, tags).pow(difficulty.unwrap_or(DEFAULT_DIFFICULTY));
// Sign event
let event = client
.sign_event_builder(builder)
.await
.map_err(|err| err.to_string())?;
// Publish
match client.send_event_builder(builder).await {
match client.send_event(event).await {
Ok(event_id) => Ok(event_id.to_hex()),
Err(err) => Err(err.to_string()),
}

View File

@@ -6,7 +6,7 @@ use std::{str::FromStr, time::Duration};
use tauri::{Emitter, Manager, State};
use crate::{
common::{get_all_accounts, get_latest_event, get_tags_content, process_event},
common::{get_all_accounts, get_latest_event, process_event},
Nostr, RichEvent, Settings,
};
@@ -182,10 +182,8 @@ pub async fn is_contact(id: String, state: State<'_, Nostr>) -> Result<bool, Str
match client.database().query(vec![filter]).await {
Ok(events) => {
if let Some(event) = events.into_iter().next() {
let hex = public_key.to_hex();
let pubkeys = get_tags_content(&event, TagKind::p());
Ok(pubkeys.iter().any(|i| i == &hex))
let pubkeys = event.tags.public_keys().collect::<Vec<_>>();
Ok(pubkeys.iter().any(|&i| i == &public_key))
} else {
Ok(false)
}
@@ -270,7 +268,7 @@ pub async fn set_group(
.authors(public_keys)
.limit(500);
if let Ok(report) = client.reconcile(filter, NegentropyOptions::default()).await {
if let Ok(report) = client.sync(filter, NegentropyOptions::default()).await {
println!("Received: {}", report.received.len());
handle.emit("synchronized", ()).unwrap();
};
@@ -357,7 +355,7 @@ pub async fn set_interest(
.hashtags(hashtags)
.limit(500);
if let Ok(report) = client.reconcile(filter, NegentropyOptions::default()).await {
if let Ok(report) = client.sync(filter, NegentropyOptions::default()).await {
println!("Received: {}", report.received.len());
handle.emit("synchronized", ()).unwrap();
};

View File

@@ -5,7 +5,7 @@ use std::str::FromStr;
use tauri::{AppHandle, Manager};
use tauri_specta::Event as TauriEvent;
use crate::{common::get_tags_content, Nostr};
use crate::Nostr;
#[derive(Clone, Serialize, Type, TauriEvent)]
pub struct NegentropyEvent {
@@ -53,7 +53,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
.limit(4);
if let Ok(report) = client
.reconcile_with(&bootstrap_relays, profile, NegentropyOptions::default())
.sync_with(&bootstrap_relays, profile, NegentropyOptions::default())
.await
{
NegentropyEvent {
@@ -72,7 +72,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
.limit(4);
if let Ok(report) = client
.reconcile_with(
.sync_with(
&bootstrap_relays,
contact_list.clone(),
NegentropyOptions::default(),
@@ -92,16 +92,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
if let Ok(events) = client.database().query(vec![contact_list]).await {
let pubkeys: Vec<PublicKey> = events
.iter()
.flat_map(|ev| {
let tags = get_tags_content(ev, TagKind::p());
tags.into_iter().filter_map(|p| {
if let Ok(pk) = PublicKey::from_hex(p) {
Some(pk)
} else {
None
}
})
})
.flat_map(|ev| ev.tags.public_keys().copied())
.collect();
for chunk in pubkeys.chunks(500) {
@@ -119,7 +110,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
.limit(1000);
if let Ok(report) = client
.reconcile_with(&bootstrap_relays, events, NegentropyOptions::default())
.sync_with(&bootstrap_relays, events, NegentropyOptions::default())
.await
{
NegentropyEvent {
@@ -138,7 +129,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
.limit(1000);
if let Ok(report) = client
.reconcile_with(&bootstrap_relays, metadata, NegentropyOptions::default())
.sync_with(&bootstrap_relays, metadata, NegentropyOptions::default())
.await
{
NegentropyEvent {
@@ -162,7 +153,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
]);
if let Ok(report) = client
.reconcile_with(&bootstrap_relays, others, NegentropyOptions::default())
.sync_with(&bootstrap_relays, others, NegentropyOptions::default())
.await
{
NegentropyEvent {
@@ -186,7 +177,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
.limit(10000);
if let Ok(report) = client
.reconcile_with(
.sync_with(
&bootstrap_relays,
notification,
NegentropyOptions::default(),

View File

@@ -100,9 +100,12 @@ pub fn update_column(
#[tauri::command(async)]
#[specta::specta]
pub fn reload_column(label: String, app_handle: tauri::AppHandle) -> Result<bool, String> {
pub fn reload_column(label: String, app_handle: tauri::AppHandle) -> Result<(), String> {
match app_handle.get_webview(&label) {
Some(webview) => Ok(webview.eval("window.location.reload()").is_ok()),
Some(webview) => {
webview.eval("location.reload(true)").unwrap();
Ok(())
}
None => Err("Cannot reload, column not found.".into()),
}
}

View File

@@ -51,15 +51,6 @@ pub fn get_latest_event(events: &Events) -> Option<&Event> {
events.iter().next()
}
pub fn get_tags_content(event: &Event, kind: TagKind) -> Vec<String> {
event
.tags
.iter()
.filter(|t| t.kind() == kind)
.filter_map(|t| t.content().map(|content| content.to_string()))
.collect()
}
pub fn create_tags(content: &str) -> Vec<Tag> {
let mut tags: Vec<Tag> = vec![];
let mut tag_set: HashSet<String> = HashSet::new();

View File

@@ -13,7 +13,8 @@ use commands::{
sync::{run_fast_sync, NegentropyEvent},
window::*,
};
use common::{get_all_accounts, get_tags_content, parse_event};
use common::{get_all_accounts, parse_event};
use log::info;
use nostr_sdk::prelude::{Profile as DatabaseProfile, *};
use serde::{Deserialize, Serialize};
use specta::Type;
@@ -94,9 +95,6 @@ pub const FETCH_LIMIT: usize = 50;
pub const NOTIFICATION_SUB_ID: &str = "lume_notification";
fn main() {
#[cfg(debug_assertions)]
tracing_subscriber::fmt::init();
let builder = Builder::<tauri::Wry>::new()
// Then register them (separated by a comma)
.commands(collect_commands![
@@ -171,10 +169,7 @@ fn main() {
.export(Typescript::default(), "../src/commands.gen.ts")
.expect("Failed to export typescript bindings");
#[cfg(target_os = "macos")]
let tauri_builder = tauri::Builder::default().plugin(tauri_nspanel::init());
#[cfg(not(target_os = "macos"))]
let mut ctx = tauri::generate_context!();
let tauri_builder = tauri::Builder::default();
tauri_builder
@@ -193,13 +188,7 @@ fn main() {
.app_config_dir()
.expect("Error: app config directory not found.");
let data_dir = handle
.path()
.app_data_dir()
.expect("Error: app data directory not found.");
let _ = fs::create_dir_all(&config_dir);
let _ = fs::create_dir_all(&data_dir);
// Set custom decoration for Windows
#[cfg(target_os = "windows")]
@@ -225,7 +214,7 @@ fn main() {
let (client, bootstrap_relays) = tauri::async_runtime::block_on(async move {
// Setup database
let database = NostrLMDB::open(config_dir.join("nostr-lmdb"))
let database = NostrLMDB::open(config_dir.join("nostr"))
.expect("Error: cannot create database.");
// Config
@@ -234,7 +223,8 @@ fn main() {
.max_avg_latency(Duration::from_millis(800))
.automatic_authentication(false)
.connection_timeout(Some(Duration::from_secs(20)))
.send_timeout(Some(Duration::from_secs(20)))
.send_timeout(Some(Duration::from_secs(10)))
.wait_for_send(false)
.timeout(Duration::from_secs(20));
// Setup nostr client
@@ -403,21 +393,6 @@ fn main() {
});
});
// Run local relay thread
//tauri::async_runtime::spawn(async move {
// let database = NostrLMDB::open(data_dir.join("local-relay"))
// .expect("Error: cannot create database.");
// let builder = RelayBuilder::default().database(database).port(1984);
//
// if let Ok(relay) = LocalRelay::run(builder).await {
// println!("Running local relay: {}", relay.url())
// }
//
// loop {
// tokio::time::sleep(Duration::from_secs(60)).await;
// }
//});
// Run notification thread
tauri::async_runtime::spawn(async move {
let state = handle_clone.state::<Nostr>();
@@ -465,6 +440,7 @@ fn main() {
while let Ok(notification) = notifications.recv().await {
match notification {
RelayPoolNotification::Message { relay_url, message } => {
info!(target: "relay_events", "message: {}", message.as_pretty_json());
if let RelayMessage::Auth { challenge } = message {
match client.auth(challenge, relay_url.clone()).await {
Ok(..) => {
@@ -521,7 +497,17 @@ fn main() {
event,
} = message
{
let tags = get_tags_content(&event, TagKind::p());
let tags: Vec<String> = event
.tags
.public_keys()
.filter_map(|pk| {
if let Ok(bech32) = pk.to_bech32() {
Some(bech32)
} else {
None
}
})
.collect();
// Handle events from notification subscription
if subscription_id == notification_id
@@ -587,6 +573,7 @@ fn main() {
Ok(())
})
.plugin(prevent_default())
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
.plugin(tauri_plugin_decorum::init())
.plugin(tauri_plugin_store::Builder::default().build())
.plugin(tauri_plugin_clipboard_manager::init())
@@ -600,7 +587,7 @@ fn main() {
.plugin(tauri_plugin_upload::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_window_state::Builder::default().build())
.run(tauri::generate_context!())
.run(ctx)
.expect("error while running tauri application");
}