feat: add check active account before init client
This commit is contained in:
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@@ -2859,6 +2859,7 @@ dependencies = [
|
|||||||
"native_db",
|
"native_db",
|
||||||
"native_model",
|
"native_model",
|
||||||
"nostr-sdk",
|
"nostr-sdk",
|
||||||
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ webpage = { version = "2.0", features = ["serde"] }
|
|||||||
keyring = "2"
|
keyring = "2"
|
||||||
native_db = "0.5.3"
|
native_db = "0.5.3"
|
||||||
native_model = "0.4.6"
|
native_model = "0.4.6"
|
||||||
|
once_cell = "1.19.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# by default Tauri runs in production mode
|
# by default Tauri runs in production mode
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
-- create accounts table
|
|
||||||
CREATE TABLE
|
|
||||||
accounts (
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
|
||||||
pubkey TEXT NOT NULL UNIQUE,
|
|
||||||
is_active INTEGER NOT NULL DEFAULT 0,
|
|
||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- create ndk cache users table
|
|
||||||
CREATE TABLE
|
|
||||||
ndk_users (
|
|
||||||
pubkey TEXT NOT NULL PRIMARY KEY,
|
|
||||||
profile TEXT,
|
|
||||||
createdAt NUMBER
|
|
||||||
);
|
|
||||||
|
|
||||||
-- create ndk cache events table
|
|
||||||
CREATE TABLE
|
|
||||||
ndk_events (
|
|
||||||
id TEXT NOT NULL PRIMARY KEY,
|
|
||||||
pubkey TEXT,
|
|
||||||
content TEXT,
|
|
||||||
kind NUMBER,
|
|
||||||
createdAt NUMBER,
|
|
||||||
relay TEXT,
|
|
||||||
event TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- create ndk cache eventtags table
|
|
||||||
CREATE TABLE
|
|
||||||
ndk_eventtags (
|
|
||||||
id TEXT NOT NULL PRIMARY KEY,
|
|
||||||
eventId TEXT,
|
|
||||||
tag TEXT,
|
|
||||||
value TEXT,
|
|
||||||
tagValue TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- create settings table
|
|
||||||
CREATE TABLE
|
|
||||||
settings (
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
|
||||||
key TEXT NOT NULL,
|
|
||||||
value TEXT NOT NULL,
|
|
||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- create columns table
|
|
||||||
CREATE TABLE
|
|
||||||
columns (
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
|
||||||
account_id INTEGER NOT NULL,
|
|
||||||
kind INTEGER NOT NULL,
|
|
||||||
title TEXT NOT NULL,
|
|
||||||
content TEXT NOT NULL,
|
|
||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
FOREIGN KEY (account_id) REFERENCES accounts (id)
|
|
||||||
);
|
|
||||||
29
src-tauri/src/db.rs
Normal file
29
src-tauri/src/db.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
pub(crate) mod api {
|
||||||
|
use native_db::{native_db, InnerKeyValue};
|
||||||
|
use native_model::{native_model, Model};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub mod v1 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[native_model(id = 1, version = 2)]
|
||||||
|
#[native_db]
|
||||||
|
pub struct Account {
|
||||||
|
#[primary_key]
|
||||||
|
pub pubkey: String,
|
||||||
|
#[secondary_key]
|
||||||
|
status: String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static DATABASE_BUILDER: Lazy<native_db::DatabaseBuilder> = Lazy::new(|| {
|
||||||
|
let mut builder = native_db::DatabaseBuilder::new();
|
||||||
|
builder
|
||||||
|
.define::<api::v1::Account>()
|
||||||
|
.expect("failed to define model Account v1");
|
||||||
|
builder
|
||||||
|
});
|
||||||
@@ -4,15 +4,20 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
pub mod db;
|
||||||
pub mod nostr;
|
pub mod nostr;
|
||||||
|
|
||||||
|
use crate::db::api::v1::AccountKey;
|
||||||
|
use crate::db::DATABASE_BUILDER;
|
||||||
|
use db::api::v1::Account;
|
||||||
|
use keyring::Entry;
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
use tauri_plugin_autostart::MacosLauncher;
|
use tauri_plugin_autostart::MacosLauncher;
|
||||||
|
|
||||||
pub struct AppState {
|
pub struct Nostr {
|
||||||
pub nostr: Arc<Client>,
|
pub client: Arc<Client>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -21,6 +26,16 @@ fn main() {
|
|||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
let handle = app.handle().clone();
|
let handle = app.handle().clone();
|
||||||
let config_dir = app.path().app_config_dir().unwrap();
|
let config_dir = app.path().app_config_dir().unwrap();
|
||||||
|
let db = DATABASE_BUILDER
|
||||||
|
.create(config_dir.join("app.db"))
|
||||||
|
.expect("failed to create app database");
|
||||||
|
|
||||||
|
// run db migrate
|
||||||
|
let rw = db
|
||||||
|
.rw_transaction()
|
||||||
|
.expect("failed to create rw migration transaction");
|
||||||
|
rw.migrate::<Account>().expect("failed to migrate Account");
|
||||||
|
rw.commit().expect("failed to commit migration");
|
||||||
|
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
// Create database connection
|
// Create database connection
|
||||||
@@ -31,8 +46,30 @@ fn main() {
|
|||||||
// Create nostr connection
|
// Create nostr connection
|
||||||
let client = ClientBuilder::default().database(nostr_db).build();
|
let client = ClientBuilder::default().database(nostr_db).build();
|
||||||
|
|
||||||
|
// get stored account
|
||||||
|
let r = db.r_transaction().expect("failed to create ro transaction");
|
||||||
|
let accounts: Vec<Account> = r
|
||||||
|
.scan()
|
||||||
|
.secondary(AccountKey::status)
|
||||||
|
.expect("failed to scan accounts")
|
||||||
|
.start_with("active")
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if let Some(account) = accounts.into_iter().nth(0) {
|
||||||
|
let entry = Entry::new("Lume", &account.pubkey).expect("failed to load secret");
|
||||||
|
|
||||||
|
if let Ok(key) = entry.get_password() {
|
||||||
|
let secret_key = SecretKey::from_bech32(key).unwrap();
|
||||||
|
let keys = Keys::new(secret_key);
|
||||||
|
let signer = ClientSigner::Keys(keys);
|
||||||
|
|
||||||
|
// update client's signer
|
||||||
|
client.set_signer(Some(signer)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add some bootstrap relays
|
// Add some bootstrap relays
|
||||||
// #TODO: Add option to user config bootstrap relay
|
// #TODO: Pull bootstrap relays from user's settings
|
||||||
client
|
client
|
||||||
.add_relay("wss://nostr.mutinywallet.com")
|
.add_relay("wss://nostr.mutinywallet.com")
|
||||||
.await
|
.await
|
||||||
@@ -46,8 +83,8 @@ fn main() {
|
|||||||
client.connect().await;
|
client.connect().await;
|
||||||
|
|
||||||
// Init global state
|
// Init global state
|
||||||
handle.manage(AppState {
|
handle.manage(Nostr {
|
||||||
nostr: client.into(),
|
client: client.into(),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use crate::AppState;
|
use crate::Nostr;
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
|
|
||||||
#[tauri::command(async)]
|
#[tauri::command(async)]
|
||||||
pub async fn get_event(id: String, app_state: State<'_, AppState>) -> Result<String, ()> {
|
pub async fn get_event(id: String, nostr: State<'_, Nostr>) -> Result<String, ()> {
|
||||||
let client = &app_state.nostr;
|
let client = &nostr.client;
|
||||||
|
|
||||||
let event_id = EventId::from_bech32(id).unwrap();
|
let event_id = EventId::from_bech32(id).unwrap();
|
||||||
let filter = Filter::new().id(event_id);
|
let filter = Filter::new().id(event_id);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::AppState;
|
use crate::Nostr;
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
|
|
||||||
@@ -29,8 +29,8 @@ pub fn get_public_key(secret_key: SecretKey) -> Result<String, ()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn update_signer(key: String, app_state: State<'_, AppState>) -> Result<(), ()> {
|
pub async fn update_signer(key: String, nostr: State<'_, Nostr>) -> Result<(), ()> {
|
||||||
let client = &app_state.nostr;
|
let client = &nostr.client;
|
||||||
let secret_key = SecretKey::from_bech32(key).unwrap();
|
let secret_key = SecretKey::from_bech32(key).unwrap();
|
||||||
let keys = Keys::new(secret_key);
|
let keys = Keys::new(secret_key);
|
||||||
let signer = ClientSigner::Keys(keys);
|
let signer = ClientSigner::Keys(keys);
|
||||||
@@ -41,8 +41,8 @@ pub async fn update_signer(key: String, app_state: State<'_, AppState>) -> Resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn verify_signer(app_state: State<'_, AppState>) -> Result<bool, ()> {
|
pub async fn verify_signer(nostr: State<'_, Nostr>) -> Result<bool, ()> {
|
||||||
let client = &app_state.nostr;
|
let client = &nostr.client;
|
||||||
let status = client.signer().await.is_ok();
|
let status = client.signer().await.is_ok();
|
||||||
|
|
||||||
Ok(status)
|
Ok(status)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use crate::AppState;
|
use crate::Nostr;
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
|
|
||||||
#[tauri::command(async)]
|
#[tauri::command(async)]
|
||||||
pub async fn get_metadata(npub: String, app_state: State<'_, AppState>) -> Result<Metadata, ()> {
|
pub async fn get_metadata(npub: String, nostr: State<'_, Nostr>) -> Result<Metadata, ()> {
|
||||||
let client = &app_state.nostr;
|
let client = &nostr.client;
|
||||||
|
|
||||||
let public_key = XOnlyPublicKey::from_bech32(npub).unwrap();
|
let public_key = XOnlyPublicKey::from_bech32(npub).unwrap();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user