diff --git a/src/components/common/ConnectWallet/MPCLogin.tsx b/src/components/common/ConnectWallet/MPCLogin.tsx index 03ead96b6e..ff783c89e7 100644 --- a/src/components/common/ConnectWallet/MPCLogin.tsx +++ b/src/components/common/ConnectWallet/MPCLogin.tsx @@ -7,6 +7,9 @@ import GoogleLogo from '@/public/images/welcome/logo-google.svg' import css from './styles.module.css' import useWallet from '@/hooks/wallets/useWallet' +import Track from '../Track' +import { CREATE_SAFE_EVENTS } from '@/services/analytics' +import { MPC_WALLET_EVENTS } from '@/services/analytics/events/mpcWallet' const MPCLogin = ({ onLogin }: { onLogin?: () => void }) => { const { triggerLogin, userInfo, walletState, recoverFactorWithPassword } = useContext(MpcWalletContext) @@ -34,44 +37,48 @@ const MPCLogin = ({ onLogin }: { onLogin?: () => void }) => { <> {wallet && userInfo ? ( <> + + + + + + + Continue as {userInfo.name} + + {userInfo.email} + + + + + + > + ) : ( + - - - - - Continue as {userInfo.name} - - {userInfo.email} - - + + Continue with Google - > - ) : ( - - - Continue with Google - - + )} {walletState === MPCWalletState.MANUAL_RECOVERY && ( diff --git a/src/components/common/ConnectWallet/PasswordRecovery.tsx b/src/components/common/ConnectWallet/PasswordRecovery.tsx index 17c8fb6060..72ed86a3ac 100644 --- a/src/components/common/ConnectWallet/PasswordRecovery.tsx +++ b/src/components/common/ConnectWallet/PasswordRecovery.tsx @@ -1,3 +1,4 @@ +import { MPC_WALLET_EVENTS } from '@/services/analytics/events/mpcWallet' import { VisibilityOff, Visibility } from '@mui/icons-material' import { DialogContent, @@ -11,6 +12,7 @@ import { } from '@mui/material' import { useState } from 'react' import ModalDialog from '../ModalDialog' +import Track from '../Track' export const PasswordRecovery = ({ recoverFactorWithPassword, @@ -52,10 +54,14 @@ export const PasswordRecovery = ({ control={ setStoreDeviceFactor((prev) => !prev)} />} label="Do not ask again on this device" /> - - recoverFactorWithPassword(recoveryPassword, storeDeviceFactor)}> - Submit - + + recoverFactorWithPassword(recoveryPassword, storeDeviceFactor)} + > + Submit + + diff --git a/src/components/settings/SignerAccountMFA/PasswordForm.tsx b/src/components/settings/SignerAccountMFA/PasswordForm.tsx index f40e2e0522..d891fd850b 100644 --- a/src/components/settings/SignerAccountMFA/PasswordForm.tsx +++ b/src/components/settings/SignerAccountMFA/PasswordForm.tsx @@ -1,4 +1,6 @@ +import Track from '@/components/common/Track' import { SecurityQuestionRecovery } from '@/hooks/wallets/mpc/recovery/SecurityQuestionRecovery' +import { MPC_WALLET_EVENTS } from '@/services/analytics/events/mpcWallet' import { Typography, TextField, Button, Box } from '@mui/material' import { type Web3AuthMPCCoreKit } from '@web3auth/mpc-core-kit' import { useState, useMemo } from 'react' @@ -92,14 +94,15 @@ export const PasswordForm = ({ mpcCoreKit }: { mpcCoreKit: Web3AuthMPCCoreKit }) }, })} /> - - - Change - + + + Change + + ) diff --git a/src/components/settings/SignerAccountMFA/helper.ts b/src/components/settings/SignerAccountMFA/helper.ts index 4c39a02a49..45ff25b062 100644 --- a/src/components/settings/SignerAccountMFA/helper.ts +++ b/src/components/settings/SignerAccountMFA/helper.ts @@ -1,4 +1,6 @@ import { SecurityQuestionRecovery } from '@/hooks/wallets/mpc/recovery/SecurityQuestionRecovery' +import { trackEvent } from '@/services/analytics' +import { MPC_WALLET_EVENTS } from '@/services/analytics/events/mpcWallet' import { logError } from '@/services/exceptions' import ErrorCodes from '@/services/exceptions/ErrorCodes' import { asError } from '@/services/exceptions/utils' @@ -35,6 +37,7 @@ export const enableMFA = async ( } if (!isMFAEnabled(mpcCoreKit)) { + trackEvent(MPC_WALLET_EVENTS.ENABLE_MFA) // 2. enable MFA in mpcCoreKit await mpcCoreKit.enableMFA({}, false) } diff --git a/src/components/welcome/WelcomeLogin/WalletLogin.tsx b/src/components/welcome/WelcomeLogin/WalletLogin.tsx index 451bf5d502..60610e478f 100644 --- a/src/components/welcome/WelcomeLogin/WalletLogin.tsx +++ b/src/components/welcome/WelcomeLogin/WalletLogin.tsx @@ -1,5 +1,7 @@ import useConnectWallet from '@/components/common/ConnectWallet/useConnectWallet' +import Track from '@/components/common/Track' import useWallet from '@/hooks/wallets/useWallet' +import { CREATE_SAFE_EVENTS } from '@/services/analytics' import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/module' import { Box, Button, Typography } from '@mui/material' import { EthHashInfo } from '@safe-global/safe-react-components' @@ -9,30 +11,41 @@ const WalletLogin = ({ onLogin }: { onLogin: () => void }) => { const connectWallet = useConnectWallet() const login = async () => { - await connectWallet() - onLogin() + const walletState = await connectWallet() + if (walletState) { + onLogin() + } } if (wallet !== null && wallet?.label !== ONBOARD_MPC_MODULE_LABEL) { return ( - - - - - Continue with {wallet.label} - - {wallet.address && } + + + + + + Continue with {wallet.label} + + {wallet.address && } + + {wallet.icon && ( + + )} - {wallet.icon && ( - - )} - - + + ) } diff --git a/src/components/welcome/WelcomeLogin/__tests__/WalletLogin.test.tsx b/src/components/welcome/WelcomeLogin/__tests__/WalletLogin.test.tsx index d3dcf4d715..a846dd5f8d 100644 --- a/src/components/welcome/WelcomeLogin/__tests__/WalletLogin.test.tsx +++ b/src/components/welcome/WelcomeLogin/__tests__/WalletLogin.test.tsx @@ -41,7 +41,7 @@ describe('WalletLogin', () => { const mockOnLogin = jest.fn() const walletAddress = hexZeroPad('0x1', 20) const mockUseWallet = jest.spyOn(useWallet, 'default').mockReturnValue(null) - jest.spyOn(useConnectWallet, 'default').mockReturnValue(jest.fn()) + jest.spyOn(useConnectWallet, 'default').mockReturnValue(jest.fn().mockReturnValue([{}])) const result = render() diff --git a/src/components/welcome/WelcomeLogin/index.tsx b/src/components/welcome/WelcomeLogin/index.tsx index 4d08ea716a..cd8c38b0a5 100644 --- a/src/components/welcome/WelcomeLogin/index.tsx +++ b/src/components/welcome/WelcomeLogin/index.tsx @@ -5,15 +5,13 @@ import SafeLogo from '@/public/images/logo-text.svg' import css from './styles.module.css' import { useRouter } from 'next/router' import WalletLogin from './WalletLogin' -import { CREATE_SAFE_EVENTS, LOAD_SAFE_EVENTS } from '@/services/analytics/events/createLoadSafe' +import { LOAD_SAFE_EVENTS } from '@/services/analytics/events/createLoadSafe' import Track from '@/components/common/Track' -import { trackEvent } from '@/services/analytics' const WelcomeLogin = () => { const router = useRouter() const continueToCreation = () => { - trackEvent(CREATE_SAFE_EVENTS.CREATE_BUTTON) router.push(AppRoutes.newSafe.create) } diff --git a/src/hooks/wallets/mpc/useMPCWallet.ts b/src/hooks/wallets/mpc/useMPCWallet.ts index caa61fe945..e544742283 100644 --- a/src/hooks/wallets/mpc/useMPCWallet.ts +++ b/src/hooks/wallets/mpc/useMPCWallet.ts @@ -7,6 +7,8 @@ import useOnboard, { connectWallet } from '../useOnboard' import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/module' import { SecurityQuestionRecovery } from './recovery/SecurityQuestionRecovery' import { DeviceShareRecovery } from './recovery/DeviceShareRecovery' +import { trackEvent } from '@/services/analytics' +import { MPC_WALLET_EVENTS } from '@/services/analytics/events/mpcWallet' export enum MPCWalletState { NOT_INITIALIZED, @@ -33,7 +35,7 @@ export const useMPCWallet = (): MPCWalletHook => { // This is a critical function that should only be used for testing purposes // Resetting your account means clearing all the metadata associated with it from the metadata server // The key details will be deleted from our server and you will not be able to recover your account - if (!mpcCoreKit || !mpcCoreKit.metadataKey) { + if (!mpcCoreKit?.metadataKey) { throw new Error('MPC Core Kit is not initialized or the user is not logged in') } @@ -73,6 +75,7 @@ export const useMPCWallet = (): MPCWalletHook => { // Check password recovery const securityQuestions = new SecurityQuestionRecovery(mpcCoreKit) if (securityQuestions.isEnabled()) { + trackEvent(MPC_WALLET_EVENTS.MANUAL_RECOVERY) setWalletState(MPCWalletState.MANUAL_RECOVERY) return false } diff --git a/src/services/analytics/events/createLoadSafe.ts b/src/services/analytics/events/createLoadSafe.ts index 98689a083d..17eaea759b 100644 --- a/src/services/analytics/events/createLoadSafe.ts +++ b/src/services/analytics/events/createLoadSafe.ts @@ -3,6 +3,11 @@ import { EventType } from '@/services/analytics/types' export const CREATE_SAFE_CATEGORY = 'create-safe' export const CREATE_SAFE_EVENTS = { + CONTINUE_TO_CREATION: { + action: 'Continue to creation', + category: CREATE_SAFE_CATEGORY, + event: EventType.META, + }, CREATE_BUTTON: { action: 'Open stepper', category: CREATE_SAFE_CATEGORY, diff --git a/src/services/analytics/events/mpcWallet.ts b/src/services/analytics/events/mpcWallet.ts new file mode 100644 index 0000000000..5f3277c789 --- /dev/null +++ b/src/services/analytics/events/mpcWallet.ts @@ -0,0 +1,31 @@ +import { EventType } from '@/services/analytics/types' + +const MPC_WALLET_CATEGORY = 'mpc-wallet' + +export const MPC_WALLET_EVENTS = { + CONNECT_GOOGLE: { + event: EventType.CLICK, + action: 'Continue with Google button', + category: MPC_WALLET_CATEGORY, + }, + MANUAL_RECOVERY: { + event: EventType.META, + action: 'Account recovery started', + category: MPC_WALLET_CATEGORY, + }, + RECOVER_PASSWORD: { + event: EventType.CLICK, + action: 'Recover account using password', + category: MPC_WALLET_CATEGORY, + }, + UPSERT_PASSWORD: { + event: EventType.CLICK, + action: 'Set or change password', + category: MPC_WALLET_CATEGORY, + }, + ENABLE_MFA: { + event: EventType.META, + action: 'Enable MFA for account', + category: MPC_WALLET_CATEGORY, + }, +}