diff --git a/.changeset/giant-beans-wait.md b/.changeset/giant-beans-wait.md new file mode 100644 index 000000000000..ccb8793e1d5c --- /dev/null +++ b/.changeset/giant-beans-wait.md @@ -0,0 +1,7 @@ +--- +"ledger-live-desktop": patch +"live-mobile": patch +"@ledgerhq/trustchain": patch +--- + +Handle TrustchainAlreadyInitialized & TrustchainAlreadyInitializedWithOtherSeed on Scan QR diff --git a/apps/ledger-live-desktop/src/newArch/features/WalletSync/hooks/useQRCode.ts b/apps/ledger-live-desktop/src/newArch/features/WalletSync/hooks/useQRCode.ts index 01f853e3fce2..54bf875c2282 100644 --- a/apps/ledger-live-desktop/src/newArch/features/WalletSync/hooks/useQRCode.ts +++ b/apps/ledger-live-desktop/src/newArch/features/WalletSync/hooks/useQRCode.ts @@ -4,6 +4,7 @@ import { InvalidDigitsError, NoTrustchainInitialized, QRCodeWSClosed, + TrustchainAlreadyInitialized, } from "@ledgerhq/trustchain/errors"; import { MemberCredentials } from "@ledgerhq/trustchain/types"; import { useDispatch, useSelector } from "react-redux"; @@ -60,7 +61,7 @@ export function useQRCode() { }, memberCredentials, memberName, - alreadyHasATrustchain: !!trustchain, + initialTrustchainId: trustchain?.rootId, }), // Don't use retry here because it always uses a delay despite setting it to 0 @@ -75,6 +76,9 @@ export function useQRCode() { if (e instanceof NoTrustchainInitialized) { dispatch(setFlow({ flow: Flow.Synchronize, step: Step.UnbackedError })); } + if (e instanceof TrustchainAlreadyInitialized) { + dispatch(setFlow({ flow: Flow.Synchronize, step: Step.SynchronizeWithQRCode })); + } }, onSuccess(newTrustchain) { diff --git a/apps/ledger-live-mobile/src/locales/en/common.json b/apps/ledger-live-mobile/src/locales/en/common.json index 119331f9eb92..6ca416bfc310 100644 --- a/apps/ledger-live-mobile/src/locales/en/common.json +++ b/apps/ledger-live-mobile/src/locales/en/common.json @@ -6869,8 +6869,17 @@ }, "unbacked": { "title": "You need to create your encryption key first", - "desc": "Please make sure you’ve created an encryption key on one of your Ledger Live apps before continuing your synchronization.", + "description": "Please make sure you’ve created an encryption key on one of your Ledger Live apps before continuing your synchronization.", "cta": "Create your encryption key" + }, + "backedWithDifferentSeeds": { + "title": "These apps have different backups", + "description": "Delete your encryption key from one of the apps and try again", + "cta": "I understand" + }, + "alreadyBacked": { + "title": "These apps are already secured by a Ledger", + "cta": "I understand" } }, "alreadySecureError": { diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/StepFlow.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/StepFlow.tsx index 5113dff3da12..d0e6b600d21d 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/StepFlow.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/StepFlow.tsx @@ -11,7 +11,8 @@ import PinCodeDisplay from "LLM/features/WalletSync/screens/Synchronize/PinCodeD import PinCodeInput from "LLM/features/WalletSync/screens/Synchronize/PinCodeInput"; import { useInitMemberCredentials } from "LLM/features/WalletSync/hooks/useInitMemberCredentials"; import { useSyncWithQrCode } from "LLM/features/WalletSync/hooks/useSyncWithQrCode"; -import UnbackedError from "~/newArch/features/WalletSync/screens/Synchronize/UnbackedError"; +import { SpecificError } from "~/newArch/features/WalletSync/components/Error/SpecificError"; +import { ErrorReason } from "~/newArch/features/WalletSync/hooks/useSpecificError"; type Props = { currentStep: Steps; @@ -99,8 +100,23 @@ const StepFlow = ({ return ; case Steps.UnbackedError: - return ; + return ; + case Steps.AlreadyBacked: + return ( + setCurrentStep(Steps.QrCodeMethod)} + error={ErrorReason.ALREADY_BACKED_SCAN} + /> + ); + + case Steps.BackedWithDifferentSeeds: + return ( + setCurrentStep(Steps.QrCodeMethod)} + error={ErrorReason.DIFFERENT_BACKUPS} + /> + ); default: return null; } diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/useAddAccountViewModel.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/useAddAccountViewModel.ts index 0afdbb6c0dec..0f2ed84de879 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/useAddAccountViewModel.ts +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/useAddAccountViewModel.ts @@ -3,11 +3,6 @@ import { track } from "~/analytics"; import { useQRCodeHost } from "LLM/features/WalletSync/hooks/useQRCodeHost"; import { Options, Steps } from "LLM/features/WalletSync/types/Activation"; import { NavigatorName, ScreenName } from "~/const"; -import { - AnalyticsButton, - AnalyticsPage, - useLedgerSyncAnalytics, -} from "~/newArch/features/WalletSync/hooks/useLedgerSyncAnalytics"; import { useNavigation } from "@react-navigation/native"; import { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; import { WalletSyncNavigatorStackParamList } from "~/components/RootNavigator/types/WalletSyncNavigator"; @@ -26,7 +21,6 @@ const startingStep = Steps.AddAccountMethod; const useAddAccountViewModel = ({ isOpened, onClose }: AddAccountDrawerProps) => { const [currentStep, setCurrentStep] = useState(startingStep); const [currentOption, setCurrentOption] = useState(Options.SCAN); - const { onClickTrack } = useLedgerSyncAnalytics(); const navigateToChooseSyncMethod = () => setCurrentStep(Steps.ChooseSyncMethod); const navigateToQrCodeMethod = () => setCurrentStep(Steps.QrCodeMethod); const navigation = useNavigation(); @@ -68,7 +62,6 @@ const useAddAccountViewModel = ({ isOpened, onClose }: AddAccountDrawerProps) => }); const onCreateKey = () => { - onClickTrack({ button: AnalyticsButton.CreateYourKey, page: AnalyticsPage.Unbacked }); navigation.navigate(NavigatorName.WalletSync, { screen: ScreenName.WalletSyncActivationProcess, }); diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Activation/ActivationFlow.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Activation/ActivationFlow.tsx index 59cf1eaa9ece..f45c01ec6e11 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Activation/ActivationFlow.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Activation/ActivationFlow.tsx @@ -10,7 +10,8 @@ import PinCodeInput from "../../screens/Synchronize/PinCodeInput"; import SyncError from "../../screens/Synchronize/SyncError"; import { useInitMemberCredentials } from "../../hooks/useInitMemberCredentials"; import { useSyncWithQrCode } from "../../hooks/useSyncWithQrCode"; -import UnbackedError from "../../screens/Synchronize/UnbackedError"; +import { SpecificError } from "../Error/SpecificError"; +import { ErrorReason } from "../../hooks/useSpecificError"; type Props = { currentStep: Steps; @@ -91,7 +92,23 @@ const ActivationFlow = ({ return ; case Steps.UnbackedError: - return ; + return ; + + case Steps.AlreadyBacked: + return ( + setCurrentStep(Steps.QrCodeMethod)} + error={ErrorReason.ALREADY_BACKED_SCAN} + /> + ); + + case Steps.BackedWithDifferentSeeds: + return ( + setCurrentStep(Steps.QrCodeMethod)} + error={ErrorReason.DIFFERENT_BACKUPS} + /> + ); default: return null; } diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Detailed.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Detailed.tsx index fa86c64c27c8..ccca7cb91ac2 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Detailed.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Detailed.tsx @@ -8,7 +8,7 @@ import styled from "styled-components/native"; interface Props { icon: React.ReactNode; title: string; - description: string; + description?: string; info?: string; cta: string; ctaSecondary?: string; @@ -42,24 +42,29 @@ export function DetailedError(props: Props) { - - {description} - - - {info} - + {description && ( + + {description} + + )} + {info && ( + + {info} + + )} - - - - {ctaSecondary} - - + {ctaSecondary && secondaryAction && ( + + + {ctaSecondary} + + + )} ); diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Simple.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Simple.tsx index 0e0820a280fb..aba928734e22 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Simple.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/components/Error/Simple.tsx @@ -3,7 +3,7 @@ import React from "react"; import styled, { useTheme } from "styled-components/native"; type Props = { title: string; - desc: string; + desc?: string; mainButton: { label: string; onPress: () => void; @@ -22,9 +22,11 @@ export function ErrorComponent({ title, desc, mainButton }: Props) { {title} - - {desc} - + {desc && ( + + {desc} + + )}