Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DSDK-331][LLD] Europa crash MyLedger "cannot ready properties of undefined reading 'dark'" #7017

Merged
merged 5 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/dry-cheetahs-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ledger-live-desktop": patch
---

Fix a crash with Europa in My Ledger when opening an app
5 changes: 5 additions & 0 deletions .changeset/polite-ladybugs-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/devices": patch
---

Add type narrowing helper isDeviceModelId
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState, useCallback } from "react";
import { useSelector } from "react-redux";
import { lastSeenDeviceSelector } from "~/renderer/reducers/settings";
import { DeviceModelId } from "@ledgerhq/devices";
import { isDeviceModelId } from "@ledgerhq/devices/helpers";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import getAppAndVersion from "@ledgerhq/live-common/hw/getAppAndVersion";
import { Subscription, from } from "rxjs";
Expand All @@ -15,6 +16,7 @@ import { Trans } from "react-i18next";
import Box from "~/renderer/components/Box";
import Button from "~/renderer/components/Button";
import { useHistory } from "react-router-dom";
import { lastSeenDeviceSelector } from "~/renderer/reducers/settings";
import { getCurrentDevice } from "~/renderer/reducers/devices";
import nanoS from "./assets/nanoS.png";
import blue from "./assets/blue.png";
Expand All @@ -25,8 +27,12 @@ import blueDark from "./assets/blue_dark.png";
import nanoXDark from "./assets/nanoX_dark.png";
import nanoSPDark from "./assets/nanoSP_dark.png";
import stax from "./assets/stax.png";
import europa from "./assets/europa.png";

const illustrations = {
const illustrations: Record<
DeviceModelId,
{ light: string; dark: string; width: number; height: number }
> = {
nanoX: {
light: nanoX,
dark: nanoXDark,
Expand All @@ -51,15 +57,22 @@ const illustrations = {
width: 141,
height: 223,
},
europa: {
light: europa,
dark: europa,
width: 141,
height: 223,
},
blue: {
light: blue,
dark: blueDark,
width: 64,
height: 64,
},
};

const Illustration = styled.div<{
modelId: string;
modelId: DeviceModelId;
}>`
// prettier-ignore
background: url('${p =>
Expand All @@ -73,7 +86,10 @@ const Illustration = styled.div<{
`;
const Disconnected = ({ onTryAgain }: { onTryAgain: (a: boolean) => void }) => {
const lastSeenDevice = useSelector(lastSeenDeviceSelector);
const modelId = process.env.OVERRIDE_MODEL_ID || lastSeenDevice?.modelId || "nanoS";
const overriddenModelId = process.env.OVERRIDE_MODELID;
const modelId: DeviceModelId = isDeviceModelId(overriddenModelId)
? overriddenModelId
: lastSeenDevice?.modelId || DeviceModelId.nanoS;
const [readyToDecide, setReadyToDecide] = useState(false);
const [showSpinner, setShowSpinner] = useState(true);
const device = useSelector(getCurrentDevice);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 20 additions & 1 deletion libs/ledgerjs/packages/devices/src/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
import { DeviceModelId } from ".";
import { stringToDeviceModelId } from "./helpers";
import { stringToDeviceModelId, isDeviceModelId } from "./helpers";

const validDeviceModelsIds = ["nanoS", "nanoX", "blue", "nanoSP", "stax", "europa"];
const invalidDeviceModelsIds = ["does-not-exist", "", null, undefined];

describe("isDeviceModelId", () => {
validDeviceModelsIds.forEach(potentialModelId => {
test(`Input: ${potentialModelId} -> Expected output: true`, () => {
const result = isDeviceModelId(potentialModelId);
expect(result).toEqual(true);
});
});

invalidDeviceModelsIds.forEach(potentialModelId => {
test(`Input: ${potentialModelId} -> Expected output: false`, () => {
const result = isDeviceModelId(potentialModelId);
expect(result).toEqual(false);
});
});
});

type Test = {
input: [string, DeviceModelId];
Expand Down
12 changes: 7 additions & 5 deletions libs/ledgerjs/packages/devices/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { DeviceModelId } from ".";

export function isDeviceModelId(val: string | undefined | null): val is DeviceModelId {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice !

if (!val) return false;
return Object.values(DeviceModelId).includes(val as DeviceModelId);
}

export const stringToDeviceModelId = (
strDeviceModelId: string,
defaultDeviceModelId: DeviceModelId,
): DeviceModelId => {
if (Object.values(DeviceModelId)?.includes(strDeviceModelId as DeviceModelId)) {
return DeviceModelId[strDeviceModelId as DeviceModelId];
}

return defaultDeviceModelId;
if (!isDeviceModelId(strDeviceModelId)) return defaultDeviceModelId;
return DeviceModelId[strDeviceModelId];
};
Loading