.
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m41s
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m41s
This commit is contained in:
@@ -37,7 +37,9 @@ pub const USER_GIFTWRAP: &str = "user-gift-wraps";
|
||||
pub const WOT_RELAYS: [&str; 1] = ["wss://relay.vertexlab.io"];
|
||||
|
||||
/// Default search relays
|
||||
pub const SEARCH_RELAYS: [&str; 2] = ["wss://antiprimal.net", "wss://search.nos.today"];
|
||||
pub const SEARCH_RELAYS: [&str; 1] = ["wss://antiprimal.net"];
|
||||
|
||||
pub const INDEXER_RELAYS: [&str; 1] = ["wss://indexer.coracle.social"];
|
||||
|
||||
/// Default bootstrap relays
|
||||
pub const BOOTSTRAP_RELAYS: [&str; 3] = [
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::time::Duration;
|
||||
|
||||
use anyhow::{anyhow, Context as AnyhowContext, Error};
|
||||
use common::config_dir;
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Task};
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Task, Window};
|
||||
use nostr_connect::prelude::*;
|
||||
use nostr_gossip_memory::prelude::*;
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
@@ -19,7 +19,7 @@ pub use constants::*;
|
||||
pub use nip05::*;
|
||||
pub use signer::*;
|
||||
|
||||
pub fn init(cx: &mut App) {
|
||||
pub fn init(window: &mut Window, cx: &mut App) {
|
||||
// rustls uses the `aws_lc_rs` provider by default
|
||||
// This only errors if the default provider has already
|
||||
// been installed. We can ignore this `Result`.
|
||||
@@ -30,7 +30,7 @@ pub fn init(cx: &mut App) {
|
||||
// Initialize the tokio runtime
|
||||
gpui_tokio::init(cx);
|
||||
|
||||
NostrRegistry::set_global(cx.new(NostrRegistry::new), cx);
|
||||
NostrRegistry::set_global(cx.new(|cx| NostrRegistry::new(window, cx)), cx);
|
||||
}
|
||||
|
||||
struct GlobalNostrRegistry(Entity<NostrRegistry>);
|
||||
@@ -82,7 +82,7 @@ impl NostrRegistry {
|
||||
}
|
||||
|
||||
/// Create a new nostr instance
|
||||
fn new(cx: &mut Context<Self>) -> Self {
|
||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
// Construct the nostr lmdb instance
|
||||
let lmdb = cx.foreground_executor().block_on(async move {
|
||||
NostrLmdb::open(config_dir().join("nostr"))
|
||||
@@ -122,7 +122,7 @@ impl NostrRegistry {
|
||||
subscriptions.push(
|
||||
// Observe the NIP-65 state
|
||||
cx.observe(&nip65, |this, state, cx| {
|
||||
if state.read(cx).configured() {
|
||||
if state.read(cx).configured().is_some() {
|
||||
this.get_profile(cx);
|
||||
this.get_messaging_relays(cx);
|
||||
}
|
||||
@@ -131,20 +131,15 @@ impl NostrRegistry {
|
||||
|
||||
subscriptions.push(
|
||||
// Observe the NIP-17 state
|
||||
cx.observe(&nip17, |this, state, cx| {
|
||||
if state.read(cx) == &RelayState::Configured {
|
||||
this.get_messages(cx);
|
||||
cx.observe(&nip17, |this, nip17, cx| {
|
||||
if let Some(event) = nip17.read(cx).configured().cloned() {
|
||||
this.subscribe_to_giftwrap_events(&event, cx);
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
cx.defer(|cx| {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
|
||||
// Connect to the bootstrapping relays
|
||||
nostr.update(cx, |this, cx| {
|
||||
this.connect(cx);
|
||||
});
|
||||
cx.defer_in(window, |this, _window, cx| {
|
||||
this.connect(cx);
|
||||
});
|
||||
|
||||
Self {
|
||||
@@ -164,36 +159,35 @@ impl NostrRegistry {
|
||||
fn connect(&mut self, cx: &mut Context<Self>) {
|
||||
let client = self.client();
|
||||
|
||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||
// Add search relay to the relay pool
|
||||
for url in SEARCH_RELAYS.into_iter() {
|
||||
client.add_relay(url).and_connect().await?;
|
||||
}
|
||||
|
||||
// Add bootstrap relay to the relay pool
|
||||
for url in BOOTSTRAP_RELAYS.into_iter() {
|
||||
client.add_relay(url).and_connect().await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
// Wait for the task to complete
|
||||
task.await?;
|
||||
|
||||
// Update the state
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_connected(cx);
|
||||
})?;
|
||||
|
||||
// Small delay
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(200))
|
||||
.await_on_background(async move {
|
||||
// Add search relay to the relay pool
|
||||
for url in INDEXER_RELAYS.into_iter() {
|
||||
client
|
||||
.add_relay(url)
|
||||
.capabilities(RelayCapabilities::DISCOVERY)
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
|
||||
// Add search relay to the relay pool
|
||||
for url in SEARCH_RELAYS.into_iter() {
|
||||
client.add_relay(url).await.ok();
|
||||
}
|
||||
|
||||
// Add bootstrap relay to the relay pool
|
||||
for url in BOOTSTRAP_RELAYS.into_iter() {
|
||||
client.add_relay(url).await.ok();
|
||||
}
|
||||
|
||||
client.connect().await;
|
||||
})
|
||||
.await;
|
||||
|
||||
// Update the state
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_connected(cx);
|
||||
this.get_signer(cx);
|
||||
})?;
|
||||
|
||||
@@ -284,15 +278,36 @@ impl NostrRegistry {
|
||||
}
|
||||
|
||||
/// Reset all relay states
|
||||
pub fn reset_relay_states(&mut self, cx: &mut Context<Self>) {
|
||||
pub fn reset_relays(&mut self, cx: &mut Context<Self>) {
|
||||
let client = self.client();
|
||||
|
||||
self.nip65.update(cx, |this, cx| {
|
||||
*this = RelayState::default();
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
self.nip17.update(cx, |this, cx| {
|
||||
*this = RelayState::default();
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
self.tasks.push(cx.background_spawn(async move {
|
||||
let relays = client.relays().await;
|
||||
|
||||
for (relay_url, relay) in relays.iter() {
|
||||
let url = relay_url.as_str();
|
||||
let default_relay = BOOTSTRAP_RELAYS.contains(&url)
|
||||
|| SEARCH_RELAYS.contains(&url)
|
||||
|| INDEXER_RELAYS.contains(&url);
|
||||
|
||||
if !default_relay {
|
||||
relay.unsubscribe_all().await?;
|
||||
relay.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
|
||||
/// Set the signer for the nostr client and verify the public key
|
||||
@@ -308,6 +323,9 @@ impl NostrRegistry {
|
||||
// Update signer
|
||||
signer.switch(new, owned).await;
|
||||
|
||||
// Unsubscribe from all subscriptions
|
||||
client.unsubscribe_all().await?;
|
||||
|
||||
// Verify signer
|
||||
let signer = client.signer().context("Signer not found")?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
@@ -322,7 +340,7 @@ impl NostrRegistry {
|
||||
|
||||
// Update states
|
||||
this.update(cx, |this, cx| {
|
||||
this.reset_relay_states(cx);
|
||||
this.reset_relays(cx);
|
||||
this.get_relay_list(cx);
|
||||
})?;
|
||||
|
||||
@@ -365,8 +383,6 @@ impl NostrRegistry {
|
||||
while let Some((_url, res)) = stream.next().await {
|
||||
match res {
|
||||
Ok(event) => {
|
||||
log::info!("Received relay list event: {event:?}");
|
||||
|
||||
// Construct a filter to continuously receive relay list events
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::RelayList)
|
||||
@@ -382,7 +398,7 @@ impl NostrRegistry {
|
||||
// Subscribe to the relay list events
|
||||
client.subscribe(target).await?;
|
||||
|
||||
return Ok(RelayState::Configured);
|
||||
return Ok(RelayState::Configured(Box::new(event)));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to receive relay list event: {e}");
|
||||
@@ -443,8 +459,6 @@ impl NostrRegistry {
|
||||
while let Some((_url, res)) = stream.next().await {
|
||||
match res {
|
||||
Ok(event) => {
|
||||
log::info!("Received messaging relays event: {event:?}");
|
||||
|
||||
// Construct a filter to continuously receive relay list events
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::InboxRelays)
|
||||
@@ -454,7 +468,7 @@ impl NostrRegistry {
|
||||
// Subscribe to the relay list events
|
||||
client.subscribe(filter).await?;
|
||||
|
||||
return Ok(RelayState::Configured);
|
||||
return Ok(RelayState::Configured(Box::new(event)));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to get messaging relays: {e}");
|
||||
@@ -485,24 +499,33 @@ impl NostrRegistry {
|
||||
}
|
||||
|
||||
/// Continuously get gift wrap events for the current user in their messaging relays
|
||||
fn get_messages(&mut self, cx: &mut Context<Self>) {
|
||||
fn subscribe_to_giftwrap_events(&mut self, relay_list: &Event, cx: &mut Context<Self>) {
|
||||
let client = self.client();
|
||||
let signer = self.signer();
|
||||
let messaging_relays = self.messaging_relays(cx);
|
||||
let relay_urls: Vec<RelayUrl> = nip17::extract_relay_list(relay_list).cloned().collect();
|
||||
|
||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||
let urls = messaging_relays.await;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
|
||||
for url in relay_urls.iter() {
|
||||
client.add_relay(url).and_connect().await?;
|
||||
}
|
||||
|
||||
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(public_key);
|
||||
let id = SubscriptionId::new(USER_GIFTWRAP);
|
||||
|
||||
// Construct target for subscription
|
||||
let target: HashMap<&RelayUrl, Filter> =
|
||||
urls.iter().map(|relay| (relay, filter.clone())).collect();
|
||||
let target: HashMap<&RelayUrl, Filter> = relay_urls
|
||||
.iter()
|
||||
.map(|relay| (relay, filter.clone()))
|
||||
.collect();
|
||||
|
||||
client.subscribe(target).with_id(id).await?;
|
||||
log::info!("Subscribed to user gift-wrap messages");
|
||||
let output = client.subscribe(target).with_id(id).await?;
|
||||
|
||||
log::info!(
|
||||
"Successfully subscribed to user gift-wrap messages on: {:?}",
|
||||
output.success
|
||||
);
|
||||
|
||||
Ok(())
|
||||
});
|
||||
@@ -973,7 +996,7 @@ fn default_relay_list() -> Vec<(RelayUrl, Option<RelayMetadata>)> {
|
||||
Some(RelayMetadata::Write),
|
||||
),
|
||||
(
|
||||
RelayUrl::parse("wss://relay.primal.net/").unwrap(),
|
||||
RelayUrl::parse("wss://relay.damus.io/").unwrap(),
|
||||
Some(RelayMetadata::Read),
|
||||
),
|
||||
(
|
||||
@@ -985,18 +1008,18 @@ fn default_relay_list() -> Vec<(RelayUrl, Option<RelayMetadata>)> {
|
||||
|
||||
fn default_messaging_relays() -> Vec<RelayUrl> {
|
||||
vec![
|
||||
RelayUrl::parse("wss://auth.nostr1.com/").unwrap(),
|
||||
//RelayUrl::parse("wss://auth.nostr1.com/").unwrap(),
|
||||
RelayUrl::parse("wss://nip17.com/").unwrap(),
|
||||
]
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub enum RelayState {
|
||||
#[default]
|
||||
Idle,
|
||||
Checking,
|
||||
NotConfigured,
|
||||
Configured,
|
||||
Configured(Box<Event>),
|
||||
}
|
||||
|
||||
impl RelayState {
|
||||
@@ -1012,8 +1035,11 @@ impl RelayState {
|
||||
matches!(self, RelayState::NotConfigured)
|
||||
}
|
||||
|
||||
pub fn configured(&self) -> bool {
|
||||
matches!(self, RelayState::Configured)
|
||||
pub fn configured(&self) -> Option<&Event> {
|
||||
match self {
|
||||
RelayState::Configured(event) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user