Skip to content

Commit

Permalink
Merge branch 'web3authcoresdk' into seedless-manual-sync
Browse files Browse the repository at this point in the history
  • Loading branch information
usame-algan authored Oct 9, 2023
2 parents c8d519c + e682af6 commit c1b666a
Show file tree
Hide file tree
Showing 23 changed files with 542 additions and 285 deletions.
3 changes: 3 additions & 0 deletions public/images/common/check-filled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions public/images/logo-text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions public/images/welcome/logo-google.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions src/components/common/ConnectWallet/AccountCenter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import ChainSwitcher from '../ChainSwitcher'
import useAddressBook from '@/hooks/useAddressBook'
import { type ConnectedWallet } from '@/hooks/wallets/useOnboard'
import WalletInfo, { UNKNOWN_CHAIN_NAME } from '../WalletInfo'
import { MPCWallet } from './MPCWallet'

const AccountCenter = ({ wallet }: { wallet: ConnectedWallet }) => {
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null)
Expand Down Expand Up @@ -115,8 +114,6 @@ const AccountCenter = ({ wallet }: { wallet: ConnectedWallet }) => {
<Button onClick={handleDisconnect} variant="danger" size="small" fullWidth disableElevation>
Disconnect
</Button>

<MPCWallet />
</Paper>
</Popover>
</>
Expand Down
82 changes: 82 additions & 0 deletions src/components/common/ConnectWallet/MPCLogin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { MPCWalletState } from '@/hooks/wallets/mpc/useMPCWallet'
import { Box, Button, SvgIcon, Typography } from '@mui/material'
import { useContext, useEffect, useState } from 'react'
import { MpcWalletContext } from './MPCWalletProvider'
import { PasswordRecovery } from './PasswordRecovery'
import GoogleLogo from '@/public/images/welcome/logo-google.svg'

import css from './styles.module.css'
import useWallet from '@/hooks/wallets/useWallet'
import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/module'

const MPCLogin = ({ onLogin }: { onLogin?: () => void }) => {
const { loginPending, triggerLogin, userInfo, walletState, recoverFactorWithPassword } = useContext(MpcWalletContext)

const wallet = useWallet()

const [loginTriggered, setLoginTriggered] = useState(false)

const login = async () => {
setLoginTriggered(true)
await triggerLogin()
}

// If login was triggered through the Button we immediately continue if logged in
useEffect(() => {
if (loginTriggered && wallet && wallet.label === ONBOARD_MPC_MODULE_LABEL && onLogin) {
onLogin()
}
}, [loginTriggered, onLogin, wallet])

return (
<>
{wallet && userInfo ? (
<>
<Button
variant="outlined"
sx={{ padding: '1 2' }}
onClick={onLogin}
size="small"
disabled={loginPending}
fullWidth
>
<Box
width="100%"
justifyContent="space-between"
display="flex"
flexDirection="row"
alignItems="center"
gap={1}
>
<img
src={userInfo.profileImage}
className={css.profileImg}
alt="Profile Image"
referrerPolicy="no-referrer"
/>
<div className={css.profileData}>
<Typography variant="subtitle2" fontWeight={700}>
Continue as {userInfo.name}
</Typography>
<Typography variant="body2">{userInfo.email}</Typography>
</div>
<SvgIcon component={GoogleLogo} inheritViewBox fontSize="medium" />
</Box>
</Button>
</>
) : (
<Button variant="outlined" onClick={login} size="small" disabled={loginPending} fullWidth>
<Box display="flex" flexDirection="row" alignItems="center" gap={1}>
<SvgIcon component={GoogleLogo} inheritViewBox fontSize="medium" /> Continue with Google
</Box>
</Button>
)}

{walletState === MPCWalletState.MANUAL_RECOVERY && (
<PasswordRecovery recoverFactorWithPassword={recoverFactorWithPassword} />
)}
</>
)
}

export default MPCLogin
40 changes: 0 additions & 40 deletions src/components/common/ConnectWallet/MPCWallet.tsx

This file was deleted.

9 changes: 3 additions & 6 deletions src/components/common/ConnectWallet/MPCWalletProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useMPCWallet, MPCWalletState } from '@/hooks/wallets/mpc/useMPCWallet'
import { type UserInfo } from '@web3auth/mpc-core-kit'
import { createContext, type ReactElement } from 'react'

