mirror of
https://github.com/lumehq/lume.git
synced 2025-03-17 21:32:32 +01:00
chore: update deps
This commit is contained in:
parent
4cb49d44c7
commit
beac1a189e
26
package.json
26
package.json
@ -10,7 +10,7 @@
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@getalby/bitcoin-connect-react": "^3.6.1",
|
||||
"@getalby/bitcoin-connect-react": "^3.6.2",
|
||||
"@phosphor-icons/react": "^2.1.7",
|
||||
"@radix-ui/react-avatar": "^1.1.0",
|
||||
"@radix-ui/react-checkbox": "^1.1.1",
|
||||
@ -21,12 +21,12 @@
|
||||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"@tanstack/query-persist-client-core": "^5.51.21",
|
||||
"@tanstack/react-query": "^5.51.23",
|
||||
"@tanstack/react-router": "^1.47.1",
|
||||
"@tauri-apps/api": "2.0.0-rc.0",
|
||||
"@tanstack/react-router": "^1.48.1",
|
||||
"@tauri-apps/api": "2.0.0-rc.1",
|
||||
"@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-dialog": "2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-fs": "2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-http": "2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-fs": "2.0.0-rc.1",
|
||||
"@tauri-apps/plugin-http": "2.0.0-rc.1",
|
||||
"@tauri-apps/plugin-os": "2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-process": "2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-shell": "2.0.0-rc.0",
|
||||
@ -36,7 +36,7 @@
|
||||
"bitcoin-units": "^1.0.0",
|
||||
"dayjs": "^1.11.12",
|
||||
"embla-carousel-react": "^8.1.8",
|
||||
"i18next": "^23.12.2",
|
||||
"i18next": "^23.13.0",
|
||||
"i18next-resources-to-backend": "^1.2.1",
|
||||
"light-bolt11-decoder": "^3.1.1",
|
||||
"minidenticons": "^4.2.1",
|
||||
@ -50,17 +50,17 @@
|
||||
"react-string-replace": "^1.1.1",
|
||||
"slate": "^0.103.0",
|
||||
"slate-react": "^0.107.1",
|
||||
"use-debounce": "^10.0.2",
|
||||
"virtua": "^0.33.5"
|
||||
"use-debounce": "^10.0.3",
|
||||
"virtua": "^0.33.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.8.3",
|
||||
"@evilmartians/harmony": "^1.2.0",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tailwindcss/typography": "^0.5.14",
|
||||
"@tanstack/router-devtools": "^1.47.1",
|
||||
"@tanstack/router-devtools": "^1.48.1",
|
||||
"@tanstack/router-plugin": "^1.47.0",
|
||||
"@tauri-apps/cli": "2.0.0-rc.1",
|
||||
"@tauri-apps/cli": "2.0.0-rc.4",
|
||||
"@types/react": "npm:types-react@19.0.0-rc.1",
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
@ -69,12 +69,12 @@
|
||||
"clsx": "^2.1.1",
|
||||
"postcss": "^8.4.41",
|
||||
"tailwind-gradient-mask-image": "^1.2.0",
|
||||
"tailwind-merge": "^2.5.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwind-scrollbar": "^3.1.0",
|
||||
"tailwindcss": "^3.4.9",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"tailwindcss-content-visibility": "^0.2.0",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.0",
|
||||
"vite": "^5.4.1",
|
||||
"vite-tsconfig-paths": "^5.0.1"
|
||||
},
|
||||
"overrides": {
|
||||
|
474
pnpm-lock.yaml
generated
474
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
782
src-tauri/Cargo.lock
generated
782
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -3443,6 +3443,13 @@
|
||||
"core:webview:allow-create-webview-window"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:allow-get-all-webviews -> Enables the get_all_webviews command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:webview:allow-get-all-webviews"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@ -3527,6 +3534,13 @@
|
||||
"core:webview:deny-create-webview-window"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:deny-get-all-webviews -> Denies the get_all_webviews command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:webview:deny-get-all-webviews"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@ -3653,6 +3667,13 @@
|
||||
"core:window:allow-destroy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:allow-get-all-windows -> Enables the get_all_windows command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:window:allow-get-all-windows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:allow-hide -> Enables the hide command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@ -4108,6 +4129,13 @@
|
||||
"core:window:deny-destroy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:deny-get-all-windows -> Denies the get_all_windows command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:window:deny-get-all-windows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:deny-hide -> Denies the hide command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
|
@ -3443,6 +3443,13 @@
|
||||
"core:webview:allow-create-webview-window"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:allow-get-all-webviews -> Enables the get_all_webviews command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:webview:allow-get-all-webviews"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@ -3527,6 +3534,13 @@
|
||||
"core:webview:deny-create-webview-window"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:deny-get-all-webviews -> Denies the get_all_webviews command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:webview:deny-get-all-webviews"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@ -3653,6 +3667,13 @@
|
||||
"core:window:allow-destroy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:allow-get-all-windows -> Enables the get_all_windows command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:window:allow-get-all-windows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:allow-hide -> Enables the hide command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@ -4108,6 +4129,13 @@
|
||||
"core:window:deny-destroy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:deny-get-all-windows -> Denies the get_all_windows command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"core:window:deny-get-all-windows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "core:window:deny-hide -> Denies the hide command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
|
@ -39,7 +39,10 @@ pub async fn get_event(id: &str, state: State<'_, Nostr>) -> Result<RichEvent, S
|
||||
};
|
||||
|
||||
match client
|
||||
.get_events_of(vec![Filter::new().id(event_id)], None)
|
||||
.get_events_of(
|
||||
vec![Filter::new().id(event_id)],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
@ -88,7 +91,10 @@ pub async fn get_event_from(
|
||||
|
||||
if !settings.use_relay_hint {
|
||||
match client
|
||||
.get_events_of(vec![Filter::new().id(event_id)], None)
|
||||
.get_events_of(
|
||||
vec![Filter::new().id(event_id)],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
@ -152,7 +158,13 @@ pub async fn get_replies(id: &str, state: State<'_, Nostr>) -> Result<Vec<RichEv
|
||||
|
||||
let filter = Filter::new().kinds(vec![Kind::TextNote]).event(event_id);
|
||||
|
||||
match client.get_events_of(vec![filter], None).await {
|
||||
match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
let futures = events.into_iter().map(|ev| async move {
|
||||
let raw = ev.as_json();
|
||||
@ -217,7 +229,13 @@ pub async fn get_events_by(
|
||||
.limit(FETCH_LIMIT)
|
||||
.until(until);
|
||||
|
||||
match client.get_events_of(vec![filter], None).await {
|
||||
match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
let futures = events.into_iter().map(|ev| async move {
|
||||
let raw = ev.as_json();
|
||||
@ -344,7 +362,10 @@ pub async fn get_group_events(
|
||||
.authors(authors);
|
||||
|
||||
match client
|
||||
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
@ -387,7 +408,10 @@ pub async fn get_global_events(
|
||||
.until(as_of);
|
||||
|
||||
match client
|
||||
.get_events_of(vec![filter], Some(Duration::from_secs(8)))
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
@ -428,7 +452,13 @@ pub async fn get_hashtag_events(
|
||||
.until(as_of)
|
||||
.hashtags(hashtags);
|
||||
|
||||
match client.get_events_of(vec![filter], None).await {
|
||||
match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
let dedup = dedup_event(&events);
|
||||
let futures = dedup.into_iter().map(|ev| async move {
|
||||
@ -644,7 +674,7 @@ pub async fn user_to_bech32(user: &str, state: State<'_, Nostr>) -> Result<Strin
|
||||
.author(public_key)
|
||||
.kind(Kind::RelayList)
|
||||
.limit(1)],
|
||||
Some(Duration::from_secs(10)),
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
@ -3,22 +3,18 @@ use nostr_sdk::prelude::*;
|
||||
use std::{str::FromStr, time::Duration};
|
||||
use tauri::State;
|
||||
|
||||
use crate::common::get_latest_event;
|
||||
use crate::{Nostr, Settings};
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn get_current_profile(state: State<'_, Nostr>) -> Result<String, String> {
|
||||
pub async fn get_profile(id: Option<String>, state: State<'_, Nostr>) -> Result<String, String> {
|
||||
let client = &state.client;
|
||||
|
||||
let signer = match client.signer().await {
|
||||
Ok(signer) => signer,
|
||||
Err(err) => return Err(format!("Failed to get signer: {}", err)),
|
||||
};
|
||||
|
||||
let public_key = match signer.public_key().await {
|
||||
Ok(pk) => pk,
|
||||
Err(err) => return Err(format!("Failed to get public key: {}", err)),
|
||||
let public_key: PublicKey = match id {
|
||||
Some(user_id) => match PublicKey::from_str(&user_id) {
|
||||
Ok(val) => val,
|
||||
Err(_) => return Err("Public Key is not valid".into()),
|
||||
},
|
||||
None => client.signer().await.unwrap().public_key().await.unwrap(),
|
||||
};
|
||||
|
||||
let filter = Filter::new()
|
||||
@ -26,70 +22,25 @@ pub async fn get_current_profile(state: State<'_, Nostr>) -> Result<String, Stri
|
||||
.kind(Kind::Metadata)
|
||||
.limit(1);
|
||||
|
||||
let events_result = client
|
||||
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
||||
let query = client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(3))),
|
||||
)
|
||||
.await;
|
||||
|
||||
match events_result {
|
||||
Ok(events) => {
|
||||
if let Some(event) = get_latest_event(&events) {
|
||||
match Metadata::from_json(&event.content) {
|
||||
Ok(metadata) => Ok(metadata.as_json()),
|
||||
Err(_) => Err("Failed to parse metadata.".into()),
|
||||
}
|
||||
if let Ok(events) = query {
|
||||
if let Some(event) = events.first() {
|
||||
if let Ok(metadata) = Metadata::from_json(&event.content) {
|
||||
Ok(metadata.as_json())
|
||||
} else {
|
||||
Err("No matching events found.".into())
|
||||
}
|
||||
}
|
||||
Err(err) => Err(format!("Failed to get events: {}", err)),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn get_profile(id: &str, state: State<'_, Nostr>) -> Result<String, String> {
|
||||
let client = &state.client;
|
||||
let public_key: Option<PublicKey> = match Nip19::from_bech32(id) {
|
||||
Ok(val) => match val {
|
||||
Nip19::Pubkey(key) => Some(key),
|
||||
Nip19::Profile(profile) => {
|
||||
let relays = profile.relays;
|
||||
for relay in relays.into_iter() {
|
||||
let _ = client.add_relay(&relay).await.unwrap_or_default();
|
||||
client.connect_relay(&relay).await.unwrap_or_default();
|
||||
}
|
||||
Some(profile.public_key)
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
Err(_) => match PublicKey::from_str(id) {
|
||||
Ok(val) => Some(val),
|
||||
Err(_) => None,
|
||||
},
|
||||
};
|
||||
|
||||
if let Some(author) = public_key {
|
||||
let filter = Filter::new().author(author).kind(Kind::Metadata).limit(1);
|
||||
let query = client
|
||||
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
||||
.await;
|
||||
|
||||
if let Ok(events) = query {
|
||||
if let Some(event) = events.first() {
|
||||
if let Ok(metadata) = Metadata::from_json(&event.content) {
|
||||
Ok(metadata.as_json())
|
||||
} else {
|
||||
Err("Parse metadata failed".into())
|
||||
}
|
||||
} else {
|
||||
let rand_metadata = Metadata::new();
|
||||
Ok(rand_metadata.as_json())
|
||||
Err("Parse metadata failed".into())
|
||||
}
|
||||
} else {
|
||||
Err("Get metadata failed".into())
|
||||
Ok(Metadata::new().as_json())
|
||||
}
|
||||
} else {
|
||||
Err("Public Key is not valid".into())
|
||||
Err("Get metadata failed".into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,10 +136,10 @@ pub async fn is_contact_list_empty(state: State<'_, Nostr>) -> Result<bool, ()>
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn check_contact(hex: &str, state: State<'_, Nostr>) -> Result<bool, String> {
|
||||
pub async fn check_contact(hex: String, state: State<'_, Nostr>) -> Result<bool, String> {
|
||||
let contact_list = state.contact_list.lock().unwrap();
|
||||
|
||||
match PublicKey::from_str(hex) {
|
||||
match PublicKey::from_str(&hex) {
|
||||
Ok(public_key) => match contact_list.iter().position(|x| x.public_key == public_key) {
|
||||
Some(_) => Ok(true),
|
||||
None => Ok(false),
|
||||
@ -244,27 +195,19 @@ pub async fn set_nstore(
|
||||
state: State<'_, Nostr>,
|
||||
) -> Result<String, String> {
|
||||
let client = &state.client;
|
||||
let signer = client.signer().await.map_err(|e| e.to_string())?;
|
||||
let public_key = signer.public_key().await.map_err(|e| e.to_string())?;
|
||||
|
||||
match client.signer().await {
|
||||
Ok(signer) => {
|
||||
let public_key = match signer.public_key().await {
|
||||
Ok(pk) => pk,
|
||||
Err(err) => return Err(format!("Failed to get public key: {}", err)),
|
||||
};
|
||||
let encrypted = signer
|
||||
.nip44_encrypt(public_key, content)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
let encrypted = match signer.nip44_encrypt(public_key, content).await {
|
||||
Ok(enc) => enc,
|
||||
Err(err) => return Err(format!("Encryption failed: {}", err)),
|
||||
};
|
||||
let tag = Tag::identifier(key);
|
||||
let builder = EventBuilder::new(Kind::ApplicationSpecificData, encrypted, vec![tag]);
|
||||
|
||||
let tag = Tag::identifier(key);
|
||||
let builder = EventBuilder::new(Kind::ApplicationSpecificData, encrypted, vec![tag]);
|
||||
|
||||
match client.send_event_builder(builder).await {
|
||||
Ok(event_id) => Ok(event_id.to_string()),
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
}
|
||||
match client.send_event_builder(builder).await {
|
||||
Ok(event_id) => Ok(event_id.to_string()),
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
}
|
||||
@ -273,38 +216,34 @@ pub async fn set_nstore(
|
||||
#[specta::specta]
|
||||
pub async fn get_nstore(key: &str, state: State<'_, Nostr>) -> Result<String, String> {
|
||||
let client = &state.client;
|
||||
let signer = client.signer().await.map_err(|e| e.to_string())?;
|
||||
let public_key = signer.public_key().await.map_err(|e| e.to_string())?;
|
||||
|
||||
if let Ok(signer) = client.signer().await {
|
||||
let public_key = match signer.public_key().await {
|
||||
Ok(pk) => pk,
|
||||
Err(err) => return Err(format!("Failed to get public key: {}", err)),
|
||||
};
|
||||
let filter = Filter::new()
|
||||
.author(public_key)
|
||||
.kind(Kind::ApplicationSpecificData)
|
||||
.identifier(key)
|
||||
.limit(1);
|
||||
|
||||
let filter = Filter::new()
|
||||
.author(public_key)
|
||||
.kind(Kind::ApplicationSpecificData)
|
||||
.identifier(key)
|
||||
.limit(1);
|
||||
|
||||
match client
|
||||
.get_events_of(vec![filter], Some(Duration::from_secs(5)))
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
if let Some(event) = events.first() {
|
||||
let content = event.content();
|
||||
match signer.nip44_decrypt(public_key, content).await {
|
||||
Ok(decrypted) => Ok(decrypted),
|
||||
Err(_) => Err(event.content.to_string()),
|
||||
}
|
||||
} else {
|
||||
Err("Value not found".into())
|
||||
match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
if let Some(event) = events.first() {
|
||||
let content = event.content();
|
||||
match signer.nip44_decrypt(public_key, content).await {
|
||||
Ok(decrypted) => Ok(decrypted),
|
||||
Err(_) => Err(event.content.to_string()),
|
||||
}
|
||||
} else {
|
||||
Err("Not found".into())
|
||||
}
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
} else {
|
||||
Err("Signer is required".into())
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,7 +268,8 @@ pub async fn set_wallet(uri: &str, state: State<'_, Nostr>) -> Result<bool, Stri
|
||||
#[specta::specta]
|
||||
pub async fn load_wallet(state: State<'_, Nostr>) -> Result<String, String> {
|
||||
let client = &state.client;
|
||||
let keyring = Entry::new("Lume Secret", "Bitcoin Connect").unwrap();
|
||||
let keyring =
|
||||
Entry::new("Lume Secret Storage", "Bitcoin Connect").map_err(|e| e.to_string())?;
|
||||
|
||||
match keyring.get_password() {
|
||||
Ok(val) => {
|
||||
@ -353,16 +293,17 @@ pub async fn load_wallet(state: State<'_, Nostr>) -> Result<String, String> {
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn remove_wallet(state: State<'_, Nostr>) -> Result<(), ()> {
|
||||
pub async fn remove_wallet(state: State<'_, Nostr>) -> Result<(), String> {
|
||||
let client = &state.client;
|
||||
let keyring = Entry::new("Lume Secret", "Bitcoin Connect").unwrap();
|
||||
let keyring =
|
||||
Entry::new("Lume Secret Storage", "Bitcoin Connect").map_err(|e| e.to_string())?;
|
||||
|
||||
match keyring.delete_credential() {
|
||||
Ok(_) => {
|
||||
client.unset_zapper().await;
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
Err(e) => Err(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,23 +316,10 @@ pub async fn zap_profile(
|
||||
state: State<'_, Nostr>,
|
||||
) -> Result<bool, String> {
|
||||
let client = &state.client;
|
||||
let public_key = match Nip19::from_bech32(id) {
|
||||
Ok(val) => match val {
|
||||
Nip19::Pubkey(key) => key,
|
||||
Nip19::Profile(profile) => profile.public_key,
|
||||
_ => return Err("Public Key is not valid.".into()),
|
||||
},
|
||||
Err(_) => match PublicKey::from_str(id) {
|
||||
Ok(val) => val,
|
||||
Err(_) => return Err("Public Key is not valid.".into()),
|
||||
},
|
||||
};
|
||||
let public_key: PublicKey = PublicKey::from_str(id).map_err(|e| e.to_string())?;
|
||||
|
||||
let details = ZapDetails::new(ZapType::Private).message(message);
|
||||
let num = match amount.parse::<u64>() {
|
||||
Ok(val) => val,
|
||||
Err(_) => return Err("Invalid amount.".into()),
|
||||
};
|
||||
let num = amount.parse::<u64>().map_err(|e| e.to_string())?;
|
||||
|
||||
if client.zap(public_key, num, Some(details)).await.is_ok() {
|
||||
Ok(true)
|
||||
@ -422,10 +350,7 @@ pub async fn zap_event(
|
||||
};
|
||||
|
||||
let details = ZapDetails::new(ZapType::Private).message(message);
|
||||
let num = match amount.parse::<u64>() {
|
||||
Ok(val) => val,
|
||||
Err(_) => return Err("Invalid amount.".into()),
|
||||
};
|
||||
let num = amount.parse::<u64>().map_err(|e| e.to_string())?;
|
||||
|
||||
if client.zap(event_id, num, Some(details)).await.is_ok() {
|
||||
Ok(true)
|
||||
@ -447,8 +372,12 @@ pub async fn friend_to_friend(npub: &str, state: State<'_, Nostr>) -> Result<boo
|
||||
.kind(Kind::ContactList)
|
||||
.limit(1);
|
||||
|
||||
if let Ok(contact_list_events) =
|
||||
client.get_events_of(vec![contact_list_filter], None).await
|
||||
if let Ok(contact_list_events) = client
|
||||
.get_events_of(
|
||||
vec![contact_list_filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
for event in contact_list_events.into_iter() {
|
||||
for tag in event.into_iter_tags() {
|
||||
@ -477,19 +406,22 @@ pub async fn friend_to_friend(npub: &str, state: State<'_, Nostr>) -> Result<boo
|
||||
pub async fn get_following(
|
||||
state: State<'_, Nostr>,
|
||||
public_key: &str,
|
||||
timeout: Option<u64>,
|
||||
) -> Result<Vec<String>, String> {
|
||||
let client = &state.client;
|
||||
let public_key = match PublicKey::from_str(public_key) {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(err.to_string()),
|
||||
};
|
||||
let duration = timeout.map(Duration::from_secs);
|
||||
let public_key = PublicKey::from_str(public_key).map_err(|e| e.to_string())?;
|
||||
|
||||
let filter = Filter::new().kind(Kind::ContactList).author(public_key);
|
||||
let events = match client.get_events_of(vec![filter], duration).await {
|
||||
let events = match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => events,
|
||||
Err(err) => return Err(err.to_string()),
|
||||
};
|
||||
|
||||
let mut ret: Vec<String> = vec![];
|
||||
if let Some(latest_event) = events.iter().max_by_key(|event| event.created_at()) {
|
||||
ret.extend(latest_event.tags().iter().filter_map(|tag| {
|
||||
@ -503,33 +435,38 @@ pub async fn get_following(
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub async fn get_followers(
|
||||
state: State<'_, Nostr>,
|
||||
public_key: &str,
|
||||
timeout: Option<u64>,
|
||||
) -> Result<Vec<String>, String> {
|
||||
let client = &state.client;
|
||||
let public_key = match PublicKey::from_str(public_key) {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(err.to_string()),
|
||||
};
|
||||
let duration = timeout.map(Duration::from_secs);
|
||||
let public_key = PublicKey::from_str(public_key).map_err(|e| e.to_string())?;
|
||||
|
||||
let filter = Filter::new().kind(Kind::ContactList).custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::P),
|
||||
vec![public_key.to_hex()],
|
||||
);
|
||||
let events = match client.get_events_of(vec![filter], duration).await {
|
||||
|
||||
let events = match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => events,
|
||||
Err(err) => return Err(err.to_string()),
|
||||
};
|
||||
|
||||
let ret: Vec<String> = events
|
||||
.into_iter()
|
||||
.map(|event| event.author().to_hex())
|
||||
.collect();
|
||||
|
||||
Ok(ret)
|
||||
// TODO: get more than 500 events
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use specta::Type;
|
||||
use std::{
|
||||
fs::OpenOptions,
|
||||
io::{self, BufRead, Write},
|
||||
time::Duration,
|
||||
};
|
||||
use tauri::{path::BaseDirectory, Manager, State};
|
||||
|
||||
@ -36,7 +37,16 @@ pub async fn get_relays(state: State<'_, Nostr>) -> Result<Relays, String> {
|
||||
.kind(Kind::RelayList)
|
||||
.limit(1);
|
||||
|
||||
match client.get_events_of(vec![filter], None).await {
|
||||
match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::Relays {
|
||||
timeout: Some(Duration::from_secs(5)),
|
||||
specific_relays: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
if let Some(event) = events.first() {
|
||||
let nip65_list = nip65::extract_relay_list(event).collect::<Vec<_>>();
|
||||
|
@ -5,6 +5,7 @@ use serde::Serialize;
|
||||
use specta::Type;
|
||||
use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::Settings;
|
||||
|
||||
@ -66,7 +67,13 @@ pub async fn init_nip65(client: &Client) {
|
||||
.kind(Kind::RelayList)
|
||||
.limit(1);
|
||||
|
||||
if let Ok(events) = client.get_events_of(vec![filter], None).await {
|
||||
if let Ok(events) = client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
if let Some(event) = events.first() {
|
||||
let relay_list = nip65::extract_relay_list(event);
|
||||
for (url, metadata) in relay_list {
|
||||
@ -107,7 +114,13 @@ pub async fn get_user_settings(client: &Client) -> Result<Settings, String> {
|
||||
.identifier(ident)
|
||||
.limit(1);
|
||||
|
||||
match client.get_events_of(vec![filter], None).await {
|
||||
match client
|
||||
.get_events_of(
|
||||
vec![filter],
|
||||
EventSource::both(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(events) => {
|
||||
if let Some(event) = events.first() {
|
||||
let content = event.content();
|
||||
|
@ -89,7 +89,6 @@ fn main() {
|
||||
connect_account,
|
||||
delete_account,
|
||||
login,
|
||||
get_current_profile,
|
||||
get_profile,
|
||||
get_contact_list,
|
||||
set_contact_list,
|
||||
|
@ -88,15 +88,7 @@ async login(account: string, password: string) : Promise<Result<string, string>>
|
||||
else return { status: "error", error: e as any };
|
||||
}
|
||||
},
|
||||
async getCurrentProfile() : Promise<Result<string, string>> {
|
||||
try {
|
||||
return { status: "ok", data: await TAURI_INVOKE("get_current_profile") };
|
||||
} catch (e) {
|
||||
if(e instanceof Error) throw e;
|
||||
else return { status: "error", error: e as any };
|
||||
}
|
||||
},
|
||||
async getProfile(id: string) : Promise<Result<string, string>> {
|
||||
async getProfile(id: string | null) : Promise<Result<string, string>> {
|
||||
try {
|
||||
return { status: "ok", data: await TAURI_INVOKE("get_profile", { id }) };
|
||||
} catch (e) {
|
||||
@ -184,7 +176,7 @@ async loadWallet() : Promise<Result<string, string>> {
|
||||
else return { status: "error", error: e as any };
|
||||
}
|
||||
},
|
||||
async removeWallet() : Promise<Result<null, null>> {
|
||||
async removeWallet() : Promise<Result<null, string>> {
|
||||
try {
|
||||
return { status: "ok", data: await TAURI_INVOKE("remove_wallet") };
|
||||
} catch (e) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user