diff --git a/src/features/nostr-relays/index.tsx b/src/features/nostr-relays/index.tsx index 2921390e7..e92f2dabe 100644 --- a/src/features/nostr-relays/index.tsx +++ b/src/features/nostr-relays/index.tsx @@ -1,7 +1,10 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { Button, Column, Form, FormActions, Stack } from 'soapbox/components/ui'; +import { useNostr } from 'soapbox/contexts/nostr-context'; +import { useNostrReq } from 'soapbox/features/nostr/hooks/useNostrReq'; +import { useOwnAccount } from 'soapbox/hooks'; import RelayEditor, { RelayData } from './components/relay-editor'; @@ -11,13 +14,39 @@ const messages = defineMessages({ const NostrRelays = () => { const intl = useIntl(); + const { account } = useOwnAccount(); + const { relay, signer } = useNostr(); + + const { events } = useNostrReq( + account?.nostr + ? [{ kinds: [10002], authors: [account?.nostr.pubkey], limit: 1 }] + : [], + ); const [relays, setRelays] = useState([]); const [isLoading, setIsLoading] = useState(false); - const handleSubmit = (): void => { + useEffect(() => { + const tags = events[0]?.tags ?? []; + const data = tags.map(tag => ({ url: tag[1], marker: tag[2] as 'read' | 'write' | undefined })); + setRelays(data); + }, [events]); + + const handleSubmit = async (): Promise => { + if (!signer || !relay) return; + setIsLoading(true); - // Save relays + + const event = await signer.signEvent({ + kind: 10002, + tags: relays.map(relay => relay.marker ? ['r', relay.url, relay.marker] : ['r', relay.url]), + content: '', + created_at: Math.floor(Date.now() / 1000), + }); + + // eslint-disable-next-line compat/compat + await relay.event(event, { signal: AbortSignal.timeout(1000) }); + setIsLoading(false); }; diff --git a/src/features/settings/index.tsx b/src/features/settings/index.tsx index f04f311a8..f2e53b867 100644 --- a/src/features/settings/index.tsx +++ b/src/features/settings/index.tsx @@ -21,6 +21,7 @@ const messages = defineMessages({ deleteAccount: { id: 'settings.delete_account', defaultMessage: 'Delete Account' }, editProfile: { id: 'settings.edit_profile', defaultMessage: 'Edit Profile' }, editIdentity: { id: 'settings.edit_identity', defaultMessage: 'Identity' }, + editRelays: { id: 'nostr_relays.title', defaultMessage: 'Relays' }, exportData: { id: 'column.export_data', defaultMessage: 'Export data' }, importData: { id: 'navigation_bar.import_data', defaultMessage: 'Import data' }, mfaDisabled: { id: 'mfa.disabled', defaultMessage: 'Disabled' }, @@ -71,6 +72,7 @@ const Settings = () => { {account?.source?.nostr?.nip05} )} + {features.nostr && } diff --git a/src/utils/features.ts b/src/utils/features.ts index 37c7af53b..8c42da8f4 100644 --- a/src/utils/features.ts +++ b/src/utils/features.ts @@ -757,6 +757,9 @@ const getInstanceFeatures = (instance: Instance) => { */ nip05: v.software === DITTO, + /** Has a Nostr relay. */ + nostr: !!instance.nostr?.relay, + /** * Ability to sign Nostr events over websocket. * @see GET /api/v1/streaming?stream=nostr