From 9b84454f53ff248a1390e9ec7a676093f7669697 Mon Sep 17 00:00:00 2001
From: fsociety
Date: Wed, 2 Oct 2024 00:33:36 +0200
Subject: [PATCH] feat: integrate nostr-login for user authentication
This commit integrates nostr-login for user authentication and removes the previous method. It includes changes in the package.json, Navbar.svelte, users.ts and the creation of a new file nostr-login/index.ts. This new method provides a more streamlined and efficient user authentication process.
---
package.json | 1 +
src/lib/components/Navbar.svelte | 45 +++++++++++++++++----------------------------
src/lib/signers/nostr-login/index.ts | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/lib/stores/users.ts | 72 +++++++++++++++++++++++-------------------------------------------------
src/lib/wrappers/Navbar.svelte | 21 ++-------------------
yarn.lock | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
6 files changed, 240 insertions(+), 109 deletions(-)
create mode 100644 src/lib/signers/nostr-login/index.ts
diff --git a/package.json b/package.json
index 8db6542..2539883 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-svelte": "^2.44.0",
+ "nostr-login": "^1.6.6",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.6",
diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte
index e66e96d..d5d3d3c 100644
--- a/src/lib/components/Navbar.svelte
+++ b/src/lib/components/Navbar.svelte
@@ -1,13 +1,28 @@
+ import { onMount } from 'svelte'
import { logout } from '$lib/stores/users'
import Container from './Container.svelte'
import UserHeader from './users/UserHeader.svelte'
import type { User } from './users/type'
export let logged_in_user: User | undefined = undefined
- export let nip07_plugin: boolean | undefined = undefined
export let login_function = () => {}
- export let singup_function = () => {}
+
+ interface NlAuthEvent extends Event {
+ detail: {
+ type: string
+ }
+ }
+
+ onMount(() => {
+ login_function()
+ document.addEventListener('nlAuth', (e: Event) => {
+ const event = e as NlAuthEvent
+ if (event.detail.type === 'logout') {
+ logout()
+ }
+ })
+ })
- {:else if nip07_plugin === undefined}
-
- {:else if nip07_plugin}
- - on:click={() => {
- login_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Login
- >
- {:else}
- - on:click={() => {
- singup_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Sign up
- >
{/if}
diff --git a/src/lib/signers/nostr-login/index.ts b/src/lib/signers/nostr-login/index.ts
new file mode 100644
index 0000000..563a8db
--- /dev/null
+++ b/src/lib/signers/nostr-login/index.ts
@@ -0,0 +1,111 @@
+import NDK, { NDKUser, NDKRelay } from '@nostr-dev-kit/ndk'
+import type { NDKSigner, NostrEvent } from '@nostr-dev-kit/ndk'
+
+export class NDKNostrLoginSigner implements NDKSigner {
+ private _userPromise: Promise | undefined
+
+ blockUntilReady(): Promise {
+ return new Promise((resolve) => {
+ const eventHandler = (event: Event) => {
+ document.removeEventListener('nlAuth', eventHandler)
+ const customEvent = event as CustomEvent<{ pubkey: string }>
+ resolve(new NDKUser({ pubkey: customEvent.detail.pubkey }))
+ }
+
+ document.addEventListener('nlAuth', eventHandler)
+ })
+ }
+
+ user(): Promise {
+ if (!this._userPromise) {
+ this._userPromise = this.blockUntilReady()
+ }
+
+ return this._userPromise
+ }
+
+ async sign(event: NostrEvent): Promise {
+ if (!window.nostr) {
+ throw new Error('window.nostr is undefined')
+ }
+ const signedEvent = await window.nostr.signEvent(event)
+ return signedEvent.sig
+ }
+
+ async relays?(ndk?: NDK): Promise {
+ const relays = (await window.nostr?.getRelays?.()) || {}
+
+ const activeRelays: string[] = []
+ for (const url of Object.keys(relays)) {
+ // Currently only respects relays that are both readable and writable.
+ if (relays[url].read && relays[url].write) {
+ activeRelays.push(url)
+ }
+ }
+ return activeRelays.map(
+ (url) => new NDKRelay(url, ndk?.relayAuthDefaultPolicy, ndk)
+ )
+ }
+
+ async encrypt(
+ recipient: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Encrypt(recipient, value)
+ } else {
+ return this.nip04Encrypt(recipient, value)
+ }
+ }
+
+ async decrypt(
+ sender: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Decrypt(sender, value)
+ } else {
+ return this.nip04Decrypt(sender, value)
+ }
+ }
+
+ private async nip44Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip04Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip44Decrypt(sender: NDKUser, value: string): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.decrypt(sender.pubkey, value)
+ }
+
+ private async nip04Decrypt(sender: NDKUser, value: string): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.decrypt(sender.pubkey, value)
+ }
+}
diff --git a/src/lib/stores/users.ts b/src/lib/stores/users.ts
index 608ffed..40ed744 100644
--- a/src/lib/stores/users.ts
+++ b/src/lib/stores/users.ts
@@ -2,13 +2,12 @@ import {
defaults as user_defaults,
type UserObject,
} from '$lib/components/users/type'
-import {
- getRelayListForUser,
- NDKNip07Signer,
- NDKRelayList,
-} from '@nostr-dev-kit/ndk'
+import { getRelayListForUser, NDKRelayList } from '@nostr-dev-kit/ndk'
import { get, writable, type Unsubscriber, type Writable } from 'svelte/store'
import { ndk } from './ndk'
+import { init as initNostrLogin } from 'nostr-login'
+import { NDKNostrLoginSigner } from '$lib/signers/nostr-login'
+import type { NostrLoginAuthOptions } from 'nostr-login/dist/types'
export const users: { [hexpubkey: string]: Writable } = {}
@@ -85,31 +84,7 @@ export const returnUser = async (hexpubkey: string): Promise => {
})
}
-// nip07_plugin is set in Navbar component
-export const nip07_plugin: Writable = writable(undefined)
-
-export const checkForNip07Plugin = () => {
- if (window.nostr) {
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- } else {
- let timerId: NodeJS.Timeout | undefined = undefined
- const intervalId = setInterval(() => {
- if (window.nostr) {
- clearTimeout(timerId)
- clearInterval(intervalId)
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- }
- }, 100)
- timerId = setTimeout(() => {
- clearInterval(intervalId)
- nip07_plugin.set(false)
- }, 5000)
- }
-}
-
-const signer = new NDKNip07Signer(2000)
+const signer = new NDKNostrLoginSigner()
export const logged_in_user: Writable =
writable(undefined)
@@ -118,24 +93,24 @@ export const login = async (): Promise => {
return new Promise(async (res, rej) => {
const user = get(logged_in_user)
if (user) return res()
- if (get(nip07_plugin)) {
- try {
- const ndk_user = await signer.blockUntilReady()
- localStorage.setItem('nip07pubkey', ndk_user.pubkey)
- logged_in_user.set({
- ...user_defaults,
- hexpubkey: ndk_user.pubkey,
- })
- ndk.signer = signer
- ensureUser(ndk_user.pubkey).subscribe((user) => {
- logged_in_user.set({ ...user })
- })
- return res()
- } catch (e) {
- alert(e)
- rej()
- }
- } else {
+ try {
+ ndk.signer = signer
+ initNostrLogin({
+ onAuth: async (_npub: string, options: NostrLoginAuthOptions) => {
+ const pubkey =
+ typeof options.pubkey === 'string' ? options.pubkey : ''
+ logged_in_user.set({
+ ...user_defaults,
+ hexpubkey: pubkey,
+ })
+ ensureUser(pubkey).subscribe((user) => {
+ logged_in_user.set({ ...user })
+ })
+ return res()
+ },
+ })
+ } catch (e) {
+ alert(e)
rej()
}
})
@@ -143,7 +118,6 @@ export const login = async (): Promise => {
export const logout = async (): Promise => {
logged_in_user.set(undefined)
- localStorage.removeItem('nip07pubkey')
ndk.signer = undefined
}
diff --git a/src/lib/wrappers/Navbar.svelte b/src/lib/wrappers/Navbar.svelte
index 4b63bc7..1f7146f 100644
--- a/src/lib/wrappers/Navbar.svelte
+++ b/src/lib/wrappers/Navbar.svelte
@@ -1,23 +1,6 @@
- import {
- checkForNip07Plugin,
- logged_in_user,
- login,
- nip07_plugin,
- } from '$lib/stores/users'
- import { onMount } from 'svelte'
+ import { logged_in_user, login } from '$lib/stores/users'
import Navbar from '$lib/components/Navbar.svelte'
-
- let singup_function = () => {
- alert('a NIP-07 browser extension is required. currently no signup page')
- }
-
- onMount(checkForNip07Plugin)
-- logged_in_user={$logged_in_user}
- nip07_plugin={$nip07_plugin}
- login_function={login}
- {singup_function}
-/>
+
diff --git a/yarn.lock b/yarn.lock
index f75be09..f976ab4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -566,6 +566,13 @@ __metadata:
languageName: node
linkType: hard
+"@noble/ciphers@npm:0.2.0":
+ version: 0.2.0
+ resolution: "@noble/ciphers@npm:0.2.0"
+ checksum: 10c0/57dea65c32741df20a1ac24f365d616a558527109d778c1bec877f20b28875a26b80097bce51ae19529f3792ccf8285fe73839ff404733e32a27a6ebf60edd2c
+ languageName: node
+ linkType: hard
+
"@noble/ciphers@npm:^0.5.1":
version: 0.5.3
resolution: "@noble/ciphers@npm:0.5.3"
@@ -573,6 +580,15 @@ __metadata:
languageName: node
linkType: hard
+"@noble/curves@npm:1.1.0, @noble/curves@npm:~1.1.0":
+ version: 1.1.0
+ resolution: "@noble/curves@npm:1.1.0"
+ dependencies:
+ "@noble/hashes": "npm:1.3.1"
+ checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
+ languageName: node
+ linkType: hard
+
"@noble/curves@npm:1.2.0":
version: 1.2.0
resolution: "@noble/curves@npm:1.2.0"
@@ -582,7 +598,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:^1.4.0":
+"@noble/curves@npm:^1.4.0, @noble/curves@npm:^1.6.0":
version: 1.6.0
resolution: "@noble/curves@npm:1.6.0"
dependencies:
@@ -591,15 +607,6 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:~1.1.0":
- version: 1.1.0
- resolution: "@noble/curves@npm:1.1.0"
- dependencies:
- "@noble/hashes": "npm:1.3.1"
- checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
- languageName: node
- linkType: hard
-
"@noble/hashes@npm:1.3.1":
version: 1.3.1
resolution: "@noble/hashes@npm:1.3.1"
@@ -614,7 +621,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1":
+"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.5.0":
version: 1.5.0
resolution: "@noble/hashes@npm:1.5.0"
checksum: 10c0/1b46539695fbfe4477c0822d90c881a04d4fa2921c08c552375b444a48cac9930cb1ee68de0a3c7859e676554d0f3771999716606dc4d8f826e414c11692cdd9
@@ -628,7 +635,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/secp256k1@npm:^2.0.0":
+"@noble/secp256k1@npm:^2.0.0, @noble/secp256k1@npm:^2.1.0":
version: 2.1.0
resolution: "@noble/secp256k1@npm:2.1.0"
checksum: 10c0/b4c7edd2a5ec5acf294546cd06d08dc2a2a2b2ebe34a6da1f2f5104f56983f81dd31c261ad365c6b9757d1c54017fc3363331ee33bba8715ff94c2bc954313cc
@@ -692,6 +699,25 @@ __metadata:
languageName: node
linkType: hard
+"@nostr-dev-kit/ndk@npm:^2.3.1":
+ version: 2.10.1
+ resolution: "@nostr-dev-kit/ndk@npm:2.10.1"
+ dependencies:
+ "@noble/curves": "npm:^1.6.0"
+ "@noble/hashes": "npm:^1.5.0"
+ "@noble/secp256k1": "npm:^2.1.0"
+ "@scure/base": "npm:^1.1.9"
+ debug: "npm:^4.3.6"
+ light-bolt11-decoder: "npm:^3.2.0"
+ nostr-tools: "npm:^2.7.1"
+ tseep: "npm:^1.2.2"
+ typescript-lru-cache: "npm:^2.0.0"
+ utf8-buffer: "npm:^1.0.0"
+ websocket-polyfill: "npm:^0.0.3"
+ checksum: 10c0/b73cd0e9f036e60893d0470d778c5e672795f93308edca389d42c9487267e95df208b2b2353b20eb766ae606cfd1c328d03a1e43d69351e27159843cdb619cc9
+ languageName: node
+ linkType: hard
+
"@npmcli/agent@npm:^2.0.0":
version: 2.2.2
resolution: "@npmcli/agent@npm:2.2.2"
@@ -854,7 +880,7 @@ __metadata:
languageName: node
linkType: hard
-"@scure/base@npm:^1.1.1, @scure/base@npm:~1.1.0":
+"@scure/base@npm:^1.1.1, @scure/base@npm:^1.1.9, @scure/base@npm:~1.1.0":
version: 1.1.9
resolution: "@scure/base@npm:1.1.9"
checksum: 10c0/77a06b9a2db8144d22d9bf198338893d77367c51b58c72b99df990c0a11f7cadd066d4102abb15e3ca6798d1529e3765f55c4355742465e49aed7a0c01fe76e8
@@ -3857,6 +3883,7 @@ __metadata:
eslint-plugin-prettier: "npm:^5.2.1"
eslint-plugin-svelte: "npm:^2.44.0"
highlight.js: "npm:^11.10.0"
+ nostr-login: "npm:^1.6.6"
nostr-tools: "npm:^2.7.2"
parse-diff: "npm:^0.11.1"
postcss: "npm:^8.4.47"
@@ -4492,6 +4519,15 @@ __metadata:
languageName: node
linkType: hard
+"light-bolt11-decoder@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "light-bolt11-decoder@npm:3.2.0"
+ dependencies:
+ "@scure/base": "npm:1.1.1"
+ checksum: 10c0/65c1514b40b3b7fd5f4f0b40412bab35b0135f20f6b4929f5616bc5693f759fa8636d2393ba71fa782b2d9204315015e044628736ee7aea72f71939b0eb486f1
+ languageName: node
+ linkType: hard
+
"lilconfig@npm:^2.0.5, lilconfig@npm:^2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
@@ -5030,6 +5066,36 @@ __metadata:
languageName: node
linkType: hard
+"nostr-login@npm:^1.6.6":
+ version: 1.6.6
+ resolution: "nostr-login@npm:1.6.6"
+ dependencies:
+ "@nostr-dev-kit/ndk": "npm:^2.3.1"
+ nostr-tools: "npm:^1.17.0"
+ tseep: "npm:^1.2.1"
+ checksum: 10c0/f521f906eef377321406838d2ab3be314c9755cbbad90328f32cd65fc5b035bb85729116bc5da313445c399aafb9f1bc12833a789f440e58f12619e84d9ff15f
+ languageName: node
+ linkType: hard
+
+"nostr-tools@npm:^1.17.0":
+ version: 1.17.0
+ resolution: "nostr-tools@npm:1.17.0"
+ dependencies:
+ "@noble/ciphers": "npm:0.2.0"
+ "@noble/curves": "npm:1.1.0"
+ "@noble/hashes": "npm:1.3.1"
+ "@scure/base": "npm:1.1.1"
+ "@scure/bip32": "npm:1.3.1"
+ "@scure/bip39": "npm:1.2.1"
+ peerDependencies:
+ typescript: ">=5.0.0"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: 10c0/b52732df3e403ef3c73a41fe1dea89accbff91597b231d811d577c35a9bd9307651de65ec7fbcc9989aef4c35e9c6b1005200fbbfec45544dcd64f928bbfc476
+ languageName: node
+ linkType: hard
+
"nostr-tools@npm:^2.7.1, nostr-tools@npm:^2.7.2":
version: 2.7.2
resolution: "nostr-tools@npm:2.7.2"
@@ -6638,6 +6704,13 @@ __metadata:
languageName: node
linkType: hard
+"tseep@npm:^1.2.1, tseep@npm:^1.2.2":
+ version: 1.3.1
+ resolution: "tseep@npm:1.3.1"
+ checksum: 10c0/01b68f1f0e1084ff78bed9f28d83a595b4b6256caecd8c245af62716037dc4e87c9916c90d5d5cd4a2935f7d438a1117b2703dbf8abc79f087bc176a6f247ed6
+ languageName: node
+ linkType: hard
+
"tslib@npm:^2.0.1, tslib@npm:^2.6.2, tslib@npm:^2.7.0":
version: 2.7.0
resolution: "tslib@npm:2.7.0"
--
libgit2 1.8.1
I test a refactored version of the signer.
From 9b84454f53ff248a1390e9ec7a676093f7669697 Mon Sep 17 00:00:00 2001
From: fsociety
Date: Wed, 2 Oct 2024 00:33:36 +0200
Subject: [PATCH] feat: integrate nostr-login for user authentication
This commit integrates nostr-login for user authentication and removes the previous method. It includes changes in the package.json, Navbar.svelte, users.ts and the creation of a new file nostr-login/index.ts. This new method provides a more streamlined and efficient user authentication process.
---
package.json | 1 +
src/lib/components/Navbar.svelte | 45 +++++++++++++++++----------------------------
src/lib/signers/nostr-login/index.ts | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/lib/stores/users.ts | 72 +++++++++++++++++++++++-------------------------------------------------
src/lib/wrappers/Navbar.svelte | 21 ++-------------------
yarn.lock | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
6 files changed, 240 insertions(+), 109 deletions(-)
create mode 100644 src/lib/signers/nostr-login/index.ts
diff --git a/package.json b/package.json
index 8db6542..2539883 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-svelte": "^2.44.0",
+ "nostr-login": "^1.6.6",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.6",
diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte
index e66e96d..d5d3d3c 100644
--- a/src/lib/components/Navbar.svelte
+++ b/src/lib/components/Navbar.svelte
@@ -1,13 +1,28 @@
+ import { onMount } from 'svelte'
import { logout } from '$lib/stores/users'
import Container from './Container.svelte'
import UserHeader from './users/UserHeader.svelte'
import type { User } from './users/type'
export let logged_in_user: User | undefined = undefined
- export let nip07_plugin: boolean | undefined = undefined
export let login_function = () => {}
- export let singup_function = () => {}
+
+ interface NlAuthEvent extends Event {
+ detail: {
+ type: string
+ }
+ }
+
+ onMount(() => {
+ login_function()
+ document.addEventListener('nlAuth', (e: Event) => {
+ const event = e as NlAuthEvent
+ if (event.detail.type === 'logout') {
+ logout()
+ }
+ })
+ })
- {:else if nip07_plugin === undefined}
-
- {:else if nip07_plugin}
- - on:click={() => {
- login_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Login
- >
- {:else}
- - on:click={() => {
- singup_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Sign up
- >
{/if}
diff --git a/src/lib/signers/nostr-login/index.ts b/src/lib/signers/nostr-login/index.ts
new file mode 100644
index 0000000..563a8db
--- /dev/null
+++ b/src/lib/signers/nostr-login/index.ts
@@ -0,0 +1,111 @@
+import NDK, { NDKUser, NDKRelay } from '@nostr-dev-kit/ndk'
+import type { NDKSigner, NostrEvent } from '@nostr-dev-kit/ndk'
+
+export class NDKNostrLoginSigner implements NDKSigner {
+ private _userPromise: Promise | undefined
+
+ blockUntilReady(): Promise {
+ return new Promise((resolve) => {
+ const eventHandler = (event: Event) => {
+ document.removeEventListener('nlAuth', eventHandler)
+ const customEvent = event as CustomEvent<{ pubkey: string }>
+ resolve(new NDKUser({ pubkey: customEvent.detail.pubkey }))
+ }
+
+ document.addEventListener('nlAuth', eventHandler)
+ })
+ }
+
+ user(): Promise {
+ if (!this._userPromise) {
+ this._userPromise = this.blockUntilReady()
+ }
+
+ return this._userPromise
+ }
+
+ async sign(event: NostrEvent): Promise {
+ if (!window.nostr) {
+ throw new Error('window.nostr is undefined')
+ }
+ const signedEvent = await window.nostr.signEvent(event)
+ return signedEvent.sig
+ }
+
+ async relays?(ndk?: NDK): Promise {
+ const relays = (await window.nostr?.getRelays?.()) || {}
+
+ const activeRelays: string[] = []
+ for (const url of Object.keys(relays)) {
+ // Currently only respects relays that are both readable and writable.
+ if (relays[url].read && relays[url].write) {
+ activeRelays.push(url)
+ }
+ }
+ return activeRelays.map(
+ (url) => new NDKRelay(url, ndk?.relayAuthDefaultPolicy, ndk)
+ )
+ }
+
+ async encrypt(
+ recipient: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Encrypt(recipient, value)
+ } else {
+ return this.nip04Encrypt(recipient, value)
+ }
+ }
+
+ async decrypt(
+ sender: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Decrypt(sender, value)
+ } else {
+ return this.nip04Decrypt(sender, value)
+ }
+ }
+
+ private async nip44Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip04Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip44Decrypt(sender: NDKUser, value: string): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.decrypt(sender.pubkey, value)
+ }
+
+ private async nip04Decrypt(sender: NDKUser, value: string): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.decrypt(sender.pubkey, value)
+ }
+}
diff --git a/src/lib/stores/users.ts b/src/lib/stores/users.ts
index 608ffed..40ed744 100644
--- a/src/lib/stores/users.ts
+++ b/src/lib/stores/users.ts
@@ -2,13 +2,12 @@ import {
defaults as user_defaults,
type UserObject,
} from '$lib/components/users/type'
-import {
- getRelayListForUser,
- NDKNip07Signer,
- NDKRelayList,
-} from '@nostr-dev-kit/ndk'
+import { getRelayListForUser, NDKRelayList } from '@nostr-dev-kit/ndk'
import { get, writable, type Unsubscriber, type Writable } from 'svelte/store'
import { ndk } from './ndk'
+import { init as initNostrLogin } from 'nostr-login'
+import { NDKNostrLoginSigner } from '$lib/signers/nostr-login'
+import type { NostrLoginAuthOptions } from 'nostr-login/dist/types'
export const users: { [hexpubkey: string]: Writable } = {}
@@ -85,31 +84,7 @@ export const returnUser = async (hexpubkey: string): Promise => {
})
}
-// nip07_plugin is set in Navbar component
-export const nip07_plugin: Writable = writable(undefined)
-
-export const checkForNip07Plugin = () => {
- if (window.nostr) {
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- } else {
- let timerId: NodeJS.Timeout | undefined = undefined
- const intervalId = setInterval(() => {
- if (window.nostr) {
- clearTimeout(timerId)
- clearInterval(intervalId)
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- }
- }, 100)
- timerId = setTimeout(() => {
- clearInterval(intervalId)
- nip07_plugin.set(false)
- }, 5000)
- }
-}
-
-const signer = new NDKNip07Signer(2000)
+const signer = new NDKNostrLoginSigner()
export const logged_in_user: Writable =
writable(undefined)
@@ -118,24 +93,24 @@ export const login = async (): Promise => {
return new Promise(async (res, rej) => {
const user = get(logged_in_user)
if (user) return res()
- if (get(nip07_plugin)) {
- try {
- const ndk_user = await signer.blockUntilReady()
- localStorage.setItem('nip07pubkey', ndk_user.pubkey)
- logged_in_user.set({
- ...user_defaults,
- hexpubkey: ndk_user.pubkey,
- })
- ndk.signer = signer
- ensureUser(ndk_user.pubkey).subscribe((user) => {
- logged_in_user.set({ ...user })
- })
- return res()
- } catch (e) {
- alert(e)
- rej()
- }
- } else {
+ try {
+ ndk.signer = signer
+ initNostrLogin({
+ onAuth: async (_npub: string, options: NostrLoginAuthOptions) => {
+ const pubkey =
+ typeof options.pubkey === 'string' ? options.pubkey : ''
+ logged_in_user.set({
+ ...user_defaults,
+ hexpubkey: pubkey,
+ })
+ ensureUser(pubkey).subscribe((user) => {
+ logged_in_user.set({ ...user })
+ })
+ return res()
+ },
+ })
+ } catch (e) {
+ alert(e)
rej()
}
})
@@ -143,7 +118,6 @@ export const login = async (): Promise => {
export const logout = async (): Promise => {
logged_in_user.set(undefined)
- localStorage.removeItem('nip07pubkey')
ndk.signer = undefined
}
diff --git a/src/lib/wrappers/Navbar.svelte b/src/lib/wrappers/Navbar.svelte
index 4b63bc7..1f7146f 100644
--- a/src/lib/wrappers/Navbar.svelte
+++ b/src/lib/wrappers/Navbar.svelte
@@ -1,23 +1,6 @@
- import {
- checkForNip07Plugin,
- logged_in_user,
- login,
- nip07_plugin,
- } from '$lib/stores/users'
- import { onMount } from 'svelte'
+ import { logged_in_user, login } from '$lib/stores/users'
import Navbar from '$lib/components/Navbar.svelte'
-
- let singup_function = () => {
- alert('a NIP-07 browser extension is required. currently no signup page')
- }
-
- onMount(checkForNip07Plugin)
-- logged_in_user={$logged_in_user}
- nip07_plugin={$nip07_plugin}
- login_function={login}
- {singup_function}
-/>
+
diff --git a/yarn.lock b/yarn.lock
index f75be09..f976ab4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -566,6 +566,13 @@ __metadata:
languageName: node
linkType: hard
+"@noble/ciphers@npm:0.2.0":
+ version: 0.2.0
+ resolution: "@noble/ciphers@npm:0.2.0"
+ checksum: 10c0/57dea65c32741df20a1ac24f365d616a558527109d778c1bec877f20b28875a26b80097bce51ae19529f3792ccf8285fe73839ff404733e32a27a6ebf60edd2c
+ languageName: node
+ linkType: hard
+
"@noble/ciphers@npm:^0.5.1":
version: 0.5.3
resolution: "@noble/ciphers@npm:0.5.3"
@@ -573,6 +580,15 @@ __metadata:
languageName: node
linkType: hard
+"@noble/curves@npm:1.1.0, @noble/curves@npm:~1.1.0":
+ version: 1.1.0
+ resolution: "@noble/curves@npm:1.1.0"
+ dependencies:
+ "@noble/hashes": "npm:1.3.1"
+ checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
+ languageName: node
+ linkType: hard
+
"@noble/curves@npm:1.2.0":
version: 1.2.0
resolution: "@noble/curves@npm:1.2.0"
@@ -582,7 +598,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:^1.4.0":
+"@noble/curves@npm:^1.4.0, @noble/curves@npm:^1.6.0":
version: 1.6.0
resolution: "@noble/curves@npm:1.6.0"
dependencies:
@@ -591,15 +607,6 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:~1.1.0":
- version: 1.1.0
- resolution: "@noble/curves@npm:1.1.0"
- dependencies:
- "@noble/hashes": "npm:1.3.1"
- checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
- languageName: node
- linkType: hard
-
"@noble/hashes@npm:1.3.1":
version: 1.3.1
resolution: "@noble/hashes@npm:1.3.1"
@@ -614,7 +621,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1":
+"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.5.0":
version: 1.5.0
resolution: "@noble/hashes@npm:1.5.0"
checksum: 10c0/1b46539695fbfe4477c0822d90c881a04d4fa2921c08c552375b444a48cac9930cb1ee68de0a3c7859e676554d0f3771999716606dc4d8f826e414c11692cdd9
@@ -628,7 +635,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/secp256k1@npm:^2.0.0":
+"@noble/secp256k1@npm:^2.0.0, @noble/secp256k1@npm:^2.1.0":
version: 2.1.0
resolution: "@noble/secp256k1@npm:2.1.0"
checksum: 10c0/b4c7edd2a5ec5acf294546cd06d08dc2a2a2b2ebe34a6da1f2f5104f56983f81dd31c261ad365c6b9757d1c54017fc3363331ee33bba8715ff94c2bc954313cc
@@ -692,6 +699,25 @@ __metadata:
languageName: node
linkType: hard
+"@nostr-dev-kit/ndk@npm:^2.3.1":
+ version: 2.10.1
+ resolution: "@nostr-dev-kit/ndk@npm:2.10.1"
+ dependencies:
+ "@noble/curves": "npm:^1.6.0"
+ "@noble/hashes": "npm:^1.5.0"
+ "@noble/secp256k1": "npm:^2.1.0"
+ "@scure/base": "npm:^1.1.9"
+ debug: "npm:^4.3.6"
+ light-bolt11-decoder: "npm:^3.2.0"
+ nostr-tools: "npm:^2.7.1"
+ tseep: "npm:^1.2.2"
+ typescript-lru-cache: "npm:^2.0.0"
+ utf8-buffer: "npm:^1.0.0"
+ websocket-polyfill: "npm:^0.0.3"
+ checksum: 10c0/b73cd0e9f036e60893d0470d778c5e672795f93308edca389d42c9487267e95df208b2b2353b20eb766ae606cfd1c328d03a1e43d69351e27159843cdb619cc9
+ languageName: node
+ linkType: hard
+
"@npmcli/agent@npm:^2.0.0":
version: 2.2.2
resolution: "@npmcli/agent@npm:2.2.2"
@@ -854,7 +880,7 @@ __metadata:
languageName: node
linkType: hard
-"@scure/base@npm:^1.1.1, @scure/base@npm:~1.1.0":
+"@scure/base@npm:^1.1.1, @scure/base@npm:^1.1.9, @scure/base@npm:~1.1.0":
version: 1.1.9
resolution: "@scure/base@npm:1.1.9"
checksum: 10c0/77a06b9a2db8144d22d9bf198338893d77367c51b58c72b99df990c0a11f7cadd066d4102abb15e3ca6798d1529e3765f55c4355742465e49aed7a0c01fe76e8
@@ -3857,6 +3883,7 @@ __metadata:
eslint-plugin-prettier: "npm:^5.2.1"
eslint-plugin-svelte: "npm:^2.44.0"
highlight.js: "npm:^11.10.0"
+ nostr-login: "npm:^1.6.6"
nostr-tools: "npm:^2.7.2"
parse-diff: "npm:^0.11.1"
postcss: "npm:^8.4.47"
@@ -4492,6 +4519,15 @@ __metadata:
languageName: node
linkType: hard
+"light-bolt11-decoder@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "light-bolt11-decoder@npm:3.2.0"
+ dependencies:
+ "@scure/base": "npm:1.1.1"
+ checksum: 10c0/65c1514b40b3b7fd5f4f0b40412bab35b0135f20f6b4929f5616bc5693f759fa8636d2393ba71fa782b2d9204315015e044628736ee7aea72f71939b0eb486f1
+ languageName: node
+ linkType: hard
+
"lilconfig@npm:^2.0.5, lilconfig@npm:^2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
@@ -5030,6 +5066,36 @@ __metadata:
languageName: node
linkType: hard
+"nostr-login@npm:^1.6.6":
+ version: 1.6.6
+ resolution: "nostr-login@npm:1.6.6"
+ dependencies:
+ "@nostr-dev-kit/ndk": "npm:^2.3.1"
+ nostr-tools: "npm:^1.17.0"
+ tseep: "npm:^1.2.1"
+ checksum: 10c0/f521f906eef377321406838d2ab3be314c9755cbbad90328f32cd65fc5b035bb85729116bc5da313445c399aafb9f1bc12833a789f440e58f12619e84d9ff15f
+ languageName: node
+ linkType: hard
+
+"nostr-tools@npm:^1.17.0":
+ version: 1.17.0
+ resolution: "nostr-tools@npm:1.17.0"
+ dependencies:
+ "@noble/ciphers": "npm:0.2.0"
+ "@noble/curves": "npm:1.1.0"
+ "@noble/hashes": "npm:1.3.1"
+ "@scure/base": "npm:1.1.1"
+ "@scure/bip32": "npm:1.3.1"
+ "@scure/bip39": "npm:1.2.1"
+ peerDependencies:
+ typescript: ">=5.0.0"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: 10c0/b52732df3e403ef3c73a41fe1dea89accbff91597b231d811d577c35a9bd9307651de65ec7fbcc9989aef4c35e9c6b1005200fbbfec45544dcd64f928bbfc476
+ languageName: node
+ linkType: hard
+
"nostr-tools@npm:^2.7.1, nostr-tools@npm:^2.7.2":
version: 2.7.2
resolution: "nostr-tools@npm:2.7.2"
@@ -6638,6 +6704,13 @@ __metadata:
languageName: node
linkType: hard
+"tseep@npm:^1.2.1, tseep@npm:^1.2.2":
+ version: 1.3.1
+ resolution: "tseep@npm:1.3.1"
+ checksum: 10c0/01b68f1f0e1084ff78bed9f28d83a595b4b6256caecd8c245af62716037dc4e87c9916c90d5d5cd4a2935f7d438a1117b2703dbf8abc79f087bc176a6f247ed6
+ languageName: node
+ linkType: hard
+
"tslib@npm:^2.0.1, tslib@npm:^2.6.2, tslib@npm:^2.7.0":
version: 2.7.0
resolution: "tslib@npm:2.7.0"
--
libgit2 1.8.1
Very nice. It works. I can now switch accounts with nostr-login.
From 9b84454f53ff248a1390e9ec7a676093f7669697 Mon Sep 17 00:00:00 2001
From: fsociety
Date: Wed, 2 Oct 2024 00:33:36 +0200
Subject: [PATCH] feat: integrate nostr-login for user authentication
This commit integrates nostr-login for user authentication and removes the previous method. It includes changes in the package.json, Navbar.svelte, users.ts and the creation of a new file nostr-login/index.ts. This new method provides a more streamlined and efficient user authentication process.
---
package.json | 1 +
src/lib/components/Navbar.svelte | 45 +++++++++++++++++----------------------------
src/lib/signers/nostr-login/index.ts | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/lib/stores/users.ts | 72 +++++++++++++++++++++++-------------------------------------------------
src/lib/wrappers/Navbar.svelte | 21 ++-------------------
yarn.lock | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
6 files changed, 240 insertions(+), 109 deletions(-)
create mode 100644 src/lib/signers/nostr-login/index.ts
diff --git a/package.json b/package.json
index 8db6542..2539883 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-svelte": "^2.44.0",
+ "nostr-login": "^1.6.6",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.6",
diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte
index e66e96d..d5d3d3c 100644
--- a/src/lib/components/Navbar.svelte
+++ b/src/lib/components/Navbar.svelte
@@ -1,13 +1,28 @@
+ import { onMount } from 'svelte'
import { logout } from '$lib/stores/users'
import Container from './Container.svelte'
import UserHeader from './users/UserHeader.svelte'
import type { User } from './users/type'
export let logged_in_user: User | undefined = undefined
- export let nip07_plugin: boolean | undefined = undefined
export let login_function = () => {}
- export let singup_function = () => {}
+
+ interface NlAuthEvent extends Event {
+ detail: {
+ type: string
+ }
+ }
+
+ onMount(() => {
+ login_function()
+ document.addEventListener('nlAuth', (e: Event) => {
+ const event = e as NlAuthEvent
+ if (event.detail.type === 'logout') {
+ logout()
+ }
+ })
+ })
- {:else if nip07_plugin === undefined}
-
- {:else if nip07_plugin}
- - on:click={() => {
- login_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Login
- >
- {:else}
- - on:click={() => {
- singup_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Sign up
- >
{/if}
diff --git a/src/lib/signers/nostr-login/index.ts b/src/lib/signers/nostr-login/index.ts
new file mode 100644
index 0000000..563a8db
--- /dev/null
+++ b/src/lib/signers/nostr-login/index.ts
@@ -0,0 +1,111 @@
+import NDK, { NDKUser, NDKRelay } from '@nostr-dev-kit/ndk'
+import type { NDKSigner, NostrEvent } from '@nostr-dev-kit/ndk'
+
+export class NDKNostrLoginSigner implements NDKSigner {
+ private _userPromise: Promise | undefined
+
+ blockUntilReady(): Promise {
+ return new Promise((resolve) => {
+ const eventHandler = (event: Event) => {
+ document.removeEventListener('nlAuth', eventHandler)
+ const customEvent = event as CustomEvent<{ pubkey: string }>
+ resolve(new NDKUser({ pubkey: customEvent.detail.pubkey }))
+ }
+
+ document.addEventListener('nlAuth', eventHandler)
+ })
+ }
+
+ user(): Promise {
+ if (!this._userPromise) {
+ this._userPromise = this.blockUntilReady()
+ }
+
+ return this._userPromise
+ }
+
+ async sign(event: NostrEvent): Promise {
+ if (!window.nostr) {
+ throw new Error('window.nostr is undefined')
+ }
+ const signedEvent = await window.nostr.signEvent(event)
+ return signedEvent.sig
+ }
+
+ async relays?(ndk?: NDK): Promise {
+ const relays = (await window.nostr?.getRelays?.()) || {}
+
+ const activeRelays: string[] = []
+ for (const url of Object.keys(relays)) {
+ // Currently only respects relays that are both readable and writable.
+ if (relays[url].read && relays[url].write) {
+ activeRelays.push(url)
+ }
+ }
+ return activeRelays.map(
+ (url) => new NDKRelay(url, ndk?.relayAuthDefaultPolicy, ndk)
+ )
+ }
+
+ async encrypt(
+ recipient: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Encrypt(recipient, value)
+ } else {
+ return this.nip04Encrypt(recipient, value)
+ }
+ }
+
+ async decrypt(
+ sender: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Decrypt(sender, value)
+ } else {
+ return this.nip04Decrypt(sender, value)
+ }
+ }
+
+ private async nip44Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip04Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip44Decrypt(sender: NDKUser, value: string): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.decrypt(sender.pubkey, value)
+ }
+
+ private async nip04Decrypt(sender: NDKUser, value: string): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.decrypt(sender.pubkey, value)
+ }
+}
diff --git a/src/lib/stores/users.ts b/src/lib/stores/users.ts
index 608ffed..40ed744 100644
--- a/src/lib/stores/users.ts
+++ b/src/lib/stores/users.ts
@@ -2,13 +2,12 @@ import {
defaults as user_defaults,
type UserObject,
} from '$lib/components/users/type'
-import {
- getRelayListForUser,
- NDKNip07Signer,
- NDKRelayList,
-} from '@nostr-dev-kit/ndk'
+import { getRelayListForUser, NDKRelayList } from '@nostr-dev-kit/ndk'
import { get, writable, type Unsubscriber, type Writable } from 'svelte/store'
import { ndk } from './ndk'
+import { init as initNostrLogin } from 'nostr-login'
+import { NDKNostrLoginSigner } from '$lib/signers/nostr-login'
+import type { NostrLoginAuthOptions } from 'nostr-login/dist/types'
export const users: { [hexpubkey: string]: Writable } = {}
@@ -85,31 +84,7 @@ export const returnUser = async (hexpubkey: string): Promise => {
})
}
-// nip07_plugin is set in Navbar component
-export const nip07_plugin: Writable = writable(undefined)
-
-export const checkForNip07Plugin = () => {
- if (window.nostr) {
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- } else {
- let timerId: NodeJS.Timeout | undefined = undefined
- const intervalId = setInterval(() => {
- if (window.nostr) {
- clearTimeout(timerId)
- clearInterval(intervalId)
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- }
- }, 100)
- timerId = setTimeout(() => {
- clearInterval(intervalId)
- nip07_plugin.set(false)
- }, 5000)
- }
-}
-
-const signer = new NDKNip07Signer(2000)
+const signer = new NDKNostrLoginSigner()
export const logged_in_user: Writable =
writable(undefined)
@@ -118,24 +93,24 @@ export const login = async (): Promise => {
return new Promise(async (res, rej) => {
const user = get(logged_in_user)
if (user) return res()
- if (get(nip07_plugin)) {
- try {
- const ndk_user = await signer.blockUntilReady()
- localStorage.setItem('nip07pubkey', ndk_user.pubkey)
- logged_in_user.set({
- ...user_defaults,
- hexpubkey: ndk_user.pubkey,
- })
- ndk.signer = signer
- ensureUser(ndk_user.pubkey).subscribe((user) => {
- logged_in_user.set({ ...user })
- })
- return res()
- } catch (e) {
- alert(e)
- rej()
- }
- } else {
+ try {
+ ndk.signer = signer
+ initNostrLogin({
+ onAuth: async (_npub: string, options: NostrLoginAuthOptions) => {
+ const pubkey =
+ typeof options.pubkey === 'string' ? options.pubkey : ''
+ logged_in_user.set({
+ ...user_defaults,
+ hexpubkey: pubkey,
+ })
+ ensureUser(pubkey).subscribe((user) => {
+ logged_in_user.set({ ...user })
+ })
+ return res()
+ },
+ })
+ } catch (e) {
+ alert(e)
rej()
}
})
@@ -143,7 +118,6 @@ export const login = async (): Promise => {
export const logout = async (): Promise => {
logged_in_user.set(undefined)
- localStorage.removeItem('nip07pubkey')
ndk.signer = undefined
}
diff --git a/src/lib/wrappers/Navbar.svelte b/src/lib/wrappers/Navbar.svelte
index 4b63bc7..1f7146f 100644
--- a/src/lib/wrappers/Navbar.svelte
+++ b/src/lib/wrappers/Navbar.svelte
@@ -1,23 +1,6 @@
- import {
- checkForNip07Plugin,
- logged_in_user,
- login,
- nip07_plugin,
- } from '$lib/stores/users'
- import { onMount } from 'svelte'
+ import { logged_in_user, login } from '$lib/stores/users'
import Navbar from '$lib/components/Navbar.svelte'
-
- let singup_function = () => {
- alert('a NIP-07 browser extension is required. currently no signup page')
- }
-
- onMount(checkForNip07Plugin)
-- logged_in_user={$logged_in_user}
- nip07_plugin={$nip07_plugin}
- login_function={login}
- {singup_function}
-/>
+
diff --git a/yarn.lock b/yarn.lock
index f75be09..f976ab4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -566,6 +566,13 @@ __metadata:
languageName: node
linkType: hard
+"@noble/ciphers@npm:0.2.0":
+ version: 0.2.0
+ resolution: "@noble/ciphers@npm:0.2.0"
+ checksum: 10c0/57dea65c32741df20a1ac24f365d616a558527109d778c1bec877f20b28875a26b80097bce51ae19529f3792ccf8285fe73839ff404733e32a27a6ebf60edd2c
+ languageName: node
+ linkType: hard
+
"@noble/ciphers@npm:^0.5.1":
version: 0.5.3
resolution: "@noble/ciphers@npm:0.5.3"
@@ -573,6 +580,15 @@ __metadata:
languageName: node
linkType: hard
+"@noble/curves@npm:1.1.0, @noble/curves@npm:~1.1.0":
+ version: 1.1.0
+ resolution: "@noble/curves@npm:1.1.0"
+ dependencies:
+ "@noble/hashes": "npm:1.3.1"
+ checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
+ languageName: node
+ linkType: hard
+
"@noble/curves@npm:1.2.0":
version: 1.2.0
resolution: "@noble/curves@npm:1.2.0"
@@ -582,7 +598,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:^1.4.0":
+"@noble/curves@npm:^1.4.0, @noble/curves@npm:^1.6.0":
version: 1.6.0
resolution: "@noble/curves@npm:1.6.0"
dependencies:
@@ -591,15 +607,6 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:~1.1.0":
- version: 1.1.0
- resolution: "@noble/curves@npm:1.1.0"
- dependencies:
- "@noble/hashes": "npm:1.3.1"
- checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
- languageName: node
- linkType: hard
-
"@noble/hashes@npm:1.3.1":
version: 1.3.1
resolution: "@noble/hashes@npm:1.3.1"
@@ -614,7 +621,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1":
+"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.5.0":
version: 1.5.0
resolution: "@noble/hashes@npm:1.5.0"
checksum: 10c0/1b46539695fbfe4477c0822d90c881a04d4fa2921c08c552375b444a48cac9930cb1ee68de0a3c7859e676554d0f3771999716606dc4d8f826e414c11692cdd9
@@ -628,7 +635,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/secp256k1@npm:^2.0.0":
+"@noble/secp256k1@npm:^2.0.0, @noble/secp256k1@npm:^2.1.0":
version: 2.1.0
resolution: "@noble/secp256k1@npm:2.1.0"
checksum: 10c0/b4c7edd2a5ec5acf294546cd06d08dc2a2a2b2ebe34a6da1f2f5104f56983f81dd31c261ad365c6b9757d1c54017fc3363331ee33bba8715ff94c2bc954313cc
@@ -692,6 +699,25 @@ __metadata:
languageName: node
linkType: hard
+"@nostr-dev-kit/ndk@npm:^2.3.1":
+ version: 2.10.1
+ resolution: "@nostr-dev-kit/ndk@npm:2.10.1"
+ dependencies:
+ "@noble/curves": "npm:^1.6.0"
+ "@noble/hashes": "npm:^1.5.0"
+ "@noble/secp256k1": "npm:^2.1.0"
+ "@scure/base": "npm:^1.1.9"
+ debug: "npm:^4.3.6"
+ light-bolt11-decoder: "npm:^3.2.0"
+ nostr-tools: "npm:^2.7.1"
+ tseep: "npm:^1.2.2"
+ typescript-lru-cache: "npm:^2.0.0"
+ utf8-buffer: "npm:^1.0.0"
+ websocket-polyfill: "npm:^0.0.3"
+ checksum: 10c0/b73cd0e9f036e60893d0470d778c5e672795f93308edca389d42c9487267e95df208b2b2353b20eb766ae606cfd1c328d03a1e43d69351e27159843cdb619cc9
+ languageName: node
+ linkType: hard
+
"@npmcli/agent@npm:^2.0.0":
version: 2.2.2
resolution: "@npmcli/agent@npm:2.2.2"
@@ -854,7 +880,7 @@ __metadata:
languageName: node
linkType: hard
-"@scure/base@npm:^1.1.1, @scure/base@npm:~1.1.0":
+"@scure/base@npm:^1.1.1, @scure/base@npm:^1.1.9, @scure/base@npm:~1.1.0":
version: 1.1.9
resolution: "@scure/base@npm:1.1.9"
checksum: 10c0/77a06b9a2db8144d22d9bf198338893d77367c51b58c72b99df990c0a11f7cadd066d4102abb15e3ca6798d1529e3765f55c4355742465e49aed7a0c01fe76e8
@@ -3857,6 +3883,7 @@ __metadata:
eslint-plugin-prettier: "npm:^5.2.1"
eslint-plugin-svelte: "npm:^2.44.0"
highlight.js: "npm:^11.10.0"
+ nostr-login: "npm:^1.6.6"
nostr-tools: "npm:^2.7.2"
parse-diff: "npm:^0.11.1"
postcss: "npm:^8.4.47"
@@ -4492,6 +4519,15 @@ __metadata:
languageName: node
linkType: hard
+"light-bolt11-decoder@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "light-bolt11-decoder@npm:3.2.0"
+ dependencies:
+ "@scure/base": "npm:1.1.1"
+ checksum: 10c0/65c1514b40b3b7fd5f4f0b40412bab35b0135f20f6b4929f5616bc5693f759fa8636d2393ba71fa782b2d9204315015e044628736ee7aea72f71939b0eb486f1
+ languageName: node
+ linkType: hard
+
"lilconfig@npm:^2.0.5, lilconfig@npm:^2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
@@ -5030,6 +5066,36 @@ __metadata:
languageName: node
linkType: hard
+"nostr-login@npm:^1.6.6":
+ version: 1.6.6
+ resolution: "nostr-login@npm:1.6.6"
+ dependencies:
+ "@nostr-dev-kit/ndk": "npm:^2.3.1"
+ nostr-tools: "npm:^1.17.0"
+ tseep: "npm:^1.2.1"
+ checksum: 10c0/f521f906eef377321406838d2ab3be314c9755cbbad90328f32cd65fc5b035bb85729116bc5da313445c399aafb9f1bc12833a789f440e58f12619e84d9ff15f
+ languageName: node
+ linkType: hard
+
+"nostr-tools@npm:^1.17.0":
+ version: 1.17.0
+ resolution: "nostr-tools@npm:1.17.0"
+ dependencies:
+ "@noble/ciphers": "npm:0.2.0"
+ "@noble/curves": "npm:1.1.0"
+ "@noble/hashes": "npm:1.3.1"
+ "@scure/base": "npm:1.1.1"
+ "@scure/bip32": "npm:1.3.1"
+ "@scure/bip39": "npm:1.2.1"
+ peerDependencies:
+ typescript: ">=5.0.0"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: 10c0/b52732df3e403ef3c73a41fe1dea89accbff91597b231d811d577c35a9bd9307651de65ec7fbcc9989aef4c35e9c6b1005200fbbfec45544dcd64f928bbfc476
+ languageName: node
+ linkType: hard
+
"nostr-tools@npm:^2.7.1, nostr-tools@npm:^2.7.2":
version: 2.7.2
resolution: "nostr-tools@npm:2.7.2"
@@ -6638,6 +6704,13 @@ __metadata:
languageName: node
linkType: hard
+"tseep@npm:^1.2.1, tseep@npm:^1.2.2":
+ version: 1.3.1
+ resolution: "tseep@npm:1.3.1"
+ checksum: 10c0/01b68f1f0e1084ff78bed9f28d83a595b4b6256caecd8c245af62716037dc4e87c9916c90d5d5cd4a2935f7d438a1117b2703dbf8abc79f087bc176a6f247ed6
+ languageName: node
+ linkType: hard
+
"tslib@npm:^2.0.1, tslib@npm:^2.6.2, tslib@npm:^2.7.0":
version: 2.7.0
resolution: "tslib@npm:2.7.0"
--
libgit2 1.8.1
I need to test account switching.
From 9b84454f53ff248a1390e9ec7a676093f7669697 Mon Sep 17 00:00:00 2001
From: fsociety
Date: Wed, 2 Oct 2024 00:33:36 +0200
Subject: [PATCH] feat: integrate nostr-login for user authentication
This commit integrates nostr-login for user authentication and removes the previous method. It includes changes in the package.json, Navbar.svelte, users.ts and the creation of a new file nostr-login/index.ts. This new method provides a more streamlined and efficient user authentication process.
---
package.json | 1 +
src/lib/components/Navbar.svelte | 45 +++++++++++++++++----------------------------
src/lib/signers/nostr-login/index.ts | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/lib/stores/users.ts | 72 +++++++++++++++++++++++-------------------------------------------------
src/lib/wrappers/Navbar.svelte | 21 ++-------------------
yarn.lock | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
6 files changed, 240 insertions(+), 109 deletions(-)
create mode 100644 src/lib/signers/nostr-login/index.ts
diff --git a/package.json b/package.json
index 8db6542..2539883 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-svelte": "^2.44.0",
+ "nostr-login": "^1.6.6",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.6",
diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte
index e66e96d..d5d3d3c 100644
--- a/src/lib/components/Navbar.svelte
+++ b/src/lib/components/Navbar.svelte
@@ -1,13 +1,28 @@
+ import { onMount } from 'svelte'
import { logout } from '$lib/stores/users'
import Container from './Container.svelte'
import UserHeader from './users/UserHeader.svelte'
import type { User } from './users/type'
export let logged_in_user: User | undefined = undefined
- export let nip07_plugin: boolean | undefined = undefined
export let login_function = () => {}
- export let singup_function = () => {}
+
+ interface NlAuthEvent extends Event {
+ detail: {
+ type: string
+ }
+ }
+
+ onMount(() => {
+ login_function()
+ document.addEventListener('nlAuth', (e: Event) => {
+ const event = e as NlAuthEvent
+ if (event.detail.type === 'logout') {
+ logout()
+ }
+ })
+ })
- {:else if nip07_plugin === undefined}
-
- {:else if nip07_plugin}
- - on:click={() => {
- login_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Login
- >
- {:else}
- - on:click={() => {
- singup_function()
- }}
- class="btn btn-ghost btn-sm normal-case">Sign up
- >
{/if}
diff --git a/src/lib/signers/nostr-login/index.ts b/src/lib/signers/nostr-login/index.ts
new file mode 100644
index 0000000..563a8db
--- /dev/null
+++ b/src/lib/signers/nostr-login/index.ts
@@ -0,0 +1,111 @@
+import NDK, { NDKUser, NDKRelay } from '@nostr-dev-kit/ndk'
+import type { NDKSigner, NostrEvent } from '@nostr-dev-kit/ndk'
+
+export class NDKNostrLoginSigner implements NDKSigner {
+ private _userPromise: Promise | undefined
+
+ blockUntilReady(): Promise {
+ return new Promise((resolve) => {
+ const eventHandler = (event: Event) => {
+ document.removeEventListener('nlAuth', eventHandler)
+ const customEvent = event as CustomEvent<{ pubkey: string }>
+ resolve(new NDKUser({ pubkey: customEvent.detail.pubkey }))
+ }
+
+ document.addEventListener('nlAuth', eventHandler)
+ })
+ }
+
+ user(): Promise {
+ if (!this._userPromise) {
+ this._userPromise = this.blockUntilReady()
+ }
+
+ return this._userPromise
+ }
+
+ async sign(event: NostrEvent): Promise {
+ if (!window.nostr) {
+ throw new Error('window.nostr is undefined')
+ }
+ const signedEvent = await window.nostr.signEvent(event)
+ return signedEvent.sig
+ }
+
+ async relays?(ndk?: NDK): Promise {
+ const relays = (await window.nostr?.getRelays?.()) || {}
+
+ const activeRelays: string[] = []
+ for (const url of Object.keys(relays)) {
+ // Currently only respects relays that are both readable and writable.
+ if (relays[url].read && relays[url].write) {
+ activeRelays.push(url)
+ }
+ }
+ return activeRelays.map(
+ (url) => new NDKRelay(url, ndk?.relayAuthDefaultPolicy, ndk)
+ )
+ }
+
+ async encrypt(
+ recipient: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Encrypt(recipient, value)
+ } else {
+ return this.nip04Encrypt(recipient, value)
+ }
+ }
+
+ async decrypt(
+ sender: NDKUser,
+ value: string,
+ type: string = 'nip04'
+ ): Promise {
+ if (type === 'nip44') {
+ return this.nip44Decrypt(sender, value)
+ } else {
+ return this.nip04Decrypt(sender, value)
+ }
+ }
+
+ private async nip44Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip04Encrypt(
+ recipient: NDKUser,
+ value: string
+ ): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.encrypt(recipient.pubkey, value)
+ }
+
+ private async nip44Decrypt(sender: NDKUser, value: string): Promise {
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ if (!window.nostr || !window.nostr.nip44) {
+ throw new Error('window.nostr or window.nostr.nip44 is undefined')
+ }
+ // @ts-expect-error window.nostr.nip44 is not defined in the type definitions
+ return await window.nostr.nip44.decrypt(sender.pubkey, value)
+ }
+
+ private async nip04Decrypt(sender: NDKUser, value: string): Promise {
+ if (!window.nostr || !window.nostr.nip04) {
+ throw new Error('window.nostr or window.nostr.nip04 is undefined')
+ }
+ return await window.nostr.nip04.decrypt(sender.pubkey, value)
+ }
+}
diff --git a/src/lib/stores/users.ts b/src/lib/stores/users.ts
index 608ffed..40ed744 100644
--- a/src/lib/stores/users.ts
+++ b/src/lib/stores/users.ts
@@ -2,13 +2,12 @@ import {
defaults as user_defaults,
type UserObject,
} from '$lib/components/users/type'
-import {
- getRelayListForUser,
- NDKNip07Signer,
- NDKRelayList,
-} from '@nostr-dev-kit/ndk'
+import { getRelayListForUser, NDKRelayList } from '@nostr-dev-kit/ndk'
import { get, writable, type Unsubscriber, type Writable } from 'svelte/store'
import { ndk } from './ndk'
+import { init as initNostrLogin } from 'nostr-login'
+import { NDKNostrLoginSigner } from '$lib/signers/nostr-login'
+import type { NostrLoginAuthOptions } from 'nostr-login/dist/types'
export const users: { [hexpubkey: string]: Writable } = {}
@@ -85,31 +84,7 @@ export const returnUser = async (hexpubkey: string): Promise => {
})
}
-// nip07_plugin is set in Navbar component
-export const nip07_plugin: Writable = writable(undefined)
-
-export const checkForNip07Plugin = () => {
- if (window.nostr) {
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- } else {
- let timerId: NodeJS.Timeout | undefined = undefined
- const intervalId = setInterval(() => {
- if (window.nostr) {
- clearTimeout(timerId)
- clearInterval(intervalId)
- nip07_plugin.set(true)
- if (localStorage.getItem('nip07pubkey')) login()
- }
- }, 100)
- timerId = setTimeout(() => {
- clearInterval(intervalId)
- nip07_plugin.set(false)
- }, 5000)
- }
-}
-
-const signer = new NDKNip07Signer(2000)
+const signer = new NDKNostrLoginSigner()
export const logged_in_user: Writable =
writable(undefined)
@@ -118,24 +93,24 @@ export const login = async (): Promise => {
return new Promise(async (res, rej) => {
const user = get(logged_in_user)
if (user) return res()
- if (get(nip07_plugin)) {
- try {
- const ndk_user = await signer.blockUntilReady()
- localStorage.setItem('nip07pubkey', ndk_user.pubkey)
- logged_in_user.set({
- ...user_defaults,
- hexpubkey: ndk_user.pubkey,
- })
- ndk.signer = signer
- ensureUser(ndk_user.pubkey).subscribe((user) => {
- logged_in_user.set({ ...user })
- })
- return res()
- } catch (e) {
- alert(e)
- rej()
- }
- } else {
+ try {
+ ndk.signer = signer
+ initNostrLogin({
+ onAuth: async (_npub: string, options: NostrLoginAuthOptions) => {
+ const pubkey =
+ typeof options.pubkey === 'string' ? options.pubkey : ''
+ logged_in_user.set({
+ ...user_defaults,
+ hexpubkey: pubkey,
+ })
+ ensureUser(pubkey).subscribe((user) => {
+ logged_in_user.set({ ...user })
+ })
+ return res()
+ },
+ })
+ } catch (e) {
+ alert(e)
rej()
}
})
@@ -143,7 +118,6 @@ export const login = async (): Promise => {
export const logout = async (): Promise => {
logged_in_user.set(undefined)
- localStorage.removeItem('nip07pubkey')
ndk.signer = undefined
}
diff --git a/src/lib/wrappers/Navbar.svelte b/src/lib/wrappers/Navbar.svelte
index 4b63bc7..1f7146f 100644
--- a/src/lib/wrappers/Navbar.svelte
+++ b/src/lib/wrappers/Navbar.svelte
@@ -1,23 +1,6 @@
- import {
- checkForNip07Plugin,
- logged_in_user,
- login,
- nip07_plugin,
- } from '$lib/stores/users'
- import { onMount } from 'svelte'
+ import { logged_in_user, login } from '$lib/stores/users'
import Navbar from '$lib/components/Navbar.svelte'
-
- let singup_function = () => {
- alert('a NIP-07 browser extension is required. currently no signup page')
- }
-
- onMount(checkForNip07Plugin)
-- logged_in_user={$logged_in_user}
- nip07_plugin={$nip07_plugin}
- login_function={login}
- {singup_function}
-/>
+
diff --git a/yarn.lock b/yarn.lock
index f75be09..f976ab4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -566,6 +566,13 @@ __metadata:
languageName: node
linkType: hard
+"@noble/ciphers@npm:0.2.0":
+ version: 0.2.0
+ resolution: "@noble/ciphers@npm:0.2.0"
+ checksum: 10c0/57dea65c32741df20a1ac24f365d616a558527109d778c1bec877f20b28875a26b80097bce51ae19529f3792ccf8285fe73839ff404733e32a27a6ebf60edd2c
+ languageName: node
+ linkType: hard
+
"@noble/ciphers@npm:^0.5.1":
version: 0.5.3
resolution: "@noble/ciphers@npm:0.5.3"
@@ -573,6 +580,15 @@ __metadata:
languageName: node
linkType: hard
+"@noble/curves@npm:1.1.0, @noble/curves@npm:~1.1.0":
+ version: 1.1.0
+ resolution: "@noble/curves@npm:1.1.0"
+ dependencies:
+ "@noble/hashes": "npm:1.3.1"
+ checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
+ languageName: node
+ linkType: hard
+
"@noble/curves@npm:1.2.0":
version: 1.2.0
resolution: "@noble/curves@npm:1.2.0"
@@ -582,7 +598,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:^1.4.0":
+"@noble/curves@npm:^1.4.0, @noble/curves@npm:^1.6.0":
version: 1.6.0
resolution: "@noble/curves@npm:1.6.0"
dependencies:
@@ -591,15 +607,6 @@ __metadata:
languageName: node
linkType: hard
-"@noble/curves@npm:~1.1.0":
- version: 1.1.0
- resolution: "@noble/curves@npm:1.1.0"
- dependencies:
- "@noble/hashes": "npm:1.3.1"
- checksum: 10c0/81115c3ebfa7e7da2d7e18d44d686f98dc6d35dbde3964412c05707c92d0994a01545bc265d5c0bc05c8c49333f75b99c9acef6750f5a79b3abcc8e0546acf88
- languageName: node
- linkType: hard
-
"@noble/hashes@npm:1.3.1":
version: 1.3.1
resolution: "@noble/hashes@npm:1.3.1"
@@ -614,7 +621,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1":
+"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.5.0":
version: 1.5.0
resolution: "@noble/hashes@npm:1.5.0"
checksum: 10c0/1b46539695fbfe4477c0822d90c881a04d4fa2921c08c552375b444a48cac9930cb1ee68de0a3c7859e676554d0f3771999716606dc4d8f826e414c11692cdd9
@@ -628,7 +635,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/secp256k1@npm:^2.0.0":
+"@noble/secp256k1@npm:^2.0.0, @noble/secp256k1@npm:^2.1.0":
version: 2.1.0
resolution: "@noble/secp256k1@npm:2.1.0"
checksum: 10c0/b4c7edd2a5ec5acf294546cd06d08dc2a2a2b2ebe34a6da1f2f5104f56983f81dd31c261ad365c6b9757d1c54017fc3363331ee33bba8715ff94c2bc954313cc
@@ -692,6 +699,25 @@ __metadata:
languageName: node
linkType: hard
+"@nostr-dev-kit/ndk@npm:^2.3.1":
+ version: 2.10.1
+ resolution: "@nostr-dev-kit/ndk@npm:2.10.1"
+ dependencies:
+ "@noble/curves": "npm:^1.6.0"
+ "@noble/hashes": "npm:^1.5.0"
+ "@noble/secp256k1": "npm:^2.1.0"
+ "@scure/base": "npm:^1.1.9"
+ debug: "npm:^4.3.6"
+ light-bolt11-decoder: "npm:^3.2.0"
+ nostr-tools: "npm:^2.7.1"
+ tseep: "npm:^1.2.2"
+ typescript-lru-cache: "npm:^2.0.0"
+ utf8-buffer: "npm:^1.0.0"
+ websocket-polyfill: "npm:^0.0.3"
+ checksum: 10c0/b73cd0e9f036e60893d0470d778c5e672795f93308edca389d42c9487267e95df208b2b2353b20eb766ae606cfd1c328d03a1e43d69351e27159843cdb619cc9
+ languageName: node
+ linkType: hard
+
"@npmcli/agent@npm:^2.0.0":
version: 2.2.2
resolution: "@npmcli/agent@npm:2.2.2"
@@ -854,7 +880,7 @@ __metadata:
languageName: node
linkType: hard
-"@scure/base@npm:^1.1.1, @scure/base@npm:~1.1.0":
+"@scure/base@npm:^1.1.1, @scure/base@npm:^1.1.9, @scure/base@npm:~1.1.0":
version: 1.1.9
resolution: "@scure/base@npm:1.1.9"
checksum: 10c0/77a06b9a2db8144d22d9bf198338893d77367c51b58c72b99df990c0a11f7cadd066d4102abb15e3ca6798d1529e3765f55c4355742465e49aed7a0c01fe76e8
@@ -3857,6 +3883,7 @@ __metadata:
eslint-plugin-prettier: "npm:^5.2.1"
eslint-plugin-svelte: "npm:^2.44.0"
highlight.js: "npm:^11.10.0"
+ nostr-login: "npm:^1.6.6"
nostr-tools: "npm:^2.7.2"
parse-diff: "npm:^0.11.1"
postcss: "npm:^8.4.47"
@@ -4492,6 +4519,15 @@ __metadata:
languageName: node
linkType: hard
+"light-bolt11-decoder@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "light-bolt11-decoder@npm:3.2.0"
+ dependencies:
+ "@scure/base": "npm:1.1.1"
+ checksum: 10c0/65c1514b40b3b7fd5f4f0b40412bab35b0135f20f6b4929f5616bc5693f759fa8636d2393ba71fa782b2d9204315015e044628736ee7aea72f71939b0eb486f1
+ languageName: node
+ linkType: hard
+
"lilconfig@npm:^2.0.5, lilconfig@npm:^2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
@@ -5030,6 +5066,36 @@ __metadata:
languageName: node
linkType: hard
+"nostr-login@npm:^1.6.6":
+ version: 1.6.6
+ resolution: "nostr-login@npm:1.6.6"
+ dependencies:
+ "@nostr-dev-kit/ndk": "npm:^2.3.1"
+ nostr-tools: "npm:^1.17.0"
+ tseep: "npm:^1.2.1"
+ checksum: 10c0/f521f906eef377321406838d2ab3be314c9755cbbad90328f32cd65fc5b035bb85729116bc5da313445c399aafb9f1bc12833a789f440e58f12619e84d9ff15f
+ languageName: node
+ linkType: hard
+
+"nostr-tools@npm:^1.17.0":
+ version: 1.17.0
+ resolution: "nostr-tools@npm:1.17.0"
+ dependencies:
+ "@noble/ciphers": "npm:0.2.0"
+ "@noble/curves": "npm:1.1.0"
+ "@noble/hashes": "npm:1.3.1"
+ "@scure/base": "npm:1.1.1"
+ "@scure/bip32": "npm:1.3.1"
+ "@scure/bip39": "npm:1.2.1"
+ peerDependencies:
+ typescript: ">=5.0.0"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: 10c0/b52732df3e403ef3c73a41fe1dea89accbff91597b231d811d577c35a9bd9307651de65ec7fbcc9989aef4c35e9c6b1005200fbbfec45544dcd64f928bbfc476
+ languageName: node
+ linkType: hard
+
"nostr-tools@npm:^2.7.1, nostr-tools@npm:^2.7.2":
version: 2.7.2
resolution: "nostr-tools@npm:2.7.2"
@@ -6638,6 +6704,13 @@ __metadata:
languageName: node
linkType: hard
+"tseep@npm:^1.2.1, tseep@npm:^1.2.2":
+ version: 1.3.1
+ resolution: "tseep@npm:1.3.1"
+ checksum: 10c0/01b68f1f0e1084ff78bed9f28d83a595b4b6256caecd8c245af62716037dc4e87c9916c90d5d5cd4a2935f7d438a1117b2703dbf8abc79f087bc176a6f247ed6
+ languageName: node
+ linkType: hard
+
"tslib@npm:^2.0.1, tslib@npm:^2.6.2, tslib@npm:^2.7.0":
version: 2.7.0
resolution: "tslib@npm:2.7.0"
--
libgit2 1.8.1
nostr:naddr1qvzqqqrhnypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqy88wumn8ghj7mn0wvhxcmmv9uqqkemfw3mk7untwd5x7uqarf775/proposals/note1es7uppvntwfduur0hag7zawjrwyh6nm9q77nz4fqdkxpaams2xas8qpjuc
I was working with Typescript for the first time and wanted gitworkshop.dev to work with the nostr-login of nostrband.
This allows you to log in to gitworkshop.dev with Amber, Nsec.app and NIP-07.
I have written a signer implementation for nostr-ndk.
nostr:npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr
Die Zahlung des Mitgliedsbeitrages via Zap auf ein Nostr Event funktioniert.
It's all connected. Maybe the lnd-rpc connection is not working. But I am in bed now :) ahahaaa
Yes, and I cannot zap. I will check this tomorrow. GN
Uhh nice. Using the nostr.band Login plugin, too. Well done.
QubesOS only - please don't use CSS blur or transparency for better website scrolling experience
𧨠𧨠𧨠𧨠𧨠𧨠𧨠π§¨
haven-relay | 2024/09/23 21:22:14 π« blasted to wss://nostr.inosta.cc
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://lnbits.papersats.io/nostrclient/api/v1/relay
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://relay.nostrview.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://relay.braydon.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://relay.nostrcheck.me
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://private.red.gb.net
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://relay.hamnet.io
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://bitcoinmaximalists.online
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://bits.lnbc.sk/nostrclient/api/v1/relay
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostrua.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostr.bch.ninja
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostr-relay.schnitzel.world
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostr.easydns.ca
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://eosla.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://ragnar-relay.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostr.tbai.me:592
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://bitstack.app
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostr.decentony.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://problematic.network
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://multiplextr.coracle.social
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://relay.nostrid.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostr.zoel.network
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://premis.one
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostrja-kari-nip50.heguro.com
haven-relay | 2024/09/23 21:22:15 π« blasted to wss://nostr-relay.nokotaro.com
haven-relay | 2024/09/23 21:22:16 π« blasted to wss://relay.nostrcn.com
haven-relay | 2024/09/23 21:22:18 π« blasted to wss://cache2.primal.net/v1
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://cache1.primal.net/v1
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://lnbits.michaelantonfischer.com/nostrrelay/michaelantonf
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://mastodon.cloud/api/v1/streaming
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://relay.nquiz.io
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://relay.nostr.bg
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://ithurtswhenip.ee
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://nostr.primz.org
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://rkgk.moe
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://relay.nostr.nu
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://nostr.schorsch.fans
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://merrcurrup.railway.app
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://relay.nostr.blockhenge.com
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://nostr.hashi.sbs
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://misskey.io
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://social.camph.net
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://cache0.primal.net/cache17
haven-relay | 2024/09/23 21:22:19 π« blasted to wss://nostr.bitcoinplebs.de
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://lnbits.satoshibox.io/nostrclient/api/v1/relay
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://node.coincreek.com/nostrclient/api/v1/relay
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://echo.websocket.org
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://wot.puhcho.me
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://api-growing-suggestion-sam264zfbecgvioim3jk.wnext.app
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://search.swarmstr.com
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://novoa.nagoya
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://relay.ghostcopywrite.com
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://nostr.middling.mydns.jp
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://misskey.04.si
haven-relay | 2024/09/23 21:22:20 π« blasted to wss://invillage-outvillage.com
haven-relay | 2024/09/23 21:22:21 π« blasted to wss://relay.lifpay.me
haven-relay | 2024/09/23 21:22:21 π« blasted to wss://sushi.ski
PR for this is open. I've tested it with an extra test account on Amethyst now. blastr is amazing....my terminal goes brrrrrrrrrrr π₯
nostr:npub1utx00neqgqln72j22kej3ux7803c2k986henvvha4thuwfkper4s7r50e8 Ok here a list of errors, if I just use the whole list of nostr.watch https://api.nostr.watch/v1/online
These errors would have to be suppressed somehow and the faulty relays then thrown out?
haven-relay | 2024/09/23 20:54:06 NOTICE from wss://hodlbod.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:07 NOTICE from wss://relay.dev.bdw.to: 'auth-required: only authenticated users can read from this relay'
haven-relay | 2024/09/23 20:54:11 NOTICE from wss://cache1.primal.net/v1: ':562'
haven-relay | 2024/09/23 20:54:12 NOTICE from wss://wot.puhcho.me: 'failed to fetch events using query "SELECT\n id, pubkey, created_at, kind, tags, content, sig\n FROM event WHERE pubkey IN (?) AND kind IN (?) ORDER BY created_at DESC, id LIMIT ?": database is locked'
haven-relay | 2024/09/23 20:54:13 NOTICE from wss://relay.nostrainsley.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:13 NOTICE from wss://search.swarmstr.com: 'Error: only filter with search is supported'
haven-relay | 2024/09/23 20:54:16 NOTICE from wss://notify-staging.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:16 NOTICE from wss://notify-staging.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:17 NOTICE from wss://relay.phantom-power.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:18 NOTICE from wss://relay.nosflare.com: 'Blocked kinds in request: 3'
haven-relay | 2024/09/23 20:54:27 π building web of trust graph
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://relay.getalby.com/v1: 'REQ filters are not accepted'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://relay.nip05.social: 'auth-required: We only serve registered, authenticated users.'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://relay.zap.store: ''
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://nip05.social: 'auth-required: We only serve registered, authenticated users.'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://groups.fiatjaf.com: 'blocked: invalid query, must have 'h', 'e' or 'a' tag'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://bostr.cx.ms: 'auth-required: authentication is required to perform this action.'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://cfrelay.snowcait.workers.dev: 'auth-required: Only the authed owner can send reqs.'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://milwaukietalkie.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://relay.groups.nip29.com: 'blocked: invalid query, must have 'h', 'e' or 'a' tag'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://theschoolofbitcoin.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://antisocial.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://bevo.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://notify.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://notify.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://libretechsystems.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://creatr.nostr.wine: 'auth-required: please authenticate before sending REQs'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://tigs.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://frens.utxo.one: 'auth-required: this query requires you to be authenticated'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://hayloo.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://moonboi.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://dm.patrickulrich.com: 'auth-required: this query requires you to be authenticated'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://relay.phantom-power.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://relay.phantom-power.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://voxonomatronics.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://nostrtalk.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://david.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://seth.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://mleku.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://groups.0xchat.com: 'blocked: invalid query, must have 'h', 'e' or 'a' tag'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://plebone.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://vitor.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://airchat.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://notify.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://inbox.nostr.wine: 'auth-required: this relay only serves notes to authenticated users'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://gnost.faust.duckdns.org: 'Invalid message'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://strava.dev.bdw.to: 'blocked: Unauthorized'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://nostrja-kari-nip50.heguro.com: 'Error: only filter with search is supported'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://bostr.erechorse.com: 'auth-required: authentication is required to perform this action.'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://relay.refinery.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:27 CLOSED from wss://relay.refinery.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://cache2.primal.net/v1: ':1251'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://cache1.primal.net/v1: ':1260'
haven-relay | 2024/09/23 20:54:27 NOTICE from wss://cache0.primal.net/cache17: ':1261'
haven-relay | 2024/09/23 20:54:28 NOTICE from wss://search.swarmstr.com: 'Error: only filter with search is supported'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://aplaceinthesun.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://nortis.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://nosdrive.app/relay: 'write-only relay'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://auth.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://hotrightnow.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://agentorange.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://thewildhustle.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://dergigi.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 NOTICE from wss://notify-staging.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:28 NOTICE from wss://hodlbod.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://hodlbod.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:28 NOTICE from wss://relay.nostrainsley.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://relay.nostrainsley.coracle.tools: 'auth-required: authentication is required for access'
haven-relay | 2024/09/23 20:54:28 NOTICE from wss://relay.dev.bdw.to: 'auth-required: only authenticated users can read from this relay'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://relay.dev.bdw.to: 'auth-required: only authenticated users can read from this relay'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://theforest.nostr1.com: 'auth-required: you must auth'
haven-relay | 2024/09/23 20:54:28 NOTICE from wss://relay.nosflare.com: 'Blocked kinds in request: 3'
haven-relay | 2024/09/23 20:54:28 CLOSED from wss://bostr.online: 'auth-required: authentication is required to perform this action.'
haven-relay | 2024/09/23 20:54:31 NOTICE from wss://notify.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:31 NOTICE from wss://gnost.faust.duckdns.org: 'Invalid message'
haven-relay | 2024/09/23 20:54:31 NOTICE from wss://notify-staging.damus.io: 'Unsupported message.'
haven-relay | 2024/09/23 20:54:33 NOTICE from wss://wot.puhcho.me: 'failed to fetch events using query "SELECT\n id, pubkey, created_at, kind, tags, content, sig\n FROM event WHERE pubkey IN (?) AND kind IN (?,?) ORDER BY created_at DESC, id LIMIT ?": database is locked'
haven-relay | 2024/09/23 20:54:34 NOTICE from wss://nostrja-kari-nip50.heguro.com: 'Error: non-text message Ping([])'
nostr:nevent1qvzqqqqqqypzpckv7l8jqspl8u4y54dn9rcduwlrs4v2040nxce0m2h0cunvrj8tqqsrhx0yq7xv20pz48m2kpxljuyedm3vmzjv4kllal0y2ggl62crz4qutht48
Yes, this would have to be added as a feature so that this list can be loaded dynamically somehow. Because at the moment it is in the build process of Go and is only loaded once.
One moment, eating right now.
Bei der normalen Version geht es. Nur auf next.nostrudel.ninja habe ich das Problem.