UNPKG

6.67 kBTypeScriptView Raw
1/// <reference types="node" />
2import EventEmitter from "events";
3import type { DeviceModel } from "@ledgerhq/devices";
4import { TransportError, StatusCodes, getAltStatusMessage, TransportStatusError } from "@ledgerhq/errors";
5export { TransportError, TransportStatusError, StatusCodes, getAltStatusMessage, };
6/**
7 */
8export declare type Subscription = {
9 unsubscribe: () => void;
10};
11/**
12 */
13export declare type Device = any;
14export declare type DescriptorEventType = "add" | "remove";
15/**
16 * type: add or remove event
17 * descriptor: a parameter that can be passed to open(descriptor)
18 * deviceModel: device info on the model (is it a nano s, nano x, ...)
19 * device: transport specific device info
20 */
21export interface DescriptorEvent<Descriptor> {
22 type: DescriptorEventType;
23 descriptor: Descriptor;
24 deviceModel?: DeviceModel | null | undefined;
25 device?: Device;
26}
27/**
28 * Observer generic type, following the Observer pattern
29 */
30export declare type Observer<EventType, EventError = unknown> = Readonly<{
31 next: (event: EventType) => unknown;
32 error: (e: EventError) => unknown;
33 complete: () => unknown;
34}>;
35/**
36 * Transport defines the generic interface to share between node/u2f impl
37 * A **Descriptor** is a parametric type that is up to be determined for the implementation.
38 * it can be for instance an ID, an file path, a URL,...
39 */
40export default class Transport {
41 exchangeTimeout: number;
42 unresponsiveTimeout: number;
43 deviceModel: DeviceModel | null | undefined;
44 /**
45 * Statically check if a transport is supported on the user's platform/browser.
46 */
47 static readonly isSupported: () => Promise<boolean>;
48 /**
49 * List once all available descriptors. For a better granularity, checkout `listen()`.
50 * @return a promise of descriptors
51 * @example
52 * TransportFoo.list().then(descriptors => ...)
53 */
54 static readonly list: () => Promise<Array<any>>;
55 /**
56 * Listen all device events for a given Transport. The method takes an Obverver of DescriptorEvent and returns a Subscription (according to Observable paradigm https://github.com/tc39/proposal-observable )
57 * a DescriptorEvent is a `{ descriptor, type }` object. type can be `"add"` or `"remove"` and descriptor is a value you can pass to `open(descriptor)`.
58 * each listen() call will first emit all potential device already connected and then will emit events can come over times,
59 * for instance if you plug a USB device after listen() or a bluetooth device become discoverable.
60 * @param observer is an object with a next, error and complete function (compatible with observer pattern)
61 * @return a Subscription object on which you can `.unsubscribe()` to stop listening descriptors.
62 * @example
63 const sub = TransportFoo.listen({
64 next: e => {
65 if (e.type==="add") {
66 sub.unsubscribe();
67 const transport = await TransportFoo.open(e.descriptor);
68 ...
69 }
70 },
71 error: error => {},
72 complete: () => {}
73 })
74 */
75 static readonly listen: (observer: Observer<DescriptorEvent<any>>) => Subscription;
76 /**
77 * attempt to create a Transport instance with potentially a descriptor.
78 * @param descriptor: the descriptor to open the transport with.
79 * @param timeout: an optional timeout
80 * @return a Promise of Transport instance
81 * @example
82 TransportFoo.open(descriptor).then(transport => ...)
83 */
84 static readonly open: (descriptor?: any, timeout?: number) => Promise<Transport>;
85 /**
86 * low level api to communicate with the device
87 * This method is for implementations to implement but should not be directly called.
88 * Instead, the recommanded way is to use send() method
89 * @param apdu the data to send
90 * @return a Promise of response data
91 */
92 exchange(_apdu: Buffer): Promise<Buffer>;
93 /**
94 * set the "scramble key" for the next exchanges with the device.
95 * Each App can have a different scramble key and they internally will set it at instanciation.
96 * @param key the scramble key
97 */
98 setScrambleKey(_key: string): void;
99 /**
100 * close the exchange with the device.
101 * @return a Promise that ends when the transport is closed.
102 */
103 close(): Promise<void>;
104 _events: EventEmitter;
105 /**
106 * Listen to an event on an instance of transport.
107 * Transport implementation can have specific events. Here is the common events:
108 * * `"disconnect"` : triggered if Transport is disconnected
109 */
110 on(eventName: string, cb: (...args: Array<any>) => any): void;
111 /**
112 * Stop listening to an event on an instance of transport.
113 */
114 off(eventName: string, cb: (...args: Array<any>) => any): void;
115 emit(event: string, ...args: any): void;
116 /**
117 * Enable or not logs of the binary exchange
118 */
119 setDebugMode(): void;
120 /**
121 * Set a timeout (in milliseconds) for the exchange call. Only some transport might implement it. (e.g. U2F)
122 */
123 setExchangeTimeout(exchangeTimeout: number): void;
124 /**
125 * Define the delay before emitting "unresponsive" on an exchange that does not respond
126 */
127 setExchangeUnresponsiveTimeout(unresponsiveTimeout: number): void;
128 /**
129 * wrapper on top of exchange to simplify work of the implementation.
130 * @param cla
131 * @param ins
132 * @param p1
133 * @param p2
134 * @param data
135 * @param statusList is a list of accepted status code (shorts). [0x9000] by default
136 * @return a Promise of response buffer
137 */
138 send: (cla: number, ins: number, p1: number, p2: number, data?: Buffer, statusList?: Array<number>) => Promise<Buffer>;
139 /**
140 * create() allows to open the first descriptor available or
141 * throw if there is none or if timeout is reached.
142 * This is a light helper, alternative to using listen() and open() (that you may need for any more advanced usecase)
143 * @example
144 TransportFoo.create().then(transport => ...)
145 */
146 static create(openTimeout?: number, listenTimeout?: number): Promise<Transport>;
147 exchangeBusyPromise: Promise<void> | null | undefined;
148 exchangeAtomicImpl: (f: () => Promise<Buffer | void>) => Promise<Buffer | void>;
149 decorateAppAPIMethods(self: Record<string, any>, methods: Array<string>, scrambleKey: string): void;
150 _appAPIlock: string | null;
151 decorateAppAPIMethod<R, A extends any[]>(methodName: string, f: (...args: A) => Promise<R>, ctx: any, scrambleKey: string): (...args: A) => Promise<R>;
152 static ErrorMessage_ListenTimeout: string;
153 static ErrorMessage_NoDeviceFound: string;
154}
155//# sourceMappingURL=Transport.d.ts.map
\No newline at end of file