feat: add more nostr commands
This commit is contained in:
@@ -8,12 +8,14 @@ pub mod nostr;
|
|||||||
|
|
||||||
use nostr_sdk::{Client, ClientBuilder};
|
use nostr_sdk::{Client, ClientBuilder};
|
||||||
use nostr_sqlite::SQLiteDatabase;
|
use nostr_sqlite::SQLiteDatabase;
|
||||||
|
use std::sync::Arc;
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
use tauri_plugin_autostart::MacosLauncher;
|
use tauri_plugin_autostart::MacosLauncher;
|
||||||
use tauri_plugin_theme::ThemePlugin;
|
use tauri_plugin_theme::ThemePlugin;
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
struct NostrClient(Mutex<Client>);
|
pub struct AppState {
|
||||||
|
pub nostr: Arc<Client>,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut ctx = tauri::generate_context!();
|
let mut ctx = tauri::generate_context!();
|
||||||
@@ -24,12 +26,12 @@ fn main() {
|
|||||||
|
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
// Create database connection
|
// Create database connection
|
||||||
let database = SQLiteDatabase::open(config_dir.join("nostr.db"))
|
let nostr_db = SQLiteDatabase::open(config_dir.join("nostr.db"))
|
||||||
.await
|
.await
|
||||||
.expect("Open database failed.");
|
.expect("Open database failed.");
|
||||||
|
|
||||||
// Create nostr connection
|
// Create nostr connection
|
||||||
let client = ClientBuilder::default().database(database).build();
|
let client = ClientBuilder::default().database(nostr_db).build();
|
||||||
|
|
||||||
// Add bootstrap relay
|
// Add bootstrap relay
|
||||||
client
|
client
|
||||||
@@ -47,7 +49,9 @@ fn main() {
|
|||||||
client.connect().await;
|
client.connect().await;
|
||||||
|
|
||||||
// Init global state
|
// Init global state
|
||||||
handle.manage(NostrClient(client.into()))
|
handle.manage(AppState {
|
||||||
|
nostr: client.into(),
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -71,6 +75,9 @@ fn main() {
|
|||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
nostr::keys::create_keys,
|
nostr::keys::create_keys,
|
||||||
nostr::keys::get_public_key,
|
nostr::keys::get_public_key,
|
||||||
|
nostr::keys::update_signer,
|
||||||
|
nostr::metadata::get_metadata,
|
||||||
|
nostr::event::get_event,
|
||||||
commands::secret::secure_save,
|
commands::secret::secure_save,
|
||||||
commands::secret::secure_load,
|
commands::secret::secure_load,
|
||||||
commands::secret::secure_remove,
|
commands::secret::secure_remove,
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
pub mod event;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
|
pub mod metadata;
|
||||||
|
|||||||
20
src-tauri/src/nostr/event.rs
Normal file
20
src-tauri/src/nostr/event.rs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
use crate::AppState;
|
||||||
|
use nostr_sdk::prelude::*;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tauri::State;
|
||||||
|
|
||||||
|
#[tauri::command(async)]
|
||||||
|
pub async fn get_event(id: String, app_state: State<'_, AppState>) -> Result<String, ()> {
|
||||||
|
let client = &app_state.nostr;
|
||||||
|
|
||||||
|
let event_id = EventId::from_bech32(id).unwrap();
|
||||||
|
let filter = Filter::new().id(event_id);
|
||||||
|
|
||||||
|
let events = client
|
||||||
|
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
||||||
|
.await
|
||||||
|
.expect("Get metadata failed");
|
||||||
|
let event = events.into_iter().nth(0).unwrap().as_json();
|
||||||
|
|
||||||
|
Ok(event)
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
|
use crate::AppState;
|
||||||
use nostr::nips::nip19::ToBech32;
|
use nostr::nips::nip19::ToBech32;
|
||||||
use nostr::secp256k1::SecretKey;
|
use nostr::secp256k1::SecretKey;
|
||||||
use nostr::{Keys, Result};
|
use nostr::{FromBech32, Keys, Result};
|
||||||
|
use nostr_sdk::ClientSigner;
|
||||||
|
use tauri::State;
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
pub struct CreateKeysResponse {
|
pub struct CreateKeysResponse {
|
||||||
@@ -27,3 +30,15 @@ pub fn get_public_key(secret_key: SecretKey) -> Result<String, ()> {
|
|||||||
let keys = Keys::new(secret_key);
|
let keys = Keys::new(secret_key);
|
||||||
Ok(keys.public_key().to_bech32().expect("secret key failed"))
|
Ok(keys.public_key().to_bech32().expect("secret key failed"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn update_signer(key: String, app_state: State<'_, AppState>) -> Result<(), ()> {
|
||||||
|
let client = &app_state.nostr;
|
||||||
|
let secret_key = SecretKey::from_bech32(key).unwrap();
|
||||||
|
let keys = Keys::new(secret_key);
|
||||||
|
let signer = ClientSigner::Keys(keys);
|
||||||
|
|
||||||
|
client.set_signer(Some(signer)).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
26
src-tauri/src/nostr/metadata.rs
Normal file
26
src-tauri/src/nostr/metadata.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use crate::AppState;
|
||||||
|
use nostr_sdk::prelude::*;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tauri::State;
|
||||||
|
|
||||||
|
#[tauri::command(async)]
|
||||||
|
pub async fn get_metadata(npub: String, app_state: State<'_, AppState>) -> Result<Metadata, ()> {
|
||||||
|
let client = &app_state.nostr;
|
||||||
|
|
||||||
|
let public_key = XOnlyPublicKey::from_bech32(npub).unwrap();
|
||||||
|
|
||||||
|
let filter = Filter::new()
|
||||||
|
.author(public_key)
|
||||||
|
.kind(Kind::Metadata)
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
let events = client
|
||||||
|
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
||||||
|
.await
|
||||||
|
.expect("Get metadata failed");
|
||||||
|
|
||||||
|
let event = events.into_iter().nth(0).unwrap();
|
||||||
|
let metadata: Metadata = Metadata::from_json(&event.content).unwrap();
|
||||||
|
|
||||||
|
Ok(metadata)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user