From 1f62afacb1a725c4d449686813f18457441804b0 Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Sun, 22 Jan 2023 16:45:44 -0500 Subject: [PATCH 1/7] nip42 initial --- src/Feed/EventPublisher.ts | 29 +++++++++++++++ src/Nostr/Auth.ts | 19 ++++++++++ src/Nostr/Connection.ts | 74 ++++++++++++++++++++++++++++++++------ src/Nostr/EventKind.ts | 3 +- 4 files changed, 113 insertions(+), 12 deletions(-) create mode 100644 src/Nostr/Auth.ts diff --git a/src/Feed/EventPublisher.ts b/src/Feed/EventPublisher.ts index 3c8cbd8c..2847ae5f 100644 --- a/src/Feed/EventPublisher.ts +++ b/src/Feed/EventPublisher.ts @@ -7,6 +7,8 @@ import { RootState } from "State/Store"; import { HexKey, RawEvent, u256, UserMetadata } from "Nostr"; import { bech32ToHex } from "Util" import { DefaultRelays, HashtagRegex } from "Const"; +import { useEffect } from "react"; +import { NIP42AuthChallenge, NIP42AuthResponse } from "Nostr/Auth"; declare global { interface Window { @@ -76,6 +78,33 @@ export default function useEventPublisher() { ev.Content = content; } + const nip42Auth = async (challenge: string, relay:string): Promise => { + if(pubKey) { + const ev = NEvent.ForPubKey(pubKey); + ev.Kind = EventKind.Auth; + ev.Content = ""; + ev.Tags.push(new Tag(["relay", relay], 0)); + ev.Tags.push(new Tag(["challenge", challenge], 1)); + return await signEvent(ev); + } + return Promise.reject(); + } + + useEffect(() =>{ + const nip42AuthEvent = async (event: NIP42AuthChallenge) => { + if(event.challenge && event.relay) { + const signedEvent = await nip42Auth(event.challenge, event.relay); + const response = new NIP42AuthResponse(event.challenge, signedEvent); + window.dispatchEvent(response); + } + } + window.addEventListener("nip42auth", nip42AuthEvent) + + return () => { + window.removeEventListener("nip42auth", nip42AuthEvent) + } + }, []) + return { broadcast: (ev: NEvent | undefined) => { if (ev) { diff --git a/src/Nostr/Auth.ts b/src/Nostr/Auth.ts new file mode 100644 index 00000000..c9a62c9f --- /dev/null +++ b/src/Nostr/Auth.ts @@ -0,0 +1,19 @@ +import {default as NEvent} from "./Event" + +export class NIP42AuthChallenge extends Event { + challenge?:string + relay?:string + constructor(challenge:string, relay:string) { + super("nip42auth"); + this.challenge = challenge; + this.relay = relay; + } +} + +export class NIP42AuthResponse extends Event { + event?: NEvent + constructor(challenge: string, event: NEvent) { + super(`nip42response:${challenge}`); + this.event = event; + } +} \ No newline at end of file diff --git a/src/Nostr/Connection.ts b/src/Nostr/Connection.ts index bd92816a..a67949eb 100644 --- a/src/Nostr/Connection.ts +++ b/src/Nostr/Connection.ts @@ -51,6 +51,8 @@ export default class Connection { IsClosed: boolean; ReconnectTimer: ReturnType | null; EventsCallback: Map void>; + Authed: boolean; + AwaitingAuth: boolean; constructor(addr: string, options: RelaySettings) { this.Id = uuid(); @@ -76,6 +78,8 @@ export default class Connection { this.IsClosed = false; this.ReconnectTimer = null; this.EventsCallback = new Map(); + this.Authed = false; + this.AwaitingAuth = false; this.Connect(); } @@ -123,17 +127,12 @@ export default class Connection { OnOpen(e: Event) { this.ConnectTimeout = DefaultConnectTimeout; console.log(`[${this.Address}] Open!`); - - // send pending - for (let p of this.Pending) { - this._SendJson(p); - } - this.Pending = []; - - for (let [_, s] of this.Subscriptions) { - this._SendSubscription(s); - } - this._UpdateState(); + setTimeout(() => { + if(this.AwaitingAuth) { + return + } + this._InitSubscriptions(); + }, 500) } OnClose(e: CloseEvent) { @@ -156,6 +155,12 @@ export default class Connection { let msg = JSON.parse(e.data); let tag = msg[0]; switch (tag) { + case "AUTH": { + this._OnAuth(msg[1]) + this.Stats.EventsReceived++; + this._UpdateState(); + break; + } case "EVENT": { this._OnEvent(msg[1], msg[2]); this.Stats.EventsReceived++; @@ -314,6 +319,19 @@ export default class Connection { } } + _InitSubscriptions() { + // send pending + for (let p of this.Pending) { + this._SendJson(p); + } + this.Pending = []; + + for (let [_, s] of this.Subscriptions) { + this._SendSubscription(s); + } + this._UpdateState(); + } + _SendSubscription(sub: Subscriptions) { let req = ["REQ", sub.Id, sub.ToObject()]; if (sub.OrSubs.length > 0) { @@ -349,6 +367,40 @@ export default class Connection { } } + async _OnAuth(challenge: string, timeout: number = 5000):Promise { + const challengeEvent = new NIP42AuthChallenge(challenge, this.Address) + + const authCallback = (e:NIP42AuthResponse):Promise => { + return new Promise((resolve,reject) => { + if(!e.event) { + return Promise.reject('no event'); + } + + let t = setTimeout(() => { + window.removeEventListener(`nip42response:${challenge}`, authCallback); + this.AwaitingAuth = false; + reject('timeout'); + }, timeout); + + this.EventsCallback.set(e.event.Id, () => { + clearTimeout(t); + this.AwaitingAuth = false; + window.removeEventListener(`nip42response:${challenge}`, authCallback) + resolve(); + }); + + let req = ["AUTH", e.event.ToObject()]; + this._SendJson(req); + this.Stats.EventsSent++; + this._UpdateState(); + }) + } + + this.AwaitingAuth = true; + window.addEventListener(`nip42response:${challenge}`, authCallback) + window.dispatchEvent(challengeEvent) + } + _OnEnd(subId: string) { let sub = this.Subscriptions.get(subId); if (sub) { diff --git a/src/Nostr/EventKind.ts b/src/Nostr/EventKind.ts index d12012b9..5b4cfbdb 100644 --- a/src/Nostr/EventKind.ts +++ b/src/Nostr/EventKind.ts @@ -7,7 +7,8 @@ const enum EventKind { DirectMessage = 4, // NIP-04 Deletion = 5, // NIP-09 Repost = 6, // NIP-18 - Reaction = 7 // NIP-25 + Reaction = 7, // NIP-25 + Auth = 22242 // NIP-42 }; export default EventKind; \ No newline at end of file From 25f8dd5ef7214fc20a07c895a88aacbfcda8f866 Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Sun, 22 Jan 2023 20:45:53 -0500 Subject: [PATCH 2/7] nip42 support --- src/Feed/EventPublisher.ts | 16 +----------- src/Nostr/Connection.ts | 50 +++++++++++++++++++++++--------------- src/Pages/Layout.tsx | 23 ++++++++++++++---- 3 files changed, 50 insertions(+), 39 deletions(-) diff --git a/src/Feed/EventPublisher.ts b/src/Feed/EventPublisher.ts index 2847ae5f..e670a579 100644 --- a/src/Feed/EventPublisher.ts +++ b/src/Feed/EventPublisher.ts @@ -90,22 +90,8 @@ export default function useEventPublisher() { return Promise.reject(); } - useEffect(() =>{ - const nip42AuthEvent = async (event: NIP42AuthChallenge) => { - if(event.challenge && event.relay) { - const signedEvent = await nip42Auth(event.challenge, event.relay); - const response = new NIP42AuthResponse(event.challenge, signedEvent); - window.dispatchEvent(response); - } - } - window.addEventListener("nip42auth", nip42AuthEvent) - - return () => { - window.removeEventListener("nip42auth", nip42AuthEvent) - } - }, []) - return { + nip42Auth: nip42Auth, broadcast: (ev: NEvent | undefined) => { if (ev) { console.debug("Sending event: ", ev); diff --git a/src/Nostr/Connection.ts b/src/Nostr/Connection.ts index a67949eb..9f810562 100644 --- a/src/Nostr/Connection.ts +++ b/src/Nostr/Connection.ts @@ -50,9 +50,9 @@ export default class Connection { LastState: Readonly; IsClosed: boolean; ReconnectTimer: ReturnType | null; - EventsCallback: Map void>; + EventsCallback: Map void>; + AwaitingAuth: Map; Authed: boolean; - AwaitingAuth: boolean; constructor(addr: string, options: RelaySettings) { this.Id = uuid(); @@ -78,8 +78,8 @@ export default class Connection { this.IsClosed = false; this.ReconnectTimer = null; this.EventsCallback = new Map(); + this.AwaitingAuth = new Map(); this.Authed = false; - this.AwaitingAuth = false; this.Connect(); } @@ -128,11 +128,10 @@ export default class Connection { this.ConnectTimeout = DefaultConnectTimeout; console.log(`[${this.Address}] Open!`); setTimeout(() => { - if(this.AwaitingAuth) { - return + if(this.Authed || this.AwaitingAuth.size === 0) { + this._InitSubscriptions(); } - this._InitSubscriptions(); - }, 500) + }, 150) } OnClose(e: CloseEvent) { @@ -156,7 +155,7 @@ export default class Connection { let tag = msg[0]; switch (tag) { case "AUTH": { - this._OnAuth(msg[1]) + this._OnAuthAsync(msg[1]) this.Stats.EventsReceived++; this._UpdateState(); break; @@ -178,7 +177,7 @@ export default class Connection { if (this.EventsCallback.has(id)) { let cb = this.EventsCallback.get(id)!; this.EventsCallback.delete(id); - cb(); + cb(msg); } break; } @@ -333,6 +332,11 @@ export default class Connection { } _SendSubscription(sub: Subscriptions) { + if(!this.Authed && this.AwaitingAuth.size > 0) { + this.Pending.push(sub); + return; + } + let req = ["REQ", sub.Id, sub.ToObject()]; if (sub.OrSubs.length > 0) { req = [ @@ -367,25 +371,33 @@ export default class Connection { } } - async _OnAuth(challenge: string, timeout: number = 5000):Promise { + async _OnAuthAsync(challenge: string) { const challengeEvent = new NIP42AuthChallenge(challenge, this.Address) + const authCleanup = () => { + this.AwaitingAuth.delete(challenge) + } + const authCallback = (e:NIP42AuthResponse):Promise => { - return new Promise((resolve,reject) => { + window.removeEventListener(`nip42response:${challenge}`, authCallback) + return new Promise((resolve,_) => { if(!e.event) { + authCleanup(); return Promise.reject('no event'); } let t = setTimeout(() => { - window.removeEventListener(`nip42response:${challenge}`, authCallback); - this.AwaitingAuth = false; - reject('timeout'); - }, timeout); + authCleanup(); + resolve(); + }, 10_000); - this.EventsCallback.set(e.event.Id, () => { + this.EventsCallback.set(e.event.Id, (msg:any[]) => { clearTimeout(t); - this.AwaitingAuth = false; - window.removeEventListener(`nip42response:${challenge}`, authCallback) + authCleanup(); + if(msg.length > 3 && msg[2] === true) { + this.Authed = true; + this._InitSubscriptions(); + } resolve(); }); @@ -396,7 +408,7 @@ export default class Connection { }) } - this.AwaitingAuth = true; + this.AwaitingAuth.set(challenge, true) window.addEventListener(`nip42response:${challenge}`, authCallback) window.dispatchEvent(challengeEvent) } diff --git a/src/Pages/Layout.tsx b/src/Pages/Layout.tsx index b173c94a..b08d4e89 100644 --- a/src/Pages/Layout.tsx +++ b/src/Pages/Layout.tsx @@ -1,12 +1,12 @@ import "./Layout.css"; -import { useEffect, useState } from "react" +import { useEffect } from "react" import { useDispatch, useSelector } from "react-redux"; import { Outlet, useNavigate } from "react-router-dom"; import { faBell, faMessage, faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { RootState } from "State/Store"; -import { init, setPreferences, UserPreferences } from "State/Login"; +import { init, UserPreferences } from "State/Login"; import { HexKey, RawEvent, TaggedRawEvent } from "Nostr"; import { RelaySettings } from "Nostr/Connection"; import { System } from "Nostr/System" @@ -14,6 +14,8 @@ import ProfileImage from "Element/ProfileImage"; import useLoginFeed from "Feed/LoginFeed"; import { totalUnread } from "Pages/MessagesPage"; import { SearchRelays } from 'Const'; +import useEventPublisher from "Feed/EventPublisher"; +import { NIP42AuthChallenge, NIP42AuthResponse } from "Nostr/Auth"; export default function Layout() { const dispatch = useDispatch(); @@ -25,13 +27,20 @@ export default function Layout() { const readNotifications = useSelector(s => s.login.readNotifications); const dms = useSelector(s => s.login.dms); const prefs = useSelector(s => s.login.preferences); - - const [keyword, setKeyword] = useState(''); - + const pub = useEventPublisher(); useLoginFeed(); useEffect(() => { if (relays) { + const nip42AuthEvent = async (event: NIP42AuthChallenge) => { + if(event.challenge && event.relay) { + const signedEvent = await pub.nip42Auth(event.challenge, event.relay); + const response = new NIP42AuthResponse(event.challenge, signedEvent); + window.dispatchEvent(response); + } + } + window.addEventListener("nip42auth", nip42AuthEvent) + for (let [k, v] of Object.entries(relays)) { System.ConnectToRelay(k, v); } @@ -40,6 +49,10 @@ export default function Layout() { System.DisconnectRelay(k); } } + + return () => { + window.removeEventListener("nip42auth", nip42AuthEvent) + } } }, [relays]); From 501b42fc9af811f2591187315c4099af52008049 Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Sun, 22 Jan 2023 20:47:52 -0500 Subject: [PATCH 3/7] move function --- src/Feed/EventPublisher.ts | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Feed/EventPublisher.ts b/src/Feed/EventPublisher.ts index e670a579..f3d56d20 100644 --- a/src/Feed/EventPublisher.ts +++ b/src/Feed/EventPublisher.ts @@ -78,20 +78,18 @@ export default function useEventPublisher() { ev.Content = content; } - const nip42Auth = async (challenge: string, relay:string): Promise => { - if(pubKey) { - const ev = NEvent.ForPubKey(pubKey); - ev.Kind = EventKind.Auth; - ev.Content = ""; - ev.Tags.push(new Tag(["relay", relay], 0)); - ev.Tags.push(new Tag(["challenge", challenge], 1)); - return await signEvent(ev); - } - return Promise.reject(); - } - return { - nip42Auth: nip42Auth, + nip42Auth: async (challenge: string, relay:string): Promise => { + if(pubKey) { + const ev = NEvent.ForPubKey(pubKey); + ev.Kind = EventKind.Auth; + ev.Content = ""; + ev.Tags.push(new Tag(["relay", relay], 0)); + ev.Tags.push(new Tag(["challenge", challenge], 1)); + return await signEvent(ev); + } + return Promise.reject(); + }, broadcast: (ev: NEvent | undefined) => { if (ev) { console.debug("Sending event: ", ev); From 822247e1fab1bc837ae640498cecd70e523f681d Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Mon, 23 Jan 2023 13:52:32 -0500 Subject: [PATCH 4/7] remove timeout on connection open --- src/Nostr/Connection.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nostr/Connection.ts b/src/Nostr/Connection.ts index 9f810562..cb90b23c 100644 --- a/src/Nostr/Connection.ts +++ b/src/Nostr/Connection.ts @@ -126,12 +126,8 @@ export default class Connection { OnOpen(e: Event) { this.ConnectTimeout = DefaultConnectTimeout; + this._InitSubscriptions(); console.log(`[${this.Address}] Open!`); - setTimeout(() => { - if(this.Authed || this.AwaitingAuth.size === 0) { - this._InitSubscriptions(); - } - }, 150) } OnClose(e: CloseEvent) { @@ -349,6 +345,10 @@ export default class Connection { } _SendJson(obj: any) { + if(!this.Authed && this.AwaitingAuth.size > 0) { + this.Pending.push(obj); + return; + } if (this.Socket?.readyState !== WebSocket.OPEN) { this.Pending.push(obj); return; @@ -456,4 +456,4 @@ export default class Connection { } return ev; } -} \ No newline at end of file +} From 97a467260d9e54f8ce975eff1978b56f1141943b Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Mon, 23 Jan 2023 21:52:52 -0500 Subject: [PATCH 5/7] could not send auth --- src/Nostr/Connection.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Nostr/Connection.ts b/src/Nostr/Connection.ts index cb90b23c..eca0b90a 100644 --- a/src/Nostr/Connection.ts +++ b/src/Nostr/Connection.ts @@ -345,10 +345,6 @@ export default class Connection { } _SendJson(obj: any) { - if(!this.Authed && this.AwaitingAuth.size > 0) { - this.Pending.push(obj); - return; - } if (this.Socket?.readyState !== WebSocket.OPEN) { this.Pending.push(obj); return; From 2d751390656ad3bb518912a87ff8ab87ff173e7b Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Wed, 25 Jan 2023 08:37:35 -0500 Subject: [PATCH 6/7] remove listeners, set auth function onto system --- src/Feed/EventPublisher.ts | 5 +-- src/Nostr/Auth.ts | 19 ----------- src/Nostr/Connection.ts | 65 +++++++++++++++++--------------------- src/Nostr/System.ts | 4 +++ src/Pages/Layout.tsx | 20 +++--------- 5 files changed, 39 insertions(+), 74 deletions(-) delete mode 100644 src/Nostr/Auth.ts diff --git a/src/Feed/EventPublisher.ts b/src/Feed/EventPublisher.ts index f3d56d20..29bb6deb 100644 --- a/src/Feed/EventPublisher.ts +++ b/src/Feed/EventPublisher.ts @@ -7,8 +7,6 @@ import { RootState } from "State/Store"; import { HexKey, RawEvent, u256, UserMetadata } from "Nostr"; import { bech32ToHex } from "Util" import { DefaultRelays, HashtagRegex } from "Const"; -import { useEffect } from "react"; -import { NIP42AuthChallenge, NIP42AuthResponse } from "Nostr/Auth"; declare global { interface Window { @@ -79,7 +77,7 @@ export default function useEventPublisher() { } return { - nip42Auth: async (challenge: string, relay:string): Promise => { + nip42Auth: async (challenge: string, relay:string) => { if(pubKey) { const ev = NEvent.ForPubKey(pubKey); ev.Kind = EventKind.Auth; @@ -88,7 +86,6 @@ export default function useEventPublisher() { ev.Tags.push(new Tag(["challenge", challenge], 1)); return await signEvent(ev); } - return Promise.reject(); }, broadcast: (ev: NEvent | undefined) => { if (ev) { diff --git a/src/Nostr/Auth.ts b/src/Nostr/Auth.ts deleted file mode 100644 index c9a62c9f..00000000 --- a/src/Nostr/Auth.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {default as NEvent} from "./Event" - -export class NIP42AuthChallenge extends Event { - challenge?:string - relay?:string - constructor(challenge:string, relay:string) { - super("nip42auth"); - this.challenge = challenge; - this.relay = relay; - } -} - -export class NIP42AuthResponse extends Event { - event?: NEvent - constructor(challenge: string, event: NEvent) { - super(`nip42response:${challenge}`); - this.event = event; - } -} \ No newline at end of file diff --git a/src/Nostr/Connection.ts b/src/Nostr/Connection.ts index eca0b90a..060fc934 100644 --- a/src/Nostr/Connection.ts +++ b/src/Nostr/Connection.ts @@ -8,6 +8,7 @@ import { ConnectionStats } from "Nostr/ConnectionStats"; import { RawEvent, TaggedRawEvent, u256 } from "Nostr"; import { RelayInfo } from "./RelayInfo"; import Nips from "./Nips"; +import { System } from "./System"; export type CustomHook = (state: Readonly) => void; @@ -367,46 +368,38 @@ export default class Connection { } } - async _OnAuthAsync(challenge: string) { - const challengeEvent = new NIP42AuthChallenge(challenge, this.Address) - + async _OnAuthAsync(challenge: string): Promise { const authCleanup = () => { this.AwaitingAuth.delete(challenge) } - - const authCallback = (e:NIP42AuthResponse):Promise => { - window.removeEventListener(`nip42response:${challenge}`, authCallback) - return new Promise((resolve,_) => { - if(!e.event) { - authCleanup(); - return Promise.reject('no event'); - } - - let t = setTimeout(() => { - authCleanup(); - resolve(); - }, 10_000); - - this.EventsCallback.set(e.event.Id, (msg:any[]) => { - clearTimeout(t); - authCleanup(); - if(msg.length > 3 && msg[2] === true) { - this.Authed = true; - this._InitSubscriptions(); - } - resolve(); - }); - - let req = ["AUTH", e.event.ToObject()]; - this._SendJson(req); - this.Stats.EventsSent++; - this._UpdateState(); - }) - } - this.AwaitingAuth.set(challenge, true) - window.addEventListener(`nip42response:${challenge}`, authCallback) - window.dispatchEvent(challengeEvent) + const authEvent = await System.nip42Auth(challenge, this.Address) + return new Promise((resolve,_) => { + if(!authEvent) { + authCleanup(); + return Promise.reject('no event'); + } + + let t = setTimeout(() => { + authCleanup(); + resolve(); + }, 10_000); + + this.EventsCallback.set(authEvent.Id, (msg:any[]) => { + clearTimeout(t); + authCleanup(); + if(msg.length > 3 && msg[2] === true) { + this.Authed = true; + this._InitSubscriptions(); + } + resolve(); + }); + + let req = ["AUTH", authEvent.ToObject()]; + this._SendJson(req); + this.Stats.EventsSent++; + this._UpdateState(); + }) } _OnEnd(subId: string) { diff --git a/src/Nostr/System.ts b/src/Nostr/System.ts index a51d2528..7c1fcb4c 100644 --- a/src/Nostr/System.ts +++ b/src/Nostr/System.ts @@ -212,6 +212,10 @@ export class NostrSystem { setTimeout(() => this._FetchMetadata(), 500); } + + async nip42Auth(challenge: string, relay:string): Promise { + return + } } export const System = new NostrSystem(); diff --git a/src/Pages/Layout.tsx b/src/Pages/Layout.tsx index b08d4e89..ba4e2a4d 100644 --- a/src/Pages/Layout.tsx +++ b/src/Pages/Layout.tsx @@ -1,5 +1,5 @@ import "./Layout.css"; -import { useEffect } from "react" +import { useEffect, useMemo } from "react" import { useDispatch, useSelector } from "react-redux"; import { Outlet, useNavigate } from "react-router-dom"; import { faBell, faMessage, faSearch } from "@fortawesome/free-solid-svg-icons"; @@ -15,7 +15,6 @@ import useLoginFeed from "Feed/LoginFeed"; import { totalUnread } from "Pages/MessagesPage"; import { SearchRelays } from 'Const'; import useEventPublisher from "Feed/EventPublisher"; -import { NIP42AuthChallenge, NIP42AuthResponse } from "Nostr/Auth"; export default function Layout() { const dispatch = useDispatch(); @@ -30,17 +29,12 @@ export default function Layout() { const pub = useEventPublisher(); useLoginFeed(); + useMemo(() => { + System.nip42Auth = pub.nip42Auth + },[pub]) + useEffect(() => { if (relays) { - const nip42AuthEvent = async (event: NIP42AuthChallenge) => { - if(event.challenge && event.relay) { - const signedEvent = await pub.nip42Auth(event.challenge, event.relay); - const response = new NIP42AuthResponse(event.challenge, signedEvent); - window.dispatchEvent(response); - } - } - window.addEventListener("nip42auth", nip42AuthEvent) - for (let [k, v] of Object.entries(relays)) { System.ConnectToRelay(k, v); } @@ -49,10 +43,6 @@ export default function Layout() { System.DisconnectRelay(k); } } - - return () => { - window.removeEventListener("nip42auth", nip42AuthEvent) - } } }, [relays]); From a9ec9334afed0a955efd8b97991b05855de1c37b Mon Sep 17 00:00:00 2001 From: Kieran Date: Sat, 28 Jan 2023 16:58:52 +0000 Subject: [PATCH 7/7] review change --- src/Pages/Layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pages/Layout.tsx b/src/Pages/Layout.tsx index ba4e2a4d..a7e2cfaa 100644 --- a/src/Pages/Layout.tsx +++ b/src/Pages/Layout.tsx @@ -29,7 +29,7 @@ export default function Layout() { const pub = useEventPublisher(); useLoginFeed(); - useMemo(() => { + useEffect(() => { System.nip42Auth = pub.nip42Auth },[pub])