Skip to content

Commit

Permalink
chore: bump dmk to stable version
Browse files Browse the repository at this point in the history
  • Loading branch information
valpinkman committed Jan 30, 2025
1 parent 467bed6 commit 1101109
Show file tree
Hide file tree
Showing 13 changed files with 264 additions and 66 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test-libs-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
test-libraries:
name: "Test Libraries"
env:
NODE_OPTIONS: "--max-old-space-size=8192"
NODE_OPTIONS: "--max-old-space-size=7168"
FORCE_COLOR: 3
CI_OS: ubuntu-22.04

Expand Down
1 change: 0 additions & 1 deletion apps/ledger-live-desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"@ledgerhq/coin-filecoin": "workspace:^",
"@ledgerhq/coin-framework": "workspace:^",
"@ledgerhq/devices": "workspace:*",
"@ledgerhq/device-management-kit": "0.5.1",
"@ledgerhq/domain-service": "workspace:^",
"@ledgerhq/errors": "workspace:^",
"@ledgerhq/ethereum-provider": "workspace:^",
Expand Down
18 changes: 1 addition & 17 deletions libs/ledger-live-common/src/hw/connectApp.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import semver from "semver";
import { Observable, concat, from, of, throwError, defer, merge, timer } from "rxjs";
import { Observable, concat, from, of, throwError, defer, merge } from "rxjs";
import { mergeMap, concatMap, map, catchError, delay } from "rxjs/operators";
import {
TransportStatusError,
Expand Down Expand Up @@ -127,10 +127,6 @@ export type ConnectAppEvent =
}
| LockedDeviceEvent;

const isDMKError = (e: unknown) => {
return e && typeof e === "object" && "_tag" in e && e._tag === "WebHidSendReportError";
};

export const openAppFromDashboard = (
transport: Transport,
appName: string,
Expand Down Expand Up @@ -439,18 +435,6 @@ const cmd = ({ deviceId, request }: Input): Observable<ConnectAppEvent> => {
});
}

if (isDMKError(e)) {
return timer(500).pipe(
mergeMap(() =>
innerSub({
appName,
dependencies,
allowPartialDependencies,
}),
),
);
}

if (e && e instanceof TransportStatusError) {
switch (e.statusCode) {
case StatusCodes.CLA_NOT_SUPPORTED: // in 1.3.1 dashboard
Expand Down
8 changes: 5 additions & 3 deletions libs/live-dmk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"typecheck": "tsc --noEmit",
"unimported": "unimported",
"test": "vitest run",
"test:watch": "vitest"
"test:watch": "vitest",
"test:coverage": "vitest run --coverage"
},
"typesVersions": {
"*": {
Expand All @@ -44,8 +45,8 @@
}
},
"dependencies": {
"@ledgerhq/device-management-kit": "0.0.0-develop-20250106155719",
"@ledgerhq/device-transport-kit-web-hid": "0.0.0-develop-20250106155719",
"@ledgerhq/device-management-kit": "0.6.0",
"@ledgerhq/device-transport-kit-web-hid": "1.0.1",
"@ledgerhq/hw-transport": "workspace:^",
"@ledgerhq/logs": "^6.12.0",
"@ledgerhq/types-devices": "workspace:^",
Expand All @@ -59,6 +60,7 @@
"@testing-library/react": "^16.1.0",
"@types/node": "22.10.1",
"@vitejs/plugin-react": "4.3.4",
"@vitest/coverage-v8": "2.1.8",
"jsdom": "25.0.1",
"vite": "6.0.7",
"vitest": "2.1.8",
Expand Down
9 changes: 9 additions & 0 deletions libs/live-dmk/src/config/deviceIdMap.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { deviceIdMap } from "./deviceIdMap";
import { DeviceModelId as DMKDeviceModelId } from "@ledgerhq/device-management-kit";
import { DeviceModelId as LLDeviceModelId } from "@ledgerhq/types-devices";

describe("deviceIdMap", () => {
it("should map DMK device model ids to LL device model ids", () => {
expect(deviceIdMap[DMKDeviceModelId.FLEX]).toBe(LLDeviceModelId.europa);
});
});
21 changes: 21 additions & 0 deletions libs/live-dmk/src/config/errors.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { DeviceBusyError } from "@ledgerhq/device-management-kit";
import { isAllowedOnboardingStatePollingErrorDmk } from "./errors";
import { WebHidSendReportError } from "@ledgerhq/device-transport-kit-web-hid";

describe("isAllowedOnboardingStatePollingErrorDmk", () => {
it("should return true if the error is a DeviceBusyError", () => {
expect(isAllowedOnboardingStatePollingErrorDmk(new DeviceBusyError())).toBe(true);
});

it("should return true if the error is a WebHidSendReportError", () => {
expect(isAllowedOnboardingStatePollingErrorDmk(new WebHidSendReportError())).toBe(true);
});

it("should return false if the error is not a DeviceBusyError or WebHidSendReportError", () => {
expect(isAllowedOnboardingStatePollingErrorDmk(new Error())).toBe(false);
});

it("should return false if the error is undefined", () => {
expect(isAllowedOnboardingStatePollingErrorDmk(undefined)).toBe(false);
});
});
6 changes: 5 additions & 1 deletion libs/live-dmk/src/config/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { WebHidSendReportError } from "@ledgerhq/device-transport-kit-web-hid";

export const isAllowedOnboardingStatePollingErrorDmk = (error: unknown): boolean => {
if (error) {
return error instanceof DeviceBusyError || error instanceof WebHidSendReportError;
return (
error instanceof DeviceBusyError ||
error instanceof WebHidSendReportError ||
(typeof error === "object" && "_tag" in error && error._tag === "DeviceSessionNotFound")
);
}

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ describe("useDeviceSessionRefresherToggle", () => {
});
});

describe.todo("enabled = false", () => {
describe("enabled = false", () => {
it("should not toggle the device session refresher on if there is no active session", () => {
renderHook(() => useDeviceSessionRefresherToggle(false));
expect(deviceManagementKitMock.toggleDeviceSessionRefresher).not.toHaveBeenCalled();
Expand Down
15 changes: 11 additions & 4 deletions libs/live-dmk/src/hooks/useDeviceSessionRefresherToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ export const useDeviceSessionRefresherToggle = (enabled: boolean) => {
if (session) {
if (sessionId.current !== session.sessionId) {
if (sessionId.current) {
sdk.toggleDeviceSessionRefresher({
sessionId: sessionId.current,
enabled: true,
});
try {
sdk.toggleDeviceSessionRefresher({
sessionId: sessionId.current,
enabled: true,
});
} catch (error) {
console.error(
`[useDeviceSessionRefresherToggle] error toggling back device session refresher ${sessionId.current}`,
error,
);
}
}

sessionId.current = session.sessionId;
Expand Down
63 changes: 63 additions & 0 deletions libs/live-dmk/src/transport/DeviceManagementKitTransport.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { of, Subject } from "rxjs";
import {
DeviceModelId,
DeviceStatus,
DiscoveredDevice,
DeviceSessionState,
} from "@ledgerhq/device-management-kit";
import { DeviceManagementKitTransport } from "./DeviceManagementKitTransport";
import { deviceManagementKit } from "../hooks/useDeviceManagementKit";
// import { activeDeviceSessionSubject } from "../config/activeDeviceSession";

let obs: Subject<DeviceSessionState> = new Subject<DeviceSessionState>();
let transport: DeviceManagementKitTransport;
describe("DeviceManagementKitTransport", () => {
beforeAll(async () => {
vi.spyOn(deviceManagementKit, "listenToKnownDevices").mockImplementation(() => {
return of<DiscoveredDevice[]>([
{
id: `test-123`,
deviceModel: {
id: `stax-123`,
model: DeviceModelId.STAX,
name: "stax",
},
transport: "web-hid",
},
]);
});
vi.spyOn(deviceManagementKit, "connect").mockResolvedValue(`session-123`);
vi.spyOn(deviceManagementKit, "getDeviceSessionState").mockImplementation(() => {
obs.next({
deviceStatus: DeviceStatus.CONNECTED,
} as DeviceSessionState);
return obs;
});

transport = await DeviceManagementKitTransport.open();
});

afterEach(() => {
obs.complete();
obs = new Subject<DeviceSessionState>();
vi.clearAllMocks();
});

it("should open a device", async () => {
expect(transport).toBeInstanceOf(DeviceManagementKitTransport);
});

it("should be able to exchange APDU", async () => {
vi.spyOn(deviceManagementKit, "sendApdu").mockResolvedValue({
data: Buffer.from([]),
statusCode: Buffer.from([0x90, 0x00]),
});

const expected = Buffer.from([0x90, 0x00]);
const apdu = Buffer.from([0x00, 0x01, 0x02, 0x03]);

const response = await transport.exchange(apdu);

expect(response).toEqual(expected);
});
});
12 changes: 11 additions & 1 deletion libs/live-dmk/src/transport/DeviceManagementKitTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { deviceManagementKit } from "../hooks/useDeviceManagementKit";
const tracer = new LocalTracer("live-dmk", { function: "DeviceManagementKitTransport" });

export class DeviceManagementKitTransport extends Transport {
readonly sessionId: string;
sessionId: string;
readonly sdk: DeviceManagementKit;

constructor(sdk: DeviceManagementKit, sessionId: string) {
Expand Down Expand Up @@ -136,6 +136,16 @@ export class DeviceManagementKitTransport extends Transport {

async exchange(apdu: Buffer): Promise<Buffer> {
tracer.trace(`[exchange] => ${apdu.toString("hex")}`);

const devices = await this.sdk.listConnectedDevices();

// If the device is not connected, connect to new session
if (!devices.some(device => device.sessionId === this.sessionId)) {
const [discoveredDevice] = await firstValueFrom(deviceManagementKit.listenToKnownDevices());
const connectedSessionId = await deviceManagementKit.connect({ device: discoveredDevice });
this.sessionId = connectedSessionId;
}

return await this.sdk
.sendApdu({
sessionId: this.sessionId,
Expand Down
7 changes: 7 additions & 0 deletions libs/live-dmk/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,12 @@ export default defineConfig({
exclude: ["node_modules", "lib-es"],
silent: false,
printConsoleTrace: true,
coverage: {
enabled: true,
provider: "v8",
reporter: ["text", "html"],
include: ["src/**/*.ts", "src/**/*.tsx"],
exclude: ["node_modules", "lib-es", "src/hooks/index.ts", "src/index.ts", "src/**/*.test.*"],
},
},
});
Loading

0 comments on commit 1101109

Please sign in to comment.