Skip to content

Commit

Permalink
✨ (lld): use dmk listenToKnownDevices in LLD
Browse files Browse the repository at this point in the history
  • Loading branch information
valpinkman committed Dec 30, 2024
1 parent c0c9da9 commit dcb02c8
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 79 deletions.
5 changes: 5 additions & 0 deletions .changeset/heavy-lobsters-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/live-dmk": minor
---

Update Transport.listen to emit add and remove events
5 changes: 5 additions & 0 deletions .changeset/tall-toys-invite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ledger-live-desktop": minor
---

use dmk listenToKnownDevices in LLD:useListenToHidDevices
1 change: 1 addition & 0 deletions apps/ledger-live-desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@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
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import Ellipsis from "~/renderer/components/Ellipsis";
import { BoxProps } from "./Box/Box";
import { Icons } from "@ledgerhq/react-ui";

console.log(Icons);

const T = styled(Box).attrs((p: { color?: string; inline?: boolean; ff?: string } & BoxProps) => ({
ff: p.ff || "Inter|Medium",
horizontal: true,
Expand All @@ -32,12 +30,10 @@ const T = styled(Box).attrs((p: { color?: string; inline?: boolean; ff?: string
width: ${p => (p.inline ? "" : "100%")};
overflow: hidden;
`;
const I = ({ color, children }: { color?: string; children: React.ReactNode }) => (
const I = ({ color = undefined, children }: { color?: string; children: React.ReactNode }) => (
<Box color={color}>{children}</Box>
);
I.defaultProps = {
color: undefined,
};

export type OwnProps = {
unit?: Unit;
val?: BigNumber | number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { Subscription, Observable } from "rxjs";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { useDeviceManagementKit, DeviceManagementKitTransport } from "@ledgerhq/live-dmk";
import { DeviceModelId } from "@ledgerhq/types-devices";
import { IPCTransport } from "~/renderer/IPCTransport";
import { addDevice, removeDevice, resetDevices } from "~/renderer/actions/devices";
import { IPCTransport } from "../IPCTransport";

export const useListenToHidDevices = () => {
const dispatch = useDispatch();
const ldmkFeatureFlag = useFeature("ldmkTransport");

const deviceManagementKit = useDeviceManagementKit();

useEffect(() => {
console.log("[[useListenToHidDevices]] init", deviceManagementKit);
let sub: Subscription;
function syncDevices() {
const devices: { [key: string]: boolean } = {};

sub = new Observable(IPCTransport.listen).subscribe(
({ device, deviceModel, type, descriptor }) => {
function syncDevices() {
sub = new Observable(IPCTransport.listen).subscribe({
next: ({ device, deviceModel, type, descriptor }) => {
if (device) {
const deviceId = descriptor || "";
const stateDevice = {
Expand All @@ -23,32 +29,63 @@ export const useListenToHidDevices = () => {
};

if (type === "add") {
devices[deviceId] = true;
dispatch(addDevice(stateDevice));
} else if (type === "remove") {
delete devices[deviceId];
dispatch(removeDevice(stateDevice));
}
}
},
() => {
error: () => {
resetDevices();
syncDevices();
},
() => {
complete: () => {
resetDevices();
syncDevices();
},
);
});
}

function syncDevicesWithDmk() {
sub = new Observable(DeviceManagementKitTransport.listen).subscribe({
next: ({ descriptor, device, deviceModel, type }) => {
if (device) {
const deviceId = descriptor || "";
const stateDevice = {
deviceId,
modelId: deviceModel ? deviceModel.id : DeviceModelId.nanoS,
// TODO: Update the Transport.listen type whenever we switch to LDMK
// @ts-expect-error remapping type
wired: deviceModel?.type === "USB",
};
if (type === "add") {
dispatch(addDevice(stateDevice));
} else if (type === "remove") {
dispatch(removeDevice(stateDevice));
}
}
},
error: () => {
resetDevices();
syncDevicesWithDmk();
},
complete: () => {
resetDevices();
syncDevicesWithDmk();
},
});
}

const timeoutSyncDevices = setTimeout(syncDevices, 1000);
const fn = ldmkFeatureFlag?.enabled ? syncDevicesWithDmk : syncDevices;

const timeoutSyncDevices = setTimeout(fn, 1000);

return () => {
console.log("[[useListenToHidDevices]] cleanup");
clearTimeout?.(timeoutSyncDevices);
sub?.unsubscribe?.();
};
}, [dispatch]);
}, [dispatch, deviceManagementKit, ldmkFeatureFlag?.enabled]);

return null;
};
118 changes: 62 additions & 56 deletions apps/ledger-live-desktop/src/renderer/live-common-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import "~/live-common-setup-base";
import "~/live-common-set-supported-currencies";
import "./families";

import { Store } from "redux";
import VaultTransport from "@ledgerhq/hw-transport-vault";
import { registerTransportModule } from "@ledgerhq/live-common/hw/index";
import { getEnv } from "@ledgerhq/live-env";
import { retry } from "@ledgerhq/live-common/promise";
import { TraceContext, listen as listenLogs, trace } from "@ledgerhq/logs";
import { getUserId } from "~/helpers/user";
Expand All @@ -17,11 +19,7 @@ import { overriddenFeatureFlagsSelector } from "~/renderer/reducers/settings";
import { State } from "./reducers";
import { DeviceManagementKitTransport } from "@ledgerhq/live-dmk";

interface Store {
getState: () => State;
}

const getFeatureWithOverrides = (key: FeatureId, store: Store) => {
const getFeatureWithOverrides = (key: FeatureId, store: Store<State>) => {
const state = store.getState();
const localOverrides = overriddenFeatureFlagsSelector(state);
return getFeature({ key, localOverrides });
Expand All @@ -30,67 +28,75 @@ const getFeatureWithOverrides = (key: FeatureId, store: Store) => {
export function registerTransportModules(store: Store) {
setEnvOnAllThreads("USER_ID", getUserId());
const vaultTransportPrefixID = "vault-transport:";
const ldmkFeatureFlag = getFeatureWithOverrides("ldmkTransport", store);
const ldmkFeatureFlag = () => getFeatureWithOverrides("ldmkTransport", store);
const isSpeculosEnabled = () => !!getEnv("SPECULOS_API_PORT");
const isProxyEnabled = () => !!getEnv("DEVICE_PROXY_URL");

listenLogs(({ id, date, ...log }) => {
if (log.type === "hid-frame") return;
logger.debug(log);
});

if (ldmkFeatureFlag.enabled) {
registerTransportModule({
id: "sdk",
open: (_id: string, timeoutMs?: number, context?: TraceContext) => {
trace({
type: "renderer-setup",
message: "Open called on registered module",
data: {
transport: "SDKTransport",
timeoutMs,
},
context: {
openContext: context,
},
});
return DeviceManagementKitTransport.open();
},
registerTransportModule({
id: "sdk",
open: (id: string, timeoutMs?: number, context?: TraceContext) => {
if (
!ldmkFeatureFlag().enabled ||
isSpeculosEnabled() ||
isProxyEnabled() ||
id.startsWith(vaultTransportPrefixID)
)
return;
trace({
type: "renderer-setup",
message: "Open called on registered module",
data: {
transport: "SDKTransport",
timeoutMs,
},
context: {
openContext: context,
},
});

return DeviceManagementKitTransport.open();
},

disconnect: () => Promise.resolve(),
});

disconnect: () => Promise.resolve(),
});
} else {
// Register IPC Transport Module
registerTransportModule({
id: "ipc",
open: (id: string, timeoutMs?: number, context?: TraceContext) => {
const originalDeviceMode = currentMode;
// id could be another type of transport such as vault-transport
if (id.startsWith(vaultTransportPrefixID)) return;
// Register IPC Transport Module
registerTransportModule({
id: "ipc",
open: (id: string, timeoutMs?: number, context?: TraceContext) => {
const originalDeviceMode = currentMode;
// id could be another type of transport such as vault-transport
if (id.startsWith(vaultTransportPrefixID)) return;

if (originalDeviceMode !== currentMode) {
setDeviceMode(originalDeviceMode);
}
if (originalDeviceMode !== currentMode) {
setDeviceMode(originalDeviceMode);
}

trace({
type: "renderer-setup",
message: "Open called on registered module",
data: {
transport: "IPCTransport",
timeoutMs,
},
context: {
openContext: context,
},
});
trace({
type: "renderer-setup",
message: "Open called on registered module",
data: {
transport: "IPCTransport",
timeoutMs,
},
context: {
openContext: context,
},
});

// Retries in the `renderer` process if the open failed. No retry is done in the `internal` process to avoid multiplying retries.
return retry(() => IPCTransport.open(id, timeoutMs, context), {
interval: 500,
maxRetry: 4,
});
},
disconnect: () => Promise.resolve(),
});
}
// Retries in the `renderer` process if the open failed. No retry is done in the `internal` process to avoid multiplying retries.
return retry(() => IPCTransport.open(id, timeoutMs, context), {
interval: 500,
maxRetry: 4,
});
},
disconnect: () => Promise.resolve(),
});

// Register Vault Transport Module
registerTransportModule({
Expand Down
1 change: 1 addition & 0 deletions libs/live-dmk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
},
"dependencies": {
"@ledgerhq/device-management-kit": "^0.5.1",
"@ledgerhq/types-devices": "workspace:^",
"@ledgerhq/hw-transport": "workspace:^",
"@ledgerhq/logs": "^6.12.0",
"@ledgerhq/types-devices": "workspace:^",
Expand Down
Loading

0 comments on commit dcb02c8

Please sign in to comment.