From 8f963a64ba9a33d502289a873fa1fdacbf63c82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Mon, 29 Apr 2024 18:43:33 +0200 Subject: [PATCH] Remove Nostr-related stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- package.json | 4 - src/actions/interactions.ts | 39 ---- src/actions/nostr.ts | 26 --- src/api/hooks/nostr/useSignerStream.ts | 148 --------------- src/api/index.ts | 11 +- src/components/mention.tsx | 4 +- src/components/status-action-bar.tsx | 25 +-- src/components/status-reply-mentions.tsx | 3 +- src/contexts/nostr-context.tsx | 57 ------ .../auth-login/components/login-page.tsx | 10 +- .../components/registration-form.tsx | 73 ++++---- .../components/registration-page.tsx | 13 +- .../compose/components/reply-mentions.tsx | 3 +- src/features/edit-identity/index.tsx | 122 ------------ src/features/edit-profile/index.tsx | 22 --- .../nostr-relays/components/relay-editor.tsx | 80 -------- src/features/nostr-relays/index.tsx | 74 -------- src/features/nostr/Bech32Redirect.tsx | 34 ---- src/features/nostr/NKeyStorage.ts | 112 ----------- src/features/nostr/hooks/useNostrReq.ts | 63 ------- src/features/nostr/keys.ts | 6 - src/features/settings/index.tsx | 8 - src/features/ui/components/modal-root.tsx | 4 - .../components/nostr-extension-indicator.tsx | 37 ---- .../nostr-login-modal/nostr-login-modal.tsx | 30 --- .../steps/extension-step.tsx | 41 ----- .../nostr-login-modal/steps/key-add-step.tsx | 71 ------- .../nostr-signup-modal/nostr-signup-modal.tsx | 33 ---- .../nostr-signup-modal/steps/key-step.tsx | 46 ----- .../nostr-signup-modal/steps/keygen-step.tsx | 81 -------- src/features/ui/components/navbar.tsx | 87 ++++----- .../ui/components/panels/sign-up-panel.tsx | 8 +- src/features/ui/index.tsx | 9 - src/features/ui/util/async-components.ts | 5 - src/init/soapbox.tsx | 13 +- src/locales/en.json | 27 +-- src/main.tsx | 1 - src/normalizers/status.ts | 1 - src/reducers/statuses.ts | 18 -- src/schemas/account.ts | 14 +- src/schemas/instance.ts | 6 - src/schemas/nostr.ts | 42 ----- src/schemas/status.ts | 1 - src/types/window.d.ts | 7 - src/utils/features.ts | 35 +--- src/utils/nostr.ts | 6 - src/workers.ts | 9 - src/workers/pow.worker.ts | 10 - yarn.lock | 174 +----------------- 49 files changed, 88 insertions(+), 1665 deletions(-) delete mode 100644 src/actions/nostr.ts delete mode 100644 src/api/hooks/nostr/useSignerStream.ts delete mode 100644 src/contexts/nostr-context.tsx delete mode 100644 src/features/edit-identity/index.tsx delete mode 100644 src/features/nostr-relays/components/relay-editor.tsx delete mode 100644 src/features/nostr-relays/index.tsx delete mode 100644 src/features/nostr/Bech32Redirect.tsx delete mode 100644 src/features/nostr/NKeyStorage.ts delete mode 100644 src/features/nostr/hooks/useNostrReq.ts delete mode 100644 src/features/nostr/keys.ts delete mode 100644 src/features/ui/components/modals/nostr-login-modal/components/nostr-extension-indicator.tsx delete mode 100644 src/features/ui/components/modals/nostr-login-modal/nostr-login-modal.tsx delete mode 100644 src/features/ui/components/modals/nostr-login-modal/steps/extension-step.tsx delete mode 100644 src/features/ui/components/modals/nostr-login-modal/steps/key-add-step.tsx delete mode 100644 src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx delete mode 100644 src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx delete mode 100644 src/features/ui/components/modals/nostr-signup-modal/steps/keygen-step.tsx delete mode 100644 src/schemas/nostr.ts delete mode 100644 src/types/window.d.ts delete mode 100644 src/utils/nostr.ts delete mode 100644 src/workers.ts delete mode 100644 src/workers/pow.worker.ts diff --git a/package.json b/package.json index 2eb18bb191..317cc552e8 100644 --- a/package.json +++ b/package.json @@ -73,8 +73,6 @@ "@sentry/browser": "^7.74.1", "@sentry/react": "^7.74.1", "@soapbox.pub/wasmboy": "^0.8.0", - "@soapbox/nspec": "npm:@jsr/soapbox__nspec", - "@soapbox/weblock": "npm:@jsr/soapbox__weblock", "@tabler/icons": "^3.1.0", "@tailwindcss/aspect-ratio": "^0.4.2", "@tailwindcss/forms": "^0.5.7", @@ -136,8 +134,6 @@ "localforage": "^1.10.0", "lodash": "^4.7.11", "mini-css-extract-plugin": "^2.6.0", - "nostr-machina": "^0.1.0", - "nostr-tools": "^2.3.0", "path-browserify": "^1.0.1", "postcss": "^8.4.29", "process": "^0.11.10", diff --git a/src/actions/interactions.ts b/src/actions/interactions.ts index cc50946319..76a0f54ea4 100644 --- a/src/actions/interactions.ts +++ b/src/actions/interactions.ts @@ -79,10 +79,6 @@ const FAVOURITES_EXPAND_FAIL = 'FAVOURITES_EXPAND_FAIL'; const REBLOGS_EXPAND_SUCCESS = 'REBLOGS_EXPAND_SUCCESS'; const REBLOGS_EXPAND_FAIL = 'REBLOGS_EXPAND_FAIL'; -const ZAP_REQUEST = 'ZAP_REQUEST'; -const ZAP_SUCCESS = 'ZAP_SUCCESS'; -const ZAP_FAIL = 'ZAP_FAIL'; - const messages = defineMessages({ bookmarkAdded: { id: 'status.bookmarked', defaultMessage: 'Bookmark added.' }, bookmarkRemoved: { id: 'status.unbookmarked', defaultMessage: 'Bookmark removed.' }, @@ -313,38 +309,6 @@ const undislikeFail = (status: StatusEntity, error: unknown) => ({ skipLoading: true, }); -const zap = (status: StatusEntity, amount: number) => - (dispatch: AppDispatch, getState: () => RootState) => { - if (!isLoggedIn(getState)) return; - - dispatch(zapRequest(status)); - - api(getState).post(`/api/v1/statuses/${status.id}/zap`, { amount }).then(function(response) { - dispatch(zapSuccess(status)); - }).catch(function(error) { - dispatch(zapFail(status, error)); - }); - }; - -const zapRequest = (status: StatusEntity) => ({ - type: ZAP_REQUEST, - status: status, - skipLoading: true, -}); - -const zapSuccess = (status: StatusEntity) => ({ - type: ZAP_SUCCESS, - status: status, - skipLoading: true, -}); - -const zapFail = (status: StatusEntity, error: unknown) => ({ - type: ZAP_FAIL, - status: status, - error: error, - skipLoading: true, -}); - const bookmark = (status: StatusEntity, folderId?: string) => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState(); @@ -775,8 +739,6 @@ export { FAVOURITES_EXPAND_FAIL, REBLOGS_EXPAND_SUCCESS, REBLOGS_EXPAND_FAIL, - ZAP_REQUEST, - ZAP_FAIL, reblog, unreblog, toggleReblog, @@ -844,5 +806,4 @@ export { remoteInteractionRequest, remoteInteractionSuccess, remoteInteractionFail, - zap, }; diff --git a/src/actions/nostr.ts b/src/actions/nostr.ts deleted file mode 100644 index 6908f06b62..0000000000 --- a/src/actions/nostr.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { nip19 } from 'nostr-tools'; - -import { type AppDispatch } from 'soapbox/store'; - -import { verifyCredentials } from './auth'; - -/** Log in with a Nostr pubkey. */ -function logInNostr(pubkey: string) { - return (dispatch: AppDispatch) => { - const npub = nip19.npubEncode(pubkey); - return dispatch(verifyCredentials(npub)); - }; -} - -/** Log in with a Nostr extension. */ -function nostrExtensionLogIn() { - return async (dispatch: AppDispatch) => { - if (!window.nostr) { - throw new Error('No Nostr signer available'); - } - const pubkey = await window.nostr.getPublicKey(); - return dispatch(logInNostr(pubkey)); - }; -} - -export { logInNostr, nostrExtensionLogIn }; \ No newline at end of file diff --git a/src/api/hooks/nostr/useSignerStream.ts b/src/api/hooks/nostr/useSignerStream.ts deleted file mode 100644 index c36b49b0d5..0000000000 --- a/src/api/hooks/nostr/useSignerStream.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { type NostrEvent } from '@soapbox/nspec'; -import { useEffect } from 'react'; - -import { useNostr } from 'soapbox/contexts/nostr-context'; -import { connectRequestSchema, nwcRequestSchema } from 'soapbox/schemas/nostr'; -import { jsonSchema } from 'soapbox/schemas/utils'; - -/** NIP-46 [response](https://github.com/nostr-protocol/nips/blob/master/46.md#response-events-kind24133) content. */ -interface NostrConnectResponse { - /** Request ID that this response is for. */ - id: string; - /** Result of the call (this can be either a string or a JSON stringified object) */ - result: string; - /** Error in string form, if any. Its presence indicates an error with the request. */ - error?: string; -} - -function useSignerStream() { - const { relay, pubkey, signer } = useNostr(); - - async function sendConnect(response: NostrConnectResponse) { - if (!relay || !pubkey || !signer) return; - - const event = await signer.signEvent({ - kind: 24133, - content: await signer.nip04!.encrypt(pubkey, JSON.stringify(response)), - tags: [['p', pubkey]], - created_at: Math.floor(Date.now() / 1000), - }); - - relay.event(event); - } - - async function handleConnectEvent(event: NostrEvent) { - if (!relay || !pubkey || !signer) return; - const decrypted = await signer.nip04!.decrypt(pubkey, event.content); - - const reqMsg = jsonSchema.pipe(connectRequestSchema).safeParse(decrypted); - if (!reqMsg.success) { - console.warn(decrypted); - console.warn(reqMsg.error); - return; - } - - const request = reqMsg.data; - - switch (request.method) { - case 'connect': - return sendConnect({ - id: request.id, - result: 'ack', - }); - case 'sign_event': - return sendConnect({ - id: request.id, - result: JSON.stringify(await signer.signEvent(JSON.parse(request.params[0]))), - }); - case 'ping': - return sendConnect({ - id: request.id, - result: 'pong', - }); - case 'get_relays': - return sendConnect({ - id: request.id, - result: JSON.stringify(await signer.getRelays?.() ?? []), - }); - case 'get_public_key': - return sendConnect({ - id: request.id, - result: await signer.getPublicKey(), - }); - case 'nip04_encrypt': - return sendConnect({ - id: request.id, - result: await signer.nip04!.encrypt(request.params[0], request.params[1]), - }); - case 'nip04_decrypt': - return sendConnect({ - id: request.id, - result: await signer.nip04!.decrypt(request.params[0], request.params[1]), - }); - case 'nip44_encrypt': - return sendConnect({ - id: request.id, - result: await signer.nip44!.encrypt(request.params[0], request.params[1]), - }); - case 'nip44_decrypt': - return sendConnect({ - id: request.id, - result: await signer.nip44!.decrypt(request.params[0], request.params[1]), - }); - default: - return sendConnect({ - id: request.id, - result: '', - error: `Unrecognized method: ${request.method}`, - }); - } - } - - async function handleWalletEvent(event: NostrEvent) { - if (!relay || !pubkey || !signer) return; - - const decrypted = await signer.nip04!.decrypt(pubkey, event.content); - - const reqMsg = jsonSchema.pipe(nwcRequestSchema).safeParse(decrypted); - if (!reqMsg.success) { - console.warn(decrypted); - console.warn(reqMsg.error); - return; - } - - await window.webln?.enable(); - await window.webln?.sendPayment(reqMsg.data.params.invoice); - } - - async function handleEvent(event: NostrEvent) { - switch (event.kind) { - case 24133: - await handleConnectEvent(event); - break; - case 23194: - await handleWalletEvent(event); - break; - } - } - - useEffect(() => { - if (!relay || !pubkey) return; - - const controller = new AbortController(); - const signal = controller.signal; - - (async() => { - for await (const msg of relay.req([{ kinds: [24133, 23194], authors: [pubkey], limit: 0 }], { signal })) { - if (msg[0] === 'EVENT') handleEvent(msg[2]); - } - })(); - - return () => { - controller.abort(); - }; - - }, [relay, pubkey, signer]); -} - -export { useSignerStream }; diff --git a/src/api/index.ts b/src/api/index.ts index dda1fa5081..c7e5654b4e 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -62,7 +62,6 @@ const getAuthBaseURL = createSelector([ export const baseClient = ( accessToken?: string | null, baseURL: string = '', - nostrSign = false, ): AxiosInstance => { const headers: Record = {}; @@ -70,10 +69,6 @@ export const baseClient = ( headers.Authorization = `Bearer ${accessToken}`; } - if (nostrSign) { - headers['X-Nostr-Sign'] = 'true'; - } - return axios.create({ // When BACKEND_URL is set, always use it. baseURL: isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : baseURL, @@ -105,11 +100,7 @@ export default (getState: () => RootState, authType: string = 'user'): AxiosInst const me = state.me; const baseURL = me ? getAuthBaseURL(state, me) : ''; - const relayUrl = state.getIn(['instance', 'nostr', 'relay']) as string | undefined; - const pubkey = state.getIn(['instance', 'nostr', 'pubkey']) as string | undefined; - const nostrSign = Boolean(relayUrl && pubkey); - - return baseClient(accessToken, baseURL, nostrSign); + return baseClient(accessToken, baseURL); }; // The Jest mock exports these, so they're needed for TypeScript. diff --git a/src/components/mention.tsx b/src/components/mention.tsx index 6f969d3577..d8fb2c66ab 100644 --- a/src/components/mention.tsx +++ b/src/components/mention.tsx @@ -1,8 +1,6 @@ import React from 'react'; import { Link } from 'react-router-dom'; -import { isPubkey } from 'soapbox/utils/nostr'; - import { Tooltip } from './ui'; import type { Mention as MentionEntity } from 'soapbox/schemas'; @@ -29,7 +27,7 @@ const Mention: React.FC = ({ mention: { acct, username }, disabled }) onClick={handleClick} dir='ltr' > - @{isPubkey(username) ? username.slice(0, 8) : username} + @{username} ); diff --git a/src/components/status-action-bar.tsx b/src/components/status-action-bar.tsx index 19c16eece2..f48151c3ef 100644 --- a/src/components/status-action-bar.tsx +++ b/src/components/status-action-bar.tsx @@ -6,7 +6,7 @@ import { blockAccount } from 'soapbox/actions/accounts'; import { launchChat } from 'soapbox/actions/chats'; import { directCompose, mentionCompose, quoteCompose, replyCompose } from 'soapbox/actions/compose'; import { editEvent } from 'soapbox/actions/events'; -import { toggleBookmark, toggleDislike, toggleFavourite, togglePin, toggleReblog, zap } from 'soapbox/actions/interactions'; +import { toggleBookmark, toggleDislike, toggleFavourite, togglePin, toggleReblog } from 'soapbox/actions/interactions'; import { openModal } from 'soapbox/actions/modals'; import { deleteStatusModal, toggleStatusSensitivityModal } from 'soapbox/actions/moderation'; import { initMuteModal } from 'soapbox/actions/mutes'; @@ -95,7 +95,6 @@ const messages = defineMessages({ unbookmark: { id: 'status.unbookmark', defaultMessage: 'Remove bookmark' }, unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute Conversation' }, unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' }, - zap: { id: 'status.zap', defaultMessage: 'Zap' }, }); interface IStatusActionBar { @@ -180,14 +179,6 @@ const StatusActionBar: React.FC = ({ } }; - const handleZapClick: React.EventHandler = (e) => { - if (me) { - dispatch(zap(status, 1337)); - } else { - onOpenUnauthorizedModal('ZAP'); - } - }; - const handleBookmarkClick: React.EventHandler = (e) => { dispatch(toggleBookmark(status)); }; @@ -647,7 +638,6 @@ const StatusActionBar: React.FC = ({ } const canShare = ('share' in navigator) && (status.visibility === 'public' || status.visibility === 'group'); - const acceptsZaps = status.account.ditto.accepts_zaps === true; const spacing: { [key: string]: React.ComponentProps['space']; @@ -735,19 +725,6 @@ const StatusActionBar: React.FC = ({ /> )} - {(acceptsZaps && window.webln) && ( - - )} - {canShare && ( = ({ status, hoverable className='inline-block max-w-[200px] truncate align-bottom text-primary-600 no-underline [direction:ltr] hover:text-primary-700 hover:underline dark:text-accent-blue dark:hover:text-accent-blue' onClick={(e) => e.stopPropagation()} > - @{isPubkey(account.username) ? account.username.slice(0, 8) : account.username} + @{account.username} ); diff --git a/src/contexts/nostr-context.tsx b/src/contexts/nostr-context.tsx deleted file mode 100644 index f06cd01bbd..0000000000 --- a/src/contexts/nostr-context.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { NRelay, NRelay1, NostrSigner } from '@soapbox/nspec'; -import React, { createContext, useContext, useState, useEffect, useMemo } from 'react'; - -import { NKeys } from 'soapbox/features/nostr/keys'; -import { useOwnAccount } from 'soapbox/hooks'; -import { useInstance } from 'soapbox/hooks/useInstance'; - -interface NostrContextType { - relay?: NRelay; - pubkey?: string; - signer?: NostrSigner; -} - -const NostrContext = createContext(undefined); - -interface NostrProviderProps { - children: React.ReactNode; -} - -export const NostrProvider: React.FC = ({ children }) => { - const instance = useInstance(); - const [relay, setRelay] = useState(); - - const { account } = useOwnAccount(); - - const url = instance.nostr?.relay; - const pubkey = instance.nostr?.pubkey; - const accountPubkey = account?.nostr.pubkey; - - const signer = useMemo( - () => (accountPubkey ? NKeys.get(accountPubkey) : undefined) ?? window.nostr, - [accountPubkey], - ); - - useEffect(() => { - if (url) { - setRelay(new NRelay1(url)); - } - return () => { - relay?.close(); - }; - }, [url]); - - return ( - - {children} - - ); -}; - -export const useNostr = () => { - const context = useContext(NostrContext); - if (context === undefined) { - throw new Error('useNostr must be used within a NostrProvider'); - } - return context; -}; diff --git a/src/features/auth-login/components/login-page.tsx b/src/features/auth-login/components/login-page.tsx index 9ceec4a556..8817b6d39d 100644 --- a/src/features/auth-login/components/login-page.tsx +++ b/src/features/auth-login/components/login-page.tsx @@ -4,9 +4,9 @@ import { Redirect } from 'react-router-dom'; import { logIn, verifyCredentials, switchAccount } from 'soapbox/actions/auth'; import { fetchInstance } from 'soapbox/actions/instance'; -import { closeModal, openModal } from 'soapbox/actions/modals'; +import { closeModal } from 'soapbox/actions/modals'; import { BigCard } from 'soapbox/components/big-card'; -import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks'; +import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; import { getRedirectUrl } from 'soapbox/utils/redirect'; import { isStandalone } from 'soapbox/utils/state'; @@ -21,7 +21,6 @@ const LoginPage = () => { const me = useAppSelector((state) => state.me); const standalone = useAppSelector((state) => isStandalone(state)); - const { nostrSignup } = useFeatures(); const token = new URLSearchParams(window.location.search).get('token'); @@ -63,11 +62,6 @@ const LoginPage = () => { event.preventDefault(); }; - if (nostrSignup) { - setTimeout(() => dispatch(openModal('NOSTR_LOGIN')), 100); - return ; - } - if (standalone) return ; if (shouldRedirect) { diff --git a/src/features/auth-login/components/registration-form.tsx b/src/features/auth-login/components/registration-form.tsx index 781e2cdbff..d4c96cd506 100644 --- a/src/features/auth-login/components/registration-form.tsx +++ b/src/features/auth-login/components/registration-form.tsx @@ -270,53 +270,46 @@ const RegistrationForm: React.FC = ({ inviteToken }) => { )} + - {!features.nostrSignup && ( + + + - )} - - {!features.nostrSignup && ( - <> - - - - - - - )} + {birthdayRequired && ( { const instance = useInstance(); const { isOpen } = useRegistrationStatus(); - const { nostrSignup } = useFeatures(); - const dispatch = useAppDispatch(); - - if (nostrSignup) { - setTimeout(() => dispatch(openModal('NOSTR_SIGNUP')), 100); - return ; - } if (!isOpen) { return ( - }> + }> = ({ composeId }) => { const username = acct.split('@')[0]; return ( - @{isPubkey(username) ? username.slice(0, 8) : username} + @{username} ); }).toArray(); diff --git a/src/features/edit-identity/index.tsx b/src/features/edit-identity/index.tsx deleted file mode 100644 index 2d65bd2058..0000000000 --- a/src/features/edit-identity/index.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import React, { useState } from 'react'; -import { defineMessages, useIntl } from 'react-intl'; - -import { patchMe } from 'soapbox/actions/me'; -import List, { ListItem } from 'soapbox/components/list'; -import { Button, Column, Emoji, HStack, Icon, Input, Tooltip } from 'soapbox/components/ui'; -import { useNostr } from 'soapbox/contexts/nostr-context'; -import { useNostrReq } from 'soapbox/features/nostr/hooks/useNostrReq'; -import { useAppDispatch, useInstance, useOwnAccount } from 'soapbox/hooks'; -import toast from 'soapbox/toast'; - -interface IEditIdentity { -} - -const messages = defineMessages({ - title: { id: 'settings.edit_identity', defaultMessage: 'Identity' }, - username: { id: 'edit_profile.fields.nip05_label', defaultMessage: 'Username' }, - unverified: { id: 'edit_profile.fields.nip05_unverified', defaultMessage: 'Name could not be verified and won\'t be used.' }, - success: { id: 'edit_profile.success', defaultMessage: 'Your profile has been successfully saved!' }, - error: { id: 'edit_profile.error', defaultMessage: 'Profile update failed' }, -}); - -/** EditIdentity component. */ -const EditIdentity: React.FC = () => { - const intl = useIntl(); - const instance = useInstance(); - const dispatch = useAppDispatch(); - const { account } = useOwnAccount(); - const { relay, signer } = useNostr(); - - const admin = instance.nostr?.pubkey; - const pubkey = account?.nostr?.pubkey; - const [username, setUsername] = useState(''); - - const { events: labels } = useNostrReq( - (admin && pubkey) - ? [{ kinds: [1985], authors: [admin], '#L': ['nip05'], '#p': [pubkey] }] - : [], - ); - - if (!account) return null; - - const updateNip05 = async (nip05: string): Promise => { - if (account.source?.nostr?.nip05 === nip05) return; - try { - await dispatch(patchMe({ nip05 })); - toast.success(intl.formatMessage(messages.success)); - } catch (e) { - toast.error(intl.formatMessage(messages.error)); - } - }; - - const submit = async () => { - if (!admin || !signer || !relay) return; - - const event = await signer.signEvent({ - kind: 5950, - content: '', - tags: [ - ['i', `${username}@${instance.domain}`, 'text'], - ['p', admin], - ], - created_at: Math.floor(Date.now() / 1000), - }); - - await relay.event(event); - }; - - return ( - - - {labels.map((label) => { - const identifier = label.tags.find(([name]) => name === 'l')?.[1]; - if (!identifier) return null; - - return ( - - {identifier} - {(account.source?.nostr?.nip05 === identifier && account.acct !== identifier) && ( - -
- -
-
- )} - - } - isSelected={account.source?.nostr?.nip05 === identifier} - onSelect={() => updateNip05(identifier)} - /> - ); - })} - setUsername(e.target.value)} />}> - - -
-
- ); -}; - -const UsernameInput: React.FC> = (props) => { - const intl = useIntl(); - const instance = useInstance(); - - return ( - - - {instance.domain} - - )} - {...props} - /> - ); -}; - -export default EditIdentity; \ No newline at end of file diff --git a/src/features/edit-profile/index.tsx b/src/features/edit-profile/index.tsx index 2f56a20a7c..26e903c152 100644 --- a/src/features/edit-profile/index.tsx +++ b/src/features/edit-profile/index.tsx @@ -54,7 +54,6 @@ const messages = defineMessages({ bioPlaceholder: { id: 'edit_profile.fields.bio_placeholder', defaultMessage: 'Tell us about yourself.' }, displayNamePlaceholder: { id: 'edit_profile.fields.display_name_placeholder', defaultMessage: 'Name' }, locationPlaceholder: { id: 'edit_profile.fields.location_placeholder', defaultMessage: 'Location' }, - nip05Placeholder: { id: 'edit_profile.fields.nip05_placeholder', defaultMessage: 'user@{domain}' }, cancel: { id: 'common.cancel', defaultMessage: 'Cancel' }, }); @@ -75,11 +74,6 @@ interface AccountCredentialsSource { sensitive?: boolean; /** Default language to use for authored statuses. (ISO 6391) */ language?: string; - /** Nostr metadata. */ - nostr?: { - /** Nostr NIP-05 identifier. */ - nip05?: string; - }; } /** @@ -123,8 +117,6 @@ interface AccountCredentials { location?: string; /** User's birthday. */ birthday?: string; - /** Nostr NIP-05 identifier. */ - nip05?: string; } /** Convert an account into an update_credentials request object. */ @@ -146,7 +138,6 @@ const accountToCredentials = (account: Account): AccountCredentials => { hide_follows_count: hideNetwork, location: account.location, birthday: account.pleroma?.birthday ?? undefined, - nip05: account.source?.nostr?.nip05 ?? '', }; }; @@ -313,19 +304,6 @@ const EditProfile: React.FC = () => { /> - {features.nip05 && ( - } - > - - - )} - {features.birthdays && ( } diff --git a/src/features/nostr-relays/components/relay-editor.tsx b/src/features/nostr-relays/components/relay-editor.tsx deleted file mode 100644 index 0806e9300f..0000000000 --- a/src/features/nostr-relays/components/relay-editor.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { HStack, Input, Select } from 'soapbox/components/ui'; -import Streamfield, { StreamfieldComponent } from 'soapbox/components/ui/streamfield/streamfield'; -import { useInstance } from 'soapbox/hooks'; - -interface IRelayEditor { - relays: RelayData[]; - setRelays: (relays: RelayData[]) => void; -} - -const RelayEditor: React.FC = ({ relays, setRelays }) => { - const handleAddRelay = (): void => { - setRelays([...relays, { url: '' }]); - }; - - const handleRemoveRelay = (i: number): void => { - const newRelays = [...relays]; - newRelays.splice(i, 1); - setRelays(newRelays); - }; - - return ( - - ); -}; - -interface RelayData { - url: string; - marker?: 'read' | 'write'; -} - -const RelayField: StreamfieldComponent = ({ value, onChange }) => { - const instance = useInstance(); - - const handleChange = (key: string): React.ChangeEventHandler => { - return e => { - onChange({ ...value, [key]: e.currentTarget.value }); - }; - }; - - const handleMarkerChange = (e: React.ChangeEvent): void => { - onChange({ ...value, marker: (e.currentTarget.value as 'read' | 'write' | '') || undefined }); - }; - - return ( - - - - - - ); -}; - -export default RelayEditor; - -export type { RelayData }; \ No newline at end of file diff --git a/src/features/nostr-relays/index.tsx b/src/features/nostr-relays/index.tsx deleted file mode 100644 index e3842f2dcb..0000000000 --- a/src/features/nostr-relays/index.tsx +++ /dev/null @@ -1,74 +0,0 @@ -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'; - -const messages = defineMessages({ - title: { id: 'nostr_relays.title', defaultMessage: 'Relays' }, -}); - -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); - - useEffect(() => { - const tags = events[0]?.tags ?? []; - const data = tags.map(tag => ({ url: tag[1], marker: tag[2] as 'read' | 'write' | undefined })); - setRelays(data); - }, [events[0]]); - - const handleSubmit = async (): Promise => { - if (!signer || !relay) return; - - setIsLoading(true); - - 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); - }; - - return ( - -
- - - - - - - - - -
-
- ); -}; - -export default NostrRelays; diff --git a/src/features/nostr/Bech32Redirect.tsx b/src/features/nostr/Bech32Redirect.tsx deleted file mode 100644 index 4c9fdb16ba..0000000000 --- a/src/features/nostr/Bech32Redirect.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { nip19 } from 'nostr-tools'; -import React from 'react'; -import { Redirect } from 'react-router-dom'; - -import MissingIndicator from 'soapbox/components/missing-indicator'; - -interface INIP19Redirect { - params: { - bech32: string; - }; -} - -const Bech32Redirect: React.FC = ({ params }) => { - try { - const result = nip19.decode(params.bech32); - - switch (result.type) { - case 'npub': - case 'nprofile': - return ; - case 'note': - return ; - case 'nevent': - return ; - default: - return ; - } - - } catch (e) { - return ; - } -}; - -export default Bech32Redirect; \ No newline at end of file diff --git a/src/features/nostr/NKeyStorage.ts b/src/features/nostr/NKeyStorage.ts deleted file mode 100644 index e297edb96d..0000000000 --- a/src/features/nostr/NKeyStorage.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { NSchema as n, NostrSigner, NSecSigner } from '@soapbox/nspec'; -import { WebLock } from '@soapbox/weblock'; -import { getPublicKey, nip19 } from 'nostr-tools'; -import { z } from 'zod'; - -/** - * Gets Nostr keypairs from storage and returns a `Map`-like object of signers. - * When instantiated, it will lock the storage key to prevent tampering. - * Changes to the object will sync to storage. - */ -export class NKeyStorage implements ReadonlyMap { - - #keypairs = new Map(); - #storage: Storage; - #storageKey: string; - - constructor(storage: Storage, storageKey: string) { - this.#storage = storage; - this.#storageKey = storageKey; - - const data = this.#storage.getItem(storageKey); - WebLock.storages.lockKey(storageKey); - - try { - const nsecs = new Set(this.#dataSchema().parse(data)); - - for (const nsec of nsecs) { - const { data: secretKey } = nip19.decode(nsec); - const pubkey = getPublicKey(secretKey); - this.#keypairs.set(pubkey, secretKey); - } - } catch (e) { - this.clear(); - } - } - - #dataSchema(): z.ZodType<`nsec1${string}`[]> { - return n.json().pipe(n.bech32('nsec').array()); - } - - #syncStorage() { - const secretKeys = [...this.#keypairs.values()].map(nip19.nsecEncode); - this.#storage.setItem(this.#storageKey, JSON.stringify(secretKeys)); - } - - get size(): number { - return this.#keypairs.size; - } - - clear(): void { - this.#keypairs.clear(); - this.#syncStorage(); - } - - delete(pubkey: string): boolean { - const result = this.#keypairs.delete(pubkey); - this.#syncStorage(); - return result; - } - - forEach(callbackfn: (signer: NostrSigner, pubkey: string, map: typeof this) => void, thisArg?: any): void { - for (const [pubkey] of this.#keypairs) { - const signer = this.get(pubkey); - if (signer) { - callbackfn.call(thisArg, signer, pubkey, this); - } - } - } - - get(pubkey: string): NostrSigner | undefined { - const secretKey = this.#keypairs.get(pubkey); - if (secretKey) { - return new NSecSigner(secretKey); - } - } - - has(pubkey: string): boolean { - return this.#keypairs.has(pubkey); - } - - add(secretKey: Uint8Array): NostrSigner { - const pubkey = getPublicKey(secretKey); - this.#keypairs.set(pubkey, secretKey); - this.#syncStorage(); - return this.get(pubkey)!; - } - - *entries(): IterableIterator<[string, NostrSigner]> { - for (const [pubkey] of this.#keypairs) { - yield [pubkey, this.get(pubkey)!]; - } - } - - *keys(): IterableIterator { - for (const pubkey of this.#keypairs.keys()) { - yield pubkey; - } - } - - *values(): IterableIterator { - for (const pubkey of this.#keypairs.keys()) { - yield this.get(pubkey)!; - } - } - - [Symbol.iterator](): IterableIterator<[string, NostrSigner]> { - return this.entries(); - } - - [Symbol.toStringTag] = 'NKeyStorage'; - -} \ No newline at end of file diff --git a/src/features/nostr/hooks/useNostrReq.ts b/src/features/nostr/hooks/useNostrReq.ts deleted file mode 100644 index 72e1187ac4..0000000000 --- a/src/features/nostr/hooks/useNostrReq.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { NSet, NostrEvent, NostrFilter } from '@soapbox/nspec'; -import isEqual from 'lodash/isEqual'; -import { useEffect, useRef, useState } from 'react'; - -import { useNostr } from 'soapbox/contexts/nostr-context'; -import { useForceUpdate } from 'soapbox/hooks/useForceUpdate'; - -/** Streams events from the relay for the given filters. */ -export function useNostrReq(filters: NostrFilter[]): { events: NostrEvent[]; eose: boolean; closed: boolean } { - const { relay } = useNostr(); - - const nset = useRef(new NSet()); - const forceUpdate = useForceUpdate(); - - const [closed, setClosed] = useState(false); - const [eose, setEose] = useState(false); - - const controller = useRef(new AbortController()); - const signal = controller.current.signal; - const value = useValue(filters); - - useEffect(() => { - if (relay && value.length) { - (async () => { - for await (const msg of relay.req(value, { signal })) { - if (msg[0] === 'EVENT') { - nset.current.add(msg[2]); - forceUpdate(); - } else if (msg[0] === 'EOSE') { - setEose(true); - } else if (msg[0] === 'CLOSED') { - setClosed(true); - break; - } - } - })(); - } - - return () => { - controller.current.abort(); - controller.current = new AbortController(); - setEose(false); - setClosed(false); - }; - }, [relay, value]); - - return { - events: [...nset.current], - eose, - closed, - }; -} - -/** Preserves the memory reference of a value across re-renders. */ -function useValue(value: T): T { - const ref = useRef(value); - - if (!isEqual(ref.current, value)) { - ref.current = value; - } - - return ref.current; -} \ No newline at end of file diff --git a/src/features/nostr/keys.ts b/src/features/nostr/keys.ts deleted file mode 100644 index 92f9fc09f7..0000000000 --- a/src/features/nostr/keys.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { NKeyStorage } from './NKeyStorage'; - -export const NKeys = new NKeyStorage( - localStorage, - 'soapbox:nostr:keys', -); diff --git a/src/features/settings/index.tsx b/src/features/settings/index.tsx index f2e53b8672..434445c4e2 100644 --- a/src/features/settings/index.tsx +++ b/src/features/settings/index.tsx @@ -20,8 +20,6 @@ const messages = defineMessages({ configureMfa: { id: 'settings.configure_mfa', defaultMessage: 'Configure MFA' }, 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' }, @@ -67,12 +65,6 @@ const Settings = () => { {displayName} - {features.nip05 && ( - - {account?.source?.nostr?.nip05} - - )} - {features.nostr && } diff --git a/src/features/ui/components/modal-root.tsx b/src/features/ui/components/modal-root.tsx index 5fdc0225a6..1c80d795eb 100644 --- a/src/features/ui/components/modal-root.tsx +++ b/src/features/ui/components/modal-root.tsx @@ -32,8 +32,6 @@ import { MentionsModal, MissingDescriptionModal, MuteModal, - NostrLoginModal, - NostrSignupModal, ReactionsModal, ReblogsModal, ReplyMentionsModal, @@ -79,8 +77,6 @@ const MODAL_COMPONENTS: Record> = { 'MENTIONS': MentionsModal, 'MISSING_DESCRIPTION': MissingDescriptionModal, 'MUTE': MuteModal, - 'NOSTR_LOGIN': NostrLoginModal, - 'NOSTR_SIGNUP': NostrSignupModal, 'REACTIONS': ReactionsModal, 'REBLOGS': ReblogsModal, 'REPLY_MENTIONS': ReplyMentionsModal, diff --git a/src/features/ui/components/modals/nostr-login-modal/components/nostr-extension-indicator.tsx b/src/features/ui/components/modals/nostr-login-modal/components/nostr-extension-indicator.tsx deleted file mode 100644 index 2c0258663e..0000000000 --- a/src/features/ui/components/modals/nostr-login-modal/components/nostr-extension-indicator.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { closeModal } from 'soapbox/actions/modals'; -import { nostrExtensionLogIn } from 'soapbox/actions/nostr'; -import Stack from 'soapbox/components/ui/stack/stack'; -import Text from 'soapbox/components/ui/text/text'; -import { useAppDispatch } from 'soapbox/hooks'; - -const NostrExtensionIndicator: React.FC = () => { - const dispatch = useAppDispatch(); - - const onClick = () => { - dispatch(nostrExtensionLogIn()); - dispatch(closeModal()); - }; - - return ( - - - {window.nostr ? ( - , - }} - /> - ) : ( - - )} - - - ); -}; - -export default NostrExtensionIndicator; \ No newline at end of file diff --git a/src/features/ui/components/modals/nostr-login-modal/nostr-login-modal.tsx b/src/features/ui/components/modals/nostr-login-modal/nostr-login-modal.tsx deleted file mode 100644 index fd81a6c9a4..0000000000 --- a/src/features/ui/components/modals/nostr-login-modal/nostr-login-modal.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { useState } from 'react'; - -import ExtensionStep from './steps/extension-step'; -import KeyAddStep from './steps/key-add-step'; - -type Step = 'extension' | 'key-add'; - -interface INostrLoginModal { - onClose: (type?: string) => void; - step?: Step; -} - -const NostrLoginModal: React.FC = ({ onClose, step: firstStep }) => { - const [step, setStep] = useState(firstStep ?? (window.nostr ? 'extension' : 'key-add')); - - const handleClose = () => onClose('NOSTR_LOGIN'); - - switch (step) { - case 'extension': - return setStep('key-add')} onClose={handleClose} />; - case 'key-add': - return ; - default: - return null; - } -}; - -export default NostrLoginModal; - -export type { Step }; diff --git a/src/features/ui/components/modals/nostr-login-modal/steps/extension-step.tsx b/src/features/ui/components/modals/nostr-login-modal/steps/extension-step.tsx deleted file mode 100644 index 2b1af1f1e7..0000000000 --- a/src/features/ui/components/modals/nostr-login-modal/steps/extension-step.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { nostrExtensionLogIn } from 'soapbox/actions/nostr'; -import EmojiGraphic from 'soapbox/components/emoji-graphic'; -import { Button, Stack, Modal } from 'soapbox/components/ui'; -import { useAppDispatch } from 'soapbox/hooks'; - -interface IExtensionStep { - onClickAlt: () => void; - onClose(): void; -} - -const ExtensionStep: React.FC = ({ onClickAlt, onClose }) => { - const dispatch = useAppDispatch(); - - const onClick = () => { - dispatch(nostrExtensionLogIn()); - onClose(); - }; - - return ( - } onClose={onClose}> - - - - - - - - - - - ); -}; - -export default ExtensionStep; diff --git a/src/features/ui/components/modals/nostr-login-modal/steps/key-add-step.tsx b/src/features/ui/components/modals/nostr-login-modal/steps/key-add-step.tsx deleted file mode 100644 index 371efffe69..0000000000 --- a/src/features/ui/components/modals/nostr-login-modal/steps/key-add-step.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { nip19 } from 'nostr-tools'; -import React, { useState } from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { logInNostr } from 'soapbox/actions/nostr'; -import EmojiGraphic from 'soapbox/components/emoji-graphic'; -import { Button, Stack, Modal, Input, FormGroup, Form } from 'soapbox/components/ui'; -import { NKeys } from 'soapbox/features/nostr/keys'; -import { useAppDispatch } from 'soapbox/hooks'; - -import NostrExtensionIndicator from '../components/nostr-extension-indicator'; - -interface IKeyAddStep { - onClose(): void; -} - -const KeyAddStep: React.FC = ({ onClose }) => { - const [nsec, setNsec] = useState(''); - const [error, setError] = useState(); - - const dispatch = useAppDispatch(); - - const handleChange = (e: React.ChangeEvent) => { - setNsec(e.target.value); - setError(undefined); - }; - - const handleSubmit = async () => { - try { - const result = nip19.decode(nsec); - if (result.type === 'nsec') { - const seckey = result.data; - const signer = NKeys.add(seckey); - const pubkey = await signer.getPublicKey(); - dispatch(logInNostr(pubkey)); - onClose(); - } - } catch (e) { - setError('Invalid nsec'); - } - }; - - return ( - } onClose={onClose}> - - - - - -
- - - - - - - -
-
-
- ); -}; - -export default KeyAddStep; diff --git a/src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx b/src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx deleted file mode 100644 index a5d47acce1..0000000000 --- a/src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React, { useState } from 'react'; - -import ExtensionStep from '../nostr-login-modal/steps/extension-step'; - -import KeyStep from './steps/key-step'; -import KeygenStep from './steps/keygen-step'; - -type Step = 'extension' | 'key' | 'keygen'; - -interface INostrSignupModal { - onClose: (type?: string) => void; -} - -const NostrSigninModal: React.FC = ({ onClose }) => { - const [step, setStep] = useState(window.nostr ? 'extension' : 'key'); - - const handleClose = () => onClose('NOSTR_SIGNUP'); - - switch (step) { - case 'extension': - return setStep('key')} onClose={handleClose} />; - case 'key': - return ; - case 'keygen': - return ; - default: - return null; - } -}; - -export default NostrSigninModal; - -export type { Step }; diff --git a/src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx b/src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx deleted file mode 100644 index e66d71b69f..0000000000 --- a/src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { openModal } from 'soapbox/actions/modals'; -import EmojiGraphic from 'soapbox/components/emoji-graphic'; -import { Button, Stack, Modal } from 'soapbox/components/ui'; -import { useAppDispatch } from 'soapbox/hooks'; - -import NostrExtensionIndicator from '../../nostr-login-modal/components/nostr-extension-indicator'; -import { Step } from '../nostr-signup-modal'; - -interface IKeyStep { - setStep(step: Step): void; - onClose(): void; -} - -const KeyStep: React.FC = ({ setStep, onClose }) => { - const dispatch = useAppDispatch(); - - const onAltClick = () => { - onClose(); - dispatch(openModal('NOSTR_LOGIN', { step: 'key-add' })); - }; - - return ( - } onClose={onClose}> - - - - - - - - - - - - - ); -}; - -export default KeyStep; diff --git a/src/features/ui/components/modals/nostr-signup-modal/steps/keygen-step.tsx b/src/features/ui/components/modals/nostr-signup-modal/steps/keygen-step.tsx deleted file mode 100644 index 83d604fa70..0000000000 --- a/src/features/ui/components/modals/nostr-signup-modal/steps/keygen-step.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { generateSecretKey, getPublicKey, nip19 } from 'nostr-tools'; -import React, { useEffect, useMemo, useState } from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { fetchAccount } from 'soapbox/actions/accounts'; -import { logInNostr } from 'soapbox/actions/nostr'; -import CopyableInput from 'soapbox/components/copyable-input'; -import EmojiGraphic from 'soapbox/components/emoji-graphic'; -import { Button, Stack, Modal, FormGroup, Text, Tooltip } from 'soapbox/components/ui'; -import { NKeys } from 'soapbox/features/nostr/keys'; -import { useAppDispatch, useInstance } from 'soapbox/hooks'; -import { download } from 'soapbox/utils/download'; -import { slugify } from 'soapbox/utils/input'; - -interface IKeygenStep { - onClose(): void; -} - -const KeygenStep: React.FC = ({ onClose }) => { - const instance = useInstance(); - const dispatch = useAppDispatch(); - - const secretKey = useMemo(() => generateSecretKey(), []); - const pubkey = useMemo(() => getPublicKey(secretKey), [secretKey]); - - const nsec = useMemo(() => nip19.nsecEncode(secretKey), [secretKey]); - const npub = useMemo(() => nip19.npubEncode(pubkey), [pubkey]); - - const [downloaded, setDownloaded] = useState(false); - - useEffect(() => { - // Pre-fetch into cache. - dispatch(fetchAccount(pubkey)).catch(() => {}); - }, [pubkey]); - - const handleDownload = () => { - download(nsec, `${slugify(instance.title)}-${npub.slice(5, 9)}.nsec.txt`); - setDownloaded(true); - }; - - const handleCopy = () => setDownloaded(true); - - const handleNext = async () => { - const signer = NKeys.add(secretKey); - const pubkey = await signer.getPublicKey(); - dispatch(logInNostr(pubkey)); - onClose(); - }; - - return ( - } onClose={onClose}> - - - - - - - - - - - - - Back up your secret key in a secure place. If lost, your account cannot be recovered. Never share your secret key with anyone. - - - - - - - - - - ); -}; - -export default KeygenStep; diff --git a/src/features/ui/components/navbar.tsx b/src/features/ui/components/navbar.tsx index 384690f103..0f9fcb0c74 100644 --- a/src/features/ui/components/navbar.tsx +++ b/src/features/ui/components/navbar.tsx @@ -5,7 +5,6 @@ import { Link, Redirect } from 'react-router-dom'; import { logIn, verifyCredentials } from 'soapbox/actions/auth'; import { fetchInstance } from 'soapbox/actions/instance'; -import { openModal } from 'soapbox/actions/modals'; import { openSidebar } from 'soapbox/actions/sidebar'; import SiteLogo from 'soapbox/components/site-logo'; import { Avatar, Button, Form, HStack, IconButton, Input, Tooltip } from 'soapbox/components/ui'; @@ -39,10 +38,6 @@ const Navbar = () => { const onOpenSidebar = () => dispatch(openSidebar()); - const handleNostrLogin = async () => { - dispatch(openModal('NOSTR_LOGIN')); - }; - const handleSubmit: React.FormEventHandler = (event) => { event.preventDefault(); setLoading(true); @@ -112,61 +107,49 @@ const Navbar = () => { ) : ( <> - {features.nostrSignup ? ( -
- -
- ) : ( -
- setUsername(event.target.value)} - type='text' - placeholder={intl.formatMessage(features.logInWithUsername ? messages.username : messages.email)} - className='max-w-[200px]' - /> + + setUsername(event.target.value)} + type='text' + placeholder={intl.formatMessage(features.logInWithUsername ? messages.username : messages.email)} + className='max-w-[200px]' + /> - setPassword(event.target.value)} - type='password' - placeholder={intl.formatMessage(messages.password)} - className='max-w-[200px]' - /> + setPassword(event.target.value)} + type='password' + placeholder={intl.formatMessage(messages.password)} + className='max-w-[200px]' + /> - - - - - + + + + + - -
- )} + +
diff --git a/src/features/ui/components/panels/sign-up-panel.tsx b/src/features/ui/components/panels/sign-up-panel.tsx index eaf30b41cd..04694854ec 100644 --- a/src/features/ui/components/panels/sign-up-panel.tsx +++ b/src/features/ui/components/panels/sign-up-panel.tsx @@ -1,16 +1,13 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; -import { openModal } from 'soapbox/actions/modals'; import { Button, Stack, Text } from 'soapbox/components/ui'; -import { useAppDispatch, useAppSelector, useFeatures, useInstance, useRegistrationStatus } from 'soapbox/hooks'; +import { useAppSelector, useInstance, useRegistrationStatus } from 'soapbox/hooks'; const SignUpPanel = () => { const instance = useInstance(); - const { nostrSignup } = useFeatures(); const { isOpen } = useRegistrationStatus(); const me = useAppSelector((state) => state.me); - const dispatch = useAppDispatch(); if (me || !isOpen) return null; @@ -28,8 +25,7 @@ const SignUpPanel = () => {