diff --git a/lib/hooks/login-hooks.js b/lib/hooks/login-hooks.js index 534cfdaaf..753340739 100644 --- a/lib/hooks/login-hooks.js +++ b/lib/hooks/login-hooks.js @@ -1,107 +1,168 @@ // @flow import * as React from 'react'; import { identityLogInActionTypes, useIdentityPasswordLogIn, + useIdentityWalletLogIn, } from '../actions/user-actions.js'; import { useKeyserverAuth } from '../keyserver-conn/keyserver-auth.js'; import { logInActionSources } from '../types/account-types.js'; import { authoritativeKeyserverID } from '../utils/authoritative-keyserver.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useSelector } from '../utils/redux-utils.js'; // We can't just do everything in one async callback, since the server calls // would get bound to Redux state from before the login. In order to pick up the // updated CSAT and currentUserInfo from Redux, we break the login into two // steps. type CurrentStep = | { +step: 'inactive' } | { +step: 'identity_login_dispatched', +resolve: () => void, +reject: Error => void, }; const inactiveStep = { step: 'inactive' }; -function usePasswordLogIn(): ( - username: string, - password: string, -) => Promise { +type LogInInputs = + | { + +accountType: 'username', + +username: string, + +password: string, + } + | { + +accountType: 'ethereum', + +walletAddress: string, + +siweMessage: string, + +siweSignature: string, + }; + +function useLogIn(): LogInInputs => Promise { const [currentStep, setCurrentStep] = React.useState(inactiveStep); const identityPasswordLogIn = useIdentityPasswordLogIn(); + const identityWalletLogIn = useIdentityWalletLogIn(); const dispatchActionPromise = useDispatchActionPromise(); const returnedFunc = React.useCallback( - (username: string, password: string) => + (logInInputs: LogInInputs) => new Promise( // eslint-disable-next-line no-async-promise-executor async (resolve, reject) => { if (currentStep.step !== 'inactive') { return; } - const action = identityPasswordLogIn(username, password); + const action = + logInInputs.accountType === 'username' + ? identityPasswordLogIn( + logInInputs.username, + logInInputs.password, + ) + : identityWalletLogIn( + logInInputs.walletAddress, + logInInputs.siweMessage, + logInInputs.siweSignature, + ); void dispatchActionPromise(identityLogInActionTypes, action); try { await action; setCurrentStep({ step: 'identity_login_dispatched', resolve, reject, }); } catch (e) { reject(e); } }, ), - [currentStep, dispatchActionPromise, identityPasswordLogIn], + [ + currentStep, + dispatchActionPromise, + identityPasswordLogIn, + identityWalletLogIn, + ], ); const keyserverAuth = useKeyserverAuth(authoritativeKeyserverID()); const isRegisteredOnIdentity = useSelector( state => !!state.commServicesAccessToken && !!state.currentUserInfo && !state.currentUserInfo.anonymous, ); const registeringOnAuthoritativeKeyserverRef = React.useRef(false); React.useEffect(() => { if ( !isRegisteredOnIdentity || currentStep.step !== 'identity_login_dispatched' || registeringOnAuthoritativeKeyserverRef.current ) { return; } registeringOnAuthoritativeKeyserverRef.current = true; const { resolve, reject } = currentStep; void (async () => { try { await keyserverAuth({ authActionSource: process.env.BROWSER ? logInActionSources.keyserverAuthFromWeb : logInActionSources.keyserverAuthFromNative, setInProgress: () => {}, hasBeenCancelled: () => false, doNotRegister: false, }); resolve(); } catch (e) { reject(e); } finally { setCurrentStep(inactiveStep); registeringOnAuthoritativeKeyserverRef.current = false; } })(); }, [currentStep, isRegisteredOnIdentity, keyserverAuth]); return returnedFunc; } -export { usePasswordLogIn }; +function usePasswordLogIn(): ( + username: string, + password: string, +) => Promise { + const logIn = useLogIn(); + return React.useCallback( + (username: string, password: string) => + logIn({ + accountType: 'username', + username, + password, + }), + [logIn], + ); +} + +function useWalletLogIn(): ( + walletAddress: string, + siweMessage: string, + siweSignature: string, +) => Promise { + const logIn = useLogIn(); + return React.useCallback( + (walletAddress: string, siweMessage: string, siweSignature: string) => + logIn({ + accountType: 'ethereum', + walletAddress, + siweMessage, + siweSignature, + }), + [logIn], + ); +} + +export { usePasswordLogIn, useWalletLogIn }; diff --git a/native/account/fullscreen-siwe-panel.react.js b/native/account/fullscreen-siwe-panel.react.js index ffa8f3b6e..2d2996642 100644 --- a/native/account/fullscreen-siwe-panel.react.js +++ b/native/account/fullscreen-siwe-panel.react.js @@ -1,173 +1,171 @@ // @flow import { useNavigation } from '@react-navigation/native'; import invariant from 'invariant'; import * as React from 'react'; import { ActivityIndicator, View } from 'react-native'; import { setDataLoadedActionType } from 'lib/actions/client-db-store-actions.js'; +import { useWalletLogIn } from 'lib/hooks/login-hooks.js'; import { type SIWEResult, SIWEMessageTypes } from 'lib/types/siwe-types.js'; import { ServerError } from 'lib/utils/errors.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js'; import { useGetEthereumAccountFromSIWEResult } from './registration/ethereum-utils.js'; import { RegistrationContext } from './registration/registration-context.js'; import { enableNewRegistrationMode } from './registration/registration-types.js'; -import { - useLegacySIWEServerCall, - useIdentityWalletLogInCall, -} from './siwe-hooks.js'; +import { useLegacySIWEServerCall } from './siwe-hooks.js'; import SIWEPanel from './siwe-panel.react.js'; import { commRustModule } from '../native-modules.js'; import { AccountDoesNotExistRouteName, RegistrationRouteName, } from '../navigation/route-names.js'; import { UnknownErrorAlertDetails } from '../utils/alert-messages.js'; import Alert from '../utils/alert.js'; import { defaultURLPrefix } from '../utils/url-utils.js'; type Props = { +goBackToPrompt: () => mixed, +closing: boolean, }; function FullscreenSIWEPanel(props: Props): React.Node { const [loading, setLoading] = React.useState(true); const activity = loading ? : null; const activityContainer = React.useMemo( () => ({ flex: 1, }), [], ); const registrationContext = React.useContext(RegistrationContext); invariant(registrationContext, 'registrationContext should be set'); const { setSkipEthereumLoginOnce, register: registrationServerCall } = registrationContext; const getEthereumAccountFromSIWEResult = useGetEthereumAccountFromSIWEResult(); const { navigate } = useNavigation(); const { goBackToPrompt } = props; const onAccountDoesNotExist = React.useCallback( async (result: SIWEResult) => { await getEthereumAccountFromSIWEResult(result); setSkipEthereumLoginOnce(true); goBackToPrompt(); navigate<'Registration'>(RegistrationRouteName, { screen: AccountDoesNotExistRouteName, }); }, [ getEthereumAccountFromSIWEResult, navigate, goBackToPrompt, setSkipEthereumLoginOnce, ], ); const legacySiweServerCall = useLegacySIWEServerCall(); - const identityWalletLogInCall = useIdentityWalletLogInCall(); + const walletLogIn = useWalletLogIn(); const successRef = React.useRef(false); const dispatch = useDispatch(); const onSuccess = React.useCallback( async (result: SIWEResult) => { successRef.current = true; if (usingCommServicesAccessToken) { try { const findUserIDResponse = await commRustModule.findUserIDForWalletAddress(result.address); if (JSON.parse(findUserIDResponse).userID) { - await identityWalletLogInCall(result); + await walletLogIn(result.address, result.message, result.signature); } else if (enableNewRegistrationMode) { await onAccountDoesNotExist(result); } else { await registrationServerCall({ coolOrNerdMode: 'cool', keyserverURL: defaultURLPrefix, farcasterID: null, accountSelection: { accountType: 'ethereum', ...result, avatarURI: null, }, avatarData: null, clearCachedSelections: () => {}, }); } } catch (e) { Alert.alert( UnknownErrorAlertDetails.title, UnknownErrorAlertDetails.message, [{ text: 'OK', onPress: goBackToPrompt }], { cancelable: false }, ); throw e; } } else { try { await legacySiweServerCall({ ...result, doNotRegister: enableNewRegistrationMode, }); } catch (e) { if ( e instanceof ServerError && e.message === 'account_does_not_exist' ) { await onAccountDoesNotExist(result); return; } Alert.alert( UnknownErrorAlertDetails.title, UnknownErrorAlertDetails.message, [{ text: 'OK', onPress: goBackToPrompt }], { cancelable: false }, ); throw e; } dispatch({ type: setDataLoadedActionType, payload: { dataLoaded: true, }, }); } }, [ - identityWalletLogInCall, + walletLogIn, registrationServerCall, goBackToPrompt, dispatch, legacySiweServerCall, onAccountDoesNotExist, ], ); const ifBeforeSuccessGoBackToPrompt = React.useCallback(() => { if (!successRef.current) { goBackToPrompt(); } }, [goBackToPrompt]); const { closing } = props; return ( <> {activity} ); } export default FullscreenSIWEPanel; diff --git a/native/account/registration/existing-ethereum-account.react.js b/native/account/registration/existing-ethereum-account.react.js index 707af41af..41ac993b0 100644 --- a/native/account/registration/existing-ethereum-account.react.js +++ b/native/account/registration/existing-ethereum-account.react.js @@ -1,166 +1,164 @@ // @flow import * as React from 'react'; import { Text, View } from 'react-native'; import { setDataLoadedActionType } from 'lib/actions/client-db-store-actions.js'; import { siweAuthActionTypes } from 'lib/actions/siwe-actions.js'; import { useENSName } from 'lib/hooks/ens-cache.js'; +import { useWalletLogIn } from 'lib/hooks/login-hooks.js'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; import type { SIWEResult } from 'lib/types/siwe-types.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js'; import RegistrationButtonContainer from './registration-button-container.react.js'; import RegistrationButton from './registration-button.react.js'; import RegistrationContainer from './registration-container.react.js'; import RegistrationContentContainer from './registration-content-container.react.js'; import type { RegistrationNavigationProp } from './registration-navigator.react.js'; import type { NavigationRoute } from '../../navigation/route-names.js'; import { useSelector } from '../../redux/redux-utils.js'; import { useStyles } from '../../themes/colors.js'; import { UnknownErrorAlertDetails } from '../../utils/alert-messages.js'; import Alert from '../../utils/alert.js'; -import { - useIdentityWalletLogInCall, - useLegacySIWEServerCall, -} from '../siwe-hooks.js'; +import { useLegacySIWEServerCall } from '../siwe-hooks.js'; const siweAuthLoadingStatusSelector = createLoadingStatusSelector(siweAuthActionTypes); export type ExistingEthereumAccountParams = SIWEResult; type Props = { +navigation: RegistrationNavigationProp<'ExistingEthereumAccount'>, +route: NavigationRoute<'ExistingEthereumAccount'>, }; function ExistingEthereumAccount(props: Props): React.Node { const legacySiweServerCall = useLegacySIWEServerCall(); - const identityWalletLogInCall = useIdentityWalletLogInCall(); + const walletLogIn = useWalletLogIn(); const { params } = props.route; const dispatch = useDispatch(); const onProceedToLogIn = React.useCallback(async () => { if (usingCommServicesAccessToken) { try { - await identityWalletLogInCall(params); + await walletLogIn(params.address, params.message, params.signature); } catch (e) { Alert.alert( UnknownErrorAlertDetails.title, UnknownErrorAlertDetails.message, [{ text: 'OK' }], { cancelable: false, }, ); throw e; } } else { try { await legacySiweServerCall({ ...params, doNotRegister: true }); } catch (e) { Alert.alert( UnknownErrorAlertDetails.title, UnknownErrorAlertDetails.message, [{ text: 'OK' }], { cancelable: false, }, ); throw e; } dispatch({ type: setDataLoadedActionType, payload: { dataLoaded: true, }, }); } - }, [legacySiweServerCall, identityWalletLogInCall, params, dispatch]); + }, [legacySiweServerCall, walletLogIn, params, dispatch]); const siweAuthCallLoading = useSelector( state => siweAuthLoadingStatusSelector(state) === 'loading', ); const { address } = params; const walletIdentifier = useENSName(address); const walletIdentifierTitle = walletIdentifier === address ? 'Ethereum wallet' : 'ENS name'; const { goBack } = props.navigation; const styles = useStyles(unboundStyles); return ( Account already exists for wallet You can proceed to log in with this wallet, or go back and use a different wallet. {walletIdentifierTitle} {walletIdentifier} ); } const unboundStyles = { header: { fontSize: 24, color: 'panelForegroundLabel', paddingBottom: 16, }, body: { fontFamily: 'Arial', fontSize: 15, lineHeight: 20, color: 'panelForegroundSecondaryLabel', paddingBottom: 40, }, walletTile: { backgroundColor: 'panelForeground', borderRadius: 8, padding: 24, alignItems: 'center', }, walletIdentifierTitleText: { fontSize: 17, color: 'panelForegroundLabel', textAlign: 'center', }, walletIdentifier: { backgroundColor: 'panelSecondaryForeground', paddingVertical: 8, paddingHorizontal: 24, borderRadius: 56, marginTop: 8, alignItems: 'center', }, walletIdentifierText: { fontSize: 15, color: 'panelForegroundLabel', }, }; export default ExistingEthereumAccount; diff --git a/native/account/siwe-hooks.js b/native/account/siwe-hooks.js index b7bf666f8..857e85254 100644 --- a/native/account/siwe-hooks.js +++ b/native/account/siwe-hooks.js @@ -1,142 +1,119 @@ // @flow import * as React from 'react'; import { siweAuth, siweAuthActionTypes } from 'lib/actions/siwe-actions.js'; import { - identityLogInActionTypes, - useIdentityWalletLogIn, identityRegisterActionTypes, useIdentityWalletRegister, } from 'lib/actions/user-actions.js'; import type { CallSingleKeyserverEndpointOptions } from 'lib/keyserver-conn/call-single-keyserver-endpoint.js'; import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; import { useInitialNotificationsEncryptedMessage } from 'lib/shared/crypto-utils.js'; import type { LogInStartingPayload, LogInExtraInfo, } from 'lib/types/account-types.js'; -import type { - SIWEResult, - IdentityWalletRegisterInput, -} from 'lib/types/siwe-types.js'; +import type { IdentityWalletRegisterInput } from 'lib/types/siwe-types.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import { authoritativeKeyserverID } from '../authoritative-keyserver.js'; import { useSelector } from '../redux/redux-utils.js'; import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js'; type SIWEServerCallParams = { +message: string, +signature: string, +doNotRegister?: boolean, ... }; function useLegacySIWEServerCall(): ( SIWEServerCallParams, ?CallSingleKeyserverEndpointOptions, ) => Promise { const siweAuthCall = useLegacyAshoatKeyserverCall(siweAuth); const callSIWE = React.useCallback( ( message: string, signature: string, extraInfo: $ReadOnly<{ ...LogInExtraInfo, +doNotRegister?: boolean }>, callSingleKeyserverEndpointOptions: ?CallSingleKeyserverEndpointOptions, ) => siweAuthCall( { message, signature, ...extraInfo, }, callSingleKeyserverEndpointOptions, ), [siweAuthCall], ); const logInExtraInfo = useSelector(nativeLogInExtraInfoSelector); const getInitialNotificationsEncryptedMessage = useInitialNotificationsEncryptedMessage(authoritativeKeyserverID); const dispatchActionPromise = useDispatchActionPromise(); return React.useCallback( async ( { message, signature, doNotRegister }, callSingleKeyserverEndpointOptions, ) => { const extraInfo = await logInExtraInfo(); const initialNotificationsEncryptedMessage = await getInitialNotificationsEncryptedMessage({ callSingleKeyserverEndpointOptions, }); const siwePromise = callSIWE( message, signature, { ...extraInfo, initialNotificationsEncryptedMessage, doNotRegister, }, callSingleKeyserverEndpointOptions, ); void dispatchActionPromise( siweAuthActionTypes, siwePromise, undefined, ({ calendarQuery: extraInfo.calendarQuery }: LogInStartingPayload), ); await siwePromise; }, [ logInExtraInfo, dispatchActionPromise, callSIWE, getInitialNotificationsEncryptedMessage, ], ); } -function useIdentityWalletLogInCall(): SIWEResult => Promise { - const identityWalletLogIn = useIdentityWalletLogIn(); - const dispatchActionPromise = useDispatchActionPromise(); - return React.useCallback( - async ({ address, message, signature }) => { - const siwePromise = identityWalletLogIn(address, message, signature); - void dispatchActionPromise(identityLogInActionTypes, siwePromise); - - await siwePromise; - }, - [dispatchActionPromise, identityWalletLogIn], - ); -} - function useIdentityWalletRegisterCall(): IdentityWalletRegisterInput => Promise { const identityWalletRegister = useIdentityWalletRegister(); const dispatchActionPromise = useDispatchActionPromise(); return React.useCallback( async ({ address, message, signature, fid }) => { const siwePromise = identityWalletRegister( address, message, signature, fid, ); void dispatchActionPromise(identityRegisterActionTypes, siwePromise); await siwePromise; }, [dispatchActionPromise, identityWalletRegister], ); } -export { - useLegacySIWEServerCall, - useIdentityWalletLogInCall, - useIdentityWalletRegisterCall, -}; +export { useLegacySIWEServerCall, useIdentityWalletRegisterCall }; diff --git a/web/account/siwe-login-form.react.js b/web/account/siwe-login-form.react.js index 9bae1645c..c0d03e169 100644 --- a/web/account/siwe-login-form.react.js +++ b/web/account/siwe-login-form.react.js @@ -1,314 +1,308 @@ // @flow import '@rainbow-me/rainbowkit/styles.css'; import classNames from 'classnames'; import invariant from 'invariant'; import * as React from 'react'; import { useAccount, useWalletClient } from 'wagmi'; import { setDataLoadedActionType } from 'lib/actions/client-db-store-actions.js'; import { getSIWENonce, getSIWENonceActionTypes, siweAuth, siweAuthActionTypes, } from 'lib/actions/siwe-actions.js'; import { identityGenerateNonceActionTypes, useIdentityGenerateNonce, - identityLogInActionTypes, - useIdentityWalletLogIn, } from 'lib/actions/user-actions.js'; import ConnectedWalletInfo from 'lib/components/connected-wallet-info.react.js'; import SWMansionIcon from 'lib/components/swmansion-icon.react.js'; import stores from 'lib/facts/stores.js'; +import { useWalletLogIn } from 'lib/hooks/login-hooks.js'; import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; import { logInExtraInfoSelector } from 'lib/selectors/account-selectors.js'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; import type { LogInStartingPayload, LogInExtraInfo, } from 'lib/types/account-types.js'; import { getMessageForException, ServerError } from 'lib/utils/errors.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js'; import { createSIWEMessage, getSIWEStatementForPublicKey, siweMessageSigningExplanationStatements, } from 'lib/utils/siwe-utils.js'; import HeaderSeparator from './header-separator.react.js'; import css from './siwe.css'; import Button from '../components/button.react.js'; import OrBreak from '../components/or-break.react.js'; import { olmAPI } from '../crypto/olm-api.js'; import LoadingIndicator from '../loading-indicator.react.js'; import { useSelector } from '../redux/redux-utils.js'; type SIWELogInError = 'account_does_not_exist'; type SIWELoginFormProps = { +cancelSIWEAuthFlow: () => void, }; const legacyGetSIWENonceLoadingStatusSelector = createLoadingStatusSelector( getSIWENonceActionTypes, ); const identityGenerateNonceLoadingStatusSelector = createLoadingStatusSelector( identityGenerateNonceActionTypes, ); const legacySiweAuthLoadingStatusSelector = createLoadingStatusSelector(siweAuthActionTypes); function SIWELoginForm(props: SIWELoginFormProps): React.Node { const { address } = useAccount(); const { data: signer } = useWalletClient(); const dispatchActionPromise = useDispatchActionPromise(); const legacyGetSIWENonceCall = useLegacyAshoatKeyserverCall(getSIWENonce); const legacyGetSIWENonceCallLoadingStatus = useSelector( legacyGetSIWENonceLoadingStatusSelector, ); const identityGenerateNonce = useIdentityGenerateNonce(); const identityGenerateNonceLoadingStatus = useSelector( identityGenerateNonceLoadingStatusSelector, ); const siweAuthLoadingStatus = useSelector( legacySiweAuthLoadingStatusSelector, ); const legacySiweAuthCall = useLegacyAshoatKeyserverCall(siweAuth); const logInExtraInfo = useSelector(logInExtraInfoSelector); - const identityWalletLogIn = useIdentityWalletLogIn(); + const walletLogIn = useWalletLogIn(); const [siweNonce, setSIWENonce] = React.useState(null); const siweNonceShouldBeFetched = !siweNonce && legacyGetSIWENonceCallLoadingStatus !== 'loading' && identityGenerateNonceLoadingStatus !== 'loading'; React.useEffect(() => { if (!siweNonceShouldBeFetched) { return; } if (usingCommServicesAccessToken) { void dispatchActionPromise( identityGenerateNonceActionTypes, (async () => { const response = await identityGenerateNonce(); setSIWENonce(response); })(), ); } else { void dispatchActionPromise( getSIWENonceActionTypes, (async () => { const response = await legacyGetSIWENonceCall(); setSIWENonce(response); })(), ); } }, [ dispatchActionPromise, identityGenerateNonce, legacyGetSIWENonceCall, siweNonceShouldBeFetched, ]); const callLegacySIWEAuthEndpoint = React.useCallback( async (message: string, signature: string, extraInfo: LogInExtraInfo) => { await olmAPI.initializeCryptoAccount(); const userPublicKey = await olmAPI.getUserPublicKey(); try { return await legacySiweAuthCall({ message, signature, signedIdentityKeysBlob: { payload: userPublicKey.blobPayload, signature: userPublicKey.signature, }, doNotRegister: true, ...extraInfo, }); } catch (e) { if ( e instanceof ServerError && e.message === 'account_does_not_exist' ) { setError('account_does_not_exist'); } throw e; } }, [legacySiweAuthCall], ); const attemptLegacySIWEAuth = React.useCallback( (message: string, signature: string) => { return dispatchActionPromise( siweAuthActionTypes, callLegacySIWEAuthEndpoint(message, signature, logInExtraInfo), undefined, ({ calendarQuery: logInExtraInfo.calendarQuery }: LogInStartingPayload), ); }, [callLegacySIWEAuthEndpoint, dispatchActionPromise, logInExtraInfo], ); - const attemptIdentityWalletLogIn = React.useCallback( - (walletAddress: string, siweMessage: string, siweSignature: string) => { - return dispatchActionPromise( - identityLogInActionTypes, - (async () => { - try { - return await identityWalletLogIn( - walletAddress, - siweMessage, - siweSignature, - ); - } catch (e) { - if (getMessageForException(e) === 'user not found') { - setError('account_does_not_exist'); - } - throw e; - } - })(), - ); + const attemptWalletLogIn = React.useCallback( + async ( + walletAddress: string, + siweMessage: string, + siweSignature: string, + ) => { + try { + return await walletLogIn(walletAddress, siweMessage, siweSignature); + } catch (e) { + if (getMessageForException(e) === 'user not found') { + setError('account_does_not_exist'); + } + throw e; + } }, - [dispatchActionPromise, identityWalletLogIn], + [walletLogIn], ); const dispatch = useDispatch(); const onSignInButtonClick = React.useCallback(async () => { invariant(signer, 'signer must be present during SIWE attempt'); invariant(siweNonce, 'nonce must be present during SIWE attempt'); await olmAPI.initializeCryptoAccount(); const { primaryIdentityPublicKeys: { ed25519 }, } = await olmAPI.getUserPublicKey(); const statement = getSIWEStatementForPublicKey(ed25519); const message = createSIWEMessage(address, statement, siweNonce); const signature = await signer.signMessage({ message }); if (usingCommServicesAccessToken) { - await attemptIdentityWalletLogIn(address, message, signature); + await attemptWalletLogIn(address, message, signature); } else { await attemptLegacySIWEAuth(message, signature); dispatch({ type: setDataLoadedActionType, payload: { dataLoaded: true, }, }); } }, [ address, attemptLegacySIWEAuth, - attemptIdentityWalletLogIn, + attemptWalletLogIn, signer, siweNonce, dispatch, ]); const { cancelSIWEAuthFlow } = props; const backButtonColor = React.useMemo( () => ({ backgroundColor: '#211E2D' }), [], ); const signInButtonColor = React.useMemo( () => ({ backgroundColor: '#6A20E3' }), [], ); const [error, setError] = React.useState(); const mainMiddleAreaClassName = classNames({ [css.mainMiddleArea]: true, [css.hidden]: !!error, }); const errorOverlayClassNames = classNames({ [css.errorOverlay]: true, [css.hidden]: !error, }); if (siweAuthLoadingStatus === 'loading' || !siweNonce) { return (
); } let errorText; if (error === 'account_does_not_exist') { errorText = ( <>

No Comm account found for that Ethereum wallet!

We require that users register on their mobile devices. Comm relies on a primary device capable of scanning QR codes in order to authorize secondary devices.

You can install our iOS app  here , or our Android app  here .

); } return (

Sign in with Ethereum

Wallet Connected

{siweMessageSigningExplanationStatements}

By signing up, you agree to our{' '} Terms of Use &{' '} Privacy Policy.

{errorText}
); } export default SIWELoginForm;