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

Reduce wallet page routing complexity #13068

Merged
merged 6 commits into from
May 20, 2022
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
36 changes: 36 additions & 0 deletions components/brave_wallet_ui/common/async/__mocks__/lib.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/.

import { mockBasicAttentionToken, mockEthToken } from '../../../stories/mock-data/mock-asset-options'
import { BraveWallet, GetChecksumEthAddressReturnInfo, GetEthAddrReturnInfo } from '../../../constants/types'
import { HardwareWalletConnectOpts } from '../../../components/desktop/popup-modals/add-account-modal/hardware-wallet-connect/types'

let mockedAllowance = '1000000000000000000' // 1 unit
let mockedIsSwapSupported = true
Expand Down Expand Up @@ -74,3 +80,33 @@ export const findUnstoppableDomainAddress = async (address: string) => {
export const getChecksumEthAddress = async () => {
return {} as GetChecksumEthAddressReturnInfo
}

export const isStrongPassword = (value: string) => {
return (
(value.length > 7) && // is at least 7 characters
/[-’/`~!#*$@_%+=.,^&(){}[\]|;:”<>?\\]/g.test(value) && // contains a special character
value.toLowerCase() !== value && // contains an uppercase character
/\d/.test(value) // contains a number
)
}

export const onConnectHardwareWallet = (opts: HardwareWalletConnectOpts): Promise<BraveWallet.HardwareWalletAccount[]> => {
const makeDerivationPath = (index: number): string => `m/44'/60'/${index}'/0/0`

return new Promise((resolve) => {
resolve(Array.from({ length: opts.stopIndex - opts.startIndex }, (_, i) => ({
address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
derivationPath: makeDerivationPath(i + opts.startIndex),
name: 'Ledger 1',
hardwareVendor: 'Ledger',
deviceId: 'device1',
coin: BraveWallet.CoinType.ETH
})))
})
}

export const getBalance = (): Promise<string> => {
return new Promise(async (resolve) => {
resolve('0')
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/.

import * as React from 'react'
import { useLib } from './useLib'

export const usePasswordStrength = () => {
// custom hooks
const { isStrongPassword: checkIsStrongPassword } = useLib()

// state
const [password, setPassword] = React.useState<string>('')
const [confirmedPassword, setConfirmedPassword] = React.useState<string>('')
const [isStrongPassword, setIsStrongPassword] = React.useState<boolean>(false)

const onPasswordChanged = React.useCallback(async (value: string) => {
setPassword(value)
const isStrong = await checkIsStrongPassword(value)
setIsStrongPassword(isStrong)
}, [])

const hasPasswordError = React.useMemo(() => {
if (password === '') {
return false
}
return !isStrongPassword
}, [password, isStrongPassword])

const hasConfirmedPasswordError = React.useMemo(() => {
if (confirmedPassword === '') {
return false
} else {
return confirmedPassword !== password
}
}, [confirmedPassword, password])

const isValid = !(
hasConfirmedPasswordError ||
hasPasswordError ||
password === '' ||
confirmedPassword === ''
)

return {
confirmedPassword,
password,
onPasswordChanged,
setConfirmedPassword,
isStrongPassword,
isValid,
hasConfirmedPasswordError,
hasPasswordError,
checkIsStrongPassword
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const defaultState: WalletState = {
isEip1559: true
}
}
} as BraveWallet.NetworkInfo,
},
accounts: [],
userVisibleTokensInfo: [],
transactions: {},
Expand Down Expand Up @@ -213,7 +213,7 @@ export const createWalletReducer = (initialState: WalletState) => {

let accounts: WalletAccountType[] = [...state.accounts]
accounts.forEach((account, accountIndex) => {
payload.balances[accountIndex].forEach((info, tokenIndex) => {
payload.balances[accountIndex]?.forEach((info, tokenIndex) => {
if (info.error === BraveWallet.ProviderError.kSuccess) {
const contractAddress = visibleTokens[tokenIndex].contractAddress.toLowerCase()
accounts[accountIndex].tokenBalanceRegistry[contractAddress] = Amount.normalize(info.balance)
Expand Down
12 changes: 9 additions & 3 deletions components/brave_wallet_ui/components/desktop/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/.

import SideNavButton from './side-nav-button'
import SideNav from './side-nav'
import TopTabNavButton from './top-tab-nav-button'
Expand All @@ -15,7 +20,7 @@ import LockScreen from './lock-screen'
import WalletMorePopup from './wallet-more-popup'
import WalletBanner from './wallet-banner'
import PopupModal from './popup-modals'
import AddAccountModal from './popup-modals/add-account-modal'
import { AddAccountModal } from './popup-modals/add-account-modal'
import AccountSettingsModal from './popup-modals/account-settings-modal'
import EditVisibleAssetsModal from './popup-modals/edit-visible-assets-modal'
import AssetWatchlistItem from './asset-watchlist-item'
Expand All @@ -24,7 +29,7 @@ import TransactionPopup from './transaction-popup'
import SwapTooltip from './swap-tooltip'
import WithHideBalancePlaceholder from './with-hide-balance-placeholder'
import NetworkFilterSelector from './network-filter-selector'
import { CryptoView, PortfolioView } from './views'
import { CryptoView, PortfolioAsset, PortfolioOverview } from './views'
import {
OnboardingWelcome,
OnboardingBackup,
Expand All @@ -49,7 +54,8 @@ export {
PortfolioTransactionItem,
AddButton,
CryptoView,
PortfolioView,
PortfolioAsset,
PortfolioOverview,
OnboardingWelcome,
OnboardingBackup,
OnboardingRecovery,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/.

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

// types
import { 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 = () => {
return (
<Switch>

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

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

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

<Redirect to={WalletRoutes.CreateAccountModalStart} />

</Switch>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/.

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

// utils
import { getLocale } from '$web-common/locale'

// options
import { CreateAccountOptions } from '../../../../options/create-account-options'

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

// actions
import { WalletPageActions } from '../../../../page/actions'

// components
import { DividerLine } from '../../../extension'
import PopupModal from '..'
import { HardwareWalletConnect } from './hardware-wallet-connect'
import { SelectAccountType } from './select-account-type/select-account-type'

// style
import {
StyledWrapper
} from './style'

interface Params {
accountTypeName: string
}

export const AddHardwareAccountModal = () => {
// routing
const history = useHistory()
const { accountTypeName } = useParams<Params>()

// redux
const dispatch = useDispatch()
const isFilecoinEnabled = useSelector(({ wallet }: { wallet: WalletState }) => wallet.isFilecoinEnabled)
const isSolanaEnabled = useSelector(({ wallet }: { wallet: WalletState }) => wallet.isSolanaEnabled)
josheleonard marked this conversation as resolved.
Show resolved Hide resolved

// memos
const createAccountOptions = React.useMemo(
() => CreateAccountOptions(isFilecoinEnabled, isSolanaEnabled),
[isFilecoinEnabled, isSolanaEnabled]
)

const selectedAccountType: CreateAccountOptionsType | undefined = React.useMemo(() => {
return createAccountOptions.find((option) => {
return option.name.toLowerCase() === accountTypeName?.toLowerCase()
})
}, [createAccountOptions, accountTypeName])

// methods
const setImportError = React.useCallback((hasError: boolean) => {
dispatch(WalletPageActions.setImportAccountError(hasError))
}, [])

const closeModal = React.useCallback(() => {
setImportError(false)
history.push(WalletRoutes.Accounts)
}, [])

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

// render
return (
<PopupModal
title={getLocale('braveWalletAddAccountImportHardware')}
onClose={closeModal}
>

<DividerLine />

{selectedAccountType &&
<StyledWrapper>
<HardwareWalletConnect
selectedAccountType={selectedAccountType}
onSuccess={closeModal}
/>
</StyledWrapper>
}

{!selectedAccountType &&
<SelectAccountType
onSelectAccountType={onSelectAccountType}
buttonText={getLocale('braveWalletAddAccountConnect')}
/>
}
</PopupModal>
)
}

export default AddHardwareAccountModal
Loading