This commit is contained in:
2026-05-18 08:07:59 +07:00
parent d2a17e54c4
commit eb5d64a3af
15 changed files with 524 additions and 333 deletions

View File

@@ -12,7 +12,7 @@ use gpui::{
};
use nostr_sdk::prelude::*;
use person::PersonRegistry;
use state::{Announcement, CoopSigner, NostrRegistry, StateEvent, TIMEOUT, app_name};
use state::{Announcement, CoopSigner, NostrRegistry, StateEvent, app_name};
use theme::ActiveTheme;
use ui::avatar::Avatar;
use ui::button::Button;
@@ -35,7 +35,7 @@ impl Global for GlobalDeviceRegistry {}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum DeviceEvent {
/// A new encryption signer has been set
Set,
Set(PublicKey),
/// The device is requesting an encryption key
Requesting,
/// The device is creating a new encryption key
@@ -90,9 +90,9 @@ impl DeviceRegistry {
// Subscribe to nostr state events
let subscription = cx.subscribe_in(&nostr, window, |this, _e, event, _window, cx| {
if event == &StateEvent::SignerSet {
if let StateEvent::SignerSet(public_key) = event {
this.set_initializing(true, cx);
this.get_announcement(cx);
this.get_announcement(public_key, cx);
};
});
@@ -190,12 +190,13 @@ impl DeviceRegistry {
let signer = nostr.read(cx).signer();
self.tasks.push(cx.spawn(async move |this, cx| {
let public_key = new.get_public_key().await?;
signer.set_encryption_signer(new).await;
// Update state
this.update(cx, |this, cx| {
this.set_initializing(false, cx);
cx.emit(DeviceEvent::Set);
cx.emit(DeviceEvent::Set(public_key));
})?;
Ok(())
@@ -219,14 +220,16 @@ impl DeviceRegistry {
}
/// Get device announcement for current user
pub fn get_announcement(&mut self, cx: &mut Context<Self>) {
pub fn get_announcement(&mut self, public_key: &PublicKey, cx: &mut Context<Self>) {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let signer = nostr.read(cx).signer();
let write_relays = nostr.read(cx).write_relays(public_key, cx);
let task: Task<Result<Event, Error>> = cx.background_spawn(async move {
let signer = signer.get().await;
let public_key = signer.get_public_key().await?;
let urls = write_relays.await;
// Construct the filter for the device announcement event
let filter = Filter::new()
@@ -234,10 +237,15 @@ impl DeviceRegistry {
.author(public_key)
.limit(1);
let target = urls
.into_iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<Vec<_>>();
// Stream events from user's write relays
let mut stream = client
.stream_events(filter)
.timeout(Duration::from_secs(TIMEOUT))
.stream_events(target)
.timeout(Duration::from_secs(10))
.await?;
while let Some((_url, res)) = stream.next().await {
@@ -373,9 +381,12 @@ impl DeviceRegistry {
let client = nostr.read(cx).client();
let signer = nostr.read(cx).signer();
let public_key = signer.public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
self.tasks.push(cx.background_spawn(async move {
let public_key = signer.get_public_key().await?;
let id = SubscriptionId::new("dekey-requests");
let urls = write_relays.await;
// Construct a filter for encryption key requests
let filter = Filter::new()
@@ -383,8 +394,13 @@ impl DeviceRegistry {
.author(public_key)
.since(Timestamp::now());
let target = urls
.into_iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<Vec<_>>();
// Subscribe to the device key requests on user's write relays
client.subscribe(vec![filter]).with_id(id).await?;
client.subscribe(target).with_id(id).await?;
Ok(())
}));
@@ -396,12 +412,13 @@ impl DeviceRegistry {
let client = nostr.read(cx).client();
let signer = nostr.read(cx).signer();
let public_key = signer.public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
let app_keys = nostr.read(cx).keys();
let app_pubkey = app_keys.public_key();
let task: Task<Result<Option<Event>, Error>> = cx.background_spawn(async move {
let public_key = signer.get_public_key().await?;
// Construct a filter to get the latest approval event
let filter = Filter::new()
.kind(Kind::Custom(4455))
@@ -414,6 +431,7 @@ impl DeviceRegistry {
Some(event) => Ok(Some(event)),
// No approval event found, construct a request event
None => {
let write_relays = write_relays.await;
let signer = signer.get().await;
// Construct an event for device key request
@@ -430,7 +448,7 @@ impl DeviceRegistry {
.await?;
// Send the event to write relays
client.send_event(&event).to_nip65().await?;
client.send_event(&event).to(write_relays).await?;
Ok(None)
}
@@ -468,8 +486,11 @@ impl DeviceRegistry {
let client = nostr.read(cx).client();
let signer = nostr.read(cx).signer();
let public_key = signer.public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
self.tasks.push(cx.background_spawn(async move {
let public_key = signer.get_public_key().await?;
let urls = write_relays.await;
// Construct a filter for device key requests
let filter = Filter::new()
@@ -477,8 +498,13 @@ impl DeviceRegistry {
.author(public_key)
.since(Timestamp::now());
let target = urls
.into_iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<Vec<_>>();
// Subscribe to the device key requests on user's write relays
client.subscribe(filter).await?;
client.subscribe(target).await?;
Ok(())
}));
@@ -531,6 +557,9 @@ impl DeviceRegistry {
let client = nostr.read(cx).client();
let signer = nostr.read(cx).signer();
let signer_pubkey = signer.public_key();
let write_relays = nostr.read(cx).write_relays(&signer_pubkey, cx);
// Get user's write relays
let event = event.clone();
let id: SharedString = event.id.to_hex().into();
@@ -542,6 +571,7 @@ impl DeviceRegistry {
let secret = keys.secret_key().to_secret_hex();
let device_signer: Arc<dyn AsyncNostrSigner> = Arc::new(keys);
let write_relays = write_relays.await;
let signer = signer.get().await;
// Extract the target public key from the event tags
@@ -569,7 +599,7 @@ impl DeviceRegistry {
.await?;
// Send the response event to the user's relay list
client.send_event(&event).to_nip65().await?;
client.send_event(&event).to(write_relays).await?;
Ok(())
});