feat: manually handle NIP-42 auth request (#132)
* improve fetch relays * . * . * . * refactor * refactor * remove identity * manually auth * auth * prevent duplicate message * clean up
This commit is contained in:
@@ -8,15 +8,16 @@ pub const ACCOUNT_IDENTIFIER: &str = "coop:user";
|
||||
pub const SETTINGS_D: &str = "coop:settings";
|
||||
|
||||
/// Bootstrap Relays.
|
||||
pub const BOOTSTRAP_RELAYS: [&str; 4] = [
|
||||
pub const BOOTSTRAP_RELAYS: [&str; 5] = [
|
||||
"wss://relay.damus.io",
|
||||
"wss://relay.primal.net",
|
||||
"wss://relay.nos.social",
|
||||
"wss://user.kindpag.es",
|
||||
"wss://purplepag.es",
|
||||
];
|
||||
|
||||
/// Search Relays.
|
||||
pub const SEARCH_RELAYS: [&str; 2] = ["wss://search.nos.today", "wss://relay.nostr.band"];
|
||||
pub const SEARCH_RELAYS: [&str; 1] = ["wss://relay.nostr.band"];
|
||||
|
||||
/// NIP65 Relays. Used for new account
|
||||
pub const NIP65_RELAYS: [&str; 4] = [
|
||||
@@ -27,14 +28,20 @@ pub const NIP65_RELAYS: [&str; 4] = [
|
||||
];
|
||||
|
||||
/// Messaging Relays. Used for new account
|
||||
pub const NIP17_RELAYS: [&str; 2] = ["wss://nip17.com", "wss://relay.0xchat.com"];
|
||||
pub const NIP17_RELAYS: [&str; 2] = ["wss://nip17.com", "wss://auth.nostr1.com"];
|
||||
|
||||
/// Default relay for Nostr Connect
|
||||
pub const NOSTR_CONNECT_RELAY: &str = "wss://relay.nsec.app";
|
||||
|
||||
/// Default retry count for fetching NIP-17 relays
|
||||
pub const TOTAL_RETRY: u64 = 2;
|
||||
|
||||
/// Default timeout (in seconds) for Nostr Connect
|
||||
pub const NOSTR_CONNECT_TIMEOUT: u64 = 200;
|
||||
|
||||
/// Default timeout (in seconds) for Nostr Connect (Bunker)
|
||||
pub const BUNKER_TIMEOUT: u64 = 30;
|
||||
|
||||
/// Total metadata requests will be grouped.
|
||||
pub const METADATA_BATCH_LIMIT: usize = 100;
|
||||
|
||||
@@ -44,9 +51,6 @@ pub const METADATA_BATCH_TIMEOUT: u64 = 300;
|
||||
/// Maximum timeout for waiting for finish (seconds)
|
||||
pub const WAIT_FOR_FINISH: u64 = 60;
|
||||
|
||||
/// Default width for all modals.
|
||||
pub const DEFAULT_MODAL_WIDTH: f32 = 420.;
|
||||
|
||||
/// Default width of the sidebar.
|
||||
pub const DEFAULT_SIDEBAR_WIDTH: f32 = 240.;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -13,41 +12,109 @@ use crate::paths::support_dir;
|
||||
pub mod constants;
|
||||
pub mod paths;
|
||||
|
||||
/// Signals sent through the global event channel to notify UI components
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AuthReq {
|
||||
pub challenge: String,
|
||||
pub url: RelayUrl,
|
||||
}
|
||||
|
||||
impl AuthReq {
|
||||
pub fn new(challenge: impl Into<String>, url: RelayUrl) -> Self {
|
||||
Self {
|
||||
challenge: challenge.into(),
|
||||
url,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Notice {
|
||||
RelayFailed(RelayUrl),
|
||||
AuthFailed(RelayUrl),
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl Notice {
|
||||
pub fn as_str(&self) -> String {
|
||||
match self {
|
||||
Notice::AuthFailed(url) => format!("Authenticate failed for relay {url}"),
|
||||
Notice::RelayFailed(url) => format!("Failed to connect the relay {url}"),
|
||||
Notice::Custom(msg) => msg.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Signals sent through the global event channel to notify UI
|
||||
#[derive(Debug)]
|
||||
pub enum NostrSignal {
|
||||
/// Signer has been set
|
||||
pub enum IngesterSignal {
|
||||
/// A signal to notify UI that the client's signer has been set
|
||||
SignerSet(PublicKey),
|
||||
|
||||
/// Signer has been unset
|
||||
/// A signal to notify UI that the client's signer has been unset
|
||||
SignerUnset,
|
||||
|
||||
/// Browser Signer Proxy service is not running
|
||||
/// A signal to notify UI that the relay requires authentication
|
||||
Auth(AuthReq),
|
||||
|
||||
/// A signal to notify UI that the browser proxy service is down
|
||||
ProxyDown,
|
||||
|
||||
/// Received a new metadata event from Relay Pool
|
||||
/// A signal to notify UI that a new metadata event has been received
|
||||
Metadata(Event),
|
||||
|
||||
/// Received a new gift wrap event from Relay Pool
|
||||
GiftWrap(Event),
|
||||
/// A signal to notify UI that a new gift wrap event has been received
|
||||
GiftWrap((EventId, Event)),
|
||||
|
||||
/// Finished processing all gift wrap events
|
||||
/// A signal to notify UI that all gift wrap events have been processed
|
||||
Finish,
|
||||
|
||||
/// Partially finished processing all gift wrap events
|
||||
/// A signal to notify UI that partial processing of gift wrap events has been completed
|
||||
PartialFinish,
|
||||
|
||||
/// DM relays have been found
|
||||
DmRelaysFound,
|
||||
/// A signal to notify UI that no DM relay for current user was found
|
||||
DmRelayNotFound,
|
||||
|
||||
/// Notice from Relay Pool
|
||||
Notice(String),
|
||||
/// A signal to notify UI that there are errors or notices occurred
|
||||
Notice(Notice),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Ingester {
|
||||
rx: Receiver<IngesterSignal>,
|
||||
tx: Sender<IngesterSignal>,
|
||||
}
|
||||
|
||||
impl Default for Ingester {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Ingester {
|
||||
pub fn new() -> Self {
|
||||
let (tx, rx) = smol::channel::bounded::<IngesterSignal>(2048);
|
||||
Self { rx, tx }
|
||||
}
|
||||
|
||||
pub fn signals(&self) -> &Receiver<IngesterSignal> {
|
||||
&self.rx
|
||||
}
|
||||
|
||||
pub async fn send(&self, signal: IngesterSignal) {
|
||||
if let Err(e) = self.tx.send(signal).await {
|
||||
log::error!("Failed to send signal: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static NOSTR_CLIENT: OnceLock<Client> = OnceLock::new();
|
||||
static GLOBAL_CHANNEL: OnceLock<(Sender<NostrSignal>, Receiver<NostrSignal>)> = OnceLock::new();
|
||||
static PROCESSED_EVENTS: OnceLock<RwLock<BTreeSet<EventId>>> = OnceLock::new();
|
||||
|
||||
static INGESTER: OnceLock<Ingester> = OnceLock::new();
|
||||
|
||||
static SENT_IDS: OnceLock<RwLock<Vec<EventId>>> = OnceLock::new();
|
||||
|
||||
static CURRENT_TIMESTAMP: OnceLock<Timestamp> = OnceLock::new();
|
||||
|
||||
static FIRST_RUN: OnceLock<bool> = OnceLock::new();
|
||||
|
||||
pub fn nostr_client() -> &'static Client {
|
||||
@@ -63,7 +130,7 @@ pub fn nostr_client() -> &'static Client {
|
||||
|
||||
let opts = ClientOptions::new()
|
||||
.gossip(true)
|
||||
.automatic_authentication(true)
|
||||
.automatic_authentication(false)
|
||||
.verify_subscriptions(false)
|
||||
// Sleep after idle for 30 seconds
|
||||
.sleep_when_idle(SleepWhenIdle::Enabled {
|
||||
@@ -74,21 +141,18 @@ pub fn nostr_client() -> &'static Client {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn global_channel() -> &'static (Sender<NostrSignal>, Receiver<NostrSignal>) {
|
||||
GLOBAL_CHANNEL.get_or_init(|| {
|
||||
let (sender, receiver) = smol::channel::bounded::<NostrSignal>(2048);
|
||||
(sender, receiver)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn processed_events() -> &'static RwLock<BTreeSet<EventId>> {
|
||||
PROCESSED_EVENTS.get_or_init(|| RwLock::new(BTreeSet::new()))
|
||||
pub fn ingester() -> &'static Ingester {
|
||||
INGESTER.get_or_init(Ingester::new)
|
||||
}
|
||||
|
||||
pub fn starting_time() -> &'static Timestamp {
|
||||
CURRENT_TIMESTAMP.get_or_init(Timestamp::now)
|
||||
}
|
||||
|
||||
pub fn sent_ids() -> &'static RwLock<Vec<EventId>> {
|
||||
SENT_IDS.get_or_init(|| RwLock::new(Vec::new()))
|
||||
}
|
||||
|
||||
pub fn first_run() -> &'static bool {
|
||||
FIRST_RUN.get_or_init(|| {
|
||||
let flag = support_dir().join(format!(".{}-first_run", env!("CARGO_PKG_VERSION")));
|
||||
|
||||
Reference in New Issue
Block a user