Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wallet): Add onboarding for hardware wallets #17637

Merged
merged 4 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions components/brave_wallet/browser/brave_wallet_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ constexpr webui::LocalizedString kLocalizedStrings[] = {
IDS_BRAVE_WALLET_WELCOME_RESTORE_BUTTON},
{"braveWalletImportExistingWallet",
IDS_BRAVE_WALLET_IMPORT_EXISTING_WALLET},
{"braveWalletConnectHardwareWallet",
IDS_BRAVE_WALLET_IMPORT_CONNECT_HARDWARE_WALLET},
{"braveWalletWelcomeDividerText", IDS_BRAVE_WALLET_WELCOME_DIVIDER_TEXT},
{"braveWalletBackupIntroTitle", IDS_BRAVE_WALLET_BACKUP_INTRO_TITLE},
{"braveWalletBackupIntroDescription",
IDS_BRAVE_WALLET_BACKUP_INTRO_DESCRIPTION},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,32 @@
// you can obtain one at https://mozilla.org/MPL/2.0/.

import * as React from 'react'
import { Redirect, Route, Switch } from 'react-router'
import { Redirect, Route, Switch, useHistory } from 'react-router'

// types
import { WalletRoutes } from '../../../../constants/types'
import { CreateAccountOptionsType, WalletRoutes } from '../../../../constants/types'

// components
import { AddHardwareAccountModal } from './add-hardware-account-modal'
import { ImportAccountModal } from './add-imported-account-modal'
import { CreateAccountModal } from './create-account-modal'

