Skip to content

Commit

Permalink
Merge pull request #6055 from LedgerHQ/support/refacto-list-apps-v2
Browse files Browse the repository at this point in the history
[LIVE-10952][Common] Refactoring of list apps
  • Loading branch information
ofreyssinet-ledger authored and jdabbech-ledger committed Feb 19, 2024
2 parents 57aacaf + 049635e commit 413e81f
Show file tree
Hide file tree
Showing 31 changed files with 809 additions and 205 deletions.
11 changes: 11 additions & 0 deletions .changeset/young-books-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@ledgerhq/live-common": patch
---

Refactor list apps v2:
- move entrypoint to `live-common/src/device/use-cases/listAppsUseCase.ts`
- move more of the `manager/api.ts` logic to `ManagerApiRepository`
- create `StubManagerApiRepository` for mocks
- implement some unit tests for `listApps/v2.ts`

Implement `getProviderIdUseCase` that takes `forceProvider: number` as a parameter
7 changes: 5 additions & 2 deletions apps/cli/src/commands/appUninstallAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { mergeMap, filter, map } from "rxjs/operators";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import getDeviceInfo from "@ledgerhq/live-common/hw/getDeviceInfo";
import { reducer, runAll } from "@ledgerhq/live-common/apps/index";
import { listApps, execWithTransport } from "@ledgerhq/live-common/apps/hw";
import {
listAppsUseCase,
execWithTransport,
} from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import { command as uninstallAllApps } from "@ledgerhq/live-common/hw/uninstallAllApps";
import { deviceOpt } from "../scan";

