@ledgerhq/hw-transport-node-hid-singleton 6.24.1 → 6.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,10 +17,13 @@ Allows to communicate with Ledger Hardware Wallets.
17
17
 
18
18
  * [TransportNodeHidSingleton](#transportnodehidsingleton)
19
19
  * [Examples](#examples)
20
+ * [exchange](#exchange)
21
+ * [Parameters](#parameters)
20
22
  * [isSupported](#issupported)
21
23
  * [list](#list)
22
24
  * [listen](#listen)
23
- * [Parameters](#parameters)
25
+ * [Parameters](#parameters-1)
26
+ * [autoDisconnect](#autodisconnect)
24
27
  * [disconnect](#disconnect)
25
28
  * [open](#open)
26
29
 
@@ -38,6 +41,16 @@ import TransportNodeHid from "@ledgerhq/hw-transport-node-hid-singleton";
38
41
  TransportNodeHid.create().then(transport => ...)
39
42
  ```
40
43
 
44
+ #### exchange
45
+
46
+ Exchange with the device using APDU protocol.
47
+
48
+ ##### Parameters
49
+
50
+ * `apdu` **[Buffer](https://nodejs.org/api/buffer.html)**
51
+
52
+ Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Buffer](https://nodejs.org/api/buffer.html)>** a promise of apdu response
53
+
41
54
  #### isSupported
42
55
 
43
56
  #### list
@@ -50,6 +63,12 @@ TransportNodeHid.create().then(transport => ...)
50
63
 
51
64
  Returns **Subscription**
52
65
 
66
+ #### autoDisconnect
67
+
68
+ convenience wrapper for auto-disconnect logic
69
+
70
+ Returns **void**
71
+
53
72
  #### disconnect
54
73
 
55
74
  globally disconnect the transport singleton
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import TransportNodeHidNoEvents from "@ledgerhq/hw-transport-node-hid-noevents";
2
3
  import type { Observer, DescriptorEvent, Subscription } from "@ledgerhq/hw-transport";
3
4
  /**
@@ -8,6 +9,7 @@ import type { Observer, DescriptorEvent, Subscription } from "@ledgerhq/hw-trans
8
9
  * TransportNodeHid.create().then(transport => ...)
9
10
  */
10
11
  export default class TransportNodeHidSingleton extends TransportNodeHidNoEvents {
12
+ preventAutoDisconnect: boolean;
11
13
  /**
12
14
  *
13
15
  */
@@ -19,6 +21,10 @@ export default class TransportNodeHidSingleton extends TransportNodeHidNoEvents
19
21
  /**
20
22
  */
21
23
  static listen: (observer: Observer<DescriptorEvent<any>>) => Subscription;
24
+ /**
25
+ * convenience wrapper for auto-disconnect logic
26
+ */
27
+ static autoDisconnect(): void;
22
28
  /**
23
29
  * globally disconnect the transport singleton
24
30
  */
@@ -27,6 +33,13 @@ export default class TransportNodeHidSingleton extends TransportNodeHidNoEvents
27
33
  * if path="" is not provided, the library will take the first device
28
34
  */
29
35
  static open(): Promise<TransportNodeHidSingleton>;
36
+ setAllowAutoDisconnect(allow: boolean): void;
37
+ /**
38
+ * Exchange with the device using APDU protocol.
39
+ * @param apdu
40
+ * @returns a promise of apdu response
41
+ */
42
+ exchange(apdu: Buffer): Promise<Buffer>;
30
43
  close(): Promise<void>;
31
44
  }
32
45
  //# sourceMappingURL=TransportNodeHid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TransportNodeHid.d.ts","sourceRoot":"","sources":["../src/TransportNodeHid.ts"],"names":[],"mappings":"AACA,OAAO,wBAEN,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACb,MAAM,wBAAwB,CAAC;AAMhC;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,yBAA0B,SAAQ,wBAAwB;IAC7E;;OAEG;IACH,MAAM,CAAC,WAAW,yBAAwC;IAE1D;;OAEG;IACH,MAAM,CAAC,IAAI,qBAAiC;IAE5C;OACG;IACH,MAAM,CAAC,MAAM,aAAc,SAAS,gBAAgB,GAAG,CAAC,CAAC,KAAG,YAAY,CAqDtE;IAEF;;OAEG;WACU,UAAU;IAQvB;;OAEG;IACH,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,yBAAyB,CAAC;IAoCjD,KAAK;CAIN"}
1
+ {"version":3,"file":"TransportNodeHid.d.ts","sourceRoot":"","sources":["../src/TransportNodeHid.ts"],"names":[],"mappings":";AACA,OAAO,wBAEN,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACb,MAAM,wBAAwB,CAAC;AAuBhC;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,yBAA0B,SAAQ,wBAAwB;IAC7E,qBAAqB,UAAS;IAC9B;;OAEG;IACH,MAAM,CAAC,WAAW,yBAAwC;IAE1D;;OAEG;IACH,MAAM,CAAC,IAAI,qBAAiC;IAE5C;OACG;IACH,MAAM,CAAC,MAAM,aAAc,SAAS,gBAAgB,GAAG,CAAC,CAAC,KAAG,YAAY,CAqDtE;IAEF;;OAEG;WACU,cAAc,IAAI,IAAI;IAWnC;;OAEG;WACU,UAAU;IASvB;;OAEG;IACH,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,yBAAyB,CAAC;IAqCjD,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI5C;;;;OAIG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAMvB"}
@@ -16,7 +16,11 @@ var __extends = (this && this.__extends) || (function () {
16
16
  })();
17
17
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
18
  if (k2 === undefined) k2 = k;
19
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
20
24
  }) : (function(o, m, k, k2) {
21
25
  if (k2 === undefined) k2 = k;
22
26
  o[k2] = m[k];
@@ -91,6 +95,17 @@ var devices_1 = require("@ledgerhq/devices");
91
95
  var errors_1 = require("@ledgerhq/errors");
92
96
  var listenDevices_1 = require("./listenDevices");
93
97
  var transportInstance;
98
+ var DISCONNECT_TIMEOUT = 5000;
99
+ var disconnectTimeout;
100
+ var clearDisconnectTimeout = function () {
101
+ if (disconnectTimeout) {
102
+ clearTimeout(disconnectTimeout);
103
+ }
104
+ };
105
+ var setDisconnectTimeout = function () {
106
+ clearDisconnectTimeout();
107
+ disconnectTimeout = setTimeout(function () { return TransportNodeHidSingleton.autoDisconnect(); }, DISCONNECT_TIMEOUT);
108
+ };
94
109
  /**
95
110
  * node-hid Transport implementation
96
111
  * @example
@@ -101,8 +116,29 @@ var transportInstance;
101
116
  var TransportNodeHidSingleton = /** @class */ (function (_super) {
102
117
  __extends(TransportNodeHidSingleton, _super);
103
118
  function TransportNodeHidSingleton() {
104
- return _super !== null && _super.apply(this, arguments) || this;
119
+ var _this = _super !== null && _super.apply(this, arguments) || this;
120
+ _this.preventAutoDisconnect = false;
121
+ return _this;
105
122
  }
123
+ /**
124
+ * convenience wrapper for auto-disconnect logic
125
+ */
126
+ TransportNodeHidSingleton.autoDisconnect = function () {
127
+ return __awaiter(this, void 0, void 0, function () {
128
+ return __generator(this, function (_a) {
129
+ if (transportInstance && !transportInstance.preventAutoDisconnect) {
130
+ (0, logs_1.log)("hid-verbose", "triggering auto disconnect");
131
+ TransportNodeHidSingleton.disconnect();
132
+ }
133
+ else if (transportInstance) {
134
+ // If we have disabled the auto-disconnect, try again in DISCONNECT_TIMEOUT
135
+ clearDisconnectTimeout();
136
+ setDisconnectTimeout();
137
+ }
138
+ return [2 /*return*/];
139
+ });
140
+ });
141
+ };
106
142
  /**
107
143
  * globally disconnect the transport singleton
108
144
  */
@@ -114,6 +150,7 @@ var TransportNodeHidSingleton = /** @class */ (function (_super) {
114
150
  transportInstance.emit("disconnect");
115
151
  transportInstance = null;
116
152
  }
153
+ clearDisconnectTimeout();
117
154
  return [2 /*return*/];
118
155
  });
119
156
  });
@@ -122,6 +159,7 @@ var TransportNodeHidSingleton = /** @class */ (function (_super) {
122
159
  * if path="" is not provided, the library will take the first device
123
160
  */
124
161
  TransportNodeHidSingleton.open = function () {
162
+ clearDisconnectTimeout();
125
163
  return Promise.resolve().then(function () {
126
164
  if (transportInstance) {
127
165
  (0, logs_1.log)("hid-verbose", "reusing opened transport instance");
@@ -150,8 +188,34 @@ var TransportNodeHidSingleton = /** @class */ (function (_super) {
150
188
  return transportInstance;
151
189
  });
152
190
  };
191
+ TransportNodeHidSingleton.prototype.setAllowAutoDisconnect = function (allow) {
192
+ this.preventAutoDisconnect = !allow;
193
+ };
194
+ /**
195
+ * Exchange with the device using APDU protocol.
196
+ * @param apdu
197
+ * @returns a promise of apdu response
198
+ */
199
+ TransportNodeHidSingleton.prototype.exchange = function (apdu) {
200
+ return __awaiter(this, void 0, void 0, function () {
201
+ var result;
202
+ return __generator(this, function (_a) {
203
+ switch (_a.label) {
204
+ case 0:
205
+ clearDisconnectTimeout();
206
+ return [4 /*yield*/, _super.prototype.exchange.call(this, apdu)];
207
+ case 1:
208
+ result = _a.sent();
209
+ setDisconnectTimeout();
210
+ return [2 /*return*/, result];
211
+ }
212
+ });
213
+ });
214
+ };
153
215
  TransportNodeHidSingleton.prototype.close = function () {
154
- // intentionally, a close will not effectively close the hid connection
216
+ // intentionally, a close will not effectively close the hid connection but
217
+ // will allow an auto-disconnection after some inactivity
218
+ this.preventAutoDisconnect = false;
155
219
  return Promise.resolve();
156
220
  };
157
221
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TransportNodeHid.js","sourceRoot":"","sources":["../src/TransportNodeHid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TransportNodeHid.js","sourceRoot":"","sources":["../src/TransportNodeHid.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/hw-transport-node-hid-singleton",
3
- "version": "6.24.1",
3
+ "version": "6.26.0",
4
4
  "description": "Ledger Hardware Wallet Node implementation of the communication layer, using node-hid and usb-detection",
5
5
  "keywords": [
6
6
  "Ledger",
@@ -42,5 +42,5 @@
42
42
  "watch": "bash ../../script/watch.sh",
43
43
  "doc": "bash ../../script/doc.sh"
44
44
  },
45
- "gitHead": "159269dafc5f177c7af5b20761ab0ef3550e3faf"
45
+ "gitHead": "5231dbe6373e3786e4d286ae17b7f88ebfd236d1"
46
46
  }
@@ -12,6 +12,23 @@ import { identifyUSBProductId } from "@ledgerhq/devices";
12
12
  import { CantOpenDevice } from "@ledgerhq/errors";
13
13
  import { listenDevices } from "./listenDevices";
14
14
  let transportInstance;
15
+
16
+ const DISCONNECT_TIMEOUT = 5000;
17
+ let disconnectTimeout;
18
+ const clearDisconnectTimeout = () => {
19
+ if (disconnectTimeout) {
20
+ clearTimeout(disconnectTimeout);
21
+ }
22
+ };
23
+
24
+ const setDisconnectTimeout = () => {
25
+ clearDisconnectTimeout();
26
+ disconnectTimeout = setTimeout(
27
+ () => TransportNodeHidSingleton.autoDisconnect(),
28
+ DISCONNECT_TIMEOUT
29
+ );
30
+ };
31
+
15
32
  /**
16
33
  * node-hid Transport implementation
17
34
  * @example
@@ -21,6 +38,7 @@ let transportInstance;
21
38
  */
22
39
 
23
40
  export default class TransportNodeHidSingleton extends TransportNodeHidNoEvents {
41
+ preventAutoDisconnect = false;
24
42
  /**
25
43
  *
26
44
  */
@@ -88,6 +106,20 @@ export default class TransportNodeHidSingleton extends TransportNodeHidNoEvents
88
106
  };
89
107
  };
90
108
 
109
+ /**
110
+ * convenience wrapper for auto-disconnect logic
111
+ */
112
+ static async autoDisconnect(): void {
113
+ if (transportInstance && !transportInstance.preventAutoDisconnect) {
114
+ log("hid-verbose", "triggering auto disconnect");
115
+ TransportNodeHidSingleton.disconnect();
116
+ } else if (transportInstance) {
117
+ // If we have disabled the auto-disconnect, try again in DISCONNECT_TIMEOUT
118
+ clearDisconnectTimeout();
119
+ setDisconnectTimeout();
120
+ }
121
+ }
122
+
91
123
  /**
92
124
  * globally disconnect the transport singleton
93
125
  */
@@ -97,12 +129,14 @@ export default class TransportNodeHidSingleton extends TransportNodeHidNoEvents
97
129
  transportInstance.emit("disconnect");
98
130
  transportInstance = null;
99
131
  }
132
+ clearDisconnectTimeout();
100
133
  }
101
134
 
102
135
  /**
103
136
  * if path="" is not provided, the library will take the first device
104
137
  */
105
138
  static open(): Promise<TransportNodeHidSingleton> {
139
+ clearDisconnectTimeout();
106
140
  return Promise.resolve().then(() => {
107
141
  if (transportInstance) {
108
142
  log("hid-verbose", "reusing opened transport instance");
@@ -138,8 +172,26 @@ export default class TransportNodeHidSingleton extends TransportNodeHidNoEvents
138
172
  });
139
173
  }
140
174
 
141
- close() {
142
- // intentionally, a close will not effectively close the hid connection
175
+ setAllowAutoDisconnect(allow: boolean): void {
176
+ this.preventAutoDisconnect = !allow;
177
+ }
178
+
179
+ /**
180
+ * Exchange with the device using APDU protocol.
181
+ * @param apdu
182
+ * @returns a promise of apdu response
183
+ */
184
+ async exchange(apdu: Buffer): Promise<Buffer> {
185
+ clearDisconnectTimeout();
186
+ const result = await super.exchange(apdu);
187
+ setDisconnectTimeout();
188
+ return result;
189
+ }
190
+
191
+ close(): Promise<void> {
192
+ // intentionally, a close will not effectively close the hid connection but
193
+ // will allow an auto-disconnection after some inactivity
194
+ this.preventAutoDisconnect = false;
143
195
  return Promise.resolve();
144
196
  }
145
197
  }