feat: add nip46

This commit is contained in:
2024-04-18 15:09:33 +07:00
parent cd31b99559
commit 89c36423ae
7 changed files with 189 additions and 65 deletions

View File

@@ -101,11 +101,14 @@ fn main() {
nostr::keys::save_key,
nostr::keys::get_encrypted_key,
nostr::keys::get_stored_nsec,
nostr::keys::nostr_connect,
nostr::keys::verify_signer,
nostr::keys::load_selected_account,
nostr::keys::event_to_bech32,
nostr::keys::user_to_bech32,
nostr::keys::to_npub,
nostr::keys::verify_nip05,
nostr::metadata::connect_user_relays,
nostr::metadata::get_current_user_profile,
nostr::metadata::get_profile,
nostr::metadata::get_contact_list,

View File

@@ -74,6 +74,39 @@ pub async fn save_key(
}
}
#[tauri::command]
pub async fn nostr_connect(
npub: &str,
uri: &str,
app_handle: tauri::AppHandle,
state: State<'_, Nostr>,
) -> Result<String, String> {
let client = &state.client;
let app_keys = Keys::generate();
match NostrConnectURI::parse(uri) {
Ok(bunker_uri) => {
println!("connecting... {}", uri);
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(120), None).await {
Ok(signer) => {
let home_dir = app_handle.path().home_dir().unwrap();
let app_dir = home_dir.join("Lume/");
let file_path = npub.to_owned() + ".npub";
let keyring = Entry::new("Lume Secret Storage", npub).unwrap();
let _ = File::create(app_dir.join(file_path)).unwrap();
let _ = keyring.set_password(uri);
let _ = client.set_signer(Some(signer.into())).await;
Ok(npub.into())
}
Err(err) => Err(err.to_string()),
}
}
Err(err) => Err(err.to_string()),
}
}
#[tauri::command]
pub async fn verify_signer(state: State<'_, Nostr>) -> Result<bool, ()> {
let client = &state.client;
@@ -119,40 +152,28 @@ pub async fn load_selected_account(npub: &str, state: State<'_, Nostr>) -> Resul
let client = &state.client;
let keyring = Entry::new("Lume Secret Storage", npub).unwrap();
if let Ok(nsec) = keyring.get_password() {
// Build nostr signer
let secret_key = SecretKey::from_bech32(nsec).expect("Get secret key failed");
let keys = Keys::new(secret_key);
let public_key = keys.public_key();
let signer = NostrSigner::Keys(keys);
if let Ok(password) = keyring.get_password() {
if password.starts_with("bunker://") {
let app_keys = Keys::generate();
let bunker_uri = NostrConnectURI::parse(password).unwrap();
let signer = Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(60), None)
.await
.unwrap();
// Update signer
client.set_signer(Some(signer)).await;
// Update signer
client.set_signer(Some(signer.into())).await;
// Done
Ok(true)
} else {
let secret_key = SecretKey::from_bech32(password).expect("Get secret key failed");
let keys = Keys::new(secret_key);
let signer = NostrSigner::Keys(keys);
// Get user's relay list
let filter = Filter::new()
.author(public_key)
.kind(Kind::RelayList)
.limit(1);
let query = client
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
.await;
// Connect user's relay list
if let Ok(events) = query {
if let Some(event) = events.first() {
let list = nip65::extract_relay_list(&event);
for item in list.into_iter() {
println!("connecting to relay: {}", item.0.to_string());
client
.connect_relay(item.0.to_string())
.await
.unwrap_or_default();
}
}
// Update signer
client.set_signer(Some(signer)).await;
// Done
Ok(true)
}
Ok(true)
} else {
Err("nsec not found".into())
}
@@ -174,6 +195,14 @@ pub fn user_to_bech32(key: &str, relays: Vec<String>) -> Result<String, ()> {
Ok(profile.to_bech32().unwrap())
}
#[tauri::command]
pub fn to_npub(hex: &str) -> Result<String, ()> {
let public_key = PublicKey::from_str(hex).unwrap();
let npub = Nip19::Pubkey(public_key);
Ok(npub.to_bech32().unwrap())
}
#[tauri::command(async)]
pub async fn verify_nip05(key: &str, nip05: &str) -> Result<bool, ()> {
let public_key = PublicKey::from_str(key).unwrap();

View File

@@ -11,6 +11,38 @@ pub struct CacheContact {
profile: Metadata,
}
#[tauri::command]
pub async fn connect_user_relays(state: State<'_, Nostr>) -> Result<(), ()> {
let client = &state.client;
let signer = client.signer().await.unwrap();
let public_key = signer.public_key().await.unwrap();
// Get user's relay list
let filter = Filter::new()
.author(public_key)
.kind(Kind::RelayList)
.limit(1);
let query = client
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
.await;
// Connect user's relay list
if let Ok(events) = query {
if let Some(event) = events.first() {
let list = nip65::extract_relay_list(&event);
for item in list.into_iter() {
println!("connecting to relay: {}", item.0.to_string());
client
.connect_relay(item.0.to_string())
.await
.unwrap_or_default();
}
}
}
Ok(())
}
#[tauri::command]
pub async fn get_current_user_profile(state: State<'_, Nostr>) -> Result<Metadata, String> {
let client = &state.client;