From 8697cc23be06764f7cdef94cc3488163caf03cc3 Mon Sep 17 00:00:00 2001
From: Jon Staab
Date: Tue, 29 Jul 2025 10:53:48 -0700
Subject: [PATCH] Add signer status, re-work bunker login
---
CHANGELOG.md | 6 ++
src/app/components/BunkerConnect.svelte | 84 +++++-------------------
src/app/components/BunkerUrl.svelte | 32 +++++++--
src/app/components/LogInBunker.svelte | 75 ++++++++++++++-------
src/app/components/PrimaryNav.svelte | 2 +-
src/app/components/SignerStatus.svelte | 48 ++++++++++++++
src/app/nip46.ts | 54 +++++++++++++++
src/routes/settings/profile/+page.svelte | 2 +
svelte.config.js | 2 +-
9 files changed, 206 insertions(+), 99 deletions(-)
create mode 100644 src/app/components/SignerStatus.svelte
create mode 100644 src/app/nip46.ts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7448dfa..af36526 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+# 1.2.3
+
+* Add `created_at` to event info dialog
+* Add signer status to profile page
+* Re-work bunker login flow
+
# 1.2.2
* Fix phantom chat notifications
diff --git a/src/app/components/BunkerConnect.svelte b/src/app/components/BunkerConnect.svelte
index 10b9d27..179b3cb 100644
--- a/src/app/components/BunkerConnect.svelte
+++ b/src/app/components/BunkerConnect.svelte
@@ -1,79 +1,25 @@
-
-
-{#if controller.url}
-
-
-
+{#if $url}
+ {#if $loading}
+
+ Establishing connection...
+
+ {:else}
+
+
+
Scan with your signer to log in, or click to copy.
+
+ {/if}
{/if}
diff --git a/src/app/components/BunkerUrl.svelte b/src/app/components/BunkerUrl.svelte
index 2d5fd0c..ab8cd5e 100644
--- a/src/app/components/BunkerUrl.svelte
+++ b/src/app/components/BunkerUrl.svelte
@@ -1,16 +1,30 @@
@@ -20,7 +34,10 @@
{#snippet input()}
{/snippet}
{#snippet info()}
@@ -30,3 +47,6 @@
{/snippet}
+{#if showScanner}
+
+{/if}
diff --git a/src/app/components/LogInBunker.svelte b/src/app/components/LogInBunker.svelte
index 72fe1e6..296d52e 100644
--- a/src/app/components/LogInBunker.svelte
+++ b/src/app/components/LogInBunker.svelte
@@ -1,4 +1,5 @@
diff --git a/src/app/components/PrimaryNav.svelte b/src/app/components/PrimaryNav.svelte
index 2fa7ee9..7564712 100644
--- a/src/app/components/PrimaryNav.svelte
+++ b/src/app/components/PrimaryNav.svelte
@@ -77,7 +77,7 @@
{/if}
-
+
{/each}
diff --git a/src/app/components/SignerStatus.svelte b/src/app/components/SignerStatus.svelte
new file mode 100644
index 0000000..e9b3f85
--- /dev/null
+++ b/src/app/components/SignerStatus.svelte
@@ -0,0 +1,48 @@
+
+
+
+
+
+ Signer Status
+
+ {#if isDisconnected}
+ Disconnected
+ {:else if recentFailure > 3}
+ Partial Failure
+ {:else if recentAvg > 1000 || recentPending > 3}
+ Slow connection
+ {:else if recentSuccess === 0 && recentFailure > 0}{:else}
+ Ok
+ {/if}
+
+
+
+ {success} requests succeeded, {failure} failed, {pending} pending
+
+
+ {#if isDisconnected}
+
+ {/if}
+
diff --git a/src/app/nip46.ts b/src/app/nip46.ts
new file mode 100644
index 0000000..fe21497
--- /dev/null
+++ b/src/app/nip46.ts
@@ -0,0 +1,54 @@
+import {writable} from "svelte/store"
+import type {Nip46ResponseWithResult} from "@welshman/signer"
+import {Nip46Broker, makeSecret} from "@welshman/signer"
+import {NIP46_PERMS, PLATFORM_URL, PLATFORM_NAME, PLATFORM_LOGO, SIGNER_RELAYS} from "@app/state"
+import {pushToast} from "@app/toast"
+
+export class Nip46Controller {
+ url = writable("")
+ bunker = writable("")
+ loading = writable(false)
+ clientSecret = makeSecret()
+ abortController = new AbortController()
+ broker = new Nip46Broker({clientSecret: this.clientSecret, relays: SIGNER_RELAYS})
+ onNostrConnect: (response: Nip46ResponseWithResult) => void
+
+ constructor({onNostrConnect}: {onNostrConnect: (response: Nip46ResponseWithResult) => void}) {
+ this.onNostrConnect = onNostrConnect
+ }
+
+ async start() {
+ const url = await this.broker.makeNostrconnectUrl({
+ perms: NIP46_PERMS,
+ url: PLATFORM_URL,
+ name: PLATFORM_NAME,
+ image: PLATFORM_LOGO,
+ })
+
+ this.url.set(url)
+
+ let response
+ try {
+ response = await this.broker.waitForNostrconnect(url, this.abortController.signal)
+ } catch (errorResponse: any) {
+ if (errorResponse?.error) {
+ pushToast({
+ theme: "error",
+ message: `Received error from signer: ${errorResponse.error}`,
+ })
+ } else if (errorResponse) {
+ console.error(errorResponse)
+ }
+ }
+
+ if (response) {
+ this.loading.set(true)
+ this.onNostrConnect(response)
+ }
+ }
+
+ stop() {
+ this.broker.cleanup()
+ this.abortController.abort()
+ }
+}
diff --git a/src/routes/settings/profile/+page.svelte b/src/routes/settings/profile/+page.svelte
index 43b9d4d..c2bcb55 100644
--- a/src/routes/settings/profile/+page.svelte
+++ b/src/routes/settings/profile/+page.svelte
@@ -11,6 +11,7 @@
import Content from "@app/components/Content.svelte"
import ProfileEdit from "@app/components/ProfileEdit.svelte"
import ProfileDelete from "@app/components/ProfileDelete.svelte"
+ import SignerStatus from "@app/components/SignerStatus.svelte"
import InfoKeys from "@app/components/InfoKeys.svelte"
import Alerts from "@app/components/Alerts.svelte"
import {PLATFORM_NAME} from "@app/state"
@@ -129,6 +130,7 @@
{/snippet}
{/if}
+
diff --git a/svelte.config.js b/svelte.config.js
index 0699ce9..7b71079 100644
--- a/svelte.config.js
+++ b/svelte.config.js
@@ -16,7 +16,7 @@ export default {
},
csp: {
directives: {
- "script-src": ["self", "plausible.coracle.social"],
+ "script-src": ["self", "wasm-unsafe-eval", "plausible.coracle.social", "sha256-NpqGpeZTuPniNAucgyfqzWy9iIHwOswFzPzpigwvp/c="],
"worker-src": ["self", "blob:"],
"style-src": ["self", "unsafe-inline"],
"frame-src": ["none"],