1 | <img src="https://user-images.githubusercontent.com/4631227/191834116-59cf590e-25cc-4956-ae5c-812ea464f324.png" height="100" />
|
2 |
|
3 | [GitHub](https://github.com/LedgerHQ/ledger-live/),
|
4 | [Ledger Devs Discord](https://developers.ledger.com/discord-pro),
|
5 | [Developer Portal](https://developers.ledger.com/)
|
6 |
|
7 | ## @ledgerhq/hw-transport
|
8 |
|
9 | `@ledgerhq/hw-transport` implements the generic interface of a Ledger Hardware Wallet transport.
|
10 |
|
11 | ## API
|
12 |
|
13 |
|
14 |
|
15 | #### Table of Contents
|
16 |
|
17 | * [Subscription](#subscription)
|
18 | * [Properties](#properties)
|
19 | * [Device](#device)
|
20 | * [DescriptorEvent](#descriptorevent)
|
21 | * [Observer](#observer)
|
22 | * [Transport](#transport)
|
23 | * [Parameters](#parameters)
|
24 | * [exchange](#exchange)
|
25 | * [Parameters](#parameters-1)
|
26 | * [exchangeBulk](#exchangebulk)
|
27 | * [Parameters](#parameters-2)
|
28 | * [setScrambleKey](#setscramblekey)
|
29 | * [Parameters](#parameters-3)
|
30 | * [close](#close)
|
31 | * [on](#on)
|
32 | * [Parameters](#parameters-4)
|
33 | * [off](#off)
|
34 | * [Parameters](#parameters-5)
|
35 | * [setDebugMode](#setdebugmode)
|
36 | * [setExchangeTimeout](#setexchangetimeout)
|
37 | * [Parameters](#parameters-6)
|
38 | * [setExchangeUnresponsiveTimeout](#setexchangeunresponsivetimeout)
|
39 | * [Parameters](#parameters-7)
|
40 | * [send](#send)
|
41 | * [Parameters](#parameters-8)
|
42 | * [exchangeAtomicImpl](#exchangeatomicimpl)
|
43 | * [Parameters](#parameters-9)
|
44 | * [setTraceContext](#settracecontext)
|
45 | * [Parameters](#parameters-10)
|
46 | * [updateTraceContext](#updatetracecontext)
|
47 | * [Parameters](#parameters-11)
|
48 | * [getTraceContext](#gettracecontext)
|
49 | * [isSupported](#issupported)
|
50 | * [list](#list)
|
51 | * [Examples](#examples)
|
52 | * [listen](#listen)
|
53 | * [Parameters](#parameters-12)
|
54 | * [Examples](#examples-1)
|
55 | * [open](#open)
|
56 | * [Parameters](#parameters-13)
|
57 | * [Examples](#examples-2)
|
58 | * [create](#create)
|
59 | * [Parameters](#parameters-14)
|
60 | * [Examples](#examples-3)
|
61 |
|
62 | ### Subscription
|
63 |
|
64 | Type: {unsubscribe: function (): void}
|
65 |
|
66 | #### Properties
|
67 |
|
68 | * `unsubscribe` **function (): void** 
|
69 |
|
70 | ### Device
|
71 |
|
72 | Type: any
|
73 |
|
74 | ### DescriptorEvent
|
75 |
|
76 | A "descriptor" is a parameter that is specific to the implementation, and can be an ID, file path, or URL.
|
77 | type: add or remove event
|
78 | descriptor: a parameter that can be passed to open(descriptor)
|
79 | deviceModel: device info on the model (is it a nano s, nano x, ...)
|
80 | device: transport specific device info
|
81 |
|
82 | ### Observer
|
83 |
|
84 | Observer generic type, following the Observer pattern
|
85 |
|
86 | Type: Readonly<{next: function (event: EventType): any, error: function (e: EventError): any, complete: function (): any}>
|
87 |
|
88 | ### Transport
|
89 |
|
90 | The Transport class defines a generic interface for communicating with a Ledger hardware wallet.
|
91 | There are different kind of transports based on the technology (channels like U2F, HID, Bluetooth, Webusb) and environment (Node, Web,...).
|
92 | It is an abstract class that needs to be implemented.
|
93 |
|
94 | #### Parameters
|
95 |
|
96 | * `$0` **{context: TraceContext?, logType: LogType?}** (optional, default `{}`)
|
97 |
|
98 | * `$0.context`  
|
99 | * `$0.logType`  
|
100 |
|
101 | #### exchange
|
102 |
|
103 | Send data to the device using a low level API.
|
104 | It's recommended to use the "send" method for a higher level API.
|
105 |
|
106 | ##### Parameters
|
107 |
|
108 | * `_apdu` **[Buffer](https://nodejs.org/api/buffer.html)** 
|
109 | * `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Contains optional options for the exchange function* abortTimeoutMs: stop the exchange after a given timeout. Another timeout exists
|
110 | to detect unresponsive device (see `unresponsiveTimeout`). This timeout aborts the exchange. (optional, default `{}`)
|
111 |
|
112 | * `options.abortTimeoutMs`  
|
113 | * `apdu` **[Buffer](https://nodejs.org/api/buffer.html)** The data to send.
|
114 |
|
115 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Buffer](https://nodejs.org/api/buffer.html)>** A promise that resolves with the response data from the device.
|
116 |
|
117 | #### exchangeBulk
|
118 |
|
119 | Send apdus in batch to the device using a low level API.
|
120 | The default implementation is to call exchange for each apdu.
|
121 |
|
122 | ##### Parameters
|
123 |
|
124 | * `apdus` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Buffer](https://nodejs.org/api/buffer.html)>** array of apdus to send.
|
125 | * `observer` **[Observer](#observer)<[Buffer](https://nodejs.org/api/buffer.html)>** an observer that will receive the response of each apdu.
|
126 |
|
127 | Returns **[Subscription](#subscription)** A Subscription object on which you can call ".unsubscribe()" to stop sending apdus.
|
128 |
|
129 | #### setScrambleKey
|
130 |
|
131 | Set the "scramble key" for the next data exchanges with the device.
|
132 | Each app can have a different scramble key and it is set internally during instantiation.
|
133 |
|
134 | ##### Parameters
|
135 |
|
136 | * `_key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
|
137 | * `key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The scramble key to set.
|
138 | deprecated This method is no longer needed for modern transports and should be migrated away from.
|
139 | no @ before deprecated as it breaks documentationjs on version 14.0.2
|
140 | <https://github.com/documentationjs/documentation/issues/1596>
|
141 |
|
142 | #### close
|
143 |
|
144 | Close the connection with the device.
|
145 |
|
146 | Note: for certain transports (hw-transport-node-hid-singleton for ex), once the promise resolved,
|
147 | the transport instance is actually still cached, and the device is disconnected only after a defined timeout.
|
148 | But for the consumer of the Transport, this does not matter and it can consider the transport to be closed.
|
149 |
|
150 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<void>** A promise that resolves when the transport is closed.
|
151 |
|
152 | #### on
|
153 |
|
154 | Listen for an event on the transport instance.
|
155 | Transport implementations may have specific events. Common events include:
|
156 | "disconnect" : triggered when the transport is disconnected.
|
157 |
|
158 | ##### Parameters
|
159 |
|
160 | * `eventName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the event to listen for.
|
161 | * `cb` **function (...args: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\<any>): any** 
|
162 |
|
163 | Returns **void** 
|
164 |
|
165 | #### off
|
166 |
|
167 | Stop listening to an event on an instance of transport.
|
168 |
|
169 | ##### Parameters
|
170 |
|
171 | * `eventName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
|
172 | * `cb` **function (...args: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\<any>): any** 
|
173 |
|
174 | Returns **void** 
|
175 |
|
176 | #### setDebugMode
|
177 |
|
178 | Enable or not logs of the binary exchange
|
179 |
|
180 | #### setExchangeTimeout
|
181 |
|
182 | Set a timeout (in milliseconds) for the exchange call. Only some transport might implement it. (e.g. U2F)
|
183 |
|
184 | ##### Parameters
|
185 |
|
186 | * `exchangeTimeout` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** 
|
187 |
|
188 | Returns **void** 
|
189 |
|
190 | #### setExchangeUnresponsiveTimeout
|
191 |
|
192 | Define the delay before emitting "unresponsive" on an exchange that does not respond
|
193 |
|
194 | ##### Parameters
|
195 |
|
196 | * `unresponsiveTimeout` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** 
|
197 |
|
198 | Returns **void** 
|
199 |
|
200 | #### send
|
201 |
|
202 | Send data to the device using the higher level API.
|
203 |
|
204 | ##### Parameters
|
205 |
|
206 | * `cla` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The instruction class for the command.
|
207 | * `ins` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The instruction code for the command.
|
208 | * `p1` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The first parameter for the instruction.
|
209 | * `p2` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The second parameter for the instruction.
|
210 | * `data` **[Buffer](https://nodejs.org/api/buffer.html)** The data to be sent. Defaults to an empty buffer. (optional, default `Buffer.alloc(0)`)
|
211 | * `statusList` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>** A list of acceptable status codes for the response. Defaults to \[StatusCodes.OK]. (optional, default `[StatusCodes.OK]`)
|
212 | * `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Contains optional options for the exchange function* abortTimeoutMs: stop the send after a given timeout. Another timeout exists
|
213 | to detect unresponsive device (see `unresponsiveTimeout`). This timeout aborts the exchange. (optional, default `{}`)
|
214 |
|
215 | * `options.abortTimeoutMs`  
|
216 |
|
217 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Buffer](https://nodejs.org/api/buffer.html)>** A promise that resolves with the response data from the device.
|
218 |
|
219 | #### exchangeAtomicImpl
|
220 |
|
221 | Wrapper to make an exchange "atomic" (blocking any other exchange)
|
222 |
|
223 | It also handles "unresponsiveness" by emitting "unresponsive" and "responsive" events.
|
224 |
|
225 | ##### Parameters
|
226 |
|
227 | * `f` **function (): [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<Output>** The exchange job, using the transport to run
|
228 |
|
229 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<Output>** a Promise resolving with the output of the given job
|
230 |
|
231 | #### setTraceContext
|
232 |
|
233 | Sets the context used by the logging/tracing mechanism
|
234 |
|
235 | Useful when re-using (cached) the same Transport instance,
|
236 | but with a new tracing context.
|
237 |
|
238 | ##### Parameters
|
239 |
|
240 | * `context` **TraceContext?** A TraceContext, that can undefined to reset the context
|
241 |
|
242 | #### updateTraceContext
|
243 |
|
244 | Updates the context used by the logging/tracing mechanism
|
245 |
|
246 | The update only overrides the key-value that are already defined in the current context.
|
247 |
|
248 | ##### Parameters
|
249 |
|
250 | * `contextToAdd` **TraceContext** A TraceContext that will be added to the current context
|
251 |
|
252 | #### getTraceContext
|
253 |
|
254 | Gets the tracing context of the transport instance
|
255 |
|
256 | Returns **(TraceContext | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** 
|
257 |
|
258 | #### isSupported
|
259 |
|
260 | Check if the transport is supported on the current platform/browser.
|
261 |
|
262 | Type: function (): [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>
|
263 |
|
264 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>** A promise that resolves with a boolean indicating support.
|
265 |
|
266 | #### list
|
267 |
|
268 | List all available descriptors for the transport.
|
269 | For a better granularity, checkout `listen()`.
|
270 |
|
271 | Type: function (): [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\<any>>
|
272 |
|
273 | ##### Examples
|
274 |
|
275 | ```javascript
|
276 | TransportFoo.list().then(descriptors => ...)
|
277 | ```
|
278 |
|
279 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\<any>>** A promise that resolves with an array of descriptors.
|
280 |
|
281 | #### listen
|
282 |
|
283 | Listen for device events for the transport. The method takes an observer of DescriptorEvent and returns a Subscription.
|
284 | A DescriptorEvent is an object containing a "descriptor" and a "type" field. The "type" field can be "add" or "remove", and the "descriptor" field can be passed to the "open" method.
|
285 | The "listen" method will first emit all currently connected devices and then will emit events as they occur, such as when a USB device is plugged in or a Bluetooth device becomes discoverable.
|
286 |
|
287 | Type: function (observer: [Observer](#observer)<[DescriptorEvent](#descriptorevent)\<any>>): [Subscription](#subscription)
|
288 |
|
289 | ##### Parameters
|
290 |
|
291 | * `observer` **[Observer](#observer)<[DescriptorEvent](#descriptorevent)\<any>>** An object with "next", "error", and "complete" functions, following the observer pattern.
|
292 |
|
293 | ##### Examples
|
294 |
|
295 | ```javascript
|
296 | const sub = TransportFoo.listen({
|
297 | next: e => {
|
298 | if (e.type==="add") {
|
299 | sub.unsubscribe();
|
300 | const transport = await TransportFoo.open(e.descriptor);
|
301 | ...
|
302 | }
|
303 | },
|
304 | error: error => {},
|
305 | complete: () => {}
|
306 | })
|
307 | ```
|
308 |
|
309 | Returns **[Subscription](#subscription)** A Subscription object on which you can call ".unsubscribe()" to stop listening to descriptors.
|
310 |
|
311 | #### open
|
312 |
|
313 | Attempt to create a Transport instance with a specific descriptor.
|
314 |
|
315 | Type: function (descriptor: any, timeoutMs: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), context: TraceContext): [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Transport](#transport)>
|
316 |
|
317 | ##### Parameters
|
318 |
|
319 | * `descriptor` **any** The descriptor to open the transport with.
|
320 | * `timeout` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** An optional timeout for the transport connection.
|
321 | * `context` **TraceContext** Optional tracing/log context
|
322 |
|
323 | ##### Examples
|
324 |
|
325 | ```javascript
|
326 | TransportFoo.open(descriptor).then(transport => ...)
|
327 | ```
|
328 |
|
329 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Transport](#transport)>** A promise that resolves with a Transport instance.
|
330 |
|
331 | #### create
|
332 |
|
333 | create() allows to open the first descriptor available or
|
334 | throw if there is none or if timeout is reached.
|
335 | This is a light helper, alternative to using listen() and open() (that you may need for any more advanced usecase)
|
336 |
|
337 | ##### Parameters
|
338 |
|
339 | * `openTimeout` (optional, default `3000`)
|
340 | * `listenTimeout` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** 
|
341 |
|
342 | ##### Examples
|
343 |
|
344 | ```javascript
|
345 | TransportFoo.create().then(transport => ...)
|
346 | ```
|
347 |
|
348 | Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Transport](#transport)>** 
|