set default data for newly created identity
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m31s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m21s
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m31s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m21s
This commit is contained in:
60
crates/state/src/constants.rs
Normal file
60
crates/state/src/constants.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use std::sync::OnceLock;
|
||||
|
||||
/// Client name (Application name)
|
||||
pub const CLIENT_NAME: &str = "Coop";
|
||||
|
||||
/// COOP's public key
|
||||
pub const COOP_PUBKEY: &str = "npub126kl5fruqan90py77gf6pvfvygefl2mu2ukew6xdx5pc5uqscwgsnkgarv";
|
||||
|
||||
/// App ID
|
||||
pub const APP_ID: &str = "su.reya.coop";
|
||||
|
||||
/// Keyring name
|
||||
pub const KEYRING: &str = "Coop Secret Storage";
|
||||
|
||||
/// Default timeout for subscription
|
||||
pub const TIMEOUT: u64 = 3;
|
||||
|
||||
/// Default delay for searching
|
||||
pub const FIND_DELAY: u64 = 600;
|
||||
|
||||
/// Default limit for searching
|
||||
pub const FIND_LIMIT: usize = 20;
|
||||
|
||||
/// Default timeout for Nostr Connect
|
||||
pub const NOSTR_CONNECT_TIMEOUT: u64 = 200;
|
||||
|
||||
/// Default Nostr Connect relay
|
||||
pub const NOSTR_CONNECT_RELAY: &str = "wss://relay.nsec.app";
|
||||
|
||||
/// Default subscription id for device gift wrap events
|
||||
pub const DEVICE_GIFTWRAP: &str = "device-gift-wraps";
|
||||
|
||||
/// Default subscription id for user gift wrap events
|
||||
pub const USER_GIFTWRAP: &str = "user-gift-wraps";
|
||||
|
||||
/// Default vertex relays
|
||||
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"];
|
||||
|
||||
/// Default bootstrap relays
|
||||
pub const BOOTSTRAP_RELAYS: [&str; 4] = [
|
||||
"wss://relay.damus.io",
|
||||
"wss://relay.primal.net",
|
||||
"wss://relay.nos.social",
|
||||
"wss://user.kindpag.es",
|
||||
];
|
||||
|
||||
static APP_NAME: OnceLock<String> = 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})")
|
||||
})
|
||||
}
|
||||
@@ -4,53 +4,25 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{anyhow, Context as AnyhowContext, Error};
|
||||
use common::{config_dir, CLIENT_NAME};
|
||||
use common::config_dir;
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Task};
|
||||
use nostr_connect::prelude::*;
|
||||
use nostr_gossip_memory::prelude::*;
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_sdk::prelude::*;
|
||||
|
||||
mod constants;
|
||||
mod device;
|
||||
mod event;
|
||||
mod gossip;
|
||||
mod nip05;
|
||||
mod signer;
|
||||
|
||||
pub use constants::*;
|
||||
pub use device::*;
|
||||
pub use event::*;
|
||||
pub use gossip::*;
|
||||
pub use nip05::*;
|
||||
pub use signer::*;
|
||||
|
||||
/// Default timeout for subscription
|
||||
pub const TIMEOUT: u64 = 3;
|
||||
/// Default delay for searching
|
||||
pub const FIND_DELAY: u64 = 600;
|
||||
/// Default limit for searching
|
||||
pub const FIND_LIMIT: usize = 20;
|
||||
/// Default timeout for Nostr Connect
|
||||
pub const NOSTR_CONNECT_TIMEOUT: u64 = 200;
|
||||
/// Default Nostr Connect relay
|
||||
pub const NOSTR_CONNECT_RELAY: &str = "wss://relay.nsec.app";
|
||||
/// Default subscription id for device gift wrap events
|
||||
pub const DEVICE_GIFTWRAP: &str = "device-gift-wraps";
|
||||
/// Default subscription id for user gift wrap events
|
||||
pub const USER_GIFTWRAP: &str = "user-gift-wraps";
|
||||
/// Default avatar for new users
|
||||
pub const DEFAULT_AVATAR: &str = "https://image.nostr.build/93bb6084457a42620849b6827f3f34f111ae5a4ac728638a989d4ed4b4bb3ac8.png";
|
||||
/// Default vertex relays
|
||||
pub const WOT_RELAYS: [&str; 1] = ["wss://relay.vertexlab.io"];
|
||||
/// Default search relays
|
||||
pub const SEARCH_RELAYS: [&str; 2] = ["wss://search.nos.today", "wss://relay.noswhere.com"];
|
||||
/// Default bootstrap relays
|
||||
pub const BOOTSTRAP_RELAYS: [&str; 4] = [
|
||||
"wss://relay.damus.io",
|
||||
"wss://relay.primal.net",
|
||||
"wss://relay.nos.social",
|
||||
"wss://user.kindpag.es",
|
||||
];
|
||||
|
||||
pub fn init(cx: &mut App) {
|
||||
// rustls uses the `aws_lc_rs` provider by default
|
||||
// This only errors if the default provider has already
|
||||
@@ -626,8 +598,8 @@ impl NostrRegistry {
|
||||
let builder = EventBuilder::metadata(&metadata);
|
||||
let event = client.sign_event_builder(builder).await?;
|
||||
|
||||
// Send event to user's write relayss
|
||||
client.send_event(&event).to_nip65().await?;
|
||||
// Send event to user's relays
|
||||
client.send_event(&event).await?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
@@ -635,7 +607,7 @@ impl NostrRegistry {
|
||||
|
||||
/// Get local stored identity
|
||||
fn get_identity(&mut self, cx: &mut Context<Self>) {
|
||||
let read_credential = cx.read_credentials(CLIENT_NAME);
|
||||
let read_credential = cx.read_credentials(KEYRING);
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
match read_credential.await {
|
||||
@@ -662,42 +634,72 @@ impl NostrRegistry {
|
||||
|
||||
/// Create a new identity
|
||||
fn create_identity(&mut self, cx: &mut Context<Self>) {
|
||||
let client = self.client();
|
||||
let keys = Keys::generate();
|
||||
let async_keys = keys.clone();
|
||||
|
||||
// Get write credential task
|
||||
let write_credential = cx.write_credentials(
|
||||
CLIENT_NAME,
|
||||
KEYRING,
|
||||
&keys.public_key().to_hex(),
|
||||
&keys.secret_key().to_secret_bytes(),
|
||||
);
|
||||
|
||||
// Update the signer
|
||||
self.set_signer(keys, false, cx);
|
||||
// Run async tasks in background
|
||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||
// Build and sign the relay list event
|
||||
let relay_list = default_relay_list();
|
||||
let event = EventBuilder::relay_list(relay_list)
|
||||
.sign(&async_keys)
|
||||
.await?;
|
||||
|
||||
// Generate a unique name and avatar for the identity
|
||||
let name = petname::petname(2, "-").unwrap_or("Cooper".to_string());
|
||||
let avatar = Url::parse(DEFAULT_AVATAR).unwrap();
|
||||
// Publish relay list event
|
||||
client.send_event(&event).await?;
|
||||
|
||||
// Construct metadata for the identity
|
||||
let metadata = Metadata::new()
|
||||
.display_name(&name)
|
||||
.name(&name)
|
||||
.picture(avatar);
|
||||
// Build and sign the metadata event
|
||||
let name = petname::petname(2, "-").unwrap_or("Cooper".to_string());
|
||||
let avatar = Url::parse(&format!("https://avatar.vercel.sh/{name}")).unwrap();
|
||||
let metadata = Metadata::new().display_name(&name).picture(avatar);
|
||||
let event = EventBuilder::metadata(&metadata).sign(&async_keys).await?;
|
||||
|
||||
// Update user's metadata
|
||||
let task = self.set_metadata(&metadata, cx);
|
||||
// Publish metadata event
|
||||
client.send_event(&event).await?;
|
||||
|
||||
// Spawn a task to write the credentials
|
||||
cx.background_spawn(async move {
|
||||
if let Err(e) = task.await {
|
||||
log::error!("Failed to update metadata: {}", e);
|
||||
}
|
||||
// Build and sign the contact list event
|
||||
let contacts = vec![Contact::new(PublicKey::parse(COOP_PUBKEY).unwrap())];
|
||||
let event = EventBuilder::contact_list(contacts)
|
||||
.sign(&async_keys)
|
||||
.await?;
|
||||
|
||||
if let Err(e) = write_credential.await {
|
||||
log::error!("Failed to write credentials: {}", e);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
// Publish contact list event
|
||||
client.send_event(&event).await?;
|
||||
|
||||
// Build and sign the messaging relay list event
|
||||
let relays = default_messaging_relays();
|
||||
let event = EventBuilder::nip17_relay_list(relays)
|
||||
.sign(&async_keys)
|
||||
.await?;
|
||||
|
||||
// Publish messaging relay list event
|
||||
client.send_event(&event).await?;
|
||||
|
||||
// Write user's credentials to the system keyring
|
||||
write_credential.await?;
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
// Wait for the task to complete
|
||||
task.await?;
|
||||
|
||||
// Update the signer
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_signer(keys, false, cx);
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
|
||||
/// Get local stored bunker connection
|
||||
@@ -922,6 +924,34 @@ impl NostrRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
fn default_relay_list() -> Vec<(RelayUrl, Option<RelayMetadata>)> {
|
||||
vec![
|
||||
(
|
||||
RelayUrl::parse("wss://relay.gulugulu.moe").unwrap(),
|
||||
Some(RelayMetadata::Write),
|
||||
),
|
||||
(
|
||||
RelayUrl::parse("wss://relay.primal.net/").unwrap(),
|
||||
Some(RelayMetadata::Write),
|
||||
),
|
||||
(
|
||||
RelayUrl::parse("wss://relay.primal.net/").unwrap(),
|
||||
Some(RelayMetadata::Read),
|
||||
),
|
||||
(
|
||||
RelayUrl::parse("wss://nos.lol/").unwrap(),
|
||||
Some(RelayMetadata::Read),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
fn default_messaging_relays() -> Vec<RelayUrl> {
|
||||
vec![
|
||||
RelayUrl::parse("wss://auth.nostr1.com/").unwrap(),
|
||||
RelayUrl::parse("wss://nip17.com/").unwrap(),
|
||||
]
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum RelayState {
|
||||
#[default]
|
||||
|
||||
Reference in New Issue
Block a user