diff --git a/native/account/registration/registration-server-call.js b/native/account/registration/registration-server-call.js --- a/native/account/registration/registration-server-call.js +++ b/native/account/registration/registration-server-call.js @@ -11,6 +11,7 @@ identityRegisterActionTypes, } from 'lib/actions/user-actions.js'; import type { LogInStartingPayload } from 'lib/types/account-types.js'; +import type { SIWEBackupSecrets } from 'lib/types/siwe-types.js'; import { syncedMetadataNames } from 'lib/types/synced-metadata-types.js'; import { useLegacyAshoatKeyserverCall } from 'lib/utils/action-utils.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; @@ -27,6 +28,7 @@ useNativeSetUserAvatar, useUploadSelectedMedia, } from '../../avatars/avatar-hooks.js'; +import { commCoreModule } from '../../native-modules.js'; import { useSelector } from '../../redux/redux-utils.js'; import { nativeLogInExtraInfoSelector } from '../../selectors/account-selectors.js'; import { @@ -57,6 +59,8 @@ | { +step: 'waiting_for_registration_call', +avatarData: ?AvatarData, + +siweBackupSecrets?: ?SIWEBackupSecrets, + +clearCachedSelections: () => void, +resolve: () => void, +reject: Error => void, }; @@ -197,8 +201,14 @@ if (currentStep.step !== 'inactive') { return; } - const { accountSelection, avatarData, keyserverURL, farcasterID } = - input; + const { + accountSelection, + avatarData, + keyserverURL, + farcasterID, + siweBackupSecrets, + clearCachedSelections, + } = input; if ( accountSelection.accountType === 'username' && !usingCommServicesAccessToken @@ -256,6 +266,8 @@ setCurrentStep({ step: 'waiting_for_registration_call', avatarData, + siweBackupSecrets, + clearCachedSelections, resolve, reject, }); @@ -274,7 +286,7 @@ ], ); - // STEP 2: SETTING AVATAR + // STEP 2: HANDLING USER SELECTIONS const uploadSelectedMedia = useUploadSelectedMedia(); const nativeSetUserAvatar = useNativeSetUserAvatar(); @@ -283,33 +295,48 @@ state => !!state.currentUserInfo && !state.currentUserInfo.anonymous, ); - const avatarBeingSetRef = React.useRef(false); + const userSelectionsBeingHandledRef = React.useRef(false); React.useEffect(() => { if ( !hasCurrentUserInfo || currentStep.step !== 'waiting_for_registration_call' || - avatarBeingSetRef.current + userSelectionsBeingHandledRef.current ) { return; } - avatarBeingSetRef.current = true; - const { avatarData, resolve } = currentStep; + userSelectionsBeingHandledRef.current = true; + const { avatarData, siweBackupSecrets, clearCachedSelections, resolve } = + currentStep; void (async () => { try { - if (!avatarData) { - return; - } - let updateUserAvatarRequest; - if (!avatarData.needsUpload) { - ({ updateUserAvatarRequest } = avatarData); - } else { - const { mediaSelection } = avatarData; - updateUserAvatarRequest = await uploadSelectedMedia(mediaSelection); - if (!updateUserAvatarRequest) { + const uploadAvatarPromise = (async () => { + if (!avatarData) { return; } - } - await nativeSetUserAvatar(updateUserAvatarRequest); + let updateUserAvatarRequest; + if (!avatarData.needsUpload) { + ({ updateUserAvatarRequest } = avatarData); + } else { + const { mediaSelection } = avatarData; + updateUserAvatarRequest = await uploadSelectedMedia(mediaSelection); + if (!updateUserAvatarRequest) { + return; + } + } + await nativeSetUserAvatar(updateUserAvatarRequest); + })(); + + const persistSIWEBackupSecretsPromise = (async () => { + if (!siweBackupSecrets) { + return; + } + await commCoreModule.setSIWEBackupSecrets(siweBackupSecrets); + })(); + + await Promise.all([ + uploadAvatarPromise, + persistSIWEBackupSecretsPromise, + ]); } finally { dispatch({ type: setDataLoadedActionType, @@ -317,8 +344,9 @@ dataLoaded: true, }, }); + clearCachedSelections(); setCurrentStep(inactiveStep); - avatarBeingSetRef.current = false; + userSelectionsBeingHandledRef.current = false; resolve(); } })(); diff --git a/native/account/registration/registration-terms.react.js b/native/account/registration/registration-terms.react.js --- a/native/account/registration/registration-terms.react.js +++ b/native/account/registration/registration-terms.react.js @@ -4,6 +4,8 @@ import * as React from 'react'; import { Text, View, Image, Linking } from 'react-native'; +import type { SIWEBackupSecrets } from 'lib/types/siwe-types.js'; + import RegistrationButtonContainer from './registration-button-container.react.js'; import RegistrationButton from './registration-button.react.js'; import RegistrationContainer from './registration-container.react.js'; @@ -26,6 +28,7 @@ +farcasterID: ?string, +accountSelection: AccountSelection, +avatarData: ?AvatarData, + +siweBackupSecrets?: ?SIWEBackupSecrets, }, }; @@ -44,20 +47,25 @@ function RegistrationTerms(props: Props): React.Node { const registrationContext = React.useContext(RegistrationContext); invariant(registrationContext, 'registrationContext should be set'); - const { register } = registrationContext; + const { register, setCachedSelections } = registrationContext; const [registrationInProgress, setRegistrationInProgress] = React.useState(false); const { userSelections } = props.route.params; + + const clearCachedSelections = React.useCallback(() => { + setCachedSelections({}); + }, [setCachedSelections]); + const onProceed = React.useCallback(async () => { setRegistrationInProgress(true); try { - await register(userSelections); + await register({ ...userSelections, clearCachedSelections }); } finally { setRegistrationInProgress(false); } - }, [register, userSelections]); + }, [register, userSelections, clearCachedSelections]); const styles = useStyles(unboundStyles); diff --git a/native/account/registration/registration-types.js b/native/account/registration/registration-types.js --- a/native/account/registration/registration-types.js +++ b/native/account/registration/registration-types.js @@ -43,6 +43,8 @@ +farcasterID: ?string, +accountSelection: AccountSelection, +avatarData: ?AvatarData, + +siweBackupSecrets?: ?SIWEBackupSecrets, + +clearCachedSelections: () => void, }; export type CachedUserSelections = { diff --git a/native/account/registration/siwe-backup-message-creation.react.js b/native/account/registration/siwe-backup-message-creation.react.js --- a/native/account/registration/siwe-backup-message-creation.react.js +++ b/native/account/registration/siwe-backup-message-creation.react.js @@ -44,6 +44,7 @@ function CreateSIWEBackupMessage(props: Props): React.Node { const { navigate } = props.navigation; const { params } = props.route; + const { userSelections } = params; const styles = useStyles(unboundStyles); @@ -76,24 +77,36 @@ const onSuccessfulWalletSignature = React.useCallback( (result: SIWEResult) => { const { message, signature } = result; + const newUserSelections = { + ...userSelections, + siweBackupSecrets: { message, signature }, + }; setCachedSelections(oldUserSelections => ({ ...oldUserSelections, siweBackupSecrets: { message, signature }, })); navigate<'RegistrationTerms'>({ name: RegistrationTermsRouteName, - params, + params: { userSelections: newUserSelections }, }); }, - [navigate, params, setCachedSelections], + [navigate, setCachedSelections, userSelections], ); + const { siweBackupSecrets } = cachedSelections; const onExistingWalletSignature = React.useCallback(() => { + const registrationTermsParams = { + userSelections: { + ...userSelections, + siweBackupSecrets, + }, + }; + navigate<'RegistrationTerms'>({ name: RegistrationTermsRouteName, - params, + params: registrationTermsParams, }); - }, [params, navigate]); + }, [navigate, siweBackupSecrets, userSelections]); let siwePanel; if (panelState !== 'closed') { @@ -109,8 +122,6 @@ ); } - const { siweBackupSecrets } = cachedSelections; - const newSignatureButtonText = siweBackupSecrets ? 'Encrypt with new signature' : 'Encrypt with Ethereum Wallet';