diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx
index a689ee28658..a42f0ddf45f 100644
--- a/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx
+++ b/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx
@@ -33,6 +33,7 @@ import { MobileMenu } from './MobileMenu/MobileMenu';
import { Sidebar } from './Sidebar/Sidebar';
import { useAppShortcuts } from './useAppShortcuts';
import { ModalSwitcher } from '../../modals/ModalSwitcher/ModalSwitcher';
+import { PassphraseModalProvider } from '../../modals/ReduxModal/DeviceContextModal/PassphraseModalContext';
export const SCROLL_WRAPPER_ID = 'layout-scroll';
export const Wrapper = styled.div`
@@ -162,49 +163,53 @@ export const SuiteLayout = ({ children }: SuiteLayoutProps) => {
-
-
-
-
-
- {isMobileLayout && }
-
- {isMobileLayout && }
-
-
-
-
-
-
- {!isMobileLayout && (
-
-
-
- )}
-
- {!isMobileLayout && }
-
-
-
- {isMobileLayout && isAccountPage && (
-
- )}
- {layoutHeader}
-
- {children}
-
-
-
-
-
-
-
- {!isMobileLayout && }
-
+
+
+
+
+
+
+ {isMobileLayout && }
+
+ {isMobileLayout && }
+
+
+
+
+
+
+ {!isMobileLayout && (
+
+
+
+ )}
+
+ {!isMobileLayout && }
+
+
+
+ {isMobileLayout && isAccountPage && (
+
+ )}
+ {layoutHeader}
+
+
+ {children}
+
+
+
+
+
+
+
+
+ {!isMobileLayout && }
+
+
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/ConfirmPassphraseBeforeAction.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/ConfirmPassphraseBeforeAction.tsx
new file mode 100644
index 00000000000..b277119c7a8
--- /dev/null
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/ConfirmPassphraseBeforeAction.tsx
@@ -0,0 +1,65 @@
+import { TrezorDevice } from '@suite-common/suite-types';
+import { selectDeviceModel } from '@suite-common/wallet-core';
+import { Column, H3, Paragraph } from '@trezor/components';
+import TrezorConnect from '@trezor/connect';
+import { PassphraseTypeCard } from '@trezor/product-components';
+import { spacings } from '@trezor/theme';
+
+import { useSelector } from '../../../../../hooks/suite';
+import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice';
+import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal';
+import { OpenGuideFromTooltip } from '../../../../guide';
+import { Translation } from '../../../Translation';
+
+type ConfirmPassphraseBeforeActionProps = {
+ onDeviceOffer: boolean;
+ onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
+ device: TrezorDevice;
+};
+
+export const ConfirmPassphraseBeforeAction = ({
+ device,
+ onSubmit,
+ onDeviceOffer,
+}: ConfirmPassphraseBeforeActionProps) => {
+ const deviceModel = useSelector(selectDeviceModel);
+
+ const onEnterPassphraseDialogCancel = () => {
+ TrezorConnect.cancel('enter-passphrase-cancel');
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ }
+ type="hidden"
+ singleColModal
+ offerPassphraseOnDevice={onDeviceOffer}
+ onSubmit={onSubmit}
+ deviceModel={deviceModel ?? undefined}
+ deviceBackup={device.features?.backup_type}
+ learnMoreTooltipOnClick={
+
+ }
+ />
+
+
+
+ );
+};
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/EnterPassphrase.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/EnterPassphrase.tsx
new file mode 100644
index 00000000000..73d57f58fc9
--- /dev/null
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/EnterPassphrase.tsx
@@ -0,0 +1,91 @@
+import { TrezorDevice } from '@suite-common/suite-types/libDev/src';
+import { selectDeviceModel } from '@suite-common/wallet-core';
+import { Column, H3, Icon, List } from '@trezor/components';
+import TrezorConnect from '@trezor/connect';
+import { PassphraseTypeCard } from '@trezor/product-components';
+import { spacings } from '@trezor/theme';
+import { HELP_CENTER_PASSPHRASE_URL } from '@trezor/urls';
+
+import { useSelector } from '../../../../../hooks/suite';
+import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice';
+import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal';
+import { OpenGuideFromTooltip } from '../../../../guide';
+import { Translation } from '../../../Translation';
+import { TrezorLink } from '../../../TrezorLink';
+
+type EnterPassphraseProps = {
+ onDeviceOffer: boolean;
+ onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
+ device: TrezorDevice;
+};
+
+export const EnterPassphrase = ({ device, onDeviceOffer, onSubmit }: EnterPassphraseProps) => {
+ const deviceModel = useSelector(selectDeviceModel);
+
+ const onEnterPassphraseDialogCancel = () => {
+ TrezorConnect.cancel('enter-passphrase-cancel');
+ };
+
+ const onEnterPassphraseDialogBack = () => {
+ TrezorConnect.cancel('enter-passphrase-back');
+ };
+
+ return (
+
+
+
+
+
+
+
+ }>
+ (
+
+ {chunks}
+
+ ),
+ }}
+ />
+
+ }>
+
+
+ }>
+
+
+
+ }
+ type="hidden"
+ singleColModal
+ offerPassphraseOnDevice={onDeviceOffer}
+ onSubmit={(value: string, passphraseOnDevice?: boolean) =>
+ onSubmit(value, passphraseOnDevice)
+ }
+ deviceModel={deviceModel ?? undefined}
+ deviceBackup={device.features?.backup_type}
+ learnMoreTooltipOnClick={
+
+ }
+ />
+
+
+
+ );
+};
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx
index e547385a214..dd3f2797569 100644
--- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx
@@ -1,39 +1,24 @@
import { useCallback } from 'react';
-import {
- onPassphraseSubmit,
- selectDeviceModel,
- selectIsDiscoveryAuthConfirmationRequired,
-} from '@suite-common/wallet-core';
-import { Column, H3, Icon, List, Paragraph } from '@trezor/components';
-import TrezorConnect from '@trezor/connect';
-import { PassphraseTypeCard } from '@trezor/product-components';
-import { spacings } from '@trezor/theme';
-import { HELP_CENTER_PASSPHRASE_URL } from '@trezor/urls';
+import { onPassphraseSubmit } from '@suite-common/wallet-core';
-import { OpenGuideFromTooltip } from 'src/components/guide';
-import { Translation } from 'src/components/suite';
-import { TrezorLink } from 'src/components/suite/TrezorLink';
-import { useDispatch, useSelector } from 'src/hooks/suite';
+import { useDispatch } from 'src/hooks/suite';
import type { TrezorDevice } from 'src/types/suite';
-import { CardWithDevice } from 'src/views/suite/SwitchDevice/CardWithDevice';
-import { SwitchDeviceModal } from 'src/views/suite/SwitchDevice/SwitchDeviceModal';
-import { PassphraseWalletConfirmation } from './PassphraseWalletConfirmation';
+import { ConfirmPassphraseBeforeAction } from './ConfirmPassphraseBeforeAction';
+import { usePassphraseModalContext } from './PassphraseModalContext';
+import { PassphraseWalletExistsFlow } from './PassphraseWalletExistsFlow';
+import { PassphraseWalletIsNotExistFlow } from './PassphraseWalletIsNotExistFlow';
interface PassphraseModalProps {
device: TrezorDevice;
}
export const PassphraseModal = ({ device }: PassphraseModalProps) => {
- const authConfirmation =
- useSelector(selectIsDiscoveryAuthConfirmationRequired) || device.authConfirm;
-
- const deviceModel = useSelector(selectDeviceModel);
-
// @ts-expect-error device.state should not be ''
const hasDeviceState = device.state !== undefined && device.state !== '';
+ const { passphraseState, setPassphraseState, isExisting } = usePassphraseModalContext();
const onDeviceOffer = !!(
device.features &&
device.features.capabilities &&
@@ -42,138 +27,47 @@ export const PassphraseModal = ({ device }: PassphraseModalProps) => {
const dispatch = useDispatch();
- const onConfirmPassphraseDialogCancel = () => {
- TrezorConnect.cancel('auth-confirm-cancel');
- };
-
- const onConfirmPassphraseDialogRetry = () => {
- TrezorConnect.cancel('auth-confirm-retry');
- };
-
- const onEnterPassphraseDialogCancel = () => {
- TrezorConnect.cancel('enter-passphrase-cancel');
- };
- const onEnterPassphraseDialogBack = () => {
- TrezorConnect.cancel('enter-passphrase-back');
- };
-
const onSubmit = useCallback(
(value: string, passphraseOnDevice?: boolean) => {
+ if (isExisting) {
+ setPassphraseState('exists-empty-wallet');
+ } else {
+ setPassphraseState('not-exist-confirm-passphrase');
+ }
dispatch(onPassphraseSubmit({ value, passphraseOnDevice: !!passphraseOnDevice }));
},
- [dispatch],
+ [dispatch, isExisting, setPassphraseState],
);
- const PassphraseDefaultForm = () => (
-
-
-
-
-
-
-
- }>
- (
-
- {chunks}
-
- ),
- }}
- />
-
- }>
-
-
- }>
-
-
-
- }
- type="hidden"
- singleColModal
- offerPassphraseOnDevice={onDeviceOffer}
- onSubmit={onSubmit}
- deviceModel={deviceModel ?? undefined}
- deviceBackup={device.features?.backup_type}
- learnMoreTooltipOnClick={
-
- }
- />
-
-
-
- );
+ onSubmit={onSubmit}
+ onDeviceOffer={onDeviceOffer}
+ />
+ );
+ }
- const ConfirmPassphraseBeforeAction = () => (
-
-
-
-
-
-
-
-
-
- }
- type="hidden"
- singleColModal
- offerPassphraseOnDevice={onDeviceOffer}
- onSubmit={onSubmit}
- deviceModel={deviceModel ?? undefined}
- deviceBackup={device.features?.backup_type}
- learnMoreTooltipOnClick={
-
- }
- />
-
-
-
- );
+ console.log('___!!!', passphraseState);
- // passphrase needs to be confirmed because wallet is empty
- if (authConfirmation) {
+ if (isExisting)
return (
-
+ );
+ if (!isExisting)
+ return (
+
);
- }
-
- // "view-only" is active, device is reconnected and you fired an action that needs passphrase (e.g. add coin, show receive address)
- if (hasDeviceState) {
- return ;
- }
- // first step of adding passphrase wallet from switch device modal
- return ;
+ throw new Error('Unexpected passphrase state');
};
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext.tsx
new file mode 100644
index 00000000000..5077569be76
--- /dev/null
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext.tsx
@@ -0,0 +1,79 @@
+import React, { createContext, useContext, useState } from 'react';
+
+import type { TrezorDevice } from '@suite-common/suite-types/libDev/src';
+
+type PassphraseWalletExistsState =
+ | 'exists-enter-passphrase'
+ | 'exists-best-practices'
+ | 'exists-empty-wallet'
+ | 'exists-confirm-passphrase';
+
+type PassphraseWalletNotExistsState =
+ | 'not-exist-enter-passphrase'
+ | 'not-exist-best-practices'
+ | 'not-exist-confirm-passphrase';
+
+type PassphraseWalletState =
+ | 'initial'
+ | PassphraseWalletExistsState
+ | PassphraseWalletNotExistsState;
+
+const INITIAL_STATE: PassphraseWalletState = 'initial';
+
+type PassphraseModalContextType = {
+ passphraseState: PassphraseWalletState;
+ setPassphraseState: (passphraseState: PassphraseWalletState) => void;
+ device: TrezorDevice | undefined;
+ setDevice: (device: TrezorDevice) => void;
+ isExisting: boolean;
+ setIsExisting: (isExisting: boolean) => void;
+};
+
+type PassphraseModalProviderProps = {
+ children: React.ReactNode;
+};
+
+const initialPassphraseModal: PassphraseModalContextType = {
+ passphraseState: INITIAL_STATE,
+ setPassphraseState: () => {},
+ device: undefined,
+ setDevice: () => {},
+ isExisting: false,
+ setIsExisting: () => {},
+};
+
+export const PassphraseModalContext =
+ createContext(initialPassphraseModal);
+
+// move this to redux
+export const PassphraseModalProvider = ({ children }: PassphraseModalProviderProps) => {
+ const [passphraseState, setPassphraseState] = useState(
+ initialPassphraseModal.passphraseState,
+ );
+ const [device, setDevice] = useState(undefined);
+ const [isExisting, setIsExisting] = useState(false);
+
+ const value: PassphraseModalContextType = {
+ passphraseState,
+ setPassphraseState,
+ device,
+ setDevice,
+ isExisting,
+ setIsExisting,
+ };
+
+ return (
+ {children}
+ );
+};
+
+PassphraseModalProvider.displayName = 'PassphraseModalProvider';
+
+export const usePassphraseModalContext = () => {
+ const context = useContext(PassphraseModalContext);
+ if (!context) {
+ throw new Error('usePassphraseModalContext must be used within a PassphraseModalProvider');
+ }
+
+ return context;
+};
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep2.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices.tsx
similarity index 60%
rename from packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep2.tsx
rename to packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices.tsx
index eab9031fa95..6ea9a4d5abc 100644
--- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep2.tsx
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices.tsx
@@ -1,18 +1,23 @@
-import { Dispatch } from 'react';
-
import { Banner, Button, Card, Column, H3, Icon, List, Text } from '@trezor/components';
import { spacings } from '@trezor/theme';
-import { Translation } from 'src/components/suite/Translation';
+import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice';
+import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal';
+import { Translation } from '../../../Translation';
-import { ContentType } from './types';
+type PassphraseWalletBestPracticesProps = {
+ onCancel: () => void;
+ onNext: () => void;
+ onBack: () => void;
+ device: any;
+};
type PassphraseWalletConfirmationStep2Props = {
- setContentType: Dispatch>;
+ onNext: () => void;
};
-export const PassphraseWalletConfirmationStep2 = ({
- setContentType,
+const PassphraseWalletBestPracticesContent = ({
+ onNext,
}: PassphraseWalletConfirmationStep2Props) => (
@@ -37,14 +42,26 @@ export const PassphraseWalletConfirmationStep2 = ({
-
);
+
+export const PassphraseWalletBestPractices = ({
+ onCancel,
+ onNext,
+ onBack,
+ device,
+}: PassphraseWalletBestPracticesProps) => (
+
+
+
+
+
+);
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx
index e4761045849..701e3e27119 100644
--- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx
@@ -1,97 +1,81 @@
-import { Dispatch, SetStateAction, useState } from 'react';
-
import { TrezorDevice } from '@suite-common/suite-types';
+import { selectDeviceFeatures, selectDeviceModel } from '@suite-common/wallet-core';
+import { Banner, Column, H3 } from '@trezor/components';
+import { PassphraseTypeCard } from '@trezor/product-components';
+import { spacings } from '@trezor/theme';
import { CardWithDevice } from 'src/views/suite/SwitchDevice/CardWithDevice';
import { SwitchDeviceModal } from 'src/views/suite/SwitchDevice/SwitchDeviceModal';
-import { PassphraseWalletConfirmationStep1 } from './PassphraseWalletConfirmationStep1';
-import { PassphraseWalletConfirmationStep2 } from './PassphraseWalletConfirmationStep2';
-import { PassphraseWalletConfirmationStep3 } from './PassphraseWalletConfirmationStep3';
-import { ContentType } from './types';
+import { useSelector } from '../../../../../hooks/suite';
+import { OpenGuideFromTooltip } from '../../../../guide';
+import { Translation } from '../../../Translation';
type PassphraseWalletConfirmationContentProps = {
- onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
onDeviceOffer: boolean;
- onRetry: () => void;
- onCancel: () => void;
- contentType: ContentType;
- setContentType: Dispatch>;
+ onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
};
const PassphraseWalletConfirmationContent = ({
- onSubmit,
onDeviceOffer,
- onRetry,
- onCancel,
- contentType,
- setContentType,
-}: PassphraseWalletConfirmationContentProps): React.JSX.Element => {
- switch (contentType) {
- case 'step1':
- return (
-
- );
- case 'step2':
- return ;
- case 'step3':
- return (
-
- );
- }
+ onSubmit,
+}: PassphraseWalletConfirmationContentProps) => {
+ const deviceModel = useSelector(selectDeviceModel);
+ const deviceFeatures = useSelector(selectDeviceFeatures);
+
+ return (
+
+
+
+
+
+
+
+ }
+ offerPassphraseOnDevice={onDeviceOffer}
+ onSubmit={onSubmit}
+ singleColModal
+ deviceModel={deviceModel ?? undefined}
+ deviceBackup={deviceFeatures?.backup_type}
+ learnMoreTooltipOnClick={
+
+ }
+ />
+
+ );
};
type PassphraseWalletConfirmationProps = {
onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
onDeviceOffer: boolean;
onCancel: () => void;
- onRetry: () => void;
+ onBack: () => void;
device: TrezorDevice;
};
export const PassphraseWalletConfirmation = ({
onCancel,
- onRetry,
+ onBack,
onSubmit,
onDeviceOffer,
device,
-}: PassphraseWalletConfirmationProps) => {
- const [contentType, setContentType] = useState('step1');
-
- const handleBackButtonClick = () => {
- const map: Record void> = {
- step1: onRetry,
- step2: () => setContentType('step1'),
- step3: () => setContentType('step2'),
- };
-
- map[contentType]();
- };
-
- return (
-
-
-
-
-
- );
-};
+}: PassphraseWalletConfirmationProps) => (
+
+
+
+
+
+);
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep3.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep3.tsx
deleted file mode 100644
index 7c1c4824120..00000000000
--- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep3.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import { selectDeviceFeatures, selectDeviceModel } from '@suite-common/wallet-core';
-import { Banner, Column, H3 } from '@trezor/components';
-import { PassphraseTypeCard } from '@trezor/product-components';
-import { spacings } from '@trezor/theme';
-
-import { OpenGuideFromTooltip } from 'src/components/guide';
-import { Translation } from 'src/components/suite/Translation';
-import { useSelector } from 'src/hooks/suite';
-
-type PassphraseWalletConfirmationStep3Props = {
- onDeviceOffer: boolean;
- onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
-};
-
-export const PassphraseWalletConfirmationStep3 = ({
- onDeviceOffer,
- onSubmit,
-}: PassphraseWalletConfirmationStep3Props) => {
- const deviceModel = useSelector(selectDeviceModel);
- const deviceFeatures = useSelector(selectDeviceFeatures);
-
- return (
-
-
-
-
-
-
-
- }
- offerPassphraseOnDevice={onDeviceOffer}
- onSubmit={onSubmit}
- singleColModal
- deviceModel={deviceModel ?? undefined}
- deviceBackup={deviceFeatures?.backup_type}
- learnMoreTooltipOnClick={
-
- }
- />
-
- );
-};
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletExistsFlow.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletExistsFlow.tsx
new file mode 100644
index 00000000000..a54c3d52864
--- /dev/null
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletExistsFlow.tsx
@@ -0,0 +1,87 @@
+import { TrezorDevice } from '@suite-common/suite-types';
+import { selectIsDiscoveryAuthConfirmationRequired } from '@suite-common/wallet-core';
+import TrezorConnect from '@trezor/connect';
+
+import { EnterPassphrase } from './EnterPassphrase';
+import { usePassphraseModalContext } from './PassphraseModalContext';
+import { PassphraseWalletBestPractices } from './PassphraseWalletBestPractices';
+import { PassphraseWalletConfirmation } from './PassphraseWalletConfirmation';
+import { PassphraseWalletIsEmpty } from './PassphraseWalletIsEmpty';
+import { useSelector } from '../../../../../hooks/suite';
+
+type PassphraseWalletExistsFlowProps = {
+ onDeviceOffer: boolean;
+ onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
+ device: TrezorDevice;
+};
+
+export const PassphraseWalletExistsFlow = ({
+ onDeviceOffer,
+ onSubmit,
+ device,
+}: PassphraseWalletExistsFlowProps) => {
+ const authConfirmation =
+ useSelector(selectIsDiscoveryAuthConfirmationRequired) || device.authConfirm;
+ const { passphraseState, setPassphraseState } = usePassphraseModalContext();
+
+ const onConfirmPassphraseDialogCancel = () => {
+ TrezorConnect.cancel('auth-confirm-cancel');
+ };
+
+ const onConfirmPassphraseDialogRetry = () => {
+ TrezorConnect.cancel('auth-confirm-retry');
+ };
+
+ if (authConfirmation) {
+ if (passphraseState === 'exists-empty-wallet') {
+ return (
+ {
+ setPassphraseState('exists-best-practices');
+ }}
+ onBack={() => {
+ onConfirmPassphraseDialogRetry();
+ setPassphraseState('exists-enter-passphrase');
+ }}
+ device={device}
+ onRetry={onConfirmPassphraseDialogRetry}
+ />
+ );
+ }
+
+ if (passphraseState === 'exists-best-practices') {
+ return (
+ {
+ setPassphraseState('exists-confirm-passphrase');
+ }}
+ onBack={() => {
+ setPassphraseState('exists-empty-wallet');
+ }}
+ device={device}
+ />
+ );
+ }
+ if (passphraseState === 'exists-confirm-passphrase') {
+ return (
+ {
+ setPassphraseState('exists-best-practices');
+ }}
+ device={device}
+ onDeviceOffer={onDeviceOffer}
+ />
+ );
+ }
+ }
+
+ if (passphraseState === 'exists-enter-passphrase') {
+ return (
+
+ );
+ }
+};
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep1.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsEmpty.tsx
similarity index 74%
rename from packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep1.tsx
rename to packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsEmpty.tsx
index a4f220ede03..64fbef63936 100644
--- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep1.tsx
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsEmpty.tsx
@@ -1,32 +1,39 @@
-import { Dispatch } from 'react';
-
+import { TrezorDevice } from '@suite-common/suite-types';
import { Button, Card, Column, H3, Paragraph, Row } from '@trezor/components';
import { CoinLogo } from '@trezor/product-components';
import { spacings } from '@trezor/theme';
import { HELP_CENTER_PASSPHRASE_URL } from '@trezor/urls';
-import { onCancel as onCancelModal } from 'src/actions/suite/modalActions';
-import { goto } from 'src/actions/suite/routerActions';
-import { Translation } from 'src/components/suite/Translation';
-import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport';
-import { useDispatch, useSelector } from 'src/hooks/suite';
-import { selectEnabledNetworks } from 'src/reducers/wallet/settingsReducer';
+import { onCancel as onCancelModal } from '../../../../../actions/suite/modalActions';
+import { goto } from '../../../../../actions/suite/routerActions';
+import { useNetworkSupport } from '../../../../../hooks/settings/useNetworkSupport';
+import { useDispatch, useSelector } from '../../../../../hooks/suite';
+import { selectEnabledNetworks } from '../../../../../reducers/wallet/settingsReducer';
+import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice';
+import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal';
+import { Translation } from '../../../Translation';
-import { ContentType } from './types';
+type PassphraseWalletIsEmptyProps = {
+ onRetry: () => void;
+ onCancel: () => void;
+ device: TrezorDevice;
+ onNext: () => void;
+ onBack: () => void;
+};
-type PassphraseWalletConfirmationStep1Props = {
- setContentType: Dispatch>;
+type PassphraseWalletIsEmptyContentProps = {
+ onNext: () => void;
onRetry: () => void;
onCancel: () => void;
'data-testid'?: string;
};
-export const PassphraseWalletConfirmationStep1 = ({
- setContentType,
+const PassphraseWalletIsEmptyContent = ({
+ onNext,
onRetry,
onCancel,
'data-testid': dataTest,
-}: PassphraseWalletConfirmationStep1Props) => {
+}: PassphraseWalletIsEmptyContentProps) => {
const { supportedMainnets } = useNetworkSupport();
const enabledNetworks = useSelector(selectEnabledNetworks);
const dispatch = useDispatch();
@@ -68,9 +75,7 @@ export const PassphraseWalletConfirmationStep1 = ({
{
- setContentType('step2');
- }}
+ onClick={onNext}
data-testid="@passphrase-confirmation/step1-open-unused-wallet-button"
>
@@ -120,3 +125,22 @@ export const PassphraseWalletConfirmationStep1 = ({
);
};
+
+export const PassphraseWalletIsEmpty = ({
+ onCancel,
+ device,
+ onBack,
+ onRetry,
+ onNext,
+}: PassphraseWalletIsEmptyProps) => (
+
+
+
+
+
+);
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsNotExistFlow.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsNotExistFlow.tsx
new file mode 100644
index 00000000000..b3dbe9a4c5e
--- /dev/null
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsNotExistFlow.tsx
@@ -0,0 +1,48 @@
+import { TrezorDevice } from '@suite-common/suite-types';
+import { selectIsDiscoveryAuthConfirmationRequired } from '@suite-common/wallet-core';
+import TrezorConnect from '@trezor/connect';
+
+import { EnterPassphrase } from './EnterPassphrase';
+import { usePassphraseModalContext } from './PassphraseModalContext';
+import { PassphraseWalletConfirmation } from './PassphraseWalletConfirmation';
+import { useSelector } from '../../../../../hooks/suite';
+
+type PassphraseWalletIsNotExistFlowProps = {
+ onDeviceOffer: boolean;
+ onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
+ device: TrezorDevice;
+};
+
+export const PassphraseWalletIsNotExistFlow = ({
+ onDeviceOffer,
+ onSubmit,
+ device,
+}: PassphraseWalletIsNotExistFlowProps) => {
+ const { passphraseState, setPassphraseState } = usePassphraseModalContext();
+ const authConfirmation =
+ useSelector(selectIsDiscoveryAuthConfirmationRequired) || device.authConfirm;
+
+ const onConfirmPassphraseDialogCancel = () => {
+ TrezorConnect.cancel('auth-confirm-cancel');
+ };
+
+ if (authConfirmation && passphraseState === 'not-exist-confirm-passphrase') {
+ return (
+ {
+ setPassphraseState('not-exist-best-practices');
+ }}
+ device={device}
+ onDeviceOffer={onDeviceOffer}
+ />
+ );
+ }
+
+ if (passphraseState === 'not-exist-enter-passphrase') {
+ return (
+
+ );
+ }
+};
diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/types.ts b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/types.ts
index 005aaf7ad5d..7daa5eb291e 100644
--- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/types.ts
+++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/types.ts
@@ -1 +1 @@
-export type ContentType = 'step1' | 'step2' | 'step3';
+// export type ContentType = 'step1' | 'step2' | 'step3';
diff --git a/packages/suite/src/views/suite/SwitchDevice/DeviceItem/AddWalletButton.tsx b/packages/suite/src/views/suite/SwitchDevice/DeviceItem/AddWalletButton.tsx
index 6da9736e344..8d69a26a291 100644
--- a/packages/suite/src/views/suite/SwitchDevice/DeviceItem/AddWalletButton.tsx
+++ b/packages/suite/src/views/suite/SwitchDevice/DeviceItem/AddWalletButton.tsx
@@ -8,6 +8,8 @@ import { useDispatch, useSelector } from 'src/hooks/suite';
import { selectIsDeviceOrUiLocked } from 'src/reducers/suite/suiteReducer';
import { AcquiredDevice, ForegroundAppProps, TrezorDevice } from 'src/types/suite';
+import { usePassphraseModalContext } from '../../../../components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext';
+
interface AddWalletButtonProps {
device: TrezorDevice;
instances: AcquiredDevice[];
@@ -26,9 +28,28 @@ export const AddWalletButton = ({ device, instances, onCancel }: AddWalletButton
// and there is no point in useDevice returning the same device object we would have passed
const isLocked = !device || !device.connected || isDeviceOrUiLocked;
- const onAddWallet = ({ walletType }: { walletType: WalletType }) => {
- dispatch(addWalletThunk({ walletType, device }));
- onCancel(false);
+ const { setPassphraseState, passphraseState, setDevice, setIsExisting } =
+ usePassphraseModalContext();
+ console.log('___!!!', passphraseState);
+ const onAddWallet = ({
+ walletType,
+ isExisting,
+ }: {
+ walletType: WalletType;
+ isExisting: boolean;
+ }) => {
+ if (!isExisting) {
+ setPassphraseState('exists-best-practices');
+ setIsExisting(false);
+ setDevice(device);
+ } else {
+ setPassphraseState('exists-enter-passphrase');
+ setIsExisting(true);
+ setDevice(device);
+
+ dispatch(addWalletThunk({ walletType, device }));
+ onCancel(false);
+ }
};
return (
@@ -45,26 +66,47 @@ export const AddWalletButton = ({ device, instances, onCancel }: AddWalletButton
isFullWidth
icon="plus"
isDisabled={isLocked}
- onClick={() => onAddWallet({ walletType: WalletType.STANDARD })}
+ onClick={() =>
+ onAddWallet({ walletType: WalletType.STANDARD, isExisting: false })
+ }
>
)}
{isPassphraseProtectionEnabled && (
- onAddWallet({ walletType: WalletType.PASSPHRASE })}
- >
-
- {' '}
- {!isLocked && }
-
-
+
+
+ onAddWallet({
+ walletType: WalletType.PASSPHRASE,
+ isExisting: false,
+ })
+ }
+ >
+ New passphrase
+
+
+ onAddWallet({ walletType: WalletType.PASSPHRASE, isExisting: true })
+ }
+ >
+
+ Open previously used
+ {!isLocked && }
+
+
+
)}
diff --git a/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx b/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx
index 59d9a9b5e3c..93f5bac5b58 100644
--- a/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx
+++ b/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx
@@ -1,18 +1,25 @@
import * as deviceUtils from '@suite-common/suite-utils';
import { selectDevices, selectSelectedDevice } from '@suite-common/wallet-core';
+import { WalletType } from '@suite-common/wallet-types';
import { Column } from '@trezor/components';
+import TrezorConnect from '@trezor/connect';
import { spacings } from '@trezor/theme';
-import { useSelector } from 'src/hooks/suite';
+import { useDispatch, useSelector } from 'src/hooks/suite';
import { ForegroundAppProps } from 'src/types/suite';
import { DeviceItem } from './DeviceItem/DeviceItem';
import { SwitchDeviceModal } from './SwitchDeviceModal';
+import { addWalletThunk } from '../../../actions/wallet/addWalletThunk';
+import { usePassphraseModalContext } from '../../../components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext';
+import { PassphraseWalletBestPractices } from '../../../components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices';
export const SwitchDevice = ({ onCancel }: ForegroundAppProps) => {
const selectedDevice = useSelector(selectSelectedDevice);
const devices = useSelector(selectDevices);
+ const { passphraseState, device, setPassphraseState, isExisting } = usePassphraseModalContext();
+ const dispatch = useDispatch();
// exclude selectedDevice from list, because other devices could have a higher priority
// and we want to have selectedDevice on top
const sortedDevices = deviceUtils
@@ -24,6 +31,31 @@ export const SwitchDevice = ({ onCancel }: ForegroundAppProps) => {
sortedDevices.unshift(selectedDevice);
}
+ // TODO: This is far from perfect. It should be on the same place with `packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsNotExistFlow.tsx` but app is divided
+ if (selectedDevice && !isExisting && passphraseState === 'not-exist-best-practices') {
+ return (
+ {
+ TrezorConnect.cancel('auth-confirm-cancel');
+ }}
+ onNext={() => {
+ dispatch(
+ addWalletThunk({
+ walletType: WalletType.PASSPHRASE,
+ device: selectedDevice,
+ }),
+ );
+ onCancel(false);
+ setPassphraseState('not-exist-enter-passphrase');
+ }}
+ onBack={() => {
+ setPassphraseState('initial');
+ }}
+ device={device}
+ />
+ );
+ }
+
return (