Skip to content

Commit

Permalink
[LW-10194] unify codebase of the onboarding and multi-wallet flows (#…
Browse files Browse the repository at this point in the history
…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 <[email protected]>
  • Loading branch information
szymonmaslowski and greatertomi authored May 20, 2024
1 parent 90d84e9 commit b613cde
Show file tree
Hide file tree
Showing 33 changed files with 520 additions and 513 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const postHogMultiWalletActions: PostHogMultiWalletActionsType = {
WALLET_ADDED: PostHogAction.MultiWalletRestoreAdded,
HD_WALLET: PostHogAction.MultiWalletRestoreHdWallet
},
hw: {
hardware: {
SETUP_OPTION_CLICK: PostHogAction.MultiWalletHWClick,
CONNECT_HW_VIEW: PostHogAction.MultiWalletHWConnectView,
HW_POPUP_CONNECT_CLICK: PostHogAction.MultiWalletHWPopupConnectClick,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export enum TxCreationType {
}

export type OnboardingFlows = 'create' | 'restore' | 'hw' | 'forgot_password' | 'onboarding';
export type MultiWalletFlows = 'create' | 'restore' | 'hw';
export type MultiWalletFlows = 'create' | 'restore' | 'hardware';
export type PostHogActionsKeys =
| 'SETUP_OPTION_CLICK'
| 'ANALYTICS_AGREE_CLICK'
Expand All @@ -64,10 +64,9 @@ export type PostHogActionsKeys =
| 'RECOVERY_PHRASE_PASTE_READ_MORE_CLICK'
| 'WALLET_ADDED'
| 'HD_WALLET';
export type PostHogOnboardingActionsValueType = Partial<Record<PostHogActionsKeys, PostHogAction>>;
export type PostHogOnboardingActionsType = Record<OnboardingFlows, PostHogOnboardingActionsValueType>;
export type PostHogMultiWalletActionsValueType = Partial<Record<PostHogActionsKeys, PostHogAction>>;
export type PostHogMultiWalletActionsType = Record<MultiWalletFlows, PostHogMultiWalletActionsValueType>;
export type PostHogActions = Partial<Record<PostHogActionsKeys, PostHogAction>>;
export type PostHogOnboardingActionsType = Record<OnboardingFlows, PostHogActions>;
export type PostHogMultiWalletActionsType = Record<MultiWalletFlows, PostHogActions>;
export type PostHogPersonProperties = {
$set: {
user_tracking_type: UserTrackingType;
Expand Down
19 changes: 3 additions & 16 deletions apps/browser-extension-wallet/src/routes/wallet-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,9 @@ export const walletRoutePaths = {
},
newWallet: {
root: '/new-wallet',
create: {
root: '/new-wallet/create',
setup: '/new-wallet/create/setup',
recoveryPhrase: '/new-wallet/create/recovery-phrase'
},
hardware: {
root: '/new-wallet/hardware',
connect: '/new-wallet/hardware/connect',
setup: '/new-wallet/hardware/setup',
create: '/new-wallet/hardware/create'
},
restore: {
root: '/new-wallet/restore',
setup: '/new-wallet/restore/setup',
enterRecoveryPhrase: '/new-wallet/restore/enter-recovery-phrase'
}
create: '/new-wallet/create',
hardware: '/new-wallet/hardware',
restore: '/new-wallet/restore'
},
sharedWallet: {
root: '/add-shared-wallet'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ export const Home = (): JSX.Element => {
<WalletSetupOptionsStep
onNewWalletRequest={() => {
void analytics.sendEventToPostHog(postHogMultiWalletActions.create.SETUP_OPTION_CLICK);
history.push(walletRoutePaths.newWallet.create.root);
history.push(walletRoutePaths.newWallet.create);
}}
onHardwareWalletRequest={() => {
void analytics.sendEventToPostHog(postHogMultiWalletActions.hw.SETUP_OPTION_CLICK);
history.push(walletRoutePaths.newWallet.hardware.root);
void analytics.sendEventToPostHog(postHogMultiWalletActions.hardware.SETUP_OPTION_CLICK);
history.push(walletRoutePaths.newWallet.hardware);
}}
onRestoreWalletRequest={() => {
void analytics.sendEventToPostHog(postHogMultiWalletActions.restore.SETUP_OPTION_CLICK);
history.push(walletRoutePaths.newWallet.restore.root);
history.push(walletRoutePaths.newWallet.restore);
}}
translations={walletSetupOptionsStepTranslations}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,97 +1,43 @@
/* eslint-disable unicorn/no-null */
/* eslint-disable react/no-multi-comp */
import React from 'react';
import { Route, Switch, useHistory, useRouteMatch } from 'react-router-dom';
import { Modal } from 'antd';

import styles from './MultiWallet.module.scss';

import { Home } from './components/Home';

import {
WalletSetupConfirmationDialogProvider,
WalletSetupFlow,
WalletSetupFlowProvider,
useWalletSetupConfirmationDialog
} from '@lace/core';
import { CreateWallet } from './create-wallet';
import { HardwareWallet } from './hardware-wallet';
import { RestoreWallet } from './restore-wallet';
import { walletRoutePaths } from '@routes';
import { Subject } from 'rxjs';
import { Wallet } from '@lace/cardano';
import { NavigationButton } from '@lace/common';
import { WalletSetupConfirmationDialogProvider, WalletSetupFlow, WalletSetupFlowProvider } from '@lace/core';
import { useBackgroundPage } from '@providers/BackgroundPageProvider';
import { walletRoutePaths } from '@routes';
import { Modal } from 'antd';
import React from 'react';
import { useHistory } from 'react-router-dom';
import styles from './MultiWallet.module.scss';
import { WalletOnboardingFlows } from './WalletOnboardingFlows';
import { postHogMultiWalletActions } from '@providers/AnalyticsProvider/analyticsTracker';
import { Home } from './Home';

const { newWallet } = walletRoutePaths;

interface Props {
shouldShowConfirmationDialog$: Subject<boolean>;
}

export const SetupHardwareWallet = ({ shouldShowConfirmationDialog$ }: Props): JSX.Element => (
<HardwareWallet
providers={{
shouldShowConfirmationDialog$
}}
/>
);

export const SetupCreateWallet = ({ shouldShowConfirmationDialog$ }: Props): JSX.Element => (
<CreateWallet
providers={{
generateMnemonicWords: Wallet.KeyManagement.util.generateMnemonicWords,
shouldShowConfirmationDialog$
}}
/>
);

export const SetupRestoreWallet = ({ shouldShowConfirmationDialog$ }: Props): JSX.Element => (
<RestoreWallet
providers={{
shouldShowConfirmationDialog$
}}
/>
);

const Component = (): JSX.Element => {
const { path } = useRouteMatch();
export const MultiWallet = (): JSX.Element => {
const history = useHistory();
const { page, setBackgroundPage } = useBackgroundPage();
const { isDialogOpen, withConfirmationDialog, shouldShowDialog$ } = useWalletSetupConfirmationDialog();
const closeWalletCreation = withConfirmationDialog(() => {
setBackgroundPage();
history.push(page);
});

return (
<WalletSetupFlowProvider flow={WalletSetupFlow.ADD_WALLET}>
<Modal centered closable={false} footer={null} open={!isDialogOpen} width="100%" className={styles.modal}>
<div className={styles.closeButton}>
<NavigationButton icon="cross" onClick={closeWalletCreation} />
</div>
<Switch>
<Route
path={newWallet.create.root}
render={() => <SetupCreateWallet shouldShowConfirmationDialog$={shouldShowDialog$} />}
/>
<Route
path={newWallet.hardware.root}
render={() => <SetupHardwareWallet shouldShowConfirmationDialog$={shouldShowDialog$} />}
/>
<Route
path={newWallet.restore.root}
render={() => <SetupRestoreWallet shouldShowConfirmationDialog$={shouldShowDialog$} />}
/>
<Route exact path={`${path}/`} component={Home} />
</Switch>
</Modal>
<WalletSetupConfirmationDialogProvider>
{({ isDialogOpen, withConfirmationDialog, shouldShowDialog$ }) => (
<Modal centered closable={false} footer={null} open={!isDialogOpen} width="100%" className={styles.modal}>
<div className={styles.closeButton}>
<NavigationButton
icon="cross"
onClick={withConfirmationDialog(() => {
setBackgroundPage();
history.push(page);
})}
/>
</div>
<WalletOnboardingFlows
postHogActions={postHogMultiWalletActions}
renderHome={() => <Home />}
setFormDirty={(dirty) => shouldShowDialog$.next(dirty)}
urlPath={walletRoutePaths.newWallet}
/>
</Modal>
)}
</WalletSetupConfirmationDialogProvider>
</WalletSetupFlowProvider>
);
};

export const MultiWallet = (): JSX.Element => (
<WalletSetupConfirmationDialogProvider>
<Component />
</WalletSetupConfirmationDialogProvider>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useKeyboardShortcut } from '@lace/common';
import { Redirect, Route, Switch, useRouteMatch } from 'react-router-dom';
import { CreateWallet } from './create-wallet';
import { HardwareWallet } from './hardware-wallet';
import { RestoreWallet } from './restore-wallet';
import React, { ReactNode, VFC } from 'react';
import { Flows, WalletOnboardingPostHogActions, SetFormDirty } from './types';
import { WalletOnboardingProvider } from './walletOnboardingContext';

type WalletOnboardingProps = {
aliasEventRequired?: boolean;
flowsEnabled?: boolean;
forgotPasswordFlowActive?: boolean;
postHogActions: WalletOnboardingPostHogActions;
renderHome: () => ReactNode;
setFormDirty?: SetFormDirty;
urlPath: Record<Flows, string>;
};

export const WalletOnboardingFlows: VFC<WalletOnboardingProps> = ({
aliasEventRequired = false,
flowsEnabled = true,
forgotPasswordFlowActive = false,
postHogActions,
renderHome,
setFormDirty = () => void 0,
urlPath
}) => {
useKeyboardShortcut(['Enter'], () => {
const nextBnt: HTMLButtonElement = document.querySelector('[data-testid="wallet-setup-step-btn-next"]');
const confirmGoBack: HTMLButtonElement = document.querySelector('[data-testid="delete-address-modal-confirm"]');

if (confirmGoBack) {
confirmGoBack.click();
} else if (nextBnt && !nextBnt.getAttribute('disabled')) {
nextBnt.click();
}
});

const { path } = useRouteMatch();
return (
<WalletOnboardingProvider value={{ aliasEventRequired, forgotPasswordFlowActive, postHogActions, setFormDirty }}>
<Switch>
<Route exact path={`${path}/`} render={renderHome} />
{flowsEnabled && (
<>
<Route path={urlPath.create} component={CreateWallet} />
<Route path={urlPath.hardware} component={HardwareWallet} />
<Route path={urlPath.restore} component={RestoreWallet} />
</>
)}
{!flowsEnabled && <Redirect to={`${path}/`} />}
</Switch>
</WalletOnboardingProvider>
);
};
Loading

0 comments on commit b613cde

Please sign in to comment.