export const AddAccountModal = () => {
// routing
const history = useHistory()

// methods
const onSelectAccountType = React.useCallback((accountType: CreateAccountOptionsType) => () => {
history.push(WalletRoutes.AddHardwareAccountModal.replace(':accountTypeName?', accountType.name.toLowerCase()))
}, [])

return (
<Switch>

<Route path={WalletRoutes.AddHardwareAccountModal} exact>
<AddHardwareAccountModal />
<AddHardwareAccountModal
onSelectAccountType={onSelectAccountType}
/>
</Route>

<Route path={WalletRoutes.ImportAccountModal} exact>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ interface Params {
accountTypeName: string
}

export const AddHardwareAccountModal = () => {
interface Props {
onSelectAccountType: (accountType: CreateAccountOptionsType) => () => void
}

export const AddHardwareAccountModal = ({ onSelectAccountType }: Props) => {
// routing
const history = useHistory()
const { accountTypeName } = useParams<Params>()
Expand Down Expand Up @@ -71,10 +75,6 @@ export const AddHardwareAccountModal = () => {
history.push(WalletRoutes.Accounts)
}, [setImportError])

const onSelectAccountType = React.useCallback((accountType: CreateAccountOptionsType) => () => {
history.push(WalletRoutes.AddHardwareAccountModal.replace(':accountTypeName?', accountType.name.toLowerCase()))
}, [])

// render
return (
<PopupModal
Expand Down
6 changes: 6 additions & 0 deletions components/brave_wallet_ui/constants/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,12 @@ export enum WalletRoutes {
OnboardingImportCryptoWallets = '/crypto/onboarding/import-legacy-wallet',
OnboardingImportCryptoWalletsSeed = '/crypto/onboarding/import-legacy-seed',

// onboarding (connect hardware wallet)
OnboardingConnectHarwareWalletCreatePassword = '/crypto/onboarding/connect-hardware-wallet/create-password',
OnboardingConnectHardwareWalletStart = '/crypto/onboarding/connect-hardware-wallet',
OnboardingConnectHardwareWallet = '/crypto/onboarding/connect-hardware-wallet/:accountTypeName?',


// onboarding complete
OnboardingComplete = '/crypto/onboarding/complete',

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import * as React from 'react'

// routes
// types
import { WalletRoutes } from '../../../../../constants/types'

// components
Expand All @@ -32,13 +32,31 @@ const NEW_WALLET_STEPS: OnboardingNewWalletSteps[] = [
WalletRoutes.OnboardingComplete
]

interface OnboardingNewWalletStepsNavigationProps extends Omit<StepsNavigationProps<OnboardingNewWalletSteps>, 'steps'> {}
///
// Connect Hardware Steps
//
type OnboardingConnectHardwareWalletSteps =
| WalletRoutes.OnboardingWelcome
| WalletRoutes.OnboardingConnectHarwareWalletCreatePassword
| WalletRoutes.OnboardingComplete

const CONNECT_HARDWARE_WALLET_STEPS: OnboardingConnectHardwareWalletSteps[] = [
WalletRoutes.OnboardingWelcome,
WalletRoutes.OnboardingConnectHarwareWalletCreatePassword,
WalletRoutes.OnboardingComplete
]

interface OnboardingNewWalletStepsNavigationProps extends Omit<StepsNavigationProps<OnboardingNewWalletSteps>, 'steps'> {
isHardwareOnboarding?: boolean
}

export const OnboardingNewWalletStepsNavigation = (
props: OnboardingNewWalletStepsNavigationProps
) => {
const { isHardwareOnboarding } = props

return <StepsNavigation
{...props}
steps={NEW_WALLET_STEPS}
steps={isHardwareOnboarding ? CONNECT_HARDWARE_WALLET_STEPS : NEW_WALLET_STEPS}
/>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import * as React from 'react'
import { useHistory } from 'react-router'

// types
import { CreateAccountOptionsType, WalletRoutes } from '../../../../constants/types'

// components
import { WalletPageLayout } from "../../../../components/desktop"
import AddHardwareAccountModal from '../../../../components/desktop/popup-modals/add-account-modal/add-hardware-account-modal'

// styles
import { OnboardingWrapper } from "../onboarding.style"

export const OnboardingConnectHardwareWallet = () => {
// routing
const history = useHistory()

// methods
const onSelectAccountType = React.useCallback((accountType: CreateAccountOptionsType) => () => {
history.push(WalletRoutes.OnboardingConnectHardwareWallet.replace(':accountTypeName?', accountType.name.toLowerCase()))
}, [])

return (
<WalletPageLayout>
<OnboardingWrapper>
<AddHardwareAccountModal onSelectAccountType={onSelectAccountType} />
</OnboardingWrapper>
</WalletPageLayout>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// you can obtain one at https://mozilla.org/MPL/2.0/.

import * as React from 'react'
import { useHistory } from 'react-router'
import { useDispatch, useSelector } from 'react-redux'

// utils
Expand Down Expand Up @@ -33,9 +32,13 @@ import {
TitleAndDescriptionContainer
} from '../onboarding.style'

export const OnboardingCreatePassword = () => {
// routing
const history = useHistory()
interface OnboardingCreatePasswordProps {
isHardwareOnboarding?: boolean
onWalletCreated: () => void
}

export const OnboardingCreatePassword = (props: OnboardingCreatePasswordProps) => {
const { isHardwareOnboarding, onWalletCreated } = props

// redux
const dispatch = useDispatch()
Expand Down Expand Up @@ -64,9 +67,9 @@ export const OnboardingCreatePassword = () => {
React.useEffect(() => {
if (isWalletCreated) {
braveWalletP3A.reportOnboardingAction(OnboardingAction.CREATED_WALLET)
history.push(WalletRoutes.OnboardingExplainRecoveryPhrase)
onWalletCreated()
}
}, [isWalletCreated])
}, [isWalletCreated, onWalletCreated])

// render
return (
Expand All @@ -77,6 +80,7 @@ export const OnboardingCreatePassword = () => {
<OnboardingNewWalletStepsNavigation
goBackUrl={WalletRoutes.OnboardingWelcome}
currentStep={WalletRoutes.OnboardingCreatePassword}
isHardwareOnboarding={isHardwareOnboarding}
preventSkipAhead
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,14 @@ import { CheckboxText } from './disclosures.style'

export type OnboardingDisclosuresNextSteps =
| WalletRoutes.OnboardingCreatePassword
| WalletRoutes.OnboardingConnectHarwareWalletCreatePassword
| WalletRoutes.OnboardingImportOrRestore
| WalletRoutes.OnboardingConnectHardwareWalletStart

interface Props {
nextStep: OnboardingDisclosuresNextSteps
onBack?: () => void
isHardwareOnboarding?: boolean
}

const TermsOfUseText: React.FC<{}> = () => {
Expand Down Expand Up @@ -100,6 +103,7 @@ export const OnboardingDisclosures = ({ nextStep, onBack }: Props) => {
<OnboardingNewWalletStepsNavigation
goBack={onBack}
currentStep={WalletRoutes.OnboardingWelcome}
isHardwareOnboarding={nextStep === WalletRoutes.OnboardingConnectHarwareWalletCreatePassword}
preventSkipAhead
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { useSelector } from 'react-redux'
import {
Redirect,
Route,
Switch
Switch,
useHistory
} from 'react-router'

// components
Expand All @@ -23,11 +24,24 @@ import { OnboardingRestoreFromRecoveryPhrase } from './restore-from-recovery-phr
// types
import { PageState, WalletRoutes, WalletState } from '../../../constants/types'
import { OnboardingSuccess } from './onboarding-success/onboarding-success'
import { OnboardingConnectHardwareWallet } from './connect-hardware/onboarding-connect-hardware-wallet'

export const OnboardingRoutes = () => {
// redux
const isWalletCreated = useSelector(({ wallet }: { wallet: WalletState }) => wallet.isWalletCreated)
const termsAcknowledged = useSelector(({ page }: { page: PageState }) => page.walletTermsAcknowledged)
// routing
const history = useHistory()

// redux
const isWalletCreated = useSelector(({ wallet }: { wallet: WalletState }) => wallet.isWalletCreated)
const termsAcknowledged = useSelector(({ page }: { page: PageState }) => page.walletTermsAcknowledged)

// methods
const goToConnectHardware = React.useCallback(() => {
history.push(WalletRoutes.OnboardingConnectHardwareWalletStart)
}, [])

const goToExplainRecoveryPhrase = React.useCallback(() => {
history.push(WalletRoutes.OnboardingExplainRecoveryPhrase)
}, [])

// render
return (
Expand All @@ -48,11 +62,21 @@ export const OnboardingRoutes = () => {
{(!termsAcknowledged && !isWalletCreated) &&
<Redirect to={WalletRoutes.OnboardingWelcome} />
}

<Route path={WalletRoutes.OnboardingCreatePassword} exact>
<OnboardingCreatePassword />
<OnboardingCreatePassword
onWalletCreated={goToExplainRecoveryPhrase}
/>
</Route>

<Route path={WalletRoutes.OnboardingConnectHarwareWalletCreatePassword} exact>
<OnboardingCreatePassword
isHardwareOnboarding={true}
onWalletCreated={goToConnectHardware}
/>
</Route>


{!isWalletCreated &&
<Route path={WalletRoutes.OnboardingImportOrRestore} exact>
<OnboardingImportOrRestoreWallet />
Expand Down Expand Up @@ -104,6 +128,14 @@ export const OnboardingRoutes = () => {
</Route>
}

<Route path={WalletRoutes.OnboardingConnectHardwareWalletStart} exact>
<OnboardingConnectHardwareWallet />
</Route>

<Route path={WalletRoutes.OnboardingConnectHardwareWallet} exact>
<OnboardingConnectHardwareWallet />
</Route>

{!isWalletCreated && <Redirect to={WalletRoutes.OnboardingWelcome} />}

<Route path={WalletRoutes.OnboardingExplainRecoveryPhrase} exact>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,22 @@ export const BlockQuoteTextContainer = styled(Column)`
align-items: flex-start;
gap: 12px;
`

export const SubDivider = styled.div`
width: 234px;
height: 1px;
background-color: ${(p) => p.theme.color.divider01};
margin-bottom: 33px;
margin-top: 33px;
`

export const SubDividerText = styled.div`
font-family: 'Poppins';
font-style: normal;
font-weight: 400;
font-size: 12px;
line-height: 18px;
color: ${(p) => p.theme.color.text02};
padding-left: 24px;
padding-right: 24px;
`
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ import {
import { OnboardingAction, PageState, WalletRoutes } from '../../../../constants/types'

// styles
import { VerticalSpace, WalletWelcomeGraphic } from '../../../../components/shared/style'
import { Row, VerticalSpace, WalletWelcomeGraphic } from '../../../../components/shared/style'
import { OnboardingWrapper } from '../onboarding.style'
import {
Title,
ButtonContainer,
LearnMoreLink,
BlockQuote,
BlockQuoteTextContainer,
VerticalRule
VerticalRule,
SubDivider,
SubDividerText
} from './onboarding-welcome.style'

export const OnboardingWelcome = () => {
Expand All @@ -46,6 +48,7 @@ export const OnboardingWelcome = () => {

// methods
const hideDisclosures = React.useCallback(() => setNextStep(undefined), [])

const showNewWalletDisclosures = React.useCallback(
() => setNextStep(WalletRoutes.OnboardingCreatePassword),
[]
Expand All @@ -56,6 +59,10 @@ export const OnboardingWelcome = () => {
[]
)

const showConnectHardwareDisclosures = React.useCallback(() => {
setNextStep(WalletRoutes.OnboardingConnectHarwareWalletCreatePassword)
}, [])

// custom hooks
const { braveWalletP3A } = useApiProxy()

Expand Down Expand Up @@ -117,6 +124,20 @@ export const OnboardingWelcome = () => {

</ButtonContainer>

<Row>
<SubDivider />
<SubDividerText>{getLocale('braveWalletWelcomeDividerText')}</SubDividerText>
<SubDivider />
</Row>

<NavButton
buttonType='primary'
text={getLocale('braveWalletConnectHardwareWallet')}
onSubmit={showConnectHardwareDisclosures}
maxHeight={'48px'}
minWidth={'267px'}
/>

<VerticalSpace space='20px' />

<LearnMoreLink
Expand Down
2 changes: 2 additions & 0 deletions components/brave_wallet_ui/stories/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ provideStrings({
braveWalletLearnMoreAboutBraveWallet: 'Learn more about Brave Wallet',
braveWalletImportExistingWallet: 'Import existing wallet',
braveWalletWelcomeRestoreButton: 'Restore',
braveWalletConnectHardwareWallet: 'Connect hardware wallet',
braveWalletWelcomeDividerText: 'Or',

// Onboarding - Disclosures
braveWalletDisclosuresTitle: 'Legal stuff',
Expand Down
Loading