diff --git a/native/account/registration/avatar-selection.react.js b/native/account/registration/avatar-selection.react.js --- a/native/account/registration/avatar-selection.react.js +++ b/native/account/registration/avatar-selection.react.js @@ -21,11 +21,13 @@ type AvatarData, ensAvatarSelection, } from './registration-types.js'; +import { enableSIWEBackupCreation } from './registration-types.js'; import EditUserAvatar from '../../avatars/edit-user-avatar.react.js'; import { useCurrentLeafRouteName } from '../../navigation/nav-selectors.js'; import { type NavigationRoute, RegistrationTermsRouteName, + CreateSIWEBackupMessageRouteName, AvatarSelectionRouteName, EmojiAvatarSelectionRouteName, RegistrationUserAvatarCameraModalRouteName, @@ -144,6 +146,16 @@ ...userSelections, avatarData, }; + if ( + userSelections.accountSelection.accountType === 'ethereum' && + enableSIWEBackupCreation + ) { + navigate<'CreateSIWEBackupMessage'>({ + name: CreateSIWEBackupMessageRouteName, + params: { userSelections: newUserSelections }, + }); + return; + } navigate<'RegistrationTerms'>({ name: RegistrationTermsRouteName, params: { userSelections: newUserSelections }, diff --git a/native/account/registration/registration-navigator.react.js b/native/account/registration/registration-navigator.react.js --- a/native/account/registration/registration-navigator.react.js +++ b/native/account/registration/registration-navigator.react.js @@ -17,6 +17,7 @@ import KeyserverSelection from './keyserver-selection.react.js'; import PasswordSelection from './password-selection.react.js'; import RegistrationTerms from './registration-terms.react.js'; +import CreateSIWEBackupMessage from './siwe-backup-message-creation.react.js'; import UsernameSelection from './username-selection.react.js'; import RegistrationUserAvatarCameraModal from '../../media/registration-user-avatar-camera-modal.react.js'; import type { RootNavigationProp } from '../../navigation/root-navigator.react.js'; @@ -24,6 +25,7 @@ KeyserverSelectionRouteName, CoolOrNerdModeSelectionRouteName, ConnectEthereumRouteName, + CreateSIWEBackupMessageRouteName, ExistingEthereumAccountRouteName, UsernameSelectionRouteName, ConnectFarcasterRouteName, @@ -89,6 +91,10 @@ name={ConnectFarcasterRouteName} component={ConnectFarcaster} /> + , + +route: NavigationRoute<'CreateSIWEBackupMessage'>, +}; +function CreateSIWEBackupMessage(props: Props): React.Node { + const { navigate } = props.navigation; + const { params } = props.route; + + const styles = useStyles(unboundStyles); + + const [panelState, setPanelState] = React.useState('closed'); + + const openPanel = React.useCallback(() => { + setPanelState('opening'); + }, []); + const onPanelClosed = React.useCallback(() => { + setPanelState('closed'); + }, []); + const onPanelClosing = React.useCallback(() => { + setPanelState('closing'); + }, []); + + const siwePanelSetLoading = React.useCallback( + (loading: boolean) => { + if (panelState === 'closing' || panelState === 'closed') { + return; + } + setPanelState(loading ? 'opening' : 'open'); + }, + [panelState], + ); + + const registrationContext = React.useContext(RegistrationContext); + invariant(registrationContext, 'registrationContext should be set'); + const { cachedSelections, setCachedSelections } = registrationContext; + + const onSuccessfulWalletSignature = React.useCallback( + (result: SIWEResult) => { + const { message, signature } = result; + setCachedSelections(oldUserSelections => ({ + ...oldUserSelections, + siweBackupSecrets: { message, signature }, + })); + navigate<'RegistrationTerms'>({ + name: RegistrationTermsRouteName, + params, + }); + }, + [navigate, params, setCachedSelections], + ); + + const onExistingWalletSignature = React.useCallback(() => { + navigate<'RegistrationTerms'>({ + name: RegistrationTermsRouteName, + params, + }); + }, [params, navigate]); + + let siwePanel; + if (panelState !== 'closed') { + siwePanel = ( + + ); + } + + const { siweBackupSecrets } = cachedSelections; + + const newSignatureButtonText = siweBackupSecrets + ? 'Encrypt with new signature' + : 'Encrypt with Ethereum signature'; + const newSignatureButtonVariant = siweBackupSecrets ? 'outline' : 'enabled'; + + let useExistingSignatureButton; + if (siweBackupSecrets) { + useExistingSignatureButton = ( + + ); + } + + const body = ( + + Comm encrypts user backups so that our backend is not able to see user + data. + + ); + + return ( + <> + + + Encrypting your Comm Backup + {body} + + + + + + {useExistingSignatureButton} + + + + {siwePanel} + + ); +} + +const unboundStyles = { + scrollViewContentContainer: { + flexGrow: 1, + }, + header: { + fontSize: 24, + color: 'panelForegroundLabel', + paddingBottom: 16, + }, + body: { + fontFamily: 'Arial', + fontSize: 15, + lineHeight: 20, + color: 'panelForegroundSecondaryLabel', + paddingBottom: 16, + }, + siweBackupIcon: { + color: 'panelForegroundIcon', + }, + siweBackupIconContainer: { + flexGrow: 1, + alignItems: 'center', + justifyContent: 'center', + }, +}; + +export default CreateSIWEBackupMessage; diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js --- a/native/navigation/route-names.js +++ b/native/navigation/route-names.js @@ -12,6 +12,7 @@ import type { KeyserverSelectionParams } from '../account/registration/keyserver-selection.react.js'; import type { PasswordSelectionParams } from '../account/registration/password-selection.react.js'; import type { RegistrationTermsParams } from '../account/registration/registration-terms.react.js'; +import type { CreateSIWEBackupMessageParams } from '../account/registration/siwe-backup-message-creation.react.js'; import type { UsernameSelectionParams } from '../account/registration/username-selection.react.js'; import type { TermsAndPrivacyModalParams } from '../account/terms-and-privacy-modal.react.js'; import type { ThreadPickerModalParams } from '../calendar/thread-picker-modal.react.js'; @@ -121,6 +122,7 @@ export const KeyserverSelectionRouteName = 'KeyserverSelection'; export const CoolOrNerdModeSelectionRouteName = 'CoolOrNerdModeSelection'; export const ConnectEthereumRouteName = 'ConnectEthereum'; +export const CreateSIWEBackupMessageRouteName = 'CreateSIWEBackupMessage'; export const ExistingEthereumAccountRouteName = 'ExistingEthereumAccount'; export const ConnectFarcasterRouteName = 'ConnectFarcaster'; export const UsernameSelectionRouteName = 'UsernameSelection'; @@ -265,6 +267,7 @@ +ConnectEthereum: ConnectEthereumParams, +ExistingEthereumAccount: ExistingEthereumAccountParams, +ConnectFarcaster: ConnectFarcasterParams, + +CreateSIWEBackupMessage: CreateSIWEBackupMessageParams, +UsernameSelection: UsernameSelectionParams, +PasswordSelection: PasswordSelectionParams, +AvatarSelection: AvatarSelectionParams, diff --git a/native/themes/colors.js b/native/themes/colors.js --- a/native/themes/colors.js +++ b/native/themes/colors.js @@ -109,6 +109,7 @@ panelForeground: designSystemColors.shadesWhite100, panelForegroundBorder: designSystemColors.shadesWhite60, panelForegroundLabel: designSystemColors.shadesBlack95, + panelForegroundIcon: designSystemColors.shadesBlack95, panelForegroundSecondaryLabel: '#333333', panelForegroundTertiaryLabel: '#888888', panelInputBackground: designSystemColors.shadesWhite60, @@ -211,6 +212,7 @@ panelForeground: designSystemColors.shadesBlack85, panelForegroundBorder: '#2C2C2E', panelForegroundLabel: designSystemColors.shadesWhite100, + panelForegroundIcon: designSystemColors.shadesWhite100, panelForegroundSecondaryLabel: designSystemColors.shadesWhite60, panelForegroundTertiaryLabel: '#AAAAAA', panelInputBackground: designSystemColors.shadesBlack75,