UNPKG

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