From c9f585dbceb1ba623e8176c316a9d08ee5ad01a7 Mon Sep 17 00:00:00 2001 From: Peter Sanderson Date: Thu, 16 May 2024 17:59:39 +0200 Subject: [PATCH] feat(suite): add anayltics to the device onboarding (seed backup types), add analytics to multi share backup --- packages/suite-analytics/src/constants.ts | 2 + .../suite-analytics/src/types/definitions.ts | 1 + packages/suite-analytics/src/types/events.ts | 7 +++ .../onboarding/SkipStepConfirmation.tsx | 6 ++- .../MultiShareBackupModal.tsx | 48 ++++++++++++++++--- .../instructionSteps.tsx | 4 +- .../src/views/onboarding/steps/Final.tsx | 1 + .../views/onboarding/steps/ResetDevice.tsx | 5 +- .../SelectBackupType/SelectBackupType.tsx | 10 +++- .../SettingsDevice/MultiShareBackup.tsx | 10 +++- packages/urls/src/urls.ts | 3 +- 11 files changed, 82 insertions(+), 15 deletions(-) diff --git a/packages/suite-analytics/src/constants.ts b/packages/suite-analytics/src/constants.ts index c20af4c43207..b79f01aa78bc 100644 --- a/packages/suite-analytics/src/constants.ts +++ b/packages/suite-analytics/src/constants.ts @@ -87,4 +87,6 @@ export enum EventType { GetDesktopApp = 'promo/desktop', GetMobileApp = 'promo/mobile', T2B1DashboardPromo = 'promo/t2b1-dashboard', + + SettingsMultiShareBackup = 'settings/device/multi-share-backup', } diff --git a/packages/suite-analytics/src/types/definitions.ts b/packages/suite-analytics/src/types/definitions.ts index 6dd48b06b830..7a53a532710d 100644 --- a/packages/suite-analytics/src/types/definitions.ts +++ b/packages/suite-analytics/src/types/definitions.ts @@ -5,6 +5,7 @@ export type OnboardingAnalytics = { firmware: 'install' | 'update' | 'skip' | 'up-to-date'; seed: 'create' | 'recovery' | 'recovery-in-progress'; seedType: 'shamir-single' | 'shamir-advanced' | '12-words' | '24-words'; + wasSelectTypeOpened: boolean; recoveryType: 'standard' | 'advanced'; backup: 'create' | 'skip'; pin: 'create' | 'skip'; diff --git a/packages/suite-analytics/src/types/events.ts b/packages/suite-analytics/src/types/events.ts index 870beb5c137e..8d27a29d0172 100644 --- a/packages/suite-analytics/src/types/events.ts +++ b/packages/suite-analytics/src/types/events.ts @@ -87,6 +87,7 @@ export type SuiteAnalyticsEvent = payload: Partial> & { duration: number; device: string; + unitPackaging: number; }; } | { @@ -417,4 +418,10 @@ export type SuiteAnalyticsEvent = payload: { action: 'shop' | 'close'; }; + } + | { + type: EventType.SettingsMultiShareBackup; + payload: { + action: 'start' | 'done' | 'learn-more' | 'close-modal'; + }; }; diff --git a/packages/suite/src/components/onboarding/SkipStepConfirmation.tsx b/packages/suite/src/components/onboarding/SkipStepConfirmation.tsx index ab144aa1f512..9ce5cbbdeacd 100644 --- a/packages/suite/src/components/onboarding/SkipStepConfirmation.tsx +++ b/packages/suite/src/components/onboarding/SkipStepConfirmation.tsx @@ -46,6 +46,10 @@ export const SkipStepConfirmation = ({ onCancel }: SkipStepConfirmationProps) => throw new Error(`Unexpected step to skip: ${activeStepId}`); } + const handleSkipStepConfirm = () => { + goToNextStep(nextStep); + }; + return ( diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupModal.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupModal.tsx index 789706f36b7f..fed4dc4dcbf5 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupModal.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupModal.tsx @@ -18,10 +18,17 @@ import { MultiShareBackupStep5Done } from './MultiShareBackupStep5Done'; import { isAdditionalShamirBackupInProgress } from '../../../../../../utils/device/isRecoveryInProgress'; import { MultiShareBackupStep3VerifyOwnership } from './MultiShareBackupStep3VerifyOwnership'; import { MultiShareBackupStep4BackupSeed } from './MultiShareBackupStep4BackupSeed'; +import { EventType, analytics } from '@trezor/suite-analytics'; type Steps = 'first-info' | 'second-info' | 'verify-ownership' | 'backup-seed' | 'done'; -export const MultiShareBackupModal = ({ onCancel }: { onCancel: () => void }) => { +type MultiShareBackupModalProps = { + onCancel: () => void; +}; + +export const MultiShareBackupModal = ({ + onCancel: onCancelFromProps, +}: MultiShareBackupModalProps) => { const device = useSelector(selectDevice); const isInBackupMode = @@ -33,9 +40,27 @@ export const MultiShareBackupModal = ({ onCancel }: { onCancel: () => void }) => const [isChecked2, setIsChecked2] = useState(false); const [isSubmitted, setIsSubmitted] = useState(false); + const learnMoreClicked = () => { + analytics.report({ + type: EventType.SettingsMultiShareBackup, + payload: { action: 'learn-more' }, + }); + }; + + const handleCancel = () => { + if (step !== 'done') { + analytics.report({ + type: EventType.SettingsMultiShareBackup, + payload: { action: 'close-modal' }, + }); + } + + onCancelFromProps(); + }; + const closeWithCancelOnDevice = () => { TrezorConnect.cancel('cancel'); - onCancel(); + handleCancel(); }; if (device === undefined) { @@ -68,7 +93,11 @@ export const MultiShareBackupModal = ({ onCancel }: { onCancel: () => void }) => - + ), }; @@ -90,13 +119,18 @@ export const MultiShareBackupModal = ({ onCancel }: { onCancel: () => void }) => setStep('backup-seed'); TrezorConnect.backupDevice().then(response => { if (response.success) { + analytics.report({ + type: EventType.SettingsMultiShareBackup, + payload: { action: 'done' }, + }); + setStep('done'); } else { - onCancel(); + handleCancel(); } }); } else { - onCancel(); + handleCancel(); } }; @@ -136,7 +170,7 @@ export const MultiShareBackupModal = ({ onCancel }: { onCancel: () => void }) => children: , bottomBarComponents: ( <> - @@ -148,5 +182,5 @@ export const MultiShareBackupModal = ({ onCancel }: { onCancel: () => void }) => } }; - return ; + return ; }; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx index 73a2e85b0c57..e01ff2f36439 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx @@ -3,7 +3,7 @@ import styled from 'styled-components'; import { Image, Text } from '@trezor/components'; import { borders, spacings, spacingsPx } from '@trezor/theme'; -import { ESHOP_KEEP_METAL_URL, HELP_CENTER_SEED_CARD_URL } from '@trezor/urls'; +import { ESHOP_KEEP_METAL_SINGLE_SHARE_URL, ESHOP_KEEP_METAL_URL, HELP_CENTER_SEED_CARD_URL } from '@trezor/urls'; import { Translation, TrezorLink } from 'src/components/suite'; import { BackupInstructionsCard } from './BackupInstructionsCard'; @@ -68,7 +68,7 @@ export const createSharesInstruction: InstructionBaseConfig = { ), keepLink: chunks => ( - + {chunks} ), diff --git a/packages/suite/src/views/onboarding/steps/Final.tsx b/packages/suite/src/views/onboarding/steps/Final.tsx index 3f028ed59314..73b8f6e2859f 100644 --- a/packages/suite/src/views/onboarding/steps/Final.tsx +++ b/packages/suite/src/views/onboarding/steps/Final.tsx @@ -221,6 +221,7 @@ export const FinalStep = () => { ...onboardingAnalytics, duration: Date.now() - onboardingAnalytics.startTime!, device: device.features.internal_model, + unitPackaging: device.features.unit_packaging ?? 0, }; delete payload.startTime; diff --git a/packages/suite/src/views/onboarding/steps/ResetDevice.tsx b/packages/suite/src/views/onboarding/steps/ResetDevice.tsx index 4bd94fd7e08e..3115e66f2e53 100644 --- a/packages/suite/src/views/onboarding/steps/ResetDevice.tsx +++ b/packages/suite/src/views/onboarding/steps/ResetDevice.tsx @@ -92,9 +92,9 @@ export const ResetDeviceStep = () => { } updateBackupType(type); - updateAnalytics({ recoveryType: undefined, seedType: type }); + updateAnalytics({ seedType: type }); }, - [updateAnalytics, onResetDevice, updateBackupType], + [updateBackupType, updateAnalytics, onResetDevice], ); useEffect(() => { @@ -154,6 +154,7 @@ export const ResetDeviceStep = () => { <> updateAnalytics({ wasSelectTypeOpened: true })} onSelect={setBackupType} isDisabled={isDeviceLocked} data-test="@onboarding/select-seed-type-open-dialog" diff --git a/packages/suite/src/views/onboarding/steps/SelectBackupType/SelectBackupType.tsx b/packages/suite/src/views/onboarding/steps/SelectBackupType/SelectBackupType.tsx index 0837769a6bcc..946c06cf58ee 100644 --- a/packages/suite/src/views/onboarding/steps/SelectBackupType/SelectBackupType.tsx +++ b/packages/suite/src/views/onboarding/steps/SelectBackupType/SelectBackupType.tsx @@ -84,6 +84,7 @@ type SelectBackupTypeProps = { selected: BackupType; onSelect: (value: BackupType) => void; 'data-test'?: string; + onOpen: () => void; }; export const SelectBackupType = ({ @@ -91,6 +92,7 @@ export const SelectBackupType = ({ onSelect, isDisabled, 'data-test': dataTest, + onOpen, }: SelectBackupTypeProps) => { const { elevation } = useElevation(); const [isOpen, setIsOpen] = useState(false); @@ -136,7 +138,13 @@ export const SelectBackupType = ({ - setIsOpen(true)}> + { + setIsOpen(true); + onOpen(); + }} + > diff --git a/packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx b/packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx index 8cba5abb4d23..e32909d677dc 100644 --- a/packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx +++ b/packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx @@ -10,6 +10,7 @@ import { useDispatch, useSelector } from 'src/hooks/suite'; import { selectDevice } from '@suite-common/wallet-core'; import { TrezorDevice } from '@suite-common/suite-types'; import { goto } from '../../../actions/suite/routerActions'; +import { EventType, analytics } from '@trezor/suite-analytics'; const doesSupportMultiShare = (device: TrezorDevice | undefined): boolean => { if (device?.features === undefined) { @@ -38,7 +39,14 @@ export const MultiShareBackup = () => { return; } - const handleClick = () => dispatch(goto('create-multi-share-backup')); + const handleClick = () => { + analytics.report({ + type: EventType.SettingsMultiShareBackup, + payload: { action: 'start' }, + }); + + dispatch(goto('create-multi-share-backup')); + }; return ( diff --git a/packages/urls/src/urls.ts b/packages/urls/src/urls.ts index 40d0c8c1afab..82e2ca7078d4 100644 --- a/packages/urls/src/urls.ts +++ b/packages/urls/src/urls.ts @@ -73,7 +73,7 @@ export const HELP_CENTER_ETH_STAKING = 'https://trezor.io/learn/a/stake-ethereum-eth-in-trezor-suite'; export const HELP_CENTER_SEED_CARD_URL = 'https://trezor.io/learn/a/recovery-seed-card'; export const HELP_CENTER_MULTI_SHARE_BACKUP_URL = - 'https://trezor.io/learn/a/introducing-multi-share-backup'; + 'https://trezor.io/learn/a/multi-share-backup-on-trezor'; export const HELP_CENTER_KEEPING_SEED_SAFE_URL = 'https://trezor.io/learn/a/keeping-your-recovery-seed-safe'; @@ -101,3 +101,4 @@ export const ZKSNACKS_TERMS_URL = export const CROWDIN_URL = 'https://crowdin.com/project/trezor-suite'; export const ESHOP_KEEP_METAL_URL = 'https://trezor.io/trezor-keep-metal'; +export const ESHOP_KEEP_METAL_SINGLE_SHARE_URL = 'https://trezor.io/trezor-keep-metal-single-share';