Expand All @@ -25,7 +28,7 @@ export default {
} else {
return from(getDeviceInfo(t)).pipe(
mergeMap(deviceInfo =>
listApps(t, deviceInfo).pipe(
listAppsUseCase(t, deviceInfo).pipe(
filter(e => e.type === "result"),
map((e: any) =>
reducer(e.result, {
Expand Down
7 changes: 5 additions & 2 deletions apps/cli/src/commands/appsCheckAllAppVersions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import network from "@ledgerhq/live-network/network";
import installApp from "@ledgerhq/live-common/hw/installApp";
import uninstallApp from "@ledgerhq/live-common/hw/uninstallApp";
import { initState, reducer, runAll } from "@ledgerhq/live-common/apps/index";
import { listApps, execWithTransport } from "@ledgerhq/live-common/apps/hw";
import {
listAppsUseCase,
execWithTransport,
} from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import { delay } from "@ledgerhq/live-common/promise";
import { getEnv } from "@ledgerhq/live-env";
import { getDependencies } from "@ledgerhq/live-common/apps/polyfill";
Expand Down Expand Up @@ -274,7 +277,7 @@ const checkInstalled = (installed, candidate: Candidate) => {
};

const wipeAll = (t, deviceInfo) =>
listApps(t, deviceInfo).pipe(
listAppsUseCase(t, deviceInfo).pipe(
filter(e => e.type === "result"),
map((e: any) => e.result),
mergeMap(listAppsResult => {
Expand Down
7 changes: 5 additions & 2 deletions apps/cli/src/commands/appsInstallAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { mergeMap, filter, map } from "rxjs/operators";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import getDeviceInfo from "@ledgerhq/live-common/hw/getDeviceInfo";
import { initState, reducer, runAll } from "@ledgerhq/live-common/apps/index";
import { listApps, execWithTransport } from "@ledgerhq/live-common/apps/hw";
import {
listAppsUseCase,
execWithTransport,
} from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import { deviceOpt } from "../scan";
export default {
description: "test script to install and uninstall all apps",
Expand All @@ -18,7 +21,7 @@ export default {
const exec = execWithTransport(t);
return from(getDeviceInfo(t)).pipe(
mergeMap(deviceInfo =>
listApps(t, deviceInfo).pipe(
listAppsUseCase(t, deviceInfo).pipe(
filter(e => e.type === "result"),
map((e: any) =>
e.result.appsListNames.reduce(
Expand Down
9 changes: 6 additions & 3 deletions apps/cli/src/commands/appsUpdateTestAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { mergeMap, ignoreElements, filter, map } from "rxjs/operators";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import getDeviceInfo from "@ledgerhq/live-common/hw/getDeviceInfo";
import { initState, reducer, runAll, getActionPlan } from "@ledgerhq/live-common/apps/index";
import { listApps, execWithTransport } from "@ledgerhq/live-common/apps/hw";
import {
listAppsUseCase,
execWithTransport,
} from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import type { AppOp } from "@ledgerhq/live-common/apps/types";
import { deviceOpt } from "../scan";

Expand Down Expand Up @@ -34,7 +37,7 @@ export default {
// FIXME: mergeMap deprecated, using map inside pipe should do the work
map(
deviceInfo =>
listApps(t, deviceInfo).pipe(
listAppsUseCase(t, deviceInfo).pipe(
filter(e => e.type === "result"),
map((e: any) => e.result),
mergeMap(listAppsResult => {
Expand Down Expand Up @@ -82,7 +85,7 @@ export default {
new Observable(o => {
let sub;
const timeout = setTimeout(() => {
sub = listApps(t, deviceInfo).subscribe(o);
sub = listAppsUseCase(t, deviceInfo).subscribe(o);
}, 4000);
return () => {
clearTimeout(timeout);
Expand Down
7 changes: 5 additions & 2 deletions apps/cli/src/commands/devDeviceAppsScenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import getDeviceInfo from "@ledgerhq/live-common/hw/getDeviceInfo";
import { initState, ListAppsResult, reducer, runAll } from "@ledgerhq/live-common/apps/index";
import ManagerAPI from "@ledgerhq/live-common/manager/api";
import { listApps, execWithTransport } from "@ledgerhq/live-common/apps/hw";
import {
listAppsUseCase,
execWithTransport,
} from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import installApp from "@ledgerhq/live-common/hw/installApp";
import { deviceOpt } from "../scan";
import { Application } from "@ledgerhq/types-live";
Expand Down Expand Up @@ -64,7 +67,7 @@ export default {
// $FlowFixMe
return from(getDeviceInfo(t)).pipe(
mergeMap(deviceInfo =>
listApps(t, deviceInfo).pipe(
listAppsUseCase(t, deviceInfo).pipe(
filter<any>(e => e.type === "result"),
map<{ type: "result"; result: ListAppsResult }, ListAppsResult>(e => e.result),
mergeMap<ListAppsResult, Observable<Application[]>>(listAppsResult => {
Expand Down
7 changes: 5 additions & 2 deletions apps/cli/src/commands/managerListApps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { from } from "rxjs";
import { filter, map, mergeMap, repeat } from "rxjs/operators";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import getDeviceInfo from "@ledgerhq/live-common/hw/getDeviceInfo";
import { enableListAppsV2, listApps } from "@ledgerhq/live-common/apps/hw";
import {
enableListAppsV2,
listAppsUseCase,
} from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import { deviceOpt } from "../scan";
export default {
description: "List apps that can be installed on the device",
Expand Down Expand Up @@ -44,7 +47,7 @@ export default {
return withDevice(device || "")(t =>
from(getDeviceInfo(t)).pipe(
mergeMap(deviceInfo =>
listApps(t, deviceInfo).pipe(
listAppsUseCase(t, deviceInfo).pipe(
filter(e => e.type === "result"),
// @ts-expect-error we need better typings and safe guard to infer types
map(e => e.result),
Expand Down
2 changes: 1 addition & 1 deletion apps/ledger-live-desktop/src/renderer/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import VaultSignerBanner from "~/renderer/components/VaultSignerBanner";
import { hasCompletedOnboardingSelector } from "~/renderer/reducers/settings";
import { updateIdentify } from "./analytics/segment";
import { useFeature, FeatureToggle } from "@ledgerhq/live-common/featureFlags/index";
import { enableListAppsV2 } from "@ledgerhq/live-common/apps/hw";
import { enableListAppsV2 } from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import {
useFetchCurrencyAll,
useFetchCurrencyFrom,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo, useState, useEffect, useRef, useContext } from "react";
import { useSelector } from "react-redux";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import { execWithTransport } from "@ledgerhq/live-common/apps/hw";
import { execWithTransport } from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import { App, DeviceInfo, FirmwareUpdateContext } from "@ledgerhq/types-live";
import { AppOp, ListAppsResult } from "@ledgerhq/live-common/apps/types";
import { distribute, initState } from "@ledgerhq/live-common/apps/logic";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import BaseOnboardingNavigator from "./BaseOnboardingNavigator";
import { RootStackParamList } from "./types/RootNavigator";
import { AnalyticsContextProvider } from "~/analytics/AnalyticsContext";
import { StartupTimeMarker } from "../../StartupTimeMarker";
import { enableListAppsV2 } from "@ledgerhq/live-common/apps/hw";
import { enableListAppsV2 } from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";

export default function RootNavigator() {
const hasCompletedOnboarding = useSelector(hasCompletedOnboardingSelector);
Expand Down
2 changes: 1 addition & 1 deletion apps/ledger-live-mobile/src/screens/Manager/shared.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useCallback } from "react";
import type { Exec, ListAppsResult } from "@ledgerhq/live-common/apps/index";
import { useAppsRunner } from "@ledgerhq/live-common/apps/react";
import { execWithTransport } from "@ledgerhq/live-common/apps/hw";
import { withDevice } from "@ledgerhq/live-common/hw/deviceAccess";
import { execWithTransport } from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";

export function useApps(listAppsRes: ListAppsResult, deviceId: string, appsToRestore?: string[]) {
const exec: Exec = useCallback(
Expand Down
4 changes: 2 additions & 2 deletions apps/ledger-live-mobile/src/screens/PairDevices/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { timeout, tap } from "rxjs/operators";
import { v4 as uuid } from "uuid";
import getDeviceInfo from "@ledgerhq/live-common/hw/getDeviceInfo";
import getDeviceName from "@ledgerhq/live-common/hw/getDeviceName";
import { listApps } from "@ledgerhq/live-common/apps/hw";
import { listAppsUseCase } from "@ledgerhq/live-common/device/use-cases/listAppsUseCase";
import { DeviceModelId } from "@ledgerhq/devices";
import { delay } from "@ledgerhq/live-common/promise";
import type { Device } from "@ledgerhq/live-common/hw/actions/types";
Expand Down Expand Up @@ -145,7 +145,7 @@ function PairDevicesInner({ navigation, route }: NavigationProps) {

// Waits until listApps completes or emits and error
await lastValueFrom(
listApps(transport, deviceInfo).pipe(
listAppsUseCase(transport, deviceInfo).pipe(
timeout(GENUINE_CHECK_TIMEOUT),
tap(e => {
tracer.trace("Event from listApps", { eventType: e.type });
Expand Down
35 changes: 0 additions & 35 deletions libs/ledger-live-common/src/apps/hw.ts

This file was deleted.

4 changes: 2 additions & 2 deletions libs/ledger-live-common/src/apps/inlineAppInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Transport from "@ledgerhq/hw-transport";
import { Observable, concat, of, from, EMPTY, defer } from "rxjs";
import { ConnectAppEvent } from "../hw/connectApp";
import getDeviceInfo from "../hw/getDeviceInfo";
import { listApps, execWithTransport } from "./hw";
import { listAppsUseCase, execWithTransport } from "../device/use-cases/listAppsUseCase";
import { reducer, initState, isOutOfMemoryState, predictOptimisticState } from "./logic";
import { runAllWithProgress } from "./runner";
import { InlineAppInstallEvent } from "./types";
Expand Down Expand Up @@ -43,7 +43,7 @@ const inlineAppInstall = ({
from(getDeviceInfo(transport)).pipe(
mergeMap(deviceInfo => {
tracer.trace("Got device info", { deviceInfo });
return listApps(transport, deviceInfo);
return listAppsUseCase(transport, deviceInfo);
}),
mergeMap(e => {
// Bubble up events
Expand Down
14 changes: 10 additions & 4 deletions libs/ledger-live-common/src/apps/listApps/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@ import { getEnv } from "@ledgerhq/live-env";
import { calculateDependencies, polyfillApp, polyfillApplication } from "../polyfill";
import getDeviceName from "../../hw/getDeviceName";
import { getLatestFirmwareForDeviceUseCase } from "../../device/use-cases/getLatestFirmwareForDeviceUseCase";
import { ManagerApiRepository } from "../../device-core/managerApi/repositories/ManagerApiRepository";

const appsThatKeepChangingHashes = ["Fido U2F", "Security Key"];

const emptyHashData = "0000000000000000000000000000000000000000000000000000000000000000";

//TODO if you are reading this, don't worry, a big rewrite is coming and we'll be able
//to simplify this a lot. Stay calm.
const listApps = (transport: Transport, deviceInfo: DeviceInfo): Observable<ListAppsEvent> => {
export const listApps = (
transport: Transport,
deviceInfo: DeviceInfo,
managerApiRepository: ManagerApiRepository,
): Observable<ListAppsEvent> => {
const tracer = new LocalTracer("list-apps", { transport: transport.getTraceContext() });
tracer.trace("Using legacy version", { deviceInfo });

Expand Down Expand Up @@ -87,7 +92,10 @@ const listApps = (transport: Transport, deviceInfo: DeviceInfo): Observable<List
}),
);

const latestFirmwareForDeviceP = getLatestFirmwareForDeviceUseCase(deviceInfo);
const latestFirmwareForDeviceP = getLatestFirmwareForDeviceUseCase(
deviceInfo,
managerApiRepository,
);

const firmwareP = Promise.all([firmwareDataP, latestFirmwareForDeviceP]).then(
([firmwareData, updateAvailable]) => ({
Expand Down Expand Up @@ -297,5 +305,3 @@ const listApps = (transport: Transport, deviceInfo: DeviceInfo): Observable<List
};
});
};

export default listApps;
Loading

0 comments on commit 413e81f

Please sign in to comment.