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 5aa346d19739..1d0e17e95129 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}
+
+ )}