type MPCWalletContext = {
Expand All @@ -8,9 +9,7 @@ type MPCWalletContext = {
upsertPasswordBackup: (password: string) => Promise<void>
recoverFactorWithPassword: (password: string, storeDeviceFactor: boolean) => Promise<void>
walletState: MPCWalletState
userInfo: {
email: string | undefined
}
userInfo: UserInfo | undefined
}

export const MpcWalletContext = createContext<MPCWalletContext>({
Expand All @@ -20,9 +19,7 @@ export const MpcWalletContext = createContext<MPCWalletContext>({
resetAccount: () => Promise.resolve(),
upsertPasswordBackup: () => Promise.resolve(),
recoverFactorWithPassword: () => Promise.resolve(),
userInfo: {
email: undefined,
},
userInfo: undefined,
})

export const MpcWalletProvider = ({ children }: { children: ReactElement }) => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/common/ConnectWallet/WalletDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { ReactElement } from 'react'

import KeyholeIcon from '@/components/common/icons/KeyholeIcon'
import useConnectWallet from '@/components/common/ConnectWallet/useConnectWallet'
import { MPCWallet } from './MPCWallet'
import MPCLogin from './MPCLogin'

const WalletDetails = ({ onConnect }: { onConnect?: () => void }): ReactElement => {
const connectWallet = useConnectWallet()
Expand All @@ -23,7 +23,7 @@ const WalletDetails = ({ onConnect }: { onConnect?: () => void }): ReactElement
Connect
</Button>

<MPCWallet />
<MPCLogin />
</>
)
}
Expand Down
107 changes: 107 additions & 0 deletions src/components/common/ConnectWallet/__tests__/MPCLogin.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { act, render, waitFor } from '@/tests/test-utils'
import * as useWallet from '@/hooks/wallets/useWallet'
import * as useMPCWallet from '@/hooks/wallets/mpc/useMPCWallet'
import MPCLogin from '../MPCLogin'
import { hexZeroPad } from '@ethersproject/bytes'
import { type EIP1193Provider } from '@web3-onboard/common'
import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/module'
import { MpcWalletProvider } from '../MPCWalletProvider'

describe('MPCLogin', () => {
beforeEach(() => {
jest.resetAllMocks()
})

it('should render continue with connected account', async () => {
const mockOnLogin = jest.fn()
const walletAddress = hexZeroPad('0x1', 20)
jest.spyOn(useWallet, 'default').mockReturnValue({
address: walletAddress,
chainId: '5',
label: ONBOARD_MPC_MODULE_LABEL,
provider: {} as unknown as EIP1193Provider,
})
jest.spyOn(useMPCWallet, 'useMPCWallet').mockReturnValue({
userInfo: {
email: '[email protected]',
name: 'Test Testermann',
profileImage: 'test.png',
},
triggerLogin: jest.fn(),
walletState: useMPCWallet.MPCWalletState.READY,
} as unknown as useMPCWallet.MPCWalletHook)

const result = render(
<MpcWalletProvider>
<MPCLogin onLogin={mockOnLogin} />
</MpcWalletProvider>,
)

await waitFor(() => {
expect(result.findByText('Continue as Test Testermann')).resolves.toBeDefined()
})

// We do not automatically invoke the callback as the user did not actively connect
expect(mockOnLogin).not.toHaveBeenCalled()

const button = await result.findByRole('button')
button.click()

expect(mockOnLogin).toHaveBeenCalled()
})

it('should render google login button and invoke the callback on connection if no wallet is connected', async () => {
const mockOnLogin = jest.fn()
const walletAddress = hexZeroPad('0x1', 20)
const mockUseWallet = jest.spyOn(useWallet, 'default').mockReturnValue(null)
const mockTriggerLogin = jest.fn()
const mockUseMPCWallet = jest.spyOn(useMPCWallet, 'useMPCWallet').mockReturnValue({
userInfo: {
email: undefined,
name: undefined,
profileImage: undefined,
},
triggerLogin: mockTriggerLogin,
walletState: useMPCWallet.MPCWalletState.NOT_INITIALIZED,
} as unknown as useMPCWallet.MPCWalletHook)

const result = render(
<MpcWalletProvider>
<MPCLogin onLogin={mockOnLogin} />
</MpcWalletProvider>,
)

await waitFor(() => {
expect(result.findByText('Continue with Google')).resolves.toBeDefined()
})

// We do not automatically invoke the callback as the user did not actively connect
expect(mockOnLogin).not.toHaveBeenCalled()

await act(async () => {
// Click the button and mock a successful login
const button = await result.findByRole('button')
button.click()
mockUseMPCWallet.mockReset().mockReturnValue({
userInfo: {
email: '[email protected]',
name: 'Test Testermann',
profileImage: 'test.png',
},
triggerLogin: jest.fn(),
walletState: useMPCWallet.MPCWalletState.READY,
} as unknown as useMPCWallet.MPCWalletHook)

mockUseWallet.mockReset().mockReturnValue({
address: walletAddress,
chainId: '5',
label: ONBOARD_MPC_MODULE_LABEL,
provider: {} as unknown as EIP1193Provider,
})
})

await waitFor(() => {
expect(mockOnLogin).toHaveBeenCalled()
})
})
})
12 changes: 12 additions & 0 deletions src/components/common/ConnectWallet/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
width: 100%;
}

.profileImg {
border-radius: var(--space-2);
width: 32px;
height: 32px;
}

.profileData {
display: flex;
flex-direction: column;
align-items: flex-start;
}

.rowContainer {
align-self: stretch;
margin-left: calc(var(--space-2) * -1);
Expand Down
1 change: 0 additions & 1 deletion src/components/common/PageLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const isNoSidebarRoute = (pathname: string): boolean => {
AppRoutes.share.safeApp,
AppRoutes.newSafe.create,
AppRoutes.newSafe.load,
AppRoutes.welcome,
AppRoutes.index,
AppRoutes.imprint,
AppRoutes.privacy,
Expand Down
Loading

0 comments on commit c1b666a

Please sign in to comment.