diff --git a/apps/desktop2/src/components/backup.tsx b/apps/desktop2/src/components/backup.tsx
index c124e665..24f68e55 100644
--- a/apps/desktop2/src/components/backup.tsx
+++ b/apps/desktop2/src/components/backup.tsx
@@ -1,13 +1,36 @@
-import { CancelIcon } from "@lume/icons";
+import { ArrowRightIcon, CancelIcon } from "@lume/icons";
import * as Dialog from "@radix-ui/react-dialog";
+import { Link, useParams } from "@tanstack/react-router";
+import { invoke } from "@tauri-apps/api/core";
import { useState } from "react";
+import { toast } from "sonner";
export function BackupDialog() {
- const [key, setKey] = useState("");
+ // @ts-ignore, magic!!!
+ const { account } = useParams({ strict: false });
+
+ const [key, setKey] = useState(null);
const [passphase, setPassphase] = useState("");
+ const [loading, setLoading] = useState(false);
const encryptKey = async () => {
- console.log("****");
+ try {
+ setLoading(true);
+
+ const encrypted: string = await invoke("get_encrypted_key", {
+ npub: account,
+ password: passphase,
+ });
+
+ if (encrypted) {
+ setKey(encrypted);
+ }
+
+ setLoading(false);
+ } catch (e) {
+ setLoading(false);
+ toast.error(String(e));
+ }
};
return (
@@ -41,20 +64,7 @@ export function BackupDialog() {
-
-
-
-
-
+
setPassphase(e.target.value)}
className="h-11 w-full resize-none rounded-lg border-transparent bg-neutral-100 placeholder:text-neutral-600 focus:border-blue-500 focus:ring focus:ring-blue-100 dark:bg-neutral-900 dark:focus:ring-blue-900"
/>
- {passphase.length ? (
-
-
-
- ) : null}
+ {key ? (
+
+
+
+
+ ) : null}
+
+
+ {!key ? (
+
+ ) : (
+
+ I've safely store my account key
+
+ )}
diff --git a/packages/ark/src/ark.ts b/packages/ark/src/ark.ts
index 340864fa..bc79b58e 100644
--- a/packages/ark/src/ark.ts
+++ b/packages/ark/src/ark.ts
@@ -22,15 +22,17 @@ export class Ark {
public async get_all_accounts() {
try {
const accounts: Account[] = [];
- const cmd: string[] = await invoke("get_all_nsecs");
+ const cmd: string[] = await invoke("get_accounts");
- for (const item of cmd) {
- accounts.push({ npub: item.replace(".npub", "") });
+ if (cmd) {
+ for (const item of cmd) {
+ accounts.push({ npub: item.replace(".npub", "") });
+ }
+
+ this.accounts = accounts;
+ return accounts;
}
-
- this.accounts = accounts;
- return accounts;
- } catch (e) {
+ } catch {
return [];
}
}
diff --git a/src-tauri/src/commands/folder.rs b/src-tauri/src/commands/folder.rs
index 2ab711e9..723d1895 100644
--- a/src-tauri/src/commands/folder.rs
+++ b/src-tauri/src/commands/folder.rs
@@ -49,10 +49,10 @@ pub async fn show_in_folder(path: String) {
}
#[tauri::command]
-pub fn get_all_nsecs(app_handle: tauri::AppHandle) -> Result, ()> {
- let dir = app_handle.path().app_config_dir().unwrap();
+pub fn get_accounts(app_handle: tauri::AppHandle) -> Result, ()> {
+ let dir = app_handle.path().home_dir().unwrap();
- if let Ok(paths) = std::fs::read_dir(dir) {
+ if let Ok(paths) = std::fs::read_dir(dir.join("Lume/")) {
let files = paths
.filter_map(|res| res.ok())
.map(|dir_entry| dir_entry.path())
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 1cae5a35..e3b54913 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -7,6 +7,8 @@ pub mod commands;
pub mod nostr;
pub mod tray;
+use std::fs;
+
use nostr_sdk::prelude::*;
use tauri::Manager;
use tauri_plugin_autostart::MacosLauncher;
@@ -20,11 +22,15 @@ fn main() {
.setup(|app| {
let _tray = tray::create_tray(app.handle()).unwrap();
let handle = app.handle().clone();
- let config_dir = handle.path().app_config_dir().unwrap();
+ let resource_dir = handle.path().resource_dir().unwrap();
+ let home_dir = handle.path().home_dir().unwrap();
+
+ // create data folder if not exist
+ fs::create_dir_all(home_dir.join("Lume/")).unwrap();
tauri::async_runtime::spawn(async move {
// Create nostr database connection
- let nostr_db = SQLiteDatabase::open(config_dir.join("nostr.db"))
+ let nostr_db = SQLiteDatabase::open(resource_dir.join("lume.db"))
.await
.expect("Open database failed.");
@@ -79,6 +85,7 @@ fn main() {
.invoke_handler(tauri::generate_handler![
nostr::keys::create_keys,
nostr::keys::save_key,
+ nostr::keys::get_encrypted_key,
nostr::keys::verify_signer,
nostr::keys::load_selected_account,
nostr::keys::event_to_bech32,
@@ -108,15 +115,21 @@ fn main() {
nostr::event::upvote,
nostr::event::downvote,
commands::folder::show_in_folder,
- commands::folder::get_all_nsecs,
+ commands::folder::get_accounts,
commands::opg::fetch_opg,
])
.build(tauri::generate_context!())
.expect("error while running tauri application")
- .run(|_app_handle, event| match event {
- tauri::RunEvent::ExitRequested { api, .. } => {
- api.prevent_exit();
+ .run(|app, event| {
+ if let tauri::RunEvent::Opened { urls } = event {
+ if let Some(w) = app.get_webview_window("main") {
+ let urls = urls
+ .iter()
+ .map(|u| u.as_str())
+ .collect::>()
+ .join(",");
+ let _ = w.eval(&format!("window.onFileOpen(`{urls}`)"));
+ }
}
- _ => {}
});
}
diff --git a/src-tauri/src/nostr/keys.rs b/src-tauri/src/nostr/keys.rs
index 33bf2959..7bf6e960 100644
--- a/src-tauri/src/nostr/keys.rs
+++ b/src-tauri/src/nostr/keys.rs
@@ -53,13 +53,14 @@ pub async fn save_key(
let npub = nostr_keys.public_key().to_bech32().unwrap();
let nsec = nostr_keys.secret_key().unwrap().to_bech32().unwrap();
- if let Ok(config_dir) = app_handle.path().app_config_dir() {
- let file_path = npub.clone() + ".npub";
- let _ = File::create(config_dir.join(file_path)).unwrap();
+ let home_dir = app_handle.path().home_dir().unwrap();
+ let app_dir = home_dir.join("Lume/");
- let keyring = Entry::new("Lume Secret Storage", &npub).unwrap();
- let _ = keyring.set_password(&nsec);
- }
+ let file_path = npub.clone() + ".npub";
+ let _ = File::create(app_dir.join(file_path)).unwrap();
+
+ let keyring = Entry::new("Lume Secret Storage", &npub).unwrap();
+ let _ = keyring.set_password(&nsec);
let signer = NostrSigner::Keys(nostr_keys);
let client = &state.client;
@@ -84,6 +85,24 @@ pub async fn verify_signer(state: State<'_, Nostr>) -> Result {
}
}
+#[tauri::command]
+pub fn get_encrypted_key(npub: &str, password: &str) -> Result {
+ let keyring = Entry::new("Lume Secret Storage", npub).unwrap();
+
+ if let Ok(nsec) = keyring.get_password() {
+ let secret_key = SecretKey::from_bech32(nsec).expect("Get secret key failed");
+ let new_key = EncryptedSecretKey::new(&secret_key, password, 16, KeySecurity::Medium);
+
+ if let Ok(key) = new_key {
+ Ok(key.to_bech32().unwrap())
+ } else {
+ Err("Encrypt key failed".into())
+ }
+ } else {
+ Err("Key not found".into())
+ }
+}
+
#[tauri::command]
pub async fn load_selected_account(npub: &str, state: State<'_, Nostr>) -> Result {
let client = &state.client;