Skip to content

Commit b613cde

Browse files
[LW-10194] unify codebase of the onboarding and multi-wallet flows (#1140)
* feat: revamp multi wallet connect flow * fix: account selection options behind modal * feat: unify codebase of the onboarding and multi-wallet flows * fix: redirect to assets after successfull HW restoration * test: fix multi-wallet hardware flow tests * fix: handle properly the case of rejecting key export * fix: update lock file * fix: typescript error in tests * test: fix failing multi-wallet hardware flow tests * test: fix multi-wallet flows * refactor: fix code issues --------- Co-authored-by: John Oshalusi <john.oshalusi@iohk.io>
1 parent 90d84e9 commit b613cde

33 files changed

+520
-513
lines changed

apps/browser-extension-wallet/src/providers/AnalyticsProvider/analyticsTracker/events.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const postHogMultiWalletActions: PostHogMultiWalletActionsType = {
6969
WALLET_ADDED: PostHogAction.MultiWalletRestoreAdded,
7070
HD_WALLET: PostHogAction.MultiWalletRestoreHdWallet
7171
},
72-
hw: {
72+
hardware: {
7373
SETUP_OPTION_CLICK: PostHogAction.MultiWalletHWClick,
7474
CONNECT_HW_VIEW: PostHogAction.MultiWalletHWConnectView,
7575
HW_POPUP_CONNECT_CLICK: PostHogAction.MultiWalletHWPopupConnectClick,

apps/browser-extension-wallet/src/providers/AnalyticsProvider/analyticsTracker/types.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export enum TxCreationType {
3939
}
4040

4141
export type OnboardingFlows = 'create' | 'restore' | 'hw' | 'forgot_password' | 'onboarding';
42-
export type MultiWalletFlows = 'create' | 'restore' | 'hw';
42+
export type MultiWalletFlows = 'create' | 'restore' | 'hardware';
4343
export type PostHogActionsKeys =
4444
| 'SETUP_OPTION_CLICK'
4545
| 'ANALYTICS_AGREE_CLICK'
@@ -64,10 +64,9 @@ export type PostHogActionsKeys =
6464
| 'RECOVERY_PHRASE_PASTE_READ_MORE_CLICK'
6565
| 'WALLET_ADDED'
6666
| 'HD_WALLET';
67-
export type PostHogOnboardingActionsValueType = Partial<Record<PostHogActionsKeys, PostHogAction>>;
68-
export type PostHogOnboardingActionsType = Record<OnboardingFlows, PostHogOnboardingActionsValueType>;
69-
export type PostHogMultiWalletActionsValueType = Partial<Record<PostHogActionsKeys, PostHogAction>>;
70-
export type PostHogMultiWalletActionsType = Record<MultiWalletFlows, PostHogMultiWalletActionsValueType>;
67+
export type PostHogActions = Partial<Record<PostHogActionsKeys, PostHogAction>>;
68+
export type PostHogOnboardingActionsType = Record<OnboardingFlows, PostHogActions>;
69+
export type PostHogMultiWalletActionsType = Record<MultiWalletFlows, PostHogActions>;
7170
export type PostHogPersonProperties = {
7271
$set: {
7372
user_tracking_type: UserTrackingType;

apps/browser-extension-wallet/src/routes/wallet-paths.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,9 @@ export const walletRoutePaths = {
2323
},
2424
newWallet: {
2525
root: '/new-wallet',
26-
create: {
27-
root: '/new-wallet/create',
28-
setup: '/new-wallet/create/setup',
29-
recoveryPhrase: '/new-wallet/create/recovery-phrase'
30-
},
31-
hardware: {
32-
root: '/new-wallet/hardware',
33-
connect: '/new-wallet/hardware/connect',
34-
setup: '/new-wallet/hardware/setup',
35-
create: '/new-wallet/hardware/create'
36-
},
37-
restore: {
38-
root: '/new-wallet/restore',
39-
setup: '/new-wallet/restore/setup',
40-
enterRecoveryPhrase: '/new-wallet/restore/enter-recovery-phrase'
41-
}
26+
create: '/new-wallet/create',
27+
hardware: '/new-wallet/hardware',
28+
restore: '/new-wallet/restore'
4229
},
4330
sharedWallet: {
4431
root: '/add-shared-wallet'
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ export const Home = (): JSX.Element => {
3535
<WalletSetupOptionsStep
3636
onNewWalletRequest={() => {
3737
void analytics.sendEventToPostHog(postHogMultiWalletActions.create.SETUP_OPTION_CLICK);
38-
history.push(walletRoutePaths.newWallet.create.root);
38+
history.push(walletRoutePaths.newWallet.create);
3939
}}
4040
onHardwareWalletRequest={() => {
41-
void analytics.sendEventToPostHog(postHogMultiWalletActions.hw.SETUP_OPTION_CLICK);
42-
history.push(walletRoutePaths.newWallet.hardware.root);
41+
void analytics.sendEventToPostHog(postHogMultiWalletActions.hardware.SETUP_OPTION_CLICK);
42+
history.push(walletRoutePaths.newWallet.hardware);
4343
}}
4444
onRestoreWalletRequest={() => {
4545
void analytics.sendEventToPostHog(postHogMultiWalletActions.restore.SETUP_OPTION_CLICK);
46-
history.push(walletRoutePaths.newWallet.restore.root);
46+
history.push(walletRoutePaths.newWallet.restore);
4747
}}
4848
translations={walletSetupOptionsStepTranslations}
4949
/>
Lines changed: 31 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,43 @@
11
/* eslint-disable unicorn/no-null */
2-
/* eslint-disable react/no-multi-comp */
3-
import React from 'react';
4-
import { Route, Switch, useHistory, useRouteMatch } from 'react-router-dom';
5-
import { Modal } from 'antd';
6-
7-
import styles from './MultiWallet.module.scss';
8-
9-
import { Home } from './components/Home';
10-
11-
import {
12-
WalletSetupConfirmationDialogProvider,
13-
WalletSetupFlow,
14-
WalletSetupFlowProvider,
15-
useWalletSetupConfirmationDialog
16-
} from '@lace/core';
17-
import { CreateWallet } from './create-wallet';
18-
import { HardwareWallet } from './hardware-wallet';
19-
import { RestoreWallet } from './restore-wallet';
20-
import { walletRoutePaths } from '@routes';
21-
import { Subject } from 'rxjs';
22-
import { Wallet } from '@lace/cardano';
232
import { NavigationButton } from '@lace/common';
3+
import { WalletSetupConfirmationDialogProvider, WalletSetupFlow, WalletSetupFlowProvider } from '@lace/core';
244
import { useBackgroundPage } from '@providers/BackgroundPageProvider';
5+
import { walletRoutePaths } from '@routes';
6+
import { Modal } from 'antd';
7+
import React from 'react';
8+
import { useHistory } from 'react-router-dom';
9+
import styles from './MultiWallet.module.scss';
10+
import { WalletOnboardingFlows } from './WalletOnboardingFlows';
11+
import { postHogMultiWalletActions } from '@providers/AnalyticsProvider/analyticsTracker';
12+
import { Home } from './Home';
2513

26-
const { newWallet } = walletRoutePaths;
27-
28-
interface Props {
29-
shouldShowConfirmationDialog$: Subject<boolean>;
30-
}
31-
32-
export const SetupHardwareWallet = ({ shouldShowConfirmationDialog$ }: Props): JSX.Element => (
33-
<HardwareWallet
34-
providers={{
35-
shouldShowConfirmationDialog$
36-
}}
37-
/>
38-
);
39-
40-
export const SetupCreateWallet = ({ shouldShowConfirmationDialog$ }: Props): JSX.Element => (
41-
<CreateWallet
42-
providers={{
43-
generateMnemonicWords: Wallet.KeyManagement.util.generateMnemonicWords,
44-
shouldShowConfirmationDialog$
45-
}}
46-
/>
47-
);
48-
49-
export const SetupRestoreWallet = ({ shouldShowConfirmationDialog$ }: Props): JSX.Element => (
50-
<RestoreWallet
51-
providers={{
52-
shouldShowConfirmationDialog$
53-
}}
54-
/>
55-
);
56-
57-
const Component = (): JSX.Element => {
58-
const { path } = useRouteMatch();
14+
export const MultiWallet = (): JSX.Element => {
5915
const history = useHistory();
6016
const { page, setBackgroundPage } = useBackgroundPage();
61-
const { isDialogOpen, withConfirmationDialog, shouldShowDialog$ } = useWalletSetupConfirmationDialog();
62-
const closeWalletCreation = withConfirmationDialog(() => {
63-
setBackgroundPage();
64-
history.push(page);
65-
});
6617

6718
return (
6819
<WalletSetupFlowProvider flow={WalletSetupFlow.ADD_WALLET}>
69-
<Modal centered closable={false} footer={null} open={!isDialogOpen} width="100%" className={styles.modal}>
70-
<div className={styles.closeButton}>
71-
<NavigationButton icon="cross" onClick={closeWalletCreation} />
72-
</div>
73-
<Switch>
74-
<Route
75-
path={newWallet.create.root}
76-
render={() => <SetupCreateWallet shouldShowConfirmationDialog$={shouldShowDialog$} />}
77-
/>
78-
<Route
79-
path={newWallet.hardware.root}
80-
render={() => <SetupHardwareWallet shouldShowConfirmationDialog$={shouldShowDialog$} />}
81-
/>
82-
<Route
83-
path={newWallet.restore.root}
84-
render={() => <SetupRestoreWallet shouldShowConfirmationDialog$={shouldShowDialog$} />}
85-
/>
86-
<Route exact path={`${path}/`} component={Home} />
87-
</Switch>
88-
</Modal>
20+
<WalletSetupConfirmationDialogProvider>
21+
{({ isDialogOpen, withConfirmationDialog, shouldShowDialog$ }) => (
22+
<Modal centered closable={false} footer={null} open={!isDialogOpen} width="100%" className={styles.modal}>
23+
<div className={styles.closeButton}>
24+
<NavigationButton
25+
icon="cross"
26+
onClick={withConfirmationDialog(() => {
27+
setBackgroundPage();
28+
history.push(page);
29+
})}
30+
/>
31+
</div>
32+
<WalletOnboardingFlows
33+
postHogActions={postHogMultiWalletActions}
34+
renderHome={() => <Home />}
35+
setFormDirty={(dirty) => shouldShowDialog$.next(dirty)}
36+
urlPath={walletRoutePaths.newWallet}
37+
/>
38+
</Modal>
39+
)}
40+
</WalletSetupConfirmationDialogProvider>
8941
</WalletSetupFlowProvider>
9042
);
9143
};
92-
93-
export const MultiWallet = (): JSX.Element => (
94-
<WalletSetupConfirmationDialogProvider>
95-
<Component />
96-
</WalletSetupConfirmationDialogProvider>
97-
);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { useKeyboardShortcut } from '@lace/common';
2+
import { Redirect, Route, Switch, useRouteMatch } from 'react-router-dom';
3+
import { CreateWallet } from './create-wallet';
4+
import { HardwareWallet } from './hardware-wallet';
5+
import { RestoreWallet } from './restore-wallet';
6+
import React, { ReactNode, VFC } from 'react';
7+
import { Flows, WalletOnboardingPostHogActions, SetFormDirty } from './types';
8+
import { WalletOnboardingProvider } from './walletOnboardingContext';
9+
10+
type WalletOnboardingProps = {
11+
aliasEventRequired?: boolean;
12+
flowsEnabled?: boolean;
13+
forgotPasswordFlowActive?: boolean;
14+
postHogActions: WalletOnboardingPostHogActions;
15+
renderHome: () => ReactNode;
16+
setFormDirty?: SetFormDirty;
17+
urlPath: Record<Flows, string>;
18+
};
19+
20+
export const WalletOnboardingFlows: VFC<WalletOnboardingProps> = ({
21+
aliasEventRequired = false,
22+
flowsEnabled = true,
23+
forgotPasswordFlowActive = false,
24+
postHogActions,
25+
renderHome,
26+
setFormDirty = () => void 0,
27+
urlPath
28+
}) => {
29+
useKeyboardShortcut(['Enter'], () => {
30+
const nextBnt: HTMLButtonElement = document.querySelector('[data-testid="wallet-setup-step-btn-next"]');
31+
const confirmGoBack: HTMLButtonElement = document.querySelector('[data-testid="delete-address-modal-confirm"]');
32+
33+
if (confirmGoBack) {
34+
confirmGoBack.click();
35+
} else if (nextBnt && !nextBnt.getAttribute('disabled')) {
36+
nextBnt.click();
37+
}
38+
});
39+
40+
const { path } = useRouteMatch();
41+
return (
42+
<WalletOnboardingProvider value={{ aliasEventRequired, forgotPasswordFlowActive, postHogActions, setFormDirty }}>
43+
<Switch>
44+
<Route exact path={`${path}/`} render={renderHome} />
45+
{flowsEnabled && (
46+
<>
47+
<Route path={urlPath.create} component={CreateWallet} />
48+
<Route path={urlPath.hardware} component={HardwareWallet} />
49+
<Route path={urlPath.restore} component={RestoreWallet} />
50+
</>
51+
)}
52+
{!flowsEnabled && <Redirect to={`${path}/`} />}
53+
</Switch>
54+
</WalletOnboardingProvider>
55+
);
56+
};

0 commit comments

Comments
 (0)