.
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m50s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m40s
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build (macos-latest, stable) (pull_request) Has been cancelled
Rust / build (windows-latest, stable) (pull_request) Has been cancelled
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m50s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m40s
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build (macos-latest, stable) (pull_request) Has been cancelled
Rust / build (windows-latest, stable) (pull_request) Has been cancelled
This commit is contained in:
@@ -122,6 +122,9 @@ impl ChatRegistry {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load rooms on every state change
|
||||||
|
this.get_rooms(cx);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -137,13 +140,8 @@ impl ChatRegistry {
|
|||||||
|
|
||||||
// Run at the end of the current cycle
|
// Run at the end of the current cycle
|
||||||
cx.defer_in(window, |this, _window, cx| {
|
cx.defer_in(window, |this, _window, cx| {
|
||||||
// Load chat rooms
|
|
||||||
this.get_rooms(cx);
|
this.get_rooms(cx);
|
||||||
|
|
||||||
// Handle nostr notifications
|
|
||||||
this.handle_notifications(cx);
|
this.handle_notifications(cx);
|
||||||
|
|
||||||
// Track unwrap gift wrap progress
|
|
||||||
this.tracking(cx);
|
this.tracking(cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -248,7 +246,7 @@ impl ChatRegistry {
|
|||||||
let status = self.tracking_flag.clone();
|
let status = self.tracking_flag.clone();
|
||||||
|
|
||||||
self.tasks.push(cx.background_spawn(async move {
|
self.tasks.push(cx.background_spawn(async move {
|
||||||
let loop_duration = Duration::from_secs(10);
|
let loop_duration = Duration::from_secs(15);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if status.load(Ordering::Acquire) {
|
if status.load(Ordering::Acquire) {
|
||||||
|
|||||||
@@ -336,68 +336,65 @@ impl Room {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let client = nostr.read(cx).client();
|
let client = nostr.read(cx).client();
|
||||||
let write_relays = nostr.read(cx).write_relays(&member, cx);
|
let ensure_write_relays = nostr.read(cx).ensure_write_relays(&member, cx);
|
||||||
|
|
||||||
tasks.insert(
|
let task = cx.background_spawn(async move {
|
||||||
member,
|
let mut has_inbox = false;
|
||||||
cx.background_spawn(async move {
|
let mut has_announcement = false;
|
||||||
let urls = write_relays.await;
|
|
||||||
|
|
||||||
// Return if no relays are available
|
// Get user's write relays
|
||||||
if urls.is_empty() {
|
let urls = ensure_write_relays.await;
|
||||||
return Err(anyhow!(
|
|
||||||
"User has not set up any relays. You cannot send messages to them."
|
// Return if no relays are available
|
||||||
));
|
if urls.is_empty() {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"User has not set up any relays. You cannot send messages to them."
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct filters for inbox relays
|
||||||
|
let inbox = Filter::new()
|
||||||
|
.kind(Kind::InboxRelays)
|
||||||
|
.author(member)
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
// Construct filters for announcement
|
||||||
|
let announcement = Filter::new()
|
||||||
|
.kind(Kind::Custom(10044))
|
||||||
|
.author(member)
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
// Create subscription targets
|
||||||
|
let target: HashMap<RelayUrl, Vec<Filter>> = urls
|
||||||
|
.into_iter()
|
||||||
|
.map(|relay| (relay, vec![inbox.clone(), announcement.clone()]))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Stream events from user's write relays
|
||||||
|
let mut stream = client
|
||||||
|
.stream_events(target)
|
||||||
|
.timeout(Duration::from_secs(TIMEOUT))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
while let Some((_url, res)) = stream.next().await {
|
||||||
|
let event = res?;
|
||||||
|
|
||||||
|
match event.kind {
|
||||||
|
Kind::InboxRelays => has_inbox = true,
|
||||||
|
Kind::Custom(10044) => has_announcement = true,
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct filters for inbox and announcement
|
// Early exit if both flags are found
|
||||||
let inbox_filter = Filter::new()
|
if has_inbox && has_announcement {
|
||||||
.kind(Kind::InboxRelays)
|
break;
|
||||||
.author(member)
|
|
||||||
.limit(1);
|
|
||||||
let announcement_filter = Filter::new()
|
|
||||||
.kind(Kind::Custom(10044))
|
|
||||||
.author(member)
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
// Create subscription targets
|
|
||||||
let target = urls
|
|
||||||
.into_iter()
|
|
||||||
.map(|relay| {
|
|
||||||
(
|
|
||||||
relay,
|
|
||||||
vec![inbox_filter.clone(), announcement_filter.clone()],
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<HashMap<_, _>>();
|
|
||||||
|
|
||||||
// Stream events from user's write relays
|
|
||||||
let mut stream = client
|
|
||||||
.stream_events(target)
|
|
||||||
.timeout(Duration::from_secs(TIMEOUT))
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let mut has_inbox = false;
|
|
||||||
let mut has_announcement = false;
|
|
||||||
|
|
||||||
while let Some((_url, res)) = stream.next().await {
|
|
||||||
let event = res?;
|
|
||||||
|
|
||||||
match event.kind {
|
|
||||||
Kind::InboxRelays => has_inbox = true,
|
|
||||||
Kind::Custom(10044) => has_announcement = true,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Early exit if both flags are found
|
|
||||||
if has_inbox && has_announcement {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok((has_inbox, has_announcement))
|
Ok((has_inbox, has_announcement))
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
|
tasks.insert(member, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks
|
tasks
|
||||||
|
|||||||
@@ -79,16 +79,14 @@ fn main() {
|
|||||||
// Initialize theme registry
|
// Initialize theme registry
|
||||||
theme::init(cx);
|
theme::init(cx);
|
||||||
|
|
||||||
|
// Initialize settings
|
||||||
|
settings::init(window, cx);
|
||||||
|
|
||||||
// Initialize the nostr client
|
// Initialize the nostr client
|
||||||
state::init(window, cx);
|
state::init(window, cx);
|
||||||
|
|
||||||
// Initialize device signer
|
// Initialize person registry
|
||||||
//
|
person::init(cx);
|
||||||
// NIP-4e: https://github.com/nostr-protocol/nips/blob/per-device-keys/4e.md
|
|
||||||
device::init(window, cx);
|
|
||||||
|
|
||||||
// Initialize settings
|
|
||||||
settings::init(window, cx);
|
|
||||||
|
|
||||||
// Initialize relay auth registry
|
// Initialize relay auth registry
|
||||||
relay_auth::init(window, cx);
|
relay_auth::init(window, cx);
|
||||||
@@ -96,8 +94,10 @@ fn main() {
|
|||||||
// Initialize app registry
|
// Initialize app registry
|
||||||
chat::init(window, cx);
|
chat::init(window, cx);
|
||||||
|
|
||||||
// Initialize person registry
|
// Initialize device signer
|
||||||
person::init(cx);
|
//
|
||||||
|
// NIP-4e: https://github.com/nostr-protocol/nips/blob/per-device-keys/4e.md
|
||||||
|
device::init(window, cx);
|
||||||
|
|
||||||
// Initialize auto update
|
// Initialize auto update
|
||||||
auto_update::init(window, cx);
|
auto_update::init(window, cx);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ pub struct RelayAuth {
|
|||||||
pending_events: HashSet<(EventId, RelayUrl)>,
|
pending_events: HashSet<(EventId, RelayUrl)>,
|
||||||
|
|
||||||
/// Tasks for asynchronous operations
|
/// Tasks for asynchronous operations
|
||||||
tasks: SmallVec<[Task<()>; 2]>,
|
_tasks: SmallVec<[Task<()>; 2]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelayAuth {
|
impl RelayAuth {
|
||||||
@@ -83,26 +83,15 @@ impl RelayAuth {
|
|||||||
|
|
||||||
/// Create a new relay auth instance
|
/// Create a new relay auth instance
|
||||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
cx.defer_in(window, |this, window, cx| {
|
|
||||||
this.handle_notifications(window, cx);
|
|
||||||
});
|
|
||||||
|
|
||||||
Self {
|
|
||||||
pending_events: HashSet::default(),
|
|
||||||
tasks: smallvec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle nostr notifications
|
|
||||||
fn handle_notifications(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
let nostr = NostrRegistry::global(cx);
|
let nostr = NostrRegistry::global(cx);
|
||||||
let client = nostr.read(cx).client();
|
let client = nostr.read(cx).client();
|
||||||
|
|
||||||
|
let mut tasks = smallvec![];
|
||||||
|
|
||||||
// Channel for communication between nostr and gpui
|
// Channel for communication between nostr and gpui
|
||||||
let (tx, rx) = flume::bounded::<Signal>(256);
|
let (tx, rx) = flume::bounded::<Signal>(256);
|
||||||
|
|
||||||
self.tasks.push(cx.background_spawn(async move {
|
tasks.push(cx.background_spawn(async move {
|
||||||
log::info!("Started handling nostr notifications");
|
|
||||||
let mut notifications = client.notifications();
|
let mut notifications = client.notifications();
|
||||||
let mut challenges: HashSet<Cow<'_, str>> = HashSet::default();
|
let mut challenges: HashSet<Cow<'_, str>> = HashSet::default();
|
||||||
|
|
||||||
@@ -117,6 +106,22 @@ impl RelayAuth {
|
|||||||
tx.send_async(signal).await.ok();
|
tx.send_async(signal).await.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RelayMessage::Closed {
|
||||||
|
subscription_id,
|
||||||
|
message,
|
||||||
|
} => {
|
||||||
|
let msg = MachineReadablePrefix::parse(&message);
|
||||||
|
|
||||||
|
if let Some(MachineReadablePrefix::AuthRequired) = msg {
|
||||||
|
if let Ok(Some(relay)) = client.relay(&relay_url).await {
|
||||||
|
// Send close message to relay
|
||||||
|
relay
|
||||||
|
.send_msg(ClientMessage::Close(subscription_id))
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
RelayMessage::Ok {
|
RelayMessage::Ok {
|
||||||
event_id, message, ..
|
event_id, message, ..
|
||||||
} => {
|
} => {
|
||||||
@@ -134,7 +139,7 @@ impl RelayAuth {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.tasks.push(cx.spawn_in(window, async move |this, cx| {
|
tasks.push(cx.spawn_in(window, async move |this, cx| {
|
||||||
while let Ok(signal) = rx.recv_async().await {
|
while let Ok(signal) = rx.recv_async().await {
|
||||||
match signal {
|
match signal {
|
||||||
Signal::Auth(req) => {
|
Signal::Auth(req) => {
|
||||||
@@ -152,6 +157,11 @@ impl RelayAuth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pending_events: HashSet::default(),
|
||||||
|
_tasks: tasks,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a pending event waiting for resend after authentication
|
/// Insert a pending event waiting for resend after authentication
|
||||||
@@ -162,15 +172,12 @@ impl RelayAuth {
|
|||||||
|
|
||||||
/// Get all pending events for a specific relay,
|
/// Get all pending events for a specific relay,
|
||||||
fn get_pending_events(&self, relay: &RelayUrl, _cx: &App) -> Vec<EventId> {
|
fn get_pending_events(&self, relay: &RelayUrl, _cx: &App) -> Vec<EventId> {
|
||||||
let pending_events: Vec<EventId> = self
|
self.pending_events
|
||||||
.pending_events
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, pending_relay)| pending_relay == relay)
|
.filter(|(_, pending_relay)| pending_relay == relay)
|
||||||
.map(|(id, _relay)| id)
|
.map(|(id, _relay)| id)
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect()
|
||||||
|
|
||||||
pending_events
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all pending events for a specific relay,
|
/// Clear all pending events for a specific relay,
|
||||||
@@ -282,10 +289,12 @@ impl RelayAuth {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// Clear pending events for the authenticated relay
|
// Clear pending events for the authenticated relay
|
||||||
this.clear_pending_events(url, cx);
|
this.clear_pending_events(url, cx);
|
||||||
|
|
||||||
// Save the authenticated relay to automatically authenticate future requests
|
// Save the authenticated relay to automatically authenticate future requests
|
||||||
settings.update(cx, |this, cx| {
|
settings.update(cx, |this, cx| {
|
||||||
this.add_trusted_relay(url, cx);
|
this.add_trusted_relay(url, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.push_notification(format!("{} has been authenticated", url), cx);
|
window.push_notification(format!("{} has been authenticated", url), cx);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub const APP_ID: &str = "su.reya.coop";
|
|||||||
pub const KEYRING: &str = "Coop Safe Storage";
|
pub const KEYRING: &str = "Coop Safe Storage";
|
||||||
|
|
||||||
/// Default timeout for subscription
|
/// Default timeout for subscription
|
||||||
pub const TIMEOUT: u64 = 3;
|
pub const TIMEOUT: u64 = 2;
|
||||||
|
|
||||||
/// Default delay for searching
|
/// Default delay for searching
|
||||||
pub const FIND_DELAY: u64 = 600;
|
pub const FIND_DELAY: u64 = 600;
|
||||||
@@ -37,12 +37,13 @@ pub const USER_GIFTWRAP: &str = "user-gift-wraps";
|
|||||||
pub const WOT_RELAYS: [&str; 1] = ["wss://relay.vertexlab.io"];
|
pub const WOT_RELAYS: [&str; 1] = ["wss://relay.vertexlab.io"];
|
||||||
|
|
||||||
/// Default search relays
|
/// Default search relays
|
||||||
pub const SEARCH_RELAYS: [&str; 1] = ["wss://antiprimal.net"];
|
pub const SEARCH_RELAYS: [&str; 2] = ["wss://antiprimal.net", "wss://search.nos.today"];
|
||||||
|
|
||||||
/// Default bootstrap relays
|
/// Default bootstrap relays
|
||||||
pub const BOOTSTRAP_RELAYS: [&str; 3] = [
|
pub const BOOTSTRAP_RELAYS: [&str; 4] = [
|
||||||
"wss://relay.damus.io",
|
|
||||||
"wss://nos.lol",
|
"wss://nos.lol",
|
||||||
|
"wss://relay.damus.io",
|
||||||
|
"wss://relay.primal.net",
|
||||||
"wss://user.kindpag.es",
|
"wss://user.kindpag.es",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -146,10 +146,7 @@ impl NostrRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect to all added relays
|
// Connect to all added relays
|
||||||
client
|
client.connect().and_wait(Duration::from_secs(5)).await;
|
||||||
.connect()
|
|
||||||
.and_wait(Duration::from_secs(TIMEOUT))
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -252,6 +249,63 @@ impl NostrRegistry {
|
|||||||
self.gossip.read(cx).read_only_relays(public_key)
|
self.gossip.read(cx).read_only_relays(public_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure write relays for a given public key
|
||||||
|
pub fn ensure_write_relays(&self, public_key: &PublicKey, cx: &App) -> Task<Vec<RelayUrl>> {
|
||||||
|
let client = self.client();
|
||||||
|
let public_key = *public_key;
|
||||||
|
|
||||||
|
cx.background_spawn(async move {
|
||||||
|
let mut relays = vec![];
|
||||||
|
|
||||||
|
let filter = Filter::new()
|
||||||
|
.kind(Kind::RelayList)
|
||||||
|
.author(public_key)
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
// Construct target for subscription
|
||||||
|
let target: HashMap<&str, Vec<Filter>> = BOOTSTRAP_RELAYS
|
||||||
|
.into_iter()
|
||||||
|
.map(|relay| (relay, vec![filter.clone()]))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if let Ok(mut stream) = client
|
||||||
|
.stream_events(target)
|
||||||
|
.timeout(Duration::from_secs(TIMEOUT))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
while let Some((_url, res)) = stream.next().await {
|
||||||
|
match res {
|
||||||
|
Ok(event) => {
|
||||||
|
// Extract relay urls
|
||||||
|
relays.extend(nip65::extract_owned_relay_list(event).filter_map(
|
||||||
|
|(url, metadata)| {
|
||||||
|
if metadata.is_none() || metadata == Some(RelayMetadata::Write)
|
||||||
|
{
|
||||||
|
Some(url)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
// Ensure connections
|
||||||
|
for url in relays.iter() {
|
||||||
|
client.add_relay(url).and_connect().await.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
return relays;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to receive relay list event: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
relays
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a list of write relays for a given public key
|
/// Get a list of write relays for a given public key
|
||||||
pub fn write_relays(&self, public_key: &PublicKey, cx: &App) -> Task<Vec<RelayUrl>> {
|
pub fn write_relays(&self, public_key: &PublicKey, cx: &App) -> Task<Vec<RelayUrl>> {
|
||||||
let client = self.client();
|
let client = self.client();
|
||||||
@@ -423,7 +477,6 @@ impl NostrRegistry {
|
|||||||
let event = EventBuilder::relay_list(relay_list).sign(&signer).await?;
|
let event = EventBuilder::relay_list(relay_list).sign(&signer).await?;
|
||||||
client
|
client
|
||||||
.send_event(&event)
|
.send_event(&event)
|
||||||
.broadcast()
|
|
||||||
.ok_timeout(Duration::from_secs(TIMEOUT))
|
.ok_timeout(Duration::from_secs(TIMEOUT))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -447,7 +500,6 @@ impl NostrRegistry {
|
|||||||
let event = EventBuilder::contact_list(contacts).sign(&signer).await?;
|
let event = EventBuilder::contact_list(contacts).sign(&signer).await?;
|
||||||
client
|
client
|
||||||
.send_event(&event)
|
.send_event(&event)
|
||||||
.broadcast()
|
|
||||||
.ok_timeout(Duration::from_secs(TIMEOUT))
|
.ok_timeout(Duration::from_secs(TIMEOUT))
|
||||||
.ack_policy(AckPolicy::none())
|
.ack_policy(AckPolicy::none())
|
||||||
.await?;
|
.await?;
|
||||||
@@ -488,9 +540,18 @@ impl NostrRegistry {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the state of the relay list
|
||||||
|
fn set_relay_state(&mut self, state: RelayState, cx: &mut Context<Self>) {
|
||||||
|
self.relay_list_state = state;
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ensure_relay_list(&mut self, cx: &mut Context<Self>) {
|
pub fn ensure_relay_list(&mut self, cx: &mut Context<Self>) {
|
||||||
let task = self.verify_relay_list(cx);
|
let task = self.verify_relay_list(cx);
|
||||||
|
|
||||||
|
// Set the state to idle before starting the task
|
||||||
|
self.set_relay_state(RelayState::default(), cx);
|
||||||
|
|
||||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||||
let result = task.await?;
|
let result = task.await?;
|
||||||
|
|
||||||
@@ -517,9 +578,15 @@ impl NostrRegistry {
|
|||||||
.author(public_key)
|
.author(public_key)
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
|
// Construct target for subscription
|
||||||
|
let target: HashMap<&str, Vec<Filter>> = BOOTSTRAP_RELAYS
|
||||||
|
.into_iter()
|
||||||
|
.map(|relay| (relay, vec![filter.clone()]))
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Stream events from the bootstrap relays
|
// Stream events from the bootstrap relays
|
||||||
let mut stream = client
|
let mut stream = client
|
||||||
.stream_events(filter)
|
.stream_events(target)
|
||||||
.timeout(Duration::from_secs(TIMEOUT))
|
.timeout(Duration::from_secs(TIMEOUT))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -601,10 +668,10 @@ impl NostrRegistry {
|
|||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
// Construct target for subscription
|
// Construct target for subscription
|
||||||
let target = BOOTSTRAP_RELAYS
|
let target: HashMap<&str, Vec<Filter>> = BOOTSTRAP_RELAYS
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|relay| (relay, vec![filter.clone()]))
|
.map(|relay| (relay, vec![filter.clone()]))
|
||||||
.collect::<HashMap<_, _>>();
|
.collect();
|
||||||
|
|
||||||
client.subscribe(target).close_on(opts).await?;
|
client.subscribe(target).close_on(opts).await?;
|
||||||
|
|
||||||
@@ -648,10 +715,10 @@ impl NostrRegistry {
|
|||||||
.limit(FIND_LIMIT);
|
.limit(FIND_LIMIT);
|
||||||
|
|
||||||
// Construct target for subscription
|
// Construct target for subscription
|
||||||
let target = SEARCH_RELAYS
|
let target: HashMap<&str, Vec<Filter>> = SEARCH_RELAYS
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|relay| (relay, vec![filter.clone()]))
|
.map(|relay| (relay, vec![filter.clone()]))
|
||||||
.collect::<HashMap<_, _>>();
|
.collect();
|
||||||
|
|
||||||
// Stream events from the search relays
|
// Stream events from the search relays
|
||||||
let mut stream = client
|
let mut stream = client
|
||||||
@@ -784,6 +851,10 @@ fn default_relay_list() -> Vec<(RelayUrl, Option<RelayMetadata>)> {
|
|||||||
RelayUrl::parse("wss://nos.lol").unwrap(),
|
RelayUrl::parse("wss://nos.lol").unwrap(),
|
||||||
Some(RelayMetadata::Read),
|
Some(RelayMetadata::Read),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
RelayUrl::parse("wss://nostr.superfriends.online").unwrap(),
|
||||||
|
None,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,6 +862,7 @@ fn default_messaging_relays() -> Vec<RelayUrl> {
|
|||||||
vec![
|
vec![
|
||||||
RelayUrl::parse("wss://nos.lol").unwrap(),
|
RelayUrl::parse("wss://nos.lol").unwrap(),
|
||||||
RelayUrl::parse("wss://nip17.com").unwrap(),
|
RelayUrl::parse("wss://nip17.com").unwrap(),
|
||||||
|
RelayUrl::parse("wss://relay.0xchat.com").unwrap(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user