chore: rewrite the backend (not tested) (#203)

* wip: refactor

* refactor

* clean up

* .

* rename

* add relay auth

* .

* .

* optimize

* .

* clean up

* add encryption crate

* .

* .

* .

* .

* .

* add encryption crate

* .

* refactor nip4e

* .

* fix endless loop

* fix metadata fetching
This commit is contained in:
reya
2025-11-11 09:09:33 +07:00
committed by GitHub
parent a1a0a7ecd4
commit 512834b640
68 changed files with 3503 additions and 3194 deletions

View File

@@ -5,12 +5,9 @@ edition.workspace = true
publish.workspace = true
[dependencies]
states = { path = "../states" }
gpui.workspace = true
nostr-connect.workspace = true
nostr-sdk.workspace = true
nostr.workspace = true
anyhow.workspace = true
itertools.workspace = true
chrono.workspace = true
@@ -19,6 +16,8 @@ smol.workspace = true
futures.workspace = true
reqwest.workspace = true
log.workspace = true
webbrowser.workspace = true
dirs = "5.0"
qrcode = "0.14.1"
whoami = "1.6.1"
nostr = { git = "https://github.com/rust-nostr/nostr" }

View File

@@ -0,0 +1,35 @@
pub const CLIENT_NAME: &str = "Coop";
pub const APP_ID: &str = "su.reya.coop";
/// Bootstrap Relays.
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; 1] = ["wss://relay.nostr.band"];
/// 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 RELAY_RETRY: u64 = 2;
/// Default retry count for sending messages
pub const SEND_RETRY: u64 = 10;
/// 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 = 20;
/// Default width of the sidebar.
pub const DEFAULT_SIDEBAR_WIDTH: f32 = 240.;

View File

@@ -2,7 +2,7 @@ use std::sync::Arc;
use anyhow::{anyhow, Error};
use chrono::{Local, TimeZone};
use gpui::{Image, ImageFormat, SharedString, SharedUri};
use gpui::{Image, ImageFormat, SharedString};
use nostr_sdk::prelude::*;
use qrcode::render::svg;
use qrcode::QrCode;
@@ -16,12 +16,12 @@ const FALLBACK_IMG: &str = "https://image.nostr.build/c30703b48f511c293a9003be81
const IMAGE_RESIZE_SERVICE: &str = "https://wsrv.nl";
pub trait RenderedProfile {
fn avatar(&self, proxy: bool) -> SharedUri;
fn avatar(&self, proxy: bool) -> SharedString;
fn display_name(&self) -> SharedString;
}
impl RenderedProfile for Profile {
fn avatar(&self, proxy: bool) -> SharedUri {
fn avatar(&self, proxy: bool) -> SharedString {
self.metadata()
.picture
.as_ref()
@@ -32,12 +32,12 @@ impl RenderedProfile for Profile {
"{IMAGE_RESIZE_SERVICE}/?url={picture}&w=100&h=100&fit=cover&mask=circle&default={FALLBACK_IMG}&n=-1"
);
SharedUri::from(url)
url.into()
} else {
SharedUri::from(picture)
picture.into()
}
})
.unwrap_or_else(|| SharedUri::from("brand/avatar.png"))
.unwrap_or_else(|| "brand/avatar.png".into())
}
fn display_name(&self) -> SharedString {

View File

@@ -48,7 +48,6 @@ impl EventUtils for UnsignedEvent {
fn all_pubkeys(&self) -> Vec<PublicKey> {
let mut public_keys: Vec<PublicKey> = self.tags.public_keys().copied().collect();
public_keys.push(self.pubkey);
public_keys
public_keys.into_iter().unique().sorted().collect()
}
}

View File

@@ -1,5 +1,68 @@
pub mod debounced_delay;
pub mod display;
pub mod event;
pub mod nip05;
pub mod nip96;
use std::sync::OnceLock;
pub use constants::*;
pub use debounced_delay::*;
pub use display::*;
pub use event::*;
pub use nip05::*;
pub use nip96::*;
use nostr_sdk::prelude::*;
pub use paths::*;
mod constants;
mod debounced_delay;
mod display;
mod event;
mod nip05;
mod nip96;
mod paths;
static APP_NAME: OnceLock<String> = OnceLock::new();
static NIP65_RELAYS: OnceLock<Vec<(RelayUrl, Option<RelayMetadata>)>> = OnceLock::new();
static NIP17_RELAYS: OnceLock<Vec<RelayUrl>> = OnceLock::new();
/// Get the app name
pub fn app_name() -> &'static String {
APP_NAME.get_or_init(|| {
let devicename = whoami::devicename();
let platform = whoami::platform();
format!("{CLIENT_NAME} on {platform} ({devicename})")
})
}
/// Default NIP-65 Relays. Used for new account
pub fn default_nip65_relays() -> &'static Vec<(RelayUrl, Option<RelayMetadata>)> {
NIP65_RELAYS.get_or_init(|| {
vec![
(
RelayUrl::parse("wss://nostr.mom").unwrap(),
Some(RelayMetadata::Read),
),
(
RelayUrl::parse("wss://nostr.bitcoiner.social").unwrap(),
Some(RelayMetadata::Read),
),
(
RelayUrl::parse("wss://nostr.oxtr.dev").unwrap(),
Some(RelayMetadata::Write),
),
(
RelayUrl::parse("wss://nostr.fmt.wiz.biz").unwrap(),
Some(RelayMetadata::Write),
),
(RelayUrl::parse("wss://relay.primal.net").unwrap(), None),
(RelayUrl::parse("wss://relay.damus.io").unwrap(), None),
]
})
}
/// Default NIP-17 Relays. Used for new account
pub fn default_nip17_relays() -> &'static Vec<RelayUrl> {
NIP17_RELAYS.get_or_init(|| {
vec![
RelayUrl::parse("wss://nip17.com").unwrap(),
RelayUrl::parse("wss://auth.nostr1.com").unwrap(),
]
})
}

View File

@@ -0,0 +1,64 @@
use std::path::PathBuf;
use std::sync::OnceLock;
/// Returns the path to the user's home directory.
pub fn home_dir() -> &'static PathBuf {
static HOME_DIR: OnceLock<PathBuf> = OnceLock::new();
HOME_DIR.get_or_init(|| dirs::home_dir().expect("failed to determine home directory"))
}
/// Returns the path to the configuration directory used by Coop.
pub fn config_dir() -> &'static PathBuf {
static CONFIG_DIR: OnceLock<PathBuf> = OnceLock::new();
CONFIG_DIR.get_or_init(|| {
if cfg!(target_os = "windows") {
return dirs::config_dir()
.expect("failed to determine RoamingAppData directory")
.join("Coop");
}
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
return if let Ok(flatpak_xdg_config) = std::env::var("FLATPAK_XDG_CONFIG_HOME") {
flatpak_xdg_config.into()
} else {
dirs::config_dir().expect("failed to determine XDG_CONFIG_HOME directory")
}
.join("coop");
}
home_dir().join(".config").join("coop")
})
}
/// Returns the path to the support directory used by Coop.
pub fn support_dir() -> &'static PathBuf {
static SUPPORT_DIR: OnceLock<PathBuf> = OnceLock::new();
SUPPORT_DIR.get_or_init(|| {
if cfg!(target_os = "macos") {
return home_dir().join("Library/Application Support/Coop");
}
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
return if let Ok(flatpak_xdg_data) = std::env::var("FLATPAK_XDG_DATA_HOME") {
flatpak_xdg_data.into()
} else {
dirs::data_local_dir().expect("failed to determine XDG_DATA_HOME directory")
}
.join("coop");
}
if cfg!(target_os = "windows") {
return dirs::data_local_dir()
.expect("failed to determine LocalAppData directory")
.join("coop");
}
config_dir().clone()
})
}
/// Returns the path to the `nostr` file.
pub fn nostr_file() -> &'static PathBuf {
static NOSTR_FILE: OnceLock<PathBuf> = OnceLock::new();
NOSTR_FILE.get_or_init(|| support_dir().join("nostr-db"))
}