From 120c1f815fc170b1278a4da5997eefeddb95c7b5 Mon Sep 17 00:00:00 2001 From: Theophile Sandoz Date: Mon, 26 Aug 2024 15:23:36 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=9D=EF=B8=8F=20[FIX]:=20llm=20"Delete?= =?UTF-8?q?=20my=20encryption=20key"=20action=20on=20wrong=20seed=20errors?= =?UTF-8?q?=20(#7668)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix the "Delete my encription key" action on sync error * Update changelog --------- Co-authored-by: Theophile Sandoz --- .changeset/selfish-poets-arrive.md | 5 ++ .../features/WalletSync/hooks/useAddMember.ts | 32 +++++----- .../hooks/useFollowInstructionDrawer.ts | 54 ++++++++++++++++ .../WalletSync/hooks/useRemoveMember.ts | 42 +++++-------- .../ActivationInstructionDrawer.tsx | 6 +- .../screens/FollowInstructions/index.tsx | 63 +++++++++++-------- .../DeletionInstructionDrawer.tsx | 7 +-- 7 files changed, 131 insertions(+), 78 deletions(-) create mode 100644 .changeset/selfish-poets-arrive.md create mode 100644 apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useFollowInstructionDrawer.ts diff --git a/.changeset/selfish-poets-arrive.md b/.changeset/selfish-poets-arrive.md new file mode 100644 index 000000000000..caa83702fbad --- /dev/null +++ b/.changeset/selfish-poets-arrive.md @@ -0,0 +1,5 @@ +--- +"live-mobile": minor +--- + +Fix "Delete my encryption key" action on wrong seed errors diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useAddMember.ts b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useAddMember.ts index cb2bbb7bc361..ec3833947489 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useAddMember.ts +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useAddMember.ts @@ -1,25 +1,24 @@ import { memberCredentialsSelector, setTrustchain } from "@ledgerhq/trustchain/store"; import { useDispatch, useSelector } from "react-redux"; import { useTrustchainSdk } from "./useTrustchainSdk"; +import { TrustchainNotAllowed } from "@ledgerhq/trustchain/errors"; import { TrustchainResult, TrustchainResultType } from "@ledgerhq/trustchain/types"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef } from "react"; import { Device } from "@ledgerhq/live-common/hw/actions/types"; import { useNavigation } from "@react-navigation/native"; import { WalletSyncNavigatorStackParamList } from "~/components/RootNavigator/types/WalletSyncNavigator"; import { StackNavigatorNavigation } from "~/components/RootNavigator/types/helpers"; import { ScreenName } from "~/const"; +import { DrawerProps, SceneKind, useFollowInstructionDrawer } from "./useFollowInstructionDrawer"; + +export function useAddMember({ device }: { device: Device | null }): DrawerProps { + const [DrawerProps, setScene] = useFollowInstructionDrawer(); -export function useAddMember({ device }: { device: Device | null }) { const dispatch = useDispatch(); const sdk = useTrustchainSdk(); const memberCredentials = useSelector(memberCredentialsSelector); - const [error, setError] = useState(null); - - const navigation = useNavigation>(); - - const [userDeviceInteraction, setUserDeviceInteraction] = useState(false); - const memberCredentialsRef = useRef(memberCredentials); + const navigation = useNavigation>(); const transitionToNextScreen = useCallback( (trustchainResult: TrustchainResult) => { @@ -31,8 +30,6 @@ export function useAddMember({ device }: { device: Device | null }) { [dispatch, navigation], ); - const onRetry = () => {}; - useEffect(() => { const addMember = async () => { try { @@ -44,21 +41,26 @@ export function useAddMember({ device }: { device: Device | null }) { device.deviceId, memberCredentialsRef.current, { - onStartRequestUserInteraction: () => setUserDeviceInteraction(true), - onEndRequestUserInteraction: () => setUserDeviceInteraction(false), + onStartRequestUserInteraction: () => + setScene({ kind: SceneKind.DeviceInstructions, device }), + onEndRequestUserInteraction: () => setScene({ kind: SceneKind.Loader }), }, ); if (trustchainResult) { transitionToNextScreen(trustchainResult); } } catch (error) { - setError(error as Error); + if (error instanceof TrustchainNotAllowed) { + setScene({ kind: SceneKind.KeyError }); + } else if (error instanceof Error) { + setScene({ kind: SceneKind.GenericError, error }); + } } }; if (device && device.deviceId) { addMember(); } - }, [device, dispatch, sdk, transitionToNextScreen]); + }, [setScene, device, dispatch, sdk, transitionToNextScreen]); - return { error, userDeviceInteraction, onRetry }; + return DrawerProps; } diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useFollowInstructionDrawer.ts b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useFollowInstructionDrawer.ts new file mode 100644 index 000000000000..5fb3ab23ef4f --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useFollowInstructionDrawer.ts @@ -0,0 +1,54 @@ +import { useNavigation } from "@react-navigation/native"; +import { Dispatch, SetStateAction, useCallback, useState } from "react"; +import { Device } from "@ledgerhq/live-common/hw/actions/types"; +import { StackNavigatorNavigation } from "~/components/RootNavigator/types/helpers"; +import { WalletSyncNavigatorStackParamList } from "~/components/RootNavigator/types/WalletSyncNavigator"; +import { ScreenName } from "~/const"; +import { useDestroyTrustchain } from "./useDestroyTrustchain"; + +export enum SceneKind { + DeviceInstructions, + Loader, + WrongSeedError, + KeyError, + GenericError, +} +type Scene = + | { kind: SceneKind.DeviceInstructions; device: Device } + | { kind: SceneKind.Loader } + | { kind: SceneKind.WrongSeedError } + | { kind: SceneKind.KeyError } + | { kind: SceneKind.GenericError; error: Error }; + +export type DrawerProps = { + scene: Scene; + onRetry: () => void; + goToDelete: () => void; + backToKeyError: () => void; + confirmDeleteKey: () => void; +}; + +export function useFollowInstructionDrawer(): [DrawerProps, Dispatch>] { + const navigation = useNavigation>(); + const { deleteMutation } = useDestroyTrustchain(); + + const [scene, setScene] = useState({ kind: SceneKind.Loader }); + + // eslint-disable-next-line no-console + const onRetry = useCallback(() => console.log("onRetry"), []); + + const goToDelete = useCallback(() => { + setScene({ kind: SceneKind.WrongSeedError }); + }, []); + + const backToKeyError = useCallback(() => { + setScene({ kind: SceneKind.KeyError }); + }, []); + + const confirmDeleteKey = useCallback(async () => { + await deleteMutation.mutateAsync(); + navigation.navigate(ScreenName.WalletSyncManageKeyDeleteSuccess); + }, [deleteMutation, navigation]); + + return [{ scene, onRetry, goToDelete, backToKeyError, confirmDeleteKey }, setScene]; +} diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useRemoveMember.ts b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useRemoveMember.ts index 1bc93ee0283f..2e544ac39ef3 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useRemoveMember.ts +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useRemoveMember.ts @@ -5,37 +5,29 @@ import { } from "@ledgerhq/trustchain/store"; import { useDispatch, useSelector } from "react-redux"; import { useTrustchainSdk } from "./useTrustchainSdk"; +import { TrustchainNotAllowed } from "@ledgerhq/trustchain/errors"; import { TrustchainMember, Trustchain } from "@ledgerhq/trustchain/types"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect } from "react"; import { Device } from "@ledgerhq/live-common/hw/actions/types"; import { useNavigation } from "@react-navigation/native"; import { ScreenName } from "~/const"; import { StackNavigatorNavigation } from "~/components/RootNavigator/types/helpers"; import { WalletSyncNavigatorStackParamList } from "~/components/RootNavigator/types/WalletSyncNavigator"; +import { DrawerProps, SceneKind, useFollowInstructionDrawer } from "./useFollowInstructionDrawer"; type Props = { device: Device | null; member: TrustchainMember | null; }; -export function useRemoveMember({ device, member }: Props) { +export function useRemoveMember({ device, member }: Props): DrawerProps { + const [DrawerProps, setScene] = useFollowInstructionDrawer(); + const dispatch = useDispatch(); const sdk = useTrustchainSdk(); const trustchain = useSelector(trustchainSelector); const memberCredentials = useSelector(memberCredentialsSelector); - const [error, setError] = useState(null); - const navigation = useNavigation>(); - const [userDeviceInteraction, setUserDeviceInteraction] = useState(false); - - // eslint-disable-next-line no-console - const onRetry = useCallback(() => console.log("onRetry"), []); - // () => dispatch(setFlow({ flow: Flow.ManageInstances, step: Step.DeviceActionInstance })), - - const goToDelete = useCallback( - () => navigation.navigate(ScreenName.WalletSyncActivated), - [navigation], - ); // eslint-disable-next-line no-console const onResetFlow = useCallback(() => console.log("onResetFlow"), []); @@ -65,17 +57,22 @@ export function useRemoveMember({ device, member }: Props) { memberCredentials, member, { - onStartRequestUserInteraction: () => setUserDeviceInteraction(true), - onEndRequestUserInteraction: () => setUserDeviceInteraction(false), + onStartRequestUserInteraction: () => + setScene({ kind: SceneKind.DeviceInstructions, device }), + onEndRequestUserInteraction: () => setScene({ kind: SceneKind.Loader }), }, ); transitionToNextScreen(newTrustchain); } catch (error) { - if (error instanceof Error) setError(error); + if (error instanceof TrustchainNotAllowed) { + setScene({ kind: SceneKind.KeyError }); + } else if (error instanceof Error) { + setScene({ kind: SceneKind.GenericError, error }); + } } }, - [device, memberCredentials, sdk, transitionToNextScreen, trustchain], + [setScene, device, memberCredentials, sdk, transitionToNextScreen, trustchain], ); useEffect(() => { @@ -86,12 +83,7 @@ export function useRemoveMember({ device, member }: Props) { removeMember(member); } } - }, [device, member, onResetFlow, onRetry, removeMember]); + }, [device, member, onResetFlow, removeMember]); - return { - error, - onRetry, - userDeviceInteraction, - goToDelete, - }; + return DrawerProps; } diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationInstructionDrawer.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationInstructionDrawer.tsx index 3562eb13a2da..eb153b2811b4 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationInstructionDrawer.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationInstructionDrawer.tsx @@ -11,15 +11,11 @@ type Props = { }; const FollowInstructionsDrawer = ({ isOpen, handleClose, device }: Props) => { - const { error, userDeviceInteraction } = useAddMember({ device }); - return ( ); }; diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/FollowInstructions/index.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/FollowInstructions/index.tsx index 0f109634fa9b..47bc40be5f01 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/FollowInstructions/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/FollowInstructions/index.tsx @@ -3,50 +3,59 @@ import QueuedDrawer from "LLM/components/QueuedDrawer"; import { TrackScreen } from "~/analytics"; import FollowInstructions from "../../components/FollowInstructions"; -import { Device } from "@ledgerhq/live-common/hw/actions/types"; import GenericErrorView from "~/components/GenericErrorView"; import { Flex, InfiniteLoader } from "@ledgerhq/native-ui"; -import { TrustchainNotAllowed } from "@ledgerhq/trustchain/errors"; +import { ConfirmManageKey } from "../../components/ManageKey/Confirm"; import { DeletionError, ErrorReason } from "../../components/ManageInstances/DeletionError"; +import { DrawerProps, SceneKind } from "../../hooks/useFollowInstructionDrawer"; -type Props = { +type Props = DrawerProps & { isOpen: boolean; handleClose: () => void; - device: Device | null; - userDeviceInteraction: boolean; - error: Error | null; - goToDelete?: () => void; }; const GenericFollowInstructionsDrawer = ({ isOpen, handleClose, - device, - error, - userDeviceInteraction, + scene, goToDelete, + backToKeyError, + confirmDeleteKey, }: Props) => { + const getScene = () => { + switch (scene.kind) { + case SceneKind.DeviceInstructions: + return ; + + case SceneKind.Loader: + return ( + + + + ); + + case SceneKind.WrongSeedError: + return ; + + case SceneKind.KeyError: + return ( + + ); + + case SceneKind.GenericError: + return ; + } + }; + return ( <> - {error ? ( - error instanceof TrustchainNotAllowed ? ( - - ) : ( - - ) - ) : userDeviceInteraction && device ? ( - - ) : ( - - - - )} + {getScene()} ); diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/ManageInstances/DeletionInstructionDrawer.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/ManageInstances/DeletionInstructionDrawer.tsx index e64ffe7f3d5b..8dd1bbf6e486 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/ManageInstances/DeletionInstructionDrawer.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/ManageInstances/DeletionInstructionDrawer.tsx @@ -13,16 +13,11 @@ type Props = { }; const DeletionFollowInstructionsDrawer = ({ isOpen, handleClose, device, member }: Props) => { - const { error, userDeviceInteraction, goToDelete } = useRemoveMember({ device, member }); - return ( ); };