commit 98d5527735a511bb0706e280191d723f81e21c47
parent 4a7487380bcd7147e41304503cf08e269e964265
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Thu, 10 Apr 2025 23:53:35 +0000
Add/edit nostr sync and poll relay utils. Edit (app) layout subscribers. Edit `/init` client logic, styles. Edit `tangle` set tauri http permissions to all http/https addresses.
Diffstat:
7 files changed, 142 insertions(+), 28 deletions(-)
diff --git a/app/src/lib/util/index.ts b/app/src/lib/util/index.ts
@@ -5,7 +5,7 @@ import { ls } from "$lib/locale/i18n";
import { TauriClientDatabase, TauriClientDatastore, TauriClientFs, TauriClientGeolocation, TauriClientGui, TauriClientHttp, TauriClientKeys, TauriClientRadroots } from "@radroots/client";
import { Geocoder } from "@radroots/geocoder";
import { app_notify, get_store, handle_err, NostrSyncService, type NavigationRouteParamKey, type NavigationRouteParamTuple } from "@radroots/lib-app";
-import { NostrEventService, NostrKeyService } from "@radroots/nostr-util";
+import { NostrEventService, NostrKeyService, NostrRelayService } from "@radroots/nostr-util";
import { encode_route, type CallbackPromise } from "@radroots/util";
import type { NavigationRoute } from "./routes";
@@ -21,6 +21,9 @@ export const radroots = new TauriClientRadroots(PUBLIC_RADROOTS_URL);
export const geoc = new Geocoder();
export const nostrkey = new NostrKeyService();
export const nostre = new NostrEventService();
+export const nostrl = new NostrRelayService();
+
+
export let nostrsync: NostrSyncService
if (browser) nostrsync = new NostrSyncService();
diff --git a/app/src/lib/util/nostr/poll.ts b/app/src/lib/util/nostr/poll.ts
@@ -0,0 +1,104 @@
+import { ls } from "$lib/locale/i18n";
+import { get_store, handle_err, ndk_user, nostr_poll_relays_stop, nostr_relays_connected } from "@radroots/lib-app";
+import { nostr_relay_parse_form_keys, type NostrRelayFormFields } from "@radroots/models";
+import { throw_err } from "@radroots/util";
+import { db, gui, http, nostrl } from "..";
+
+export const nostr_poll_relays = async (): Promise<void> => {
+ try {
+ console.log(`[nostr_poll_relays] start`);
+ const $ls = get_store(ls);
+ const $ndk_user = get_store(ndk_user);
+ const public_key = $ndk_user?.pubkey;
+ if (!public_key) return void await gui.alert(
+ `${$ls(`error.client.nostr_poll_relays_failure`)}`
+ );
+
+ const $nostr_relays_connected = get_store(nostr_relays_connected);
+
+ const nostr_relays = await db.nostr_relay_read_list({
+ table: [`on_profile`, { public_key }],
+ });
+ console.log(JSON.stringify(nostr_relays, null, 4), `nostr_relays`)
+ if (`err` in nostr_relays) return throw_err(nostr_relays.err);
+ const unconnected_relays = nostr_relays.results.filter(
+ (i) => !$nostr_relays_connected.includes(i.id),
+ );
+ console.log(JSON.stringify(unconnected_relays, null, 4), `unconnected_relays`)
+ if (unconnected_relays.length === 0) return void nostr_poll_relays_stop.set(true);
+
+ for (const nostr_relay of unconnected_relays) {
+ const res = await http.fetch({
+ url: nostr_relay.url.replace(`ws://`, `http://`).replace(`wss://`, `https://`),
+ headers: {
+ Accept: "application/nostr+json",
+ },
+ });
+ if (`err` in res) continue;
+ else if (res.status === 200 && res.data) {
+ const relaydoc = nostrl.parse_information_document(res.data);
+ if (!relaydoc) continue;
+ const fields: Partial<NostrRelayFormFields> = {};
+ for (const [k, v] of Object.entries(relaydoc)) {
+ const field_k = nostr_relay_parse_form_keys(k);
+ if (field_k) fields[field_k] = v;
+ }
+ if (Object.keys(fields).length < 1) continue;
+ await db.nostr_relay_update({
+ filter: {
+ url: nostr_relay.url,
+ },
+ fields,
+ });
+ nostr_relays_connected.set(
+ Array.from(
+ new Set([
+ ...$nostr_relays_connected,
+ nostr_relay.id,
+ ]),
+ ),
+ );
+ }
+ }
+ console.log(`[nostr_poll_relays] done`);
+ } catch (e) {
+ await handle_err(e, `nostr_poll_relays`);
+ }
+};
+
+
+/*
+import { get_store, handle_err, ndk_user, nostr_poll_relays, nostr_poll_relays_attempts, nostr_poll_relays_attempts_max, nostr_relays_connected } from "$lib";
+import type { db } from "@nostr-dev-kit/ndk-cache-dexie";
+import { throw_err } from "@radroots/util";
+
+export const nostr_fetch_relay_documents = async (
+ callback: () => Promise<void>
+): Promise<void> => {
+ try {
+
+ if (
+ $nostr_poll_relays_attempts >=
+ $nostr_poll_relays_attempts_max
+ ) {
+ nostr_poll_relays.set(false);
+ return;
+ }
+ nostr_poll_relays_attempts.set(
+ $nostr_poll_relays_attempts + 1,
+ );
+
+ -
+ if (unconnected_relays.length === 0) return void nostr_poll_relays.set(false);
+
+ setTimeout(
+ async () => nostr_fetch_relay_documents(callback),
+ 3000
+ );
+ } catch (e) {
+ await handle_err(e, `nostr_fetch_relay_documents`);
+ }
+};
+
+
+*/
+\ No newline at end of file
diff --git a/app/src/lib/util/nostr/sync.ts b/app/src/lib/util/nostr/sync.ts
@@ -6,9 +6,11 @@ import { err } from "../err";
export const nostr_sync = async (): Promise<void> => {
try {
+ console.log(`[nostr_sync] start`);
const $ls = get_store(ls);
const $ndk_user = get_store(ndk_user);
- if (!$ndk_user.pubkey) return void await gui.alert(
+ const public_key = $ndk_user.pubkey;
+ if (!public_key) return void await gui.alert(
`${$ls(`error.client.nostr_sync_failure`)}`
);
const $nostr_sync_prevent = get_store(nostr_sync_prevent);
@@ -22,13 +24,13 @@ export const nostr_sync = async (): Promise<void> => {
}
return;
}
- console.log(`[nostr_sync] start`);
const nostr_relays = await db.nostr_relay_read_list({
- table: [`on_profile`, { public_key: $ndk_user.pubkey }]
+ table: [`on_profile`, { public_key }]
}); //@todo
-
+ console.log(JSON.stringify(nostr_relays, null, 4), `nostr_relays`)
if (`err` in nostr_relays) return throw_err(nostr_relays);
if (!nostr_relays.results.length) return throw_err(err.nostr.no_relays);
+
await nostr_sync_metadata();
console.log(`[nostr_sync] done`);
} catch (e) {
diff --git a/app/src/routes/(app)/+layout.svelte b/app/src/routes/(app)/+layout.svelte
@@ -8,6 +8,7 @@
ndk,
ndk_user,
nostr_ndk_configured,
+ nostr_poll_relays_retry_handler,
nostr_sync_retry_handler,
} from "@radroots/lib-app";
import { ndk_init } from "@radroots/nostr-util";
@@ -15,7 +16,8 @@
import { _cfg } from "$lib/config";
import { cfg_role, cfg_setup } from "$lib/store";
- import { nostr_sync_metadata } from "$lib/util/nostr/sync";
+ import { nostr_poll_relays } from "$lib/util/nostr/poll";
+ import { nostr_sync } from "$lib/util/nostr/sync";
import { onMount } from "svelte";
import type { LayoutProps } from "./$types";
@@ -74,27 +76,30 @@
$ndk,
secret_key: keys_nostr_read.secret_key,
});
- nostr_ndk_configured.set(!!ndk_user_init);
if (!ndk_user_init) throw_err(`error.nostr.ndk_user_undefined`);
$ndk_user = ndk_user_init;
$ndk_user.ndk = $ndk;
- await nostr_sync_retry_handler(nostr_sync_metadata);
+ nostr_ndk_configured.set(true);
};
- app_notify.subscribe(async (_app_notify) => {
- console.log(`_app_notify `, _app_notify);
- if (!_app_notify) return;
- await gui.notify_send($app_notify);
+ nostr_ndk_configured.subscribe(async (_sub) => {
+ if (!_sub) return;
+ await nostr_sync_retry_handler(nostr_sync);
+ await nostr_poll_relays_retry_handler(nostr_poll_relays);
+ });
+
+ app_notify.subscribe(async (_sub) => {
+ if (!_sub) return;
+ await gui.notify_send(_sub);
app_notify.set(``);
});
- cfg_role.subscribe(async (_cfg_role) => {
- if (!_cfg_role) return;
+ cfg_role.subscribe(async (_sub) => {
+ if (!_sub) return;
});
- cfg_setup.subscribe(async (_cfg_setup) => {
- console.log(`_cfg_setup `, _cfg_setup);
- if (!_cfg_setup) return;
+ cfg_setup.subscribe(async (_sub) => {
+ if (!_sub) return;
});
</script>
diff --git a/app/src/routes/(cfg)/init/+page.svelte b/app/src/routes/(cfg)/init/+page.svelte
@@ -59,9 +59,7 @@
let cfg_profile_name_loading = $state(false);
const cfg_profile_name_skip = $derived(
- view.toString() === `cfg_profile` &&
- $carousel_index === 0 &&
- !cfg_profile_nip05_opt,
+ view.toString() === `cfg_profile` && $carousel_index === 0,
);
onMount(async () => {
@@ -586,7 +584,7 @@
class={`carousel-item flex flex-col h-full w-full justify-center items-center`}
>
<div
- class={`flex flex-col h-[16rem] w-full px-4 gap-10 justify-start items-center`}
+ class={`flex flex-col h-[16rem] w-full px-4 gap-6 justify-start items-center`}
>
<p class={`font-sans font-[600] text-layer-0-glyph text-3xl`}>
{`${$ls(`icu.add_*`, { value: `${$ls(`common.profile`)}` })}`}
@@ -635,11 +633,11 @@
}}
>
<p
- class={`font-sans font-[500] text-layer-0-glyph text-[14px] tracking-wide`}
+ class={`font-sans font-[400] text-layer-0-glyph text-[14px] tracking-wide`}
>
{`${$ls(`common.create`)}`}
<span
- class={`font-mono font-[600] tracking-tight px-[2px]`}
+ class={`font-mono font-[600] tracking-tight px-[3px]`}
>
{`@radroots`}
</span>
@@ -711,9 +709,10 @@
continue: {
label: `${$ls(`common.continue`)}`,
disabled:
- // ($carousel_index === 0 &&
- // !cfg_profile_name_valid) ||
- $carousel_index === 1 && !cfg_role,
+ (cfg_profile_name_skip &&
+ cfg_profile_nip05_opt &&
+ !cfg_profile_name_valid) ||
+ ($carousel_index === 1 && !cfg_role),
callback: async () => await handle_continue(),
},
back: {
diff --git a/crates/tangle/capabilities/default.json b/crates/tangle/capabilities/default.json
@@ -13,10 +13,10 @@
"identifier": "http:default",
"allow": [
{
- "url": "https://radroots.market"
+ "url": "https://*"
},
{
- "url": "https://*.radroots.market"
+ "url": "http://*"
},
{
"url": "http://127.0.0.1:*"
diff --git a/crates/tangle/icons/icon.icns b/crates/tangle/icons/icon.icns
Binary files differ.