feat: rewrite the nip-4e implementation #1
@@ -324,11 +324,16 @@ impl Room {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
let members = self.members();
|
||||
let id = SubscriptionId::new(format!("room-{}", self.id));
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let signer = client.signer().await?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||
|
||||
// Subscription options
|
||||
let opts = SubscribeAutoCloseOptions::default()
|
||||
.timeout(Some(Duration::from_secs(2)))
|
||||
.exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||
|
||||
for member in members.into_iter() {
|
||||
if member == public_key {
|
||||
@@ -339,7 +344,9 @@ impl Room {
|
||||
let filter = Filter::new().kind(Kind::RelayList).author(member).limit(1);
|
||||
|
||||
// Subscribe to get member's gossip relays
|
||||
client.subscribe(filter, Some(opts)).await?;
|
||||
client
|
||||
.subscribe_with_id(id.clone(), filter, Some(opts))
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -100,10 +100,10 @@ impl RelayAuth {
|
||||
|
||||
if auto_auth && is_authenticated {
|
||||
// Automatically authenticate if the relay is authenticated before
|
||||
this.response(req.to_owned(), window, cx);
|
||||
this.response(req, window, cx);
|
||||
} else {
|
||||
// Otherwise open the auth request popup
|
||||
this.ask_for_approval(req.to_owned(), window, cx);
|
||||
this.ask_for_approval(req, window, cx);
|
||||
}
|
||||
}
|
||||
}),
|
||||
@@ -111,9 +111,7 @@ impl RelayAuth {
|
||||
|
||||
tasks.push(
|
||||
// Handle nostr notifications
|
||||
cx.background_spawn(async move {
|
||||
Self::handle_notifications(&client, &tx).await;
|
||||
}),
|
||||
cx.background_spawn(async move { Self::handle_notifications(&client, &tx).await }),
|
||||
);
|
||||
|
||||
tasks.push(
|
||||
@@ -138,7 +136,6 @@ impl RelayAuth {
|
||||
// Handle nostr notifications
|
||||
async fn handle_notifications(client: &Client, tx: &flume::Sender<AuthRequest>) {
|
||||
let mut notifications = client.notifications();
|
||||
let mut processed_challenges = HashSet::new();
|
||||
|
||||
while let Ok(notification) = notifications.recv().await {
|
||||
if let RelayPoolNotification::Message {
|
||||
@@ -146,10 +143,11 @@ impl RelayAuth {
|
||||
relay_url,
|
||||
} = notification
|
||||
{
|
||||
if processed_challenges.insert(challenge.clone()) {
|
||||
let request = AuthRequest::new(challenge, relay_url);
|
||||
tx.send_async(request).await.ok();
|
||||
};
|
||||
let request = AuthRequest::new(challenge, relay_url);
|
||||
|
||||
if let Err(e) = tx.send_async(request).await {
|
||||
log::error!("Failed to send auth request: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ impl Gossip {
|
||||
})
|
||||
.take(3),
|
||||
);
|
||||
|
||||
log::info!("Updating gossip relays for: {}", event.pubkey);
|
||||
}
|
||||
|
||||
/// Get messaging relays for a given public key
|
||||
@@ -99,5 +101,7 @@ impl Gossip {
|
||||
})
|
||||
.take(3),
|
||||
);
|
||||
|
||||
log::info!("Updating messaging relays for: {}", event.pubkey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,10 @@ impl NostrRegistry {
|
||||
while let Ok(notification) = notifications.recv().await {
|
||||
if let RelayPoolNotification::Message { message, relay_url } = notification {
|
||||
match message {
|
||||
RelayMessage::Event { event, .. } => {
|
||||
RelayMessage::Event {
|
||||
event,
|
||||
subscription_id,
|
||||
} => {
|
||||
if !processed_events.insert(event.id) {
|
||||
// Skip if the event has already been processed
|
||||
continue;
|
||||
@@ -222,6 +225,11 @@ impl NostrRegistry {
|
||||
|
||||
match event.kind {
|
||||
Kind::RelayList => {
|
||||
// Automatically get messaging relays for each member when the user opens a room
|
||||
if subscription_id.as_str().starts_with("room-") {
|
||||
Self::get_messaging_relays_by(client, event.as_ref()).await?;
|
||||
}
|
||||
|
||||
tx.send_async(event.into_owned()).await?;
|
||||
}
|
||||
Kind::InboxRelays => {
|
||||
@@ -253,6 +261,45 @@ impl NostrRegistry {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Automatically get messaging relays from a received relay list
|
||||
async fn get_messaging_relays_by(client: &Client, event: &Event) -> Result<(), Error> {
|
||||
// Subscription options
|
||||
let opts = SubscribeAutoCloseOptions::default()
|
||||
.timeout(Some(Duration::from_secs(TIMEOUT)))
|
||||
.exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||
|
||||
// Extract write relays from event
|
||||
let write_relays: Vec<&RelayUrl> = nip65::extract_relay_list(event)
|
||||
.filter_map(|(url, metadata)| {
|
||||
if metadata.is_none() || metadata == &Some(RelayMetadata::Write) {
|
||||
Some(url)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Ensure relay connections
|
||||
for relay in write_relays.iter() {
|
||||
client.add_write_relay(*relay).await?;
|
||||
client.connect_relay(*relay).await?;
|
||||
}
|
||||
|
||||
// Construct filter for inbox relays
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::InboxRelays)
|
||||
.author(event.pubkey)
|
||||
.limit(1);
|
||||
|
||||
client
|
||||
.subscribe_to(write_relays, vec![filter], Some(opts))
|
||||
.await?;
|
||||
|
||||
log::info!("Getting inbox relays for: {}", event.pubkey);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get or create a new app keys
|
||||
fn create_or_init_app_keys() -> Result<Keys, Error> {
|
||||
let dir = config_dir().join(".app_keys");
|
||||
@@ -308,7 +355,7 @@ impl NostrRegistry {
|
||||
// Ensure relay connections
|
||||
cx.background_spawn(async move {
|
||||
for url in async_relays.iter() {
|
||||
client.add_relay(url).await.ok();
|
||||
client.add_write_relay(url).await.ok();
|
||||
client.connect_relay(url).await.ok();
|
||||
}
|
||||
})
|
||||
@@ -326,7 +373,7 @@ impl NostrRegistry {
|
||||
// Ensure relay connections
|
||||
cx.background_spawn(async move {
|
||||
for url in async_relays.iter() {
|
||||
client.add_relay(url).await.ok();
|
||||
client.add_read_relay(url).await.ok();
|
||||
client.connect_relay(url).await.ok();
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user