1 | import HID from "node-hid";
|
2 | import TransportNodeHidNoEvents, { getDevices } from "@ledgerhq/hw-transport-node-hid-noevents";
|
3 | import { identifyUSBProductId } from "@ledgerhq/devices";
|
4 | import { TransportError } from "@ledgerhq/errors";
|
5 | import listenDevices from "./listenDevices";
|
6 | let listenDevicesDebounce = 500;
|
7 | let listenDevicesPollingSkip = () => false;
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | class TransportNodeHid extends TransportNodeHidNoEvents {
|
16 | |
17 |
|
18 |
|
19 | static open(path) {
|
20 | return Promise.resolve().then(() => {
|
21 | if (path) {
|
22 | return new TransportNodeHid(new HID.HID(path));
|
23 | }
|
24 | const device = getDevices()[0];
|
25 | if (!device)
|
26 | throw new TransportError("NoDevice", "NoDevice");
|
27 | return new TransportNodeHid(new HID.HID(device.path));
|
28 | });
|
29 | }
|
30 | }
|
31 |
|
32 |
|
33 |
|
34 | TransportNodeHid.isSupported = TransportNodeHidNoEvents.isSupported;
|
35 |
|
36 |
|
37 |
|
38 | TransportNodeHid.list = TransportNodeHidNoEvents.list;
|
39 |
|
40 |
|
41 |
|
42 | TransportNodeHid.setListenDevicesDebounce = (delay) => {
|
43 | listenDevicesDebounce = delay;
|
44 | };
|
45 |
|
46 |
|
47 |
|
48 | TransportNodeHid.setListenDevicesPollingSkip = (conditionToSkip) => {
|
49 | listenDevicesPollingSkip = conditionToSkip;
|
50 | };
|
51 |
|
52 |
|
53 |
|
54 | TransportNodeHid.setListenDevicesDebug = () => {
|
55 | console.warn("setListenDevicesDebug is deprecated. Use @ledgerhq/logs instead. No logs will get emitted there anymore.");
|
56 | };
|
57 |
|
58 |
|
59 | TransportNodeHid.listen = (observer) => {
|
60 | let unsubscribed = false;
|
61 | Promise.resolve(getDevices()).then(devices => {
|
62 |
|
63 | for (const device of devices) {
|
64 | if (!unsubscribed) {
|
65 | const descriptor = device.path;
|
66 | const deviceModel = identifyUSBProductId(device.productId);
|
67 | observer.next({
|
68 | type: "add",
|
69 | descriptor,
|
70 | device,
|
71 | deviceModel,
|
72 | });
|
73 | }
|
74 | }
|
75 | });
|
76 | const { events, stop } = listenDevices(listenDevicesDebounce, listenDevicesPollingSkip);
|
77 | const onAdd = device => {
|
78 | if (unsubscribed || !device)
|
79 | return;
|
80 | const deviceModel = identifyUSBProductId(device.productId);
|
81 | observer.next({
|
82 | type: "add",
|
83 | descriptor: device.path,
|
84 | deviceModel,
|
85 | device,
|
86 | });
|
87 | };
|
88 | const onRemove = device => {
|
89 | if (unsubscribed || !device)
|
90 | return;
|
91 | const deviceModel = identifyUSBProductId(device.productId);
|
92 | observer.next({
|
93 | type: "remove",
|
94 | descriptor: device.path,
|
95 | deviceModel,
|
96 | device,
|
97 | });
|
98 | };
|
99 | events.on("add", onAdd);
|
100 | events.on("remove", onRemove);
|
101 | function unsubscribe() {
|
102 | unsubscribed = true;
|
103 | events.removeListener("add", onAdd);
|
104 | events.removeListener("remove", onRemove);
|
105 | stop();
|
106 | }
|
107 | return {
|
108 | unsubscribe,
|
109 | };
|
110 | };
|
111 | export default TransportNodeHid;
|
112 |
|
\ | No newline at end of file |