PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@ledgerhq/hw-transport/lib-es
Просмотр файла: Transport.js
import EventEmitter from "events";
import { TransportRaceCondition, TransportError, StatusCodes, getAltStatusMessage, TransportStatusError } from "@ledgerhq/errors";
export { TransportError, TransportStatusError, StatusCodes, getAltStatusMessage };
/**
*/
/**
* Transport defines the generic interface to share between node/u2f impl
* A **Descriptor** is a parametric type that is up to be determined for the implementation.
* it can be for instance an ID, an file path, a URL,...
*/
export default class Transport {
constructor() {
this.exchangeTimeout = 30000;
this.unresponsiveTimeout = 15000;
this.deviceModel = null;
this._events = new EventEmitter();
this.send = async (cla, ins, p1, p2, data = Buffer.alloc(0), statusList = [StatusCodes.OK]) => {
if (data.length >= 256) {
throw new TransportError("data.length exceed 256 bytes limit. Got: " + data.length, "DataLengthTooBig");
}
const response = await this.exchange(Buffer.concat([Buffer.from([cla, ins, p1, p2]), Buffer.from([data.length]), data]));
const sw = response.readUInt16BE(response.length - 2);
if (!statusList.some(s => s === sw)) {
throw new TransportStatusError(sw);
}
return response;
};
this.exchangeBusyPromise = void 0;
this.exchangeAtomicImpl = async f => {
if (this.exchangeBusyPromise) {
throw new TransportRaceCondition("An action was already pending on the Ledger device. Please deny or reconnect.");
}
let resolveBusy;
const busyPromise = new Promise(r => {
resolveBusy = r;
});
this.exchangeBusyPromise = busyPromise;
let unresponsiveReached = false;
const timeout = setTimeout(() => {
unresponsiveReached = true;
this.emit("unresponsive");
}, this.unresponsiveTimeout);
try {
const res = await f();
if (unresponsiveReached) {
this.emit("responsive");
}
return res;
} finally {
clearTimeout(timeout);
if (resolveBusy) resolveBusy();
this.exchangeBusyPromise = null;
}
};
this._appAPIlock = null;
}
/**
* low level api to communicate with the device
* This method is for implementations to implement but should not be directly called.
* Instead, the recommanded way is to use send() method
* @param apdu the data to send
* @return a Promise of response data
*/
exchange(_apdu) {
throw new Error("exchange not implemented");
}
/**
* set the "scramble key" for the next exchanges with the device.
* Each App can have a different scramble key and they internally will set it at instanciation.
* @param key the scramble key
*/
setScrambleKey(_key) {}
/**
* close the exchange with the device.
* @return a Promise that ends when the transport is closed.
*/
close() {
return Promise.resolve();
}
/**
* Listen to an event on an instance of transport.
* Transport implementation can have specific events. Here is the common events:
* * `"disconnect"` : triggered if Transport is disconnected
*/
on(eventName, cb) {
this._events.on(eventName, cb);
}
/**
* Stop listening to an event on an instance of transport.
*/
off(eventName, cb) {
this._events.removeListener(eventName, cb);
}
emit(event, ...args) {
this._events.emit(event, ...args);
}
/**
* Enable or not logs of the binary exchange
*/
setDebugMode() {
console.warn("setDebugMode is deprecated. use @ledgerhq/logs instead. No logs are emitted in this anymore.");
}
/**
* Set a timeout (in milliseconds) for the exchange call. Only some transport might implement it. (e.g. U2F)
*/
setExchangeTimeout(exchangeTimeout) {
this.exchangeTimeout = exchangeTimeout;
}
/**
* Define the delay before emitting "unresponsive" on an exchange that does not respond
*/
setExchangeUnresponsiveTimeout(unresponsiveTimeout) {
this.unresponsiveTimeout = unresponsiveTimeout;
}
/**
* wrapper on top of exchange to simplify work of the implementation.
* @param cla
* @param ins
* @param p1
* @param p2
* @param data
* @param statusList is a list of accepted status code (shorts). [0x9000] by default
* @return a Promise of response buffer
*/
/**
* create() allows to open the first descriptor available or
* throw if there is none or if timeout is reached.
* This is a light helper, alternative to using listen() and open() (that you may need for any more advanced usecase)
* @example
TransportFoo.create().then(transport => ...)
*/
static create(openTimeout = 3000, listenTimeout) {
return new Promise((resolve, reject) => {
let found = false;
const sub = this.listen({
next: e => {
found = true;
if (sub) sub.unsubscribe();
if (listenTimeoutId) clearTimeout(listenTimeoutId);
this.open(e.descriptor, openTimeout).then(resolve, reject);
},
error: e => {
if (listenTimeoutId) clearTimeout(listenTimeoutId);
reject(e);
},
complete: () => {
if (listenTimeoutId) clearTimeout(listenTimeoutId);
if (!found) {
reject(new TransportError(this.ErrorMessage_NoDeviceFound, "NoDeviceFound"));
}
}
});
const listenTimeoutId = listenTimeout ? setTimeout(() => {
sub.unsubscribe();
reject(new TransportError(this.ErrorMessage_ListenTimeout, "ListenTimeout"));
}, listenTimeout) : null;
});
}
decorateAppAPIMethods(self, methods, scrambleKey) {
for (let methodName of methods) {
self[methodName] = this.decorateAppAPIMethod(methodName, self[methodName], self, scrambleKey);
}
}
decorateAppAPIMethod(methodName, f, ctx, scrambleKey) {
return async (...args) => {
const {
_appAPIlock
} = this;
if (_appAPIlock) {
return Promise.reject(new TransportError("Ledger Device is busy (lock " + _appAPIlock + ")", "TransportLocked"));
}
try {
this._appAPIlock = methodName;
this.setScrambleKey(scrambleKey);
return await f.apply(ctx, args);
} finally {
this._appAPIlock = null;
}
};
}
}
Transport.isSupported = void 0;
Transport.list = void 0;
Transport.listen = void 0;
Transport.open = void 0;
Transport.ErrorMessage_ListenTimeout = "No Ledger device found (timeout)";
Transport.ErrorMessage_NoDeviceFound = "No Ledger device found";
//# sourceMappingURL=Transport.js.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!