mirror of
https://github.com/hoornet/vega.git
synced 2026-04-27 00:00:00 -07:00
Add OS keychain for persistent nsec sessions (roadmap #1)
- Rust: store_nsec / load_nsec / delete_nsec Tauri commands via keyring crate (macOS Keychain, Windows Credential Manager, Linux Secret Service) - On nsec login: key is stored in OS keychain keyed by hex pubkey - On startup: restoreSession() auto-loads nsec from keychain and re-establishes the NDK signer — no manual re-login required after restart - On logout: keychain entry is deleted - Graceful degradation: if keychain is unavailable (e.g. Linux without a Secret Service daemon), the app starts logged-out — same UX as before, no crash Also updates ROADMAP.md with 4 new items from the Windows playtest (multi-account switcher, NWC wizard, system tray, zap history view) and reorders the list. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,14 +1,41 @@
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
use keyring::Entry;
|
||||
|
||||
const KEYRING_SERVICE: &str = "wrystr";
|
||||
|
||||
/// Store an nsec in the OS keychain, keyed by pubkey (hex).
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||
fn store_nsec(pubkey: String, nsec: String) -> Result<(), String> {
|
||||
let entry = Entry::new(KEYRING_SERVICE, &pubkey).map_err(|e| e.to_string())?;
|
||||
entry.set_password(&nsec).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Load a stored nsec from the OS keychain. Returns None if no entry exists.
|
||||
#[tauri::command]
|
||||
fn load_nsec(pubkey: String) -> Result<Option<String>, String> {
|
||||
let entry = Entry::new(KEYRING_SERVICE, &pubkey).map_err(|e| e.to_string())?;
|
||||
match entry.get_password() {
|
||||
Ok(nsec) => Ok(Some(nsec)),
|
||||
Err(keyring::Error::NoEntry) => Ok(None),
|
||||
Err(e) => Err(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete a stored nsec from the OS keychain.
|
||||
#[tauri::command]
|
||||
fn delete_nsec(pubkey: String) -> Result<(), String> {
|
||||
let entry = Entry::new(KEYRING_SERVICE, &pubkey).map_err(|e| e.to_string())?;
|
||||
match entry.delete_credential() {
|
||||
Ok(()) => Ok(()),
|
||||
Err(keyring::Error::NoEntry) => Ok(()), // already gone — that's fine
|
||||
Err(e) => Err(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.invoke_handler(tauri::generate_handler![greet])
|
||||
.invoke_handler(tauri::generate_handler![store_nsec, load_nsec, delete_nsec])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user