This commit is contained in:
Ren Amamiya
2026-04-03 15:23:26 +07:00
parent fbc9883680
commit 163865eb46
4 changed files with 67 additions and 108 deletions

View File

@@ -41,8 +41,6 @@ pub enum DeviceEvent {
Creating,
/// Encryption key is not set
NotSet { reason: SharedString },
/// An event to notify that Coop isn't subscribed to gift wrap events
NotSubscribe { reason: SharedString },
/// An error occurred
Error(SharedString),
}
@@ -55,15 +53,6 @@ impl DeviceEvent {
Self::Error(error.into())
}
pub fn not_subscribe<T>(reason: T) -> Self
where
T: Into<SharedString>,
{
Self::NotSubscribe {
reason: reason.into(),
}
}
pub fn not_set<T>(reason: T) -> Self
where
T: Into<SharedString>,
@@ -79,14 +68,14 @@ impl DeviceEvent {
/// NIP-4e: https://github.com/nostr-protocol/nips/blob/per-device-keys/4e.md
#[derive(Debug)]
pub struct DeviceRegistry {
/// Whether the registry is currently subscribing to gift wrap events
pub subscribing: bool,
/// Whether the registry is currently initializing
pub initializing: bool,
/// Whether the registry is waiting for encryption key approval from other devices
pub requesting: bool,
/// Whether there is a pending request for encryption key approval
pub has_pending_request: bool,
pub pending_request: bool,
/// Async tasks
tasks: Vec<Task<Result<(), Error>>>,
@@ -111,10 +100,13 @@ impl DeviceRegistry {
/// Create a new device registry instance
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let nostr = NostrRegistry::global(cx);
// Subscribe to nostr state events
let subscription = cx.subscribe_in(&nostr, window, |this, _e, event, _window, cx| {
if event == &StateEvent::SignerSet {
this.set_subscribing(false, cx);
this.set_initializing(true, cx);
this.set_requesting(false, cx);
this.get_announcement(cx);
};
});
@@ -123,9 +115,9 @@ impl DeviceRegistry {
});
Self {
subscribing: false,
initializing: true,
requesting: false,
has_pending_request: false,
pending_request: false,
tasks: vec![],
_subscription: Some(subscription),
}
@@ -139,7 +131,6 @@ impl DeviceRegistry {
self.tasks.push(cx.background_spawn(async move {
let mut notifications = client.notifications();
let mut processed_events = HashSet::new();
let mut found_relay_list = false;
while let Some(notification) = notifications.next().await {
if let ClientNotification::Message { message, .. } = notification
@@ -151,17 +142,6 @@ impl DeviceRegistry {
}
match event.kind {
Kind::RelayList => {
// Skip if the relay list has already been found
if found_relay_list {
continue;
}
// Verify the relay list event is signed by the user's signer
if verify_author(&client, event.as_ref()).await {
tx.send_async(event.into_owned()).await?;
found_relay_list = true;
}
}
Kind::Custom(4454) => {
if verify_author(&client, event.as_ref()).await {
tx.send_async(event.into_owned()).await?;
@@ -202,9 +182,9 @@ impl DeviceRegistry {
}));
}
/// Set whether the registry is currently subscribing to gift wrap events
fn set_subscribing(&mut self, subscribing: bool, cx: &mut Context<Self>) {
self.subscribing = subscribing;
/// Set whether the registry is currently initializing
fn set_initializing(&mut self, initializing: bool, cx: &mut Context<Self>) {
self.initializing = initializing;
cx.notify();
}
@@ -215,8 +195,8 @@ impl DeviceRegistry {
}
/// Set whether there is a pending request for encryption key approval
fn set_has_pending_request(&mut self, pending: bool, cx: &mut Context<Self>) {
self.has_pending_request = pending;
fn set_pending_request(&mut self, pending: bool, cx: &mut Context<Self>) {
self.pending_request = pending;
cx.notify();
}
@@ -243,16 +223,16 @@ impl DeviceRegistry {
/// Get all messages for encryption keys
fn get_messages(&mut self, cx: &mut Context<Self>) {
let task = self.subscribe_to_giftwrap_events(cx);
let task = self.subscribe_gift_wrap_events(cx);
self.tasks.push(cx.spawn(async move |this, cx| {
if let Err(e) = task.await {
this.update(cx, |_this, cx| {
cx.emit(DeviceEvent::not_subscribe(e.to_string()));
cx.emit(DeviceEvent::error(e.to_string()));
})?;
} else {
this.update(cx, |this, cx| {
this.set_subscribing(true, cx);
this.set_initializing(false, cx);
})?;
}
Ok(())
@@ -260,7 +240,7 @@ impl DeviceRegistry {
}
/// Continuously get gift wrap events for the current user in their messaging relays
fn subscribe_to_giftwrap_events(&self, cx: &App) -> Task<Result<(), Error>> {
fn subscribe_gift_wrap_events(&self, cx: &App) -> Task<Result<(), Error>> {
let persons = PersonRegistry::global(cx);
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
@@ -471,21 +451,16 @@ impl DeviceRegistry {
self.tasks.push(cx.background_spawn(async move {
let public_key = signer.get_public_key().await?;
let id = SubscriptionId::new("dekey-requests");
// Construct a filter for encryption key requests
let now = Filter::new()
let filter = Filter::new()
.kind(Kind::Custom(4454))
.author(public_key)
.since(Timestamp::now());
// Construct a filter for the last encryption key request
let last = Filter::new()
.kind(Kind::Custom(4454))
.author(public_key)
.limit(1);
// Subscribe to the device key requests on user's write relays
client.subscribe(vec![now, last]).await?;
client.subscribe(vec![filter]).with_id(id).await?;
Ok(())
}));
@@ -687,10 +662,10 @@ impl DeviceRegistry {
/// Handle encryption request
fn ask_for_approval(&mut self, event: Event, window: &mut Window, cx: &mut Context<Self>) {
// Ignore if there is already a pending request
if self.has_pending_request {
if self.pending_request {
return;
}
self.set_has_pending_request(true, cx);
self.set_pending_request(true, cx);
// Show notification
let notification = self.notification(event, cx);