Skip to content

Commit

Permalink
gossip: init nostr-gossip
Browse files Browse the repository at this point in the history
  • Loading branch information
yukibtc committed Apr 9, 2024
1 parent 6de5d5b commit 7eefdca
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions crates/nostr-gossip/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "nostr-gossip"
version = "0.29.0"
edition = "2021"
description = "Implementation of gossip protocol for nostr clients."
authors.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true
readme = "README.md"
rust-version.workspace = true
keywords = ["nostr", "gossip"]

[dependencies]
nostr-relay-pool.workspace = true
13 changes: 13 additions & 0 deletions crates/nostr-gossip/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Nostr Gossip

## State

**This library is in an ALPHA state**, things that are implemented generally work but the API will change in breaking ways.

## Donations

`rust-nostr` is free and open-source. This means we do not earn any revenue by selling it. Instead, we rely on your financial support. If you actively use any of the `rust-nostr` libs/software/services, then please [donate](https://rust-nostr.org/donate).

## License

This project is distributed under the MIT software license - see the [LICENSE](../../LICENSE) file for details
7 changes: 7 additions & 0 deletions crates/nostr-gossip/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) 2022-2023 Yuki Kishimoto
// Copyright (c) 2023-2024 Rust Nostr Developers
// Distributed under the MIT software license

//! Constants
pub const DEFAULT_DISCOVERY_RELAYS: [&str; 1] = ["wss://purplepag.es"];
106 changes: 106 additions & 0 deletions crates/nostr-gossip/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2022-2023 Yuki Kishimoto
// Copyright (c) 2023-2024 Rust Nostr Developers
// Distributed under the MIT software license

//! Gossip
use std::ops::Deref;
use std::time::Duration;

use nostr_relay_pool::pool::Error;
use nostr_relay_pool::prelude::*;
use nostr_relay_pool::{FilterOptions, RelayOptions, RelayPool, RelayServiceFlags};

pub mod constants;

/// Gossip client
#[derive(Debug, Clone)]
pub struct NostrGossip {
pool: RelayPool,
}

impl Deref for NostrGossip {
type Target = RelayPool;

fn deref(&self) -> &Self::Target {
&self.pool
}
}

impl NostrGossip {
pub async fn add_discovery_relay<U>(&self, url: U) -> Result<bool, Error>
where
U: TryIntoUrl,
Error: From<<U as TryIntoUrl>::Err>,
{
// Compose flags
let mut flags: RelayServiceFlags = RelayServiceFlags::NONE;
flags.add(RelayServiceFlags::DISCOVERY);

// Compose options
let opts: RelayOptions = RelayOptions::default().flags(flags);

// Add relay
self.pool.add_relay(url, opts).await
}

pub async fn add_inbox_relay<U>(&self, url: U) -> Result<bool, Error>
where
U: TryIntoUrl,
Error: From<<U as TryIntoUrl>::Err>,
{
// Compose flags
let mut flags: RelayServiceFlags = RelayServiceFlags::NONE;
flags.add(RelayServiceFlags::READ);
flags.add(RelayServiceFlags::INBOX);

// Compose options
let opts: RelayOptions = RelayOptions::default().flags(flags);

// Add relay
self.pool.add_relay(url, opts).await
}

pub async fn add_outbox_relay<U>(&self, url: U) -> Result<bool, Error>
where
U: TryIntoUrl,
Error: From<<U as TryIntoUrl>::Err>,
{
// Compose flags
let mut flags: RelayServiceFlags = RelayServiceFlags::NONE;
flags.add(RelayServiceFlags::WRITE);
flags.add(RelayServiceFlags::OUTBOX);

// Compose options
let opts: RelayOptions = RelayOptions::default().flags(flags);

// Add relay
self.pool.add_relay(url, opts).await
}

pub async fn get_relays_for_public_key(
&self,
public_key: PublicKey,
timeout: Duration,
) -> Result<Vec<(UncheckedUrl, Option<RelayMetadata>)>, Error> {
// Get discovery relays
let relays = self
.pool
.relays_with_flag(RelayServiceFlags::DISCOVERY)
.await
.into_keys();

// Get events
let filter: Filter = Filter::default()
.author(public_key)
.kind(Kind::RelayList)
.limit(1);
let events: Vec<Event> = self
.get_events_from(relays, vec![filter], timeout, FilterOptions::ExitOnEOSE)
.await?;

// Extract relay list (NIP65)
let event: &Event = events.first().unwrap(); // TODO: remove unwrap
Ok(nip65::extract_relay_list(&event))
}
}

0 comments on commit 7eefdca

Please sign in to comment.