Refactor to use NDK instead of custom relay and metadata controllers #89

Merged
enes merged 6 commits from ndk-refactor into staging 2024-10-21 13:39:56 +00:00
17 changed files with 229 additions and 291 deletions
Showing only changes of commit b0ebe7154a - Show all commits

View File

@ -4,13 +4,12 @@ import { QRCodeSVG } from 'qrcode.react'
import { useState } from 'react'
import { Link } from 'react-router-dom'
import { toast } from 'react-toastify'
import { UserRelaysType } from '../controllers'
import { useAppSelector, useDidMount, useNDKContext } from '../hooks'
import { appRoutes, getProfilePageRoute } from '../routes'
import '../styles/author.css'
import '../styles/innerPage.css'
import '../styles/socialPosts.css'
import { UserProfile } from '../types'
import { UserProfile, UserRelaysType } from '../types'
import {
copyTextToClipboard,
hexToNpub,

View File

@ -1,3 +1,4 @@
import { getRelayListForUser } from '@nostr-dev-kit/ndk'
import { QRCodeSVG } from 'qrcode.react'
import React, {
Dispatch,
@ -9,7 +10,7 @@ import React, {
} from 'react'
import Countdown, { CountdownRenderProps } from 'react-countdown'
import { toast } from 'react-toastify'
import { MetadataController, ZapController } from '../controllers'
import { ZapController } from '../controllers'
import { useAppSelector, useDidMount, useNDKContext } from '../hooks'
import '../styles/popup.css'
import { PaymentRequest, UserProfile } from '../types'
@ -251,7 +252,7 @@ export const ZapPopUp = ({
setHasZapped,
handleClose
}: ZapPopUpProps) => {
const { findMetadata } = useNDKContext()
const { ndk, findMetadata } = useNDKContext()
const [isLoading, setIsLoading] = useState(false)
const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')
const [amount, setAmount] = useState<number>(0)
@ -300,6 +301,20 @@ export const ZapPopUp = ({
return null
}
// Find the receiver's read relays.
const receiverRelays = await getRelayListForUser(receiver, ndk)
.then((ndkRelayList) => {
if (ndkRelayList) return ndkRelayList.readRelayUrls
return [] // Return an empty array if ndkRelayList is undefined
})
.catch((err) => {
console.error(
`An error occurred in getting zap receiver's read relays`,
err
)
return [] as string[]
})
const zapController = ZapController.getInstance()
setLoadingSpinnerDesc('Creating zap request')
@ -308,6 +323,7 @@ export const ZapPopUp = ({
receiverMetadata.lud16,
amount,
receiverMetadata.pubkey as string,
receiverRelays,
userHexKey,
message,
eventId,
@ -482,7 +498,7 @@ export const ZapSplit = ({
setHasZapped,
handleClose
}: ZapSplitProps) => {
const { findMetadata } = useNDKContext()
const { ndk, findMetadata } = useNDKContext()
const [isLoading, setIsLoading] = useState(false)
const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')
const [amount, setAmount] = useState<number>(0)
@ -502,8 +518,8 @@ export const ZapSplit = ({
setAuthor(res)
})
const metadataController = await MetadataController.getInstance()
findMetadata(metadataController.adminNpubs[0]).then((res) => {
const adminNpubs = import.meta.env.VITE_ADMIN_NPUBS.split(',')
findMetadata(adminNpubs[0]).then((res) => {
setAdmin(res)
})
})
@ -557,12 +573,30 @@ export const ZapSplit = ({
const invoices = new Map<string, PaymentRequest>()
if (authorShare > 0 && author?.pubkey && author?.lud16) {
// Find the receiver's read relays.
const authorRelays = await getRelayListForUser(
author.pubkey as string,
ndk
)
.then((ndkRelayList) => {
if (ndkRelayList) return ndkRelayList.readRelayUrls
return [] // Return an empty array if ndkRelayList is undefined
})
.catch((err) => {
console.error(
`An error occurred in getting zap receiver's read relays`,
err
)
return [] as string[]
})
setLoadingSpinnerDesc('Generating invoice for author')
const invoice = await zapController
.getLightningPaymentRequest(
author.lud16,
authorShare,
author.pubkey as string,
authorRelays,
userHexKey,
message,
eventId,
@ -579,12 +613,27 @@ export const ZapSplit = ({
}
if (adminShare > 0 && admin?.pubkey && admin?.lud16) {
// Find the receiver's read relays.
const adminRelays = await getRelayListForUser(admin.pubkey as string, ndk)
.then((ndkRelayList) => {
if (ndkRelayList) return ndkRelayList.readRelayUrls
return [] // Return an empty array if ndkRelayList is undefined
})
.catch((err) => {
console.error(
`An error occurred in getting zap receiver's read relays`,
err
)
return [] as string[]
})
setLoadingSpinnerDesc('Generating invoice for site owner')
const invoice = await zapController
.getLightningPaymentRequest(
admin.lud16,
adminShare,
admin.pubkey as string,
adminRelays,
userHexKey,
message,
eventId,

View File

@ -3,6 +3,7 @@ import NDK, {
NDKEvent,
NDKFilter,
NDKKind,
NDKList,
NDKRelaySet,
NDKSubscriptionCacheUsage,
NDKUser,
@ -10,11 +11,10 @@ import NDK, {
} from '@nostr-dev-kit/ndk'
import NDKCacheAdapterDexie from '@nostr-dev-kit/ndk-cache-dexie'
import { MOD_FILTER_LIMIT, T_TAG_VALUE } from 'constants.ts'
import { UserRelaysType } from 'controllers'
import { Dexie } from 'dexie'
import { createContext, ReactNode, useEffect, useMemo } from 'react'
import { toast } from 'react-toastify'
import { ModDetails, UserProfile } from 'types'
import { ModDetails, MuteLists, UserProfile, UserRelaysType } from 'types'
import {
constructModListFromEvents,
hexToNpub,
@ -57,6 +57,11 @@ interface NDKContextType {
hasZapped: boolean
}>
publish: (event: NDKEvent) => Promise<string[]>
getNSFWList: () => Promise<string[]>
getMuteLists: (pubkey?: string) => Promise<{
admin: MuteLists
user: MuteLists
}>
}
// Create the context with an initial value of `null`
@ -368,6 +373,117 @@ export const NDKContextProvider = ({ children }: { children: ReactNode }) => {
})
}
/**
* Retrieves a list of NSFW (Not Safe For Work) posts that were not specified as NSFW by post author but marked as NSFW by admin.
*
* @returns {Promise<string[]>} - A promise that resolves to an array of NSFW post identifiers (e.g., URLs or IDs).
*/
const getNSFWList = async (): Promise<string[]> => {
// Initialize an array to store the NSFW post identifiers
const nsfwPosts: string[] = []
const reportingNpub = import.meta.env.VITE_REPORTING_NPUB
// Convert the public key (npub) to a hexadecimal format
const hexKey = npubToHex(reportingNpub)
// If the conversion is successful and we have a hexKey
if (hexKey) {
// Fetch the event that contains the NSFW list
const nsfwListEvent = await fetchEvent({
kinds: [NDKKind.ArticleCurationSet],
authors: [hexKey],
'#d': ['nsfw']
})
if (nsfwListEvent) {
// Convert the event data to an NDKList, which is a structured list format
const list = NDKList.from(nsfwListEvent)
// Iterate through the items in the list
list.items.forEach((item) => {
if (item[0] === 'a') {
// Add the identifier of the NSFW post to the nsfwPosts array
nsfwPosts.push(item[1])
}
})
}
}
// Return the array of NSFW post identifiers
return nsfwPosts
}
const getMuteLists = async (
pubkey?: string
): Promise<{
admin: MuteLists
user: MuteLists
}> => {
const adminMutedAuthors = new Set<string>()
const adminMutedPosts = new Set<string>()
const reportingNpub = import.meta.env.VITE_REPORTING_NPUB
const adminHexKey = npubToHex(reportingNpub)
if (adminHexKey) {
const muteListEvent = await fetchEvent({
kinds: [NDKKind.MuteList],
authors: [adminHexKey]
})
if (muteListEvent) {
const list = NDKList.from(muteListEvent)
list.items.forEach((item) => {
if (item[0] === 'p') {
adminMutedAuthors.add(item[1])
} else if (item[0] === 'a') {
adminMutedPosts.add(item[1])
}
})
}
}
const userMutedAuthors = new Set<string>()
const userMutedPosts = new Set<string>()
if (pubkey) {
const userHexKey = npubToHex(pubkey)
if (userHexKey) {
const muteListEvent = await fetchEvent({
kinds: [NDKKind.MuteList],
authors: [userHexKey]
})
if (muteListEvent) {
const list = NDKList.from(muteListEvent)
list.items.forEach((item) => {
if (item[0] === 'p') {
userMutedAuthors.add(item[1])
} else if (item[0] === 'a') {
userMutedPosts.add(item[1])
}
})
}
}
}
return {
admin: {
authors: Array.from(adminMutedAuthors),
replaceableEvents: Array.from(adminMutedPosts)
},
user: {
authors: Array.from(userMutedAuthors),
replaceableEvents: Array.from(userMutedPosts)
}
}
}
return (
<NDKContext.Provider
value={{
@ -379,7 +495,9 @@ export const NDKContextProvider = ({ children }: { children: ReactNode }) => {
fetchEventFromUserRelays,
findMetadata,
getTotalZapAmount,
publish
publish,
getNSFWList,
getMuteLists
}}
>
{children}

View File

@ -1,2 +1 @@
export * from './metadata'
export * from './zap'

View File

@ -1,217 +0,0 @@
import NDK, { getRelayListForUser, NDKList } from '@nostr-dev-kit/ndk'
import { kinds } from 'nostr-tools'
import { MuteLists } from '../types'
import { log, LogType, npubToHex, timeout } from '../utils'
export enum UserRelaysType {
Read = 'readRelayUrls',
Write = 'writeRelayUrls',
Both = 'bothRelayUrls'
}
/**
* Singleton class to manage metadata operations using NDK.
*/
export class MetadataController {
private static instance: MetadataController
private ndk: NDK
public adminNpubs: string[]
public adminRelays = new Set<string>()
public reportingNpub: string
private constructor() {
this.ndk = new NDK({
explicitRelayUrls: [
'wss://user.kindpag.es',
'wss://purplepag.es',
'wss://relay.damus.io/',
import.meta.env.VITE_APP_RELAY
]
})
this.ndk
.connect()
.then(() => {
console.log('NDK connected')
})
.catch((err) => {
console.log('error in ndk connection', err)
})
this.adminNpubs = import.meta.env.VITE_ADMIN_NPUBS.split(',')
this.reportingNpub = import.meta.env.VITE_REPORTING_NPUB
}
private setAdminRelays = async () => {
const promises = this.adminNpubs.map((npub) => {
const hexKey = npubToHex(npub)
if (!hexKey) return null
return getRelayListForUser(hexKey, this.ndk)
.then((ndkRelayList) => {
if (ndkRelayList) {
ndkRelayList.writeRelayUrls.forEach((url) =>
this.adminRelays.add(url)
)
}
})
.catch((err) => {
log(
true,
LogType.Error,
`❌ Error occurred in getting the instance of NDKRelayList for npub: ${npub}`,
err
)
})
})
await Promise.allSettled(promises)
}
/**
* Provides the singleton instance of MetadataController.
*
* @returns The singleton instance of MetadataController.
*/
public static async getInstance(): Promise<MetadataController> {
if (!MetadataController.instance) {
MetadataController.instance = new MetadataController()
await MetadataController.instance.setAdminRelays()
}
return MetadataController.instance
}
public findUserRelays = async (
hexKey: string,
userRelaysType: UserRelaysType = UserRelaysType.Both
): Promise<string[]> => {
log(true, LogType.Info, ` Finding user's relays`, hexKey, userRelaysType)
const ndkRelayListPromise = getRelayListForUser(hexKey, this.ndk)
// Use Promise.race to either get the NDKRelayList instance or handle the timeout
return await Promise.race([
ndkRelayListPromise,
timeout() // Custom timeout function that rejects after a specified time
])
.then((ndkRelayList) => {
if (ndkRelayList) return ndkRelayList[userRelaysType]
return [] // Return an empty array if ndkRelayList is undefined
})
.catch((err) => {
log(true, LogType.Error, err)
return [] // Return an empty array if an error occurs
})
}
public getNDKRelayList = async (hexKey: string) =>
getRelayListForUser(hexKey, this.ndk)
public getMuteLists = async (
pubkey?: string
): Promise<{
admin: MuteLists
user: MuteLists
}> => {
const adminMutedAuthors = new Set<string>()
const adminMutedPosts = new Set<string>()
const adminHexKey = npubToHex(this.reportingNpub)
if (adminHexKey) {
const muteListEvent = await this.ndk.fetchEvent({
kinds: [kinds.Mutelist],
authors: [adminHexKey]
})
if (muteListEvent) {
const list = NDKList.from(muteListEvent)
list.items.forEach((item) => {
if (item[0] === 'p') {
adminMutedAuthors.add(item[1])
} else if (item[0] === 'a') {
adminMutedPosts.add(item[1])
}
})
}
}
const userMutedAuthors = new Set<string>()
const userMutedPosts = new Set<string>()
if (pubkey) {
const userHexKey = npubToHex(pubkey)
if (userHexKey) {
const muteListEvent = await this.ndk.fetchEvent({
kinds: [kinds.Mutelist],
authors: [userHexKey]
})
if (muteListEvent) {
const list = NDKList.from(muteListEvent)
list.items.forEach((item) => {
if (item[0] === 'p') {
userMutedAuthors.add(item[1])
} else if (item[0] === 'a') {
userMutedPosts.add(item[1])
}
})
}
}
}
return {
admin: {
authors: Array.from(adminMutedAuthors),
replaceableEvents: Array.from(adminMutedPosts)
},
user: {
authors: Array.from(userMutedAuthors),
replaceableEvents: Array.from(userMutedPosts)
}
}
}
/**
* Retrieves a list of NSFW (Not Safe For Work) posts that were not specified as NSFW by post author but marked as NSFW by admin.
*
* @returns {Promise<string[]>} - A promise that resolves to an array of NSFW post identifiers (e.g., URLs or IDs).
*/
public getNSFWList = async (): Promise<string[]> => {
// Initialize an array to store the NSFW post identifiers
const nsfwPosts: string[] = []
// Convert the public key (npub) to a hexadecimal format
const hexKey = npubToHex(this.reportingNpub)
// If the conversion is successful and we have a hexKey
if (hexKey) {
// Fetch the event that contains the NSFW list
const nsfwListEvent = await this.ndk.fetchEvent({
kinds: [kinds.Curationsets],
authors: [hexKey],
'#d': ['nsfw']
})
if (nsfwListEvent) {
// Convert the event data to an NDKList, which is a structured list format
const list = NDKList.from(nsfwListEvent)
// Iterate through the items in the list
list.items.forEach((item) => {
if (item[0] === 'a') {
// Add the identifier of the NSFW post to the nsfwPosts array
nsfwPosts.push(item[1])
}
})
}
}
// Return the array of NSFW post identifiers
return nsfwPosts
}
}

View File

@ -17,7 +17,6 @@ import {
ZapRequest
} from '../types'
import { log, LogType, npubToHex } from '../utils'
import { MetadataController, UserRelaysType } from './metadata'
/**
* Singleton class to manage zap related operations.
@ -48,6 +47,7 @@ export class ZapController {
* @param lud16 - LUD-16 of the recipient.
* @param amount - payment amount (will be multiplied by 1000 to represent sats).
* @param recipientPubKey - pubKey of the recipient.
* @param recipientRelays - relays on which zap receipt will be published.
* @param senderPubkey - pubKey of of the sender.
* @param content - optional content (comment).
* @param eventId - event id, if zapping an event.
@ -59,6 +59,7 @@ export class ZapController {
lud16: string,
amount: number,
recipientPubKey: string,
recipientRelays: string[],
senderPubkey: string,
content?: string,
eventId?: string,
@ -88,6 +89,7 @@ export class ZapController {
amount,
content,
recipientPubKey,
recipientRelays,
senderPubkey,
eventId,
aTag
@ -273,6 +275,7 @@ export class ZapController {
* @param amount - request amount (sats).
* @param content - comment.
* @param recipientPubKey - pubKey of the recipient.
* @param recipientRelays - relays on which zap receipt will be published.
* @param senderPubkey - pubKey of of the sender.
* @param eventId - event id, if zapping an event.
* @param aTag - value of `a` tag.
@ -282,6 +285,7 @@ export class ZapController {
amount: number,
content = '',
recipientPubKey: string,
recipientRelays: string[],
senderPubkey: string,
eventId?: string,
aTag?: string
@ -290,21 +294,15 @@ export class ZapController {
if (!recipientHexKey) throw 'Invalid recipient pubKey.'
const metadataController = await MetadataController.getInstance()
const receiverReadRelays = await metadataController.findUserRelays(
recipientHexKey,
UserRelaysType.Read
)
if (!receiverReadRelays.includes(this.appRelay)) {
receiverReadRelays.push(this.appRelay)
if (!recipientRelays.includes(this.appRelay)) {
recipientRelays.push(this.appRelay)
}
const zapRequest: ZapRequest = {
kind: kinds.ZapRequest,
content,
tags: [
['relays', ...receiverReadRelays],
['relays', ...recipientRelays],
['amount', `${amount}`],
['p', recipientHexKey]
],

View File

@ -6,9 +6,8 @@ import {
NDKSubscription,
NDKSubscriptionCacheUsage
} from '@nostr-dev-kit/ndk'
import { UserRelaysType } from 'controllers'
import { useEffect, useState } from 'react'
import { CommentEvent, ModDetails } from 'types'
import { CommentEvent, ModDetails, UserRelaysType } from 'types'
import { log, LogType } from 'utils'
import { useNDKContext } from './useNDKContext'

View File

@ -1,9 +1,10 @@
import { useEffect, useState } from 'react'
import { MuteLists } from 'types'
import { useAppSelector } from './redux'
import { MetadataController } from 'controllers'
import { useNDKContext } from './useNDKContext'
export const useMuteLists = () => {
const { getMuteLists } = useNDKContext()
const [muteLists, setMuteLists] = useState<{
admin: MuteLists
user: MuteLists
@ -21,17 +22,11 @@ export const useMuteLists = () => {
const userState = useAppSelector((state) => state.user)
useEffect(() => {
const getMuteLists = async () => {
const pubkey = userState.user?.pubkey as string | undefined
const metadataController = await MetadataController.getInstance()
metadataController.getMuteLists(pubkey).then((lists) => {
setMuteLists(lists)
})
}
getMuteLists()
}, [userState])
const pubkey = userState.user?.pubkey as string | undefined
getMuteLists(pubkey).then((lists) => {
setMuteLists(lists)
})
}, [userState, getMuteLists])
return muteLists
}

View File

@ -1,14 +1,13 @@
import { MetadataController } from 'controllers'
import { useState } from 'react'
import { useDidMount } from './useDidMount'
import { useNDKContext } from './useNDKContext'
export const useNSFWList = () => {
const { getNSFWList } = useNDKContext()
const [nsfwList, setNSFWList] = useState<string[]>([])
useDidMount(async () => {
const metadataController = await MetadataController.getInstance()
metadataController.getNSFWList().then((list) => {
getNSFWList().then((list) => {
setNSFWList(list)
})
})

View File

@ -1,10 +1,10 @@
import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'
import { REACTIONS } from 'constants.ts'
import { UserRelaysType } from 'controllers'
import { useAppSelector, useDidMount, useNDKContext } from 'hooks'
import { Event, kinds, UnsignedEvent } from 'nostr-tools'
import { useMemo, useState } from 'react'
import { toast } from 'react-toastify'
import { UserRelaysType } from 'types'
import { abbreviateNumber, log, LogType, now } from 'utils'
type UseReactionsParams = {

View File

@ -6,7 +6,6 @@ import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { Banner } from '../components/Banner'
import { ZapPopUp } from '../components/Zap'
import { MetadataController } from '../controllers'
import {
useAppDispatch,
useAppSelector,
@ -261,8 +260,8 @@ const TipButtonWithDialog = React.memo(() => {
const [isOpen, setIsOpen] = useState(false)
useDidMount(async () => {
const metadataController = await MetadataController.getInstance()
setAdminNpub(metadataController.adminNpubs[0])
const adminNpubs = import.meta.env.VITE_ADMIN_NPUBS.split(',')
setAdminNpub(adminNpubs[0])
})
return (

View File

@ -152,7 +152,7 @@ const SlideContent = ({ naddr }: SlideContentProps) => {
useDidMount(() => {
const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
const { identifier, kind, pubkey, relays = [] } = decoded.data
const { identifier, kind, pubkey } = decoded.data
const ndkFilter: NDKFilter = {
'#a': [identifier],
@ -160,7 +160,7 @@ const SlideContent = ({ naddr }: SlideContentProps) => {
kinds: [kind]
}
fetchEvent(ndkFilter, relays)
fetchEvent(ndkFilter)
.then((ndkEvent) => {
if (ndkEvent) {
const extracted = extractModData(ndkEvent)
@ -225,7 +225,7 @@ const DisplayMod = ({ naddr }: DisplayModProps) => {
useDidMount(() => {
const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
const { identifier, kind, pubkey, relays = [] } = decoded.data
const { identifier, kind, pubkey } = decoded.data
const ndkFilter: NDKFilter = {
'#a': [identifier],
@ -233,7 +233,7 @@ const DisplayMod = ({ naddr }: DisplayModProps) => {
kinds: [kind]
}
fetchEvent(ndkFilter, relays)
fetchEvent(ndkFilter)
.then((ndkEvent) => {
if (ndkEvent) {
const extracted = extractModData(ndkEvent)

View File

@ -11,7 +11,6 @@ import { toast } from 'react-toastify'
import { BlogCard } from '../../components/BlogCard'
import { LoadingSpinner } from '../../components/LoadingSpinner'
import { ProfileSection } from '../../components/ProfileSection'
import { MetadataController, UserRelaysType } from '../../controllers'
import { useAppSelector, useDidMount, useNDKContext } from '../../hooks'
import { getGamePageRoute, getModsEditPageRoute } from '../../routes'
import '../../styles/comments.css'
@ -24,7 +23,7 @@ import '../../styles/styles.css'
import '../../styles/tabs.css'
import '../../styles/tags.css'
import '../../styles/write.css'
import { DownloadUrl, ModDetails } from '../../types'
import { DownloadUrl, ModDetails, UserRelaysType } from '../../types'
import {
abbreviateNumber,
copyTextToClipboard,
@ -708,8 +707,8 @@ const ReportPopup = ({ aTag, handleClose }: ReportPopupProps) => {
return
}
const metadataController = await MetadataController.getInstance()
const reportingPubkey = npubToHex(metadataController.reportingNpub)
const reportingNpub = import.meta.env.VITE_REPORTING_NPUB
const reportingPubkey = npubToHex(reportingNpub)
if (reportingPubkey === hexPubkey) {
setLoadingSpinnerDesc(`Finding user's mute list`)

View File

@ -1,5 +1,4 @@
import { AdminSVG, PreferenceSVG, ProfileSVG, RelaySVG } from 'components/SVGs'
import { MetadataController } from 'controllers'
import { useAppSelector } from 'hooks'
import { logout } from 'nostr-login'
import { useEffect, useState } from 'react'
@ -57,15 +56,12 @@ const SettingTabs = () => {
const userState = useAppSelector((state) => state.user)
useEffect(() => {
MetadataController.getInstance().then((controller) => {
if (userState.auth && userState.user?.npub) {
setIsAdmin(
controller.adminNpubs.includes(userState.user.npub as string)
)
} else {
setIsAdmin(false)
}
})
const adminNpubs = import.meta.env.VITE_ADMIN_NPUBS.split(',')
if (userState.auth && userState.user?.npub) {
setIsAdmin(adminNpubs.includes(userState.user.npub as string))
} else {
setIsAdmin(false)
}
}, [userState])
const handleSignOut = () => {

View File

@ -1,11 +1,16 @@
import { NDKEvent, NDKRelayList, NDKRelayStatus } from '@nostr-dev-kit/ndk'
import {
getRelayListForUser,
NDKEvent,
NDKRelayList,
NDKRelayStatus
} from '@nostr-dev-kit/ndk'
import { InputField } from 'components/Inputs'
import { LoadingSpinner } from 'components/LoadingSpinner'
import { MetadataController, UserRelaysType } from 'controllers'
import { useAppSelector, useDidMount, useNDKContext } from 'hooks'
import { Event, kinds, UnsignedEvent } from 'nostr-tools'
import { useEffect, useState } from 'react'
import { toast } from 'react-toastify'
import { UserRelaysType } from 'types'
import { log, LogType, normalizeWebSocketURL, now } from 'utils'
const READ_MARKER = 'read'
@ -20,10 +25,8 @@ export const RelaySettings = () => {
const [inputValue, setInputValue] = useState('')
useEffect(() => {
const fetchRelayList = async (pubkey: string) => {
const metadataController = await MetadataController.getInstance()
metadataController
.getNDKRelayList(pubkey)
if (userState.auth && userState.user?.pubkey) {
getRelayListForUser(userState.user.pubkey as string, ndk)
.then((res) => {
setNDKRelayList(res)
})
@ -35,14 +38,10 @@ export const RelaySettings = () => {
)
setNDKRelayList(null)
})
}
if (userState.auth && userState.user?.pubkey) {
fetchRelayList(userState.user.pubkey as string)
} else {
setNDKRelayList(null)
}
}, [userState])
}, [userState, ndk])
const handleAdd = async (relayUrl: string) => {
if (!ndkRelayList) return

View File

@ -29,7 +29,7 @@ export const SubmitModPage = () => {
useDidMount(async () => {
if (naddr) {
const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
const { identifier, kind, pubkey, relays = [] } = decoded.data
const { identifier, kind, pubkey } = decoded.data
const filter: NDKFilter = {
'#a': [identifier],
@ -39,7 +39,7 @@ export const SubmitModPage = () => {
setIsFetching(true)
fetchEvent(filter, relays)
fetchEvent(filter)
.then((event) => {
if (event) {
const extracted = extractModData(event)

View File

@ -1,3 +1,9 @@
import { NDKUserProfile } from '@nostr-dev-kit/ndk'
export type UserProfile = NDKUserProfile | null
export enum UserRelaysType {
Read = 'readRelayUrls',
Write = 'writeRelayUrls',
Both = 'bothRelayUrls'
}