app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 7adb4880324ea899a484b8d3e24d98b8917b5fab
parent e7da58c033a8e6476ae015fe88d6ffc111b2f282
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Fri, 27 Sep 2024 14:05:21 +0000

Add `nostr_relay` model, edit nostr relay connection logic, add default relays as models in (conf) `/init` configure device function, edit utils

Diffstat:
Msrc/lib/client.ts | 6++++--
Msrc/lib/utils/index.ts | 5++---
Msrc/routes/(app)/+layout.svelte | 1-
Msrc/routes/(conf)/init/+page.svelte | 67+++++++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/routes/+layout.svelte | 94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
5 files changed, 127 insertions(+), 46 deletions(-)

diff --git a/src/lib/client.ts b/src/lib/client.ts @@ -1,5 +1,5 @@ import { ClientCapacitor } from "@radroots/client"; -import { location_gcs_table, nostr_profile_table, trade_product_table } from "@radroots/models"; +import { location_gcs_table, nostr_profile_relay_table, nostr_profile_table, nostr_relay_table, trade_product_table } from "@radroots/models"; export const lc = new ClientCapacitor({ sqlite_upgrade: [ { @@ -8,7 +8,9 @@ export const lc = new ClientCapacitor({ `PRAGMA foreign_keys = ON;`, location_gcs_table, trade_product_table, - nostr_profile_table + nostr_profile_table, + nostr_relay_table, + nostr_profile_relay_table ] } ] diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts @@ -1,12 +1,11 @@ -import { route, type NavigationRoute } from "@radroots/svelte-lib"; +import { app_notify, route, type NavigationRoute } from "@radroots/svelte-lib"; import { lc } from "../client"; export const restart = async (route_to: true | NavigationRoute, notify_message?: string): Promise<void> => { try { await lc.window.splash_show(); if (notify_message) { - console.log(`todo! notify_message `, notify_message) - //app_notify.set(notify_message); + app_notify.set(notify_message); } await route(typeof route_to === `string` ? route_to : `/`) location.reload(); diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte @@ -37,7 +37,6 @@ { icon: `bell-simple`, callback: async (tab_i) => { - app_tab_active.set(tab_i); await route(`/settings`); }, }, diff --git a/src/routes/(conf)/init/+page.svelte b/src/routes/(conf)/init/+page.svelte @@ -1,4 +1,5 @@ <script lang="ts"> + import { PUBLIC_NOSTR_RELAY_DEFAULTS } from "$env/static/public"; import { lc } from "$lib/client"; import { _conf } from "$lib/conf"; import { restart } from "$lib/utils"; @@ -84,32 +85,62 @@ const secret_key = lc.nostr.lib.generate_key(); const public_key = lc.nostr.lib.public_key(secret_key); - const key_added = await lc.keystore.set( + const ks_key_add = await lc.keystore.set( _conf.kv.nostr_key(public_key), secret_key, ); - if (key_added) { - await lc.preferences.set(_conf.kv.nostr_key_active, public_key); + if (!ks_key_add) { + //@todo reset + alert(`!ks_key_add`); + return; + } - const key_profile_added = await lc.db.nostr_profile_add({ - public_key, - }); + const pref_key_add = await lc.preferences.set( + _conf.kv.nostr_key_active, + public_key, + ); + if (!pref_key_add) { + //@todo reset + alert(`!pref_key_add`); + return; + } + + const nostr_profile_add = await lc.db.nostr_profile_add({ + public_key, + }); - if (typeof key_profile_added === `string`) { - // @todo - alert(key_profile_added); - } else if (Array.isArray(key_profile_added)) { - //@todo - alert(key_profile_added.join(` `)); - } else { - await sleep(_conf.delay.load); - await restart( - true, - `Welcome! Your device was configured. To view or change your configuration go to Settings > Configuration.`, - ); + if (typeof nostr_profile_add === `string`) { + // @todo reset + alert(nostr_profile_add); + return; + } else if (Array.isArray(nostr_profile_add)) { + //@todo reset + alert(nostr_profile_add.join(` `)); + return; + } + + for (const url of PUBLIC_NOSTR_RELAY_DEFAULTS.split(",") || []) { + const nostr_relay_add = await lc.db.nostr_relay_add({ url }); + if (typeof nostr_relay_add === `string`) { + // @todo reset + alert(nostr_relay_add); + return; + } else if (Array.isArray(nostr_relay_add)) { + //@todo reset + alert(nostr_relay_add.join(` `)); return; } + await lc.db.set_nostr_profile_relay({ + nostr_profile_id: nostr_profile_add.id, + nostr_relay_id: nostr_relay_add.id, + }); } + + await sleep(_conf.delay.load); + await restart( + true, + `Welcome! Your device was configured. To view or change your configuration go to Settings > Configuration.`, + ); } catch (e) { console.log(`(error) configure_device `, e); } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte @@ -1,9 +1,6 @@ <script lang="ts"> import { browser } from "$app/environment"; - import { - PUBLIC_DATABASE_NAME, - PUBLIC_NOSTR_RELAY_DEFAULTS, - } from "$env/static/public"; + import { PUBLIC_DATABASE_NAME } from "$env/static/public"; import { lc } from "$lib/client"; import { _conf } from "$lib/conf"; import { @@ -14,19 +11,24 @@ app_thc, } from "$lib/stores"; import { + parse_nostr_relay_form_keys, + type NostrRelayFormFields, + } from "@radroots/models"; + import { app_config, app_notify, app_render, AppConfig, CssStatic, ndk, - ndk_setup_privkey, + ndk_init, ndk_user, route, sleep, theme_set, } from "@radroots/svelte-lib"; import { parse_color_mode, parse_theme_key } from "@radroots/theme"; + import { parse_nostr_relay_information_document_fields } from "@radroots/utils"; import "../app.css"; let render_pwa = browser && lc.platform === `web`; @@ -114,28 +116,76 @@ } }); - app_nostr_key.subscribe(async (app_nostr_key) => { + app_nostr_key.subscribe(async (_app_nostr_key) => { try { - if (!app_nostr_key) return; - const private_key = await lc.keystore.get( - `nostr:key:${app_nostr_key}`, + if (!_app_nostr_key) return; + + const secret_key = await lc.keystore.get( + _conf.kv.nostr_key(_app_nostr_key), ); - if (private_key) { - for (const url of PUBLIC_NOSTR_RELAY_DEFAULTS.split(",")) - $ndk.addExplicitRelay(url); - await $ndk.connect().then(() => { - console.log(`(ndk) connected`); - }); - const setup_user = await ndk_setup_privkey({ - $ndk, - private_key, + if (!secret_key) { + alert(`!secret_key`); //@todo + return; + } + + const nostr_relays = await lc.db.nostr_relay_get({ + list: ["all"], + }); + if (typeof nostr_relays === `string`) { + alert(nostr_relays); //@todo + return; + } + + for (const { url } of nostr_relays) { + $ndk.addExplicitRelay(url); + const response = await lc.http.fetch({ + url: url.replace(`ws://`, `http://`), + headers: { + Accept: "application/nostr+json", + }, }); - if (setup_user) { - $ndk_user = setup_user; - $ndk_user.ndk = $ndk; - console.log(`(ndk_user) connected`); + if (typeof response === `string`) { + console.log(`response `, response); + return; + } + + if (response.status === 200 && response.data) { + const info_doc = + parse_nostr_relay_information_document_fields( + response.data, + ); + if (!info_doc) return; + const fields: Partial<NostrRelayFormFields> = {}; + for (const [k, v] of Object.entries(info_doc)) { + const field_k = parse_nostr_relay_form_keys(k); + if (field_k) fields[field_k] = v; + } + if (Object.keys(fields).length < 1) return; + await lc.db.nostr_relay_update({ + on: { + url, + }, + fields, + }); } } + + await $ndk.connect().then(() => { + console.log(`(ndk) connected`); + }); + + const ndk_user = await ndk_init({ + $ndk, + secret_key, + }); + if (!ndk_user) { + alert(`!ndk_user`); //@todo + return; + } + + $ndk_user = ndk_user; + $ndk_user.ndk = $ndk; + console.log(`(ndk) initialized`); } catch (e) { console.log(`(app_nostr_key) error `, e); }