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 @@
{#snippet title()} -
Log In
+
Log In with a Signer
{/snippet} {#snippet info()} -
Connect your signer by scanning the QR code below or pasting a bunker link.
+
Using a remote signer app helps you keep your keys safe.
{/snippet}
- - +
+ {#if mode === "connect"} + + {:else} + + + {/if} - - + {#if mode === "bunker"} + + {/if} 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"],