1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | var __generator = (this && this.__generator) || function (thisArg, body) {
|
12 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
13 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
14 | function verb(n) { return function (v) { return step([n, v]); }; }
|
15 | function step(op) {
|
16 | if (f) throw new TypeError("Generator is already executing.");
|
17 | while (_) try {
|
18 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
19 | if (y = 0, t) op = [op[0] & 2, t.value];
|
20 | switch (op[0]) {
|
21 | case 0: case 1: t = op; break;
|
22 | case 4: _.label++; return { value: op[1], done: false };
|
23 | case 5: _.label++; y = op[1]; op = [0]; continue;
|
24 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
25 | default:
|
26 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
27 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
28 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
29 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
30 | if (t[2]) _.ops.pop();
|
31 | _.trys.pop(); continue;
|
32 | }
|
33 | op = body.call(thisArg, _);
|
34 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
35 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
36 | }
|
37 | };
|
38 | var __read = (this && this.__read) || function (o, n) {
|
39 | var m = typeof Symbol === "function" && o[Symbol.iterator];
|
40 | if (!m) return o;
|
41 | var i = m.call(o), r, ar = [], e;
|
42 | try {
|
43 | while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
44 | }
|
45 | catch (error) { e = { error: error }; }
|
46 | finally {
|
47 | try {
|
48 | if (r && !r.done && (m = i["return"])) m.call(i);
|
49 | }
|
50 | finally { if (e) throw e.error; }
|
51 | }
|
52 | return ar;
|
53 | };
|
54 | var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
55 | if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
56 | if (ar || !(i in from)) {
|
57 | if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
58 | ar[i] = from[i];
|
59 | }
|
60 | }
|
61 | return to.concat(ar || Array.prototype.slice.call(from));
|
62 | };
|
63 | var __values = (this && this.__values) || function(o) {
|
64 | var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
65 | if (m) return m.call(o);
|
66 | if (o && typeof o.length === "number") return {
|
67 | next: function () {
|
68 | if (o && i >= o.length) o = void 0;
|
69 | return { value: o && o[i++], done: !o };
|
70 | }
|
71 | };
|
72 | throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
73 | };
|
74 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
75 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
76 | };
|
77 | exports.__esModule = true;
|
78 | exports.getAltStatusMessage = exports.StatusCodes = exports.TransportStatusError = exports.TransportError = void 0;
|
79 | var events_1 = __importDefault(require("events"));
|
80 | var errors_1 = require("@ledgerhq/errors");
|
81 | exports.TransportError = errors_1.TransportError;
|
82 | exports.StatusCodes = errors_1.StatusCodes;
|
83 | exports.getAltStatusMessage = errors_1.getAltStatusMessage;
|
84 | exports.TransportStatusError = errors_1.TransportStatusError;
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | var Transport = (function () {
|
91 | function Transport() {
|
92 | var _this = this;
|
93 | this.exchangeTimeout = 30000;
|
94 | this.unresponsiveTimeout = 15000;
|
95 | this.deviceModel = null;
|
96 | this._events = new events_1["default"]();
|
97 | |
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | this.send = function (cla, ins, p1, p2, data, statusList) {
|
108 | if (data === void 0) { data = Buffer.alloc(0); }
|
109 | if (statusList === void 0) { statusList = [errors_1.StatusCodes.OK]; }
|
110 | return __awaiter(_this, void 0, void 0, function () {
|
111 | var response, sw;
|
112 | return __generator(this, function (_a) {
|
113 | switch (_a.label) {
|
114 | case 0:
|
115 | if (data.length >= 256) {
|
116 | throw new errors_1.TransportError("data.length exceed 256 bytes limit. Got: " + data.length, "DataLengthTooBig");
|
117 | }
|
118 | return [4 , this.exchange(Buffer.concat([
|
119 | Buffer.from([cla, ins, p1, p2]),
|
120 | Buffer.from([data.length]),
|
121 | data,
|
122 | ]))];
|
123 | case 1:
|
124 | response = _a.sent();
|
125 | sw = response.readUInt16BE(response.length - 2);
|
126 | if (!statusList.some(function (s) { return s === sw; })) {
|
127 | throw new errors_1.TransportStatusError(sw);
|
128 | }
|
129 | return [2 , response];
|
130 | }
|
131 | });
|
132 | });
|
133 | };
|
134 | this.exchangeAtomicImpl = function (f) { return __awaiter(_this, void 0, void 0, function () {
|
135 | var resolveBusy, busyPromise, unresponsiveReached, timeout, res;
|
136 | var _this = this;
|
137 | return __generator(this, function (_a) {
|
138 | switch (_a.label) {
|
139 | case 0:
|
140 | if (this.exchangeBusyPromise) {
|
141 | throw new errors_1.TransportRaceCondition("An action was already pending on the Ledger device. Please deny or reconnect.");
|
142 | }
|
143 | busyPromise = new Promise(function (r) {
|
144 | resolveBusy = r;
|
145 | });
|
146 | this.exchangeBusyPromise = busyPromise;
|
147 | unresponsiveReached = false;
|
148 | timeout = setTimeout(function () {
|
149 | unresponsiveReached = true;
|
150 | _this.emit("unresponsive");
|
151 | }, this.unresponsiveTimeout);
|
152 | _a.label = 1;
|
153 | case 1:
|
154 | _a.trys.push([1, , 3, 4]);
|
155 | return [4 , f()];
|
156 | case 2:
|
157 | res = _a.sent();
|
158 | if (unresponsiveReached) {
|
159 | this.emit("responsive");
|
160 | }
|
161 | return [2 , res];
|
162 | case 3:
|
163 | clearTimeout(timeout);
|
164 | if (resolveBusy)
|
165 | resolveBusy();
|
166 | this.exchangeBusyPromise = null;
|
167 | return [7 ];
|
168 | case 4: return [2 ];
|
169 | }
|
170 | });
|
171 | }); };
|
172 | this._appAPIlock = null;
|
173 | }
|
174 | |
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | Transport.prototype.exchange = function (_apdu) {
|
182 | throw new Error("exchange not implemented");
|
183 | };
|
184 | |
185 |
|
186 |
|
187 |
|
188 |
|
189 | Transport.prototype.setScrambleKey = function (_key) { };
|
190 | |
191 |
|
192 |
|
193 |
|
194 | Transport.prototype.close = function () {
|
195 | return Promise.resolve();
|
196 | };
|
197 | |
198 |
|
199 |
|
200 |
|
201 |
|
202 | Transport.prototype.on = function (eventName, cb) {
|
203 | this._events.on(eventName, cb);
|
204 | };
|
205 | |
206 |
|
207 |
|
208 | Transport.prototype.off = function (eventName, cb) {
|
209 | this._events.removeListener(eventName, cb);
|
210 | };
|
211 | Transport.prototype.emit = function (event) {
|
212 | var _a;
|
213 | var args = [];
|
214 | for (var _i = 1; _i < arguments.length; _i++) {
|
215 | args[_i - 1] = arguments[_i];
|
216 | }
|
217 | (_a = this._events).emit.apply(_a, __spreadArray([event], __read(args), false));
|
218 | };
|
219 | |
220 |
|
221 |
|
222 | Transport.prototype.setDebugMode = function () {
|
223 | console.warn("setDebugMode is deprecated. use @ledgerhq/logs instead. No logs are emitted in this anymore.");
|
224 | };
|
225 | |
226 |
|
227 |
|
228 | Transport.prototype.setExchangeTimeout = function (exchangeTimeout) {
|
229 | this.exchangeTimeout = exchangeTimeout;
|
230 | };
|
231 | |
232 |
|
233 |
|
234 | Transport.prototype.setExchangeUnresponsiveTimeout = function (unresponsiveTimeout) {
|
235 | this.unresponsiveTimeout = unresponsiveTimeout;
|
236 | };
|
237 | |
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 | Transport.create = function (openTimeout, listenTimeout) {
|
245 | var _this = this;
|
246 | if (openTimeout === void 0) { openTimeout = 3000; }
|
247 | return new Promise(function (resolve, reject) {
|
248 | var found = false;
|
249 | var sub = _this.listen({
|
250 | next: function (e) {
|
251 | found = true;
|
252 | if (sub)
|
253 | sub.unsubscribe();
|
254 | if (listenTimeoutId)
|
255 | clearTimeout(listenTimeoutId);
|
256 | _this.open(e.descriptor, openTimeout).then(resolve, reject);
|
257 | },
|
258 | error: function (e) {
|
259 | if (listenTimeoutId)
|
260 | clearTimeout(listenTimeoutId);
|
261 | reject(e);
|
262 | },
|
263 | complete: function () {
|
264 | if (listenTimeoutId)
|
265 | clearTimeout(listenTimeoutId);
|
266 | if (!found) {
|
267 | reject(new errors_1.TransportError(_this.ErrorMessage_NoDeviceFound, "NoDeviceFound"));
|
268 | }
|
269 | }
|
270 | });
|
271 | var listenTimeoutId = listenTimeout
|
272 | ? setTimeout(function () {
|
273 | sub.unsubscribe();
|
274 | reject(new errors_1.TransportError(_this.ErrorMessage_ListenTimeout, "ListenTimeout"));
|
275 | }, listenTimeout)
|
276 | : null;
|
277 | });
|
278 | };
|
279 | Transport.prototype.decorateAppAPIMethods = function (self, methods, scrambleKey) {
|
280 | var e_1, _a;
|
281 | try {
|
282 | for (var methods_1 = __values(methods), methods_1_1 = methods_1.next(); !methods_1_1.done; methods_1_1 = methods_1.next()) {
|
283 | var methodName = methods_1_1.value;
|
284 | self[methodName] = this.decorateAppAPIMethod(methodName, self[methodName], self, scrambleKey);
|
285 | }
|
286 | }
|
287 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
288 | finally {
|
289 | try {
|
290 | if (methods_1_1 && !methods_1_1.done && (_a = methods_1["return"])) _a.call(methods_1);
|
291 | }
|
292 | finally { if (e_1) throw e_1.error; }
|
293 | }
|
294 | };
|
295 | Transport.prototype.decorateAppAPIMethod = function (methodName, f, ctx, scrambleKey) {
|
296 | var _this = this;
|
297 | return function () {
|
298 | var args = [];
|
299 | for (var _i = 0; _i < arguments.length; _i++) {
|
300 | args[_i] = arguments[_i];
|
301 | }
|
302 | return __awaiter(_this, void 0, void 0, function () {
|
303 | var _appAPIlock;
|
304 | return __generator(this, function (_a) {
|
305 | switch (_a.label) {
|
306 | case 0:
|
307 | _appAPIlock = this._appAPIlock;
|
308 | if (_appAPIlock) {
|
309 | return [2 , Promise.reject(new errors_1.TransportError("Ledger Device is busy (lock " + _appAPIlock + ")", "TransportLocked"))];
|
310 | }
|
311 | _a.label = 1;
|
312 | case 1:
|
313 | _a.trys.push([1, , 3, 4]);
|
314 | this._appAPIlock = methodName;
|
315 | this.setScrambleKey(scrambleKey);
|
316 | return [4 , f.apply(ctx, args)];
|
317 | case 2: return [2 , _a.sent()];
|
318 | case 3:
|
319 | this._appAPIlock = null;
|
320 | return [7 ];
|
321 | case 4: return [2 ];
|
322 | }
|
323 | });
|
324 | });
|
325 | };
|
326 | };
|
327 | Transport.ErrorMessage_ListenTimeout = "No Ledger device found (timeout)";
|
328 | Transport.ErrorMessage_NoDeviceFound = "No Ledger device found";
|
329 | return Transport;
|
330 | }());
|
331 | exports["default"] = Transport;
|
332 |
|
\ | No newline at end of file |