Skip to content

Commit

Permalink
[FEAT]: User scans instance with same backup or different backup
Browse files Browse the repository at this point in the history
  • Loading branch information
mcayuelas-ledger committed Aug 30, 2024
1 parent c0bcef6 commit 75fc5c0
Show file tree
Hide file tree
Showing 23 changed files with 218 additions and 123 deletions.
7 changes: 7 additions & 0 deletions .changeset/giant-beans-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"ledger-live-desktop": patch
"live-mobile": patch
"@ledgerhq/trustchain": patch
---

Handle TrustchainAlreadyInitialized & TrustchainAlreadyInitializedWithOtherSeed on Scan QR
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand Down
11 changes: 10 additions & 1 deletion apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -99,8 +100,23 @@ const StepFlow = ({
return <SyncError tryAgain={navigateToQrCodeMethod} />;

case Steps.UnbackedError:
return <UnbackedError create={onCreateKey} />;
return <SpecificError primaryAction={onCreateKey} error={ErrorReason.NO_BACKUP} />;

case Steps.AlreadyBacked:
return (
<SpecificError
primaryAction={() => setCurrentStep(Steps.QrCodeMethod)}
error={ErrorReason.ALREADY_BACKED_SCAN}
/>
);

case Steps.BackedWithDifferentSeeds:
return (
<SpecificError
primaryAction={() => setCurrentStep(Steps.QrCodeMethod)}
error={ErrorReason.DIFFERENT_BACKUPS}
/>
);
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -26,7 +21,6 @@ const startingStep = Steps.AddAccountMethod;
const useAddAccountViewModel = ({ isOpened, onClose }: AddAccountDrawerProps) => {
const [currentStep, setCurrentStep] = useState<Steps>(startingStep);
const [currentOption, setCurrentOption] = useState<Options>(Options.SCAN);
const { onClickTrack } = useLedgerSyncAnalytics();
const navigateToChooseSyncMethod = () => setCurrentStep(Steps.ChooseSyncMethod);
const navigateToQrCodeMethod = () => setCurrentStep(Steps.QrCodeMethod);
const navigation = useNavigation<NavigationProps["navigation"]>();
Expand Down Expand Up @@ -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,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -91,7 +92,23 @@ const ActivationFlow = ({
return <SyncError tryAgain={navigateToQrCodeMethod} />;

case Steps.UnbackedError:
return <UnbackedError create={onCreateKey} />;
return <SpecificError primaryAction={onCreateKey} error={ErrorReason.NO_BACKUP} />;

case Steps.AlreadyBacked:
return (
<SpecificError
primaryAction={() => setCurrentStep(Steps.QrCodeMethod)}
error={ErrorReason.ALREADY_BACKED_SCAN}
/>
);

case Steps.BackedWithDifferentSeeds:
return (
<SpecificError
primaryAction={() => setCurrentStep(Steps.QrCodeMethod)}
error={ErrorReason.DIFFERENT_BACKUPS}
/>
);
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -42,24 +42,29 @@ export function DetailedError(props: Props) {
</Text>

<Flex flexDirection="column" mb={8} rowGap={16}>
<Text variant="bodyLineHeight" color="neutral.c70" textAlign="center">
{description}
</Text>
<Text variant="bodyLineHeight" color="neutral.c70" textAlign="center">
{info}
</Text>
{description && (
<Text variant="bodyLineHeight" color="neutral.c70" textAlign="center">
{description}
</Text>
)}
{info && (
<Text variant="bodyLineHeight" color="neutral.c70" textAlign="center">
{info}
</Text>
)}
</Flex>

<Flex flexDirection="column" rowGap={24} mb={6} width={"100%"} px={"16px"}>
<Button type={buttonType} outline={outline} onPress={primaryAction}>
{cta}
</Button>

<Link onPress={secondaryAction}>
<Text variant="paragraph" fontWeight="semiBold" color="neutral.c70">
{ctaSecondary}
</Text>
</Link>
{ctaSecondary && secondaryAction && (
<Link onPress={secondaryAction}>
<Text variant="paragraph" fontWeight="semiBold" color="neutral.c70">
{ctaSecondary}
</Text>
</Link>
)}
</Flex>
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,9 +22,11 @@ export function ErrorComponent({ title, desc, mainButton }: Props) {
<Text variant="h4" color="neutral.c100" textAlign="center" fontWeight="semiBold" mt={7}>
{title}
</Text>
<Text variant="bodyLineHeight" color="neutral.c70" textAlign="center" mt={6}>
{desc}
</Text>
{desc && (
<Text variant="bodyLineHeight" color="neutral.c70" textAlign="center" mt={6}>
{desc}
</Text>
)}
</Flex>
<Flex mt={8}>
<Button type="main" outline={mainButton.outline} onPress={mainButton.onPress}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import React from "react";
import { ErrorReason, useSpecificError } from "../../hooks/useSpecificError";
import { ErrorReason, SpecificProps, useSpecificError } from "../../hooks/useSpecificError";
import { DetailedError } from "./Detailed";

type Props = {
export const SpecificError = ({
error,
primaryAction,
secondaryAction,
}: SpecificProps & {
error: ErrorReason;
cancel?: () => void;
understood?: () => void;
goToDelete?: () => void;
tryAgain?: () => void;
};

export const SpecificError = ({ error, cancel, goToDelete, understood, tryAgain }: Props) => {
const { getErrorConfig } = useSpecificError({ cancel, goToDelete, understood, tryAgain });
}) => {
const { getErrorConfig } = useSpecificError({ primaryAction, secondaryAction });
const config = getErrorConfig(error);

return <DetailedError {...config} />;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import React from "react";
import { ErrorReason } from "../../hooks/useSpecificError";
import { ErrorReason, SpecificProps } from "../../hooks/useSpecificError";
import { SpecificError } from "../Error/SpecificError";

type Props = {
type Props = SpecificProps & {
error: ErrorReason;
tryAgain?: () => void;
understood?: () => void;
goToDelete?: () => void;
};

export const DeletionError = (props: Props) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export enum AnalyticsPage {
Unbacked = "Unbacked",
OtherSeed = "Other seed",
SameSeed = "Same seed",
ScanAttemptWithSameBackup = "Scan attempt with same backup",
ScanAttemptWithDifferentBackups = "Scan attempt with different backups",
}

export enum AnalyticsFlow {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function useQRCodeHost({ setCurrentStep, currentStep, currentOption }: Pr
},
memberCredentials,
memberName,
alreadyHasATrustchain: !!trustchain,
initialTrustchainId: trustchain?.rootId,
}),

onSuccess: newTrustchain => {
Expand Down
Loading

0 comments on commit 75fc5c0

Please sign in to comment.