@trezor/connect 9.3.1-beta.1 → 9.3.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/core/index.js CHANGED
@@ -20,52 +20,26 @@ const debug_1 = require("../utils/debug");
20
20
  const BlockchainLink_1 = require("../backend/BlockchainLink");
21
21
  const interactionTimeout_1 = require("../utils/interactionTimeout");
22
22
  const onCallFirmwareUpdate_1 = require("./onCallFirmwareUpdate");
23
- let _core;
24
- let _deviceList;
25
- const _callMethods = [];
26
- let _interactionTimeout;
27
- let _deviceListInitTimeout;
28
- let _overridePromise;
29
- const methodSynchronize = (0, utils_2.getSynchronize)();
30
- let waitForFirstMethod = (0, utils_1.createDeferred)();
31
23
  const _log = (0, debug_1.initLog)('Core');
32
- const postMessage = (message) => {
33
- if (message.event === events_2.RESPONSE_EVENT) {
34
- const index = _callMethods.findIndex(call => call && call.responseID === message.id);
35
- if (index >= 0) {
36
- _callMethods.splice(index, 1);
37
- if (_callMethods.length === 0) {
38
- waitForFirstMethod = (0, utils_1.createDeferred)();
39
- }
40
- }
41
- }
42
- _core.emit(events_2.CORE_EVENT, message);
43
- };
44
- const popupPromise = (0, popupPromiseManager_1.createPopupPromiseManager)();
45
- const waitForPopup = () => {
46
- postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_UI_WINDOW));
24
+ const waitForPopup = ({ popupPromise, sendCoreMessage }) => {
25
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_UI_WINDOW));
47
26
  return popupPromise.wait();
48
27
  };
49
- const interactionTimeout = () => _interactionTimeout.start(() => {
50
- onPopupClosed('Interaction timeout');
28
+ const startInteractionTimeout = (context) => context.interactionTimeout.start(() => {
29
+ onPopupClosed(context, 'Interaction timeout');
51
30
  });
52
- const uiPromises = (0, uiPromiseManager_1.createUiPromiseManager)(interactionTimeout);
53
- const initDevice = async (devicePath) => {
54
- if (!_deviceList) {
55
- throw constants_1.ERRORS.TypedError('Transport_Missing');
56
- }
57
- await _deviceList.transportFirstEventPromise;
58
- if (!_deviceList) {
59
- throw constants_1.ERRORS.TypedError('Transport_Missing');
60
- }
61
- const isWebUsb = _deviceList.transportType() === 'WebUsbTransport';
31
+ const initDevice = async (context, devicePath) => {
32
+ const { uiPromises, deviceList, sendCoreMessage } = context;
33
+ await deviceList.pendingConnection();
34
+ (0, DeviceList_1.assertDeviceListConnected)(deviceList);
35
+ const isWebUsb = deviceList.transportType() === 'WebUsbTransport';
62
36
  let device;
63
37
  let showDeviceSelection = isWebUsb;
64
38
  const isUsingPopup = DataManager_1.DataManager.getSettings('popup');
65
39
  const origin = DataManager_1.DataManager.getSettings('origin');
66
40
  const useCoreInPopup = DataManager_1.DataManager.getSettings('useCoreInPopup');
67
41
  const { preferredDevice } = connect_common_1.storage.load().origin[origin] || {};
68
- const preferredDeviceInList = preferredDevice && _deviceList.getDevice(preferredDevice.path);
42
+ const preferredDeviceInList = preferredDevice && deviceList.getDevice(preferredDevice.path);
69
43
  if (preferredDevice && !preferredDeviceInList) {
70
44
  connect_common_1.storage.save(store => {
71
45
  store.origin[origin] = { ...store.origin[origin], preferredDevice: undefined };
@@ -73,14 +47,14 @@ const initDevice = async (devicePath) => {
73
47
  });
74
48
  }
75
49
  if (devicePath) {
76
- device = _deviceList.getDevice(devicePath);
50
+ device = deviceList.getDevice(devicePath);
77
51
  showDeviceSelection =
78
52
  !device || !!(device === null || device === void 0 ? void 0 : device.unreadableError) || (device.isUnacquired() && !!isUsingPopup);
79
53
  }
80
54
  else {
81
- const devices = _deviceList.asArray();
55
+ const devices = deviceList.asArray();
82
56
  if (devices.length === 1 && (!isWebUsb || !isUsingPopup)) {
83
- device = _deviceList.getDevice(devices[0].path);
57
+ device = deviceList.getDevice(devices[0].path);
84
58
  showDeviceSelection =
85
59
  !!(device === null || device === void 0 ? void 0 : device.unreadableError) || device.isUnacquired() || !!useCoreInPopup;
86
60
  }
@@ -90,22 +64,20 @@ const initDevice = async (devicePath) => {
90
64
  }
91
65
  if (showDeviceSelection) {
92
66
  uiPromises.create(events_2.UI.RECEIVE_DEVICE);
93
- await waitForPopup();
94
- if (!_deviceList) {
95
- throw constants_1.ERRORS.TypedError('Transport_Missing');
96
- }
97
- const devices = _deviceList.asArray();
67
+ await waitForPopup(context);
68
+ (0, DeviceList_1.assertDeviceListConnected)(deviceList);
69
+ const devices = deviceList.asArray();
98
70
  if (devices.length === 1 &&
99
71
  devices[0].type !== 'unreadable' &&
100
72
  devices[0].features &&
101
73
  !isWebUsb &&
102
74
  !useCoreInPopup) {
103
- device = _deviceList.getDevice(devices[0].path);
75
+ device = deviceList.getDevice(devices[0].path);
104
76
  }
105
77
  else {
106
- postMessage((0, events_2.createUiMessage)(events_2.UI.SELECT_DEVICE, {
78
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.SELECT_DEVICE, {
107
79
  webusb: isWebUsb,
108
- devices: _deviceList.asArray(),
80
+ devices: deviceList.asArray(),
109
81
  }));
110
82
  if (uiPromises.exists(events_2.UI.RECEIVE_DEVICE)) {
111
83
  const { payload } = await uiPromises.get(events_2.UI.RECEIVE_DEVICE);
@@ -119,24 +91,27 @@ const initDevice = async (devicePath) => {
119
91
  return store;
120
92
  });
121
93
  }
122
- device = _deviceList.getDevice(payload.device.path);
94
+ device = deviceList.getDevice(payload.device.path);
123
95
  }
124
96
  }
125
97
  }
98
+ else if (uiPromises.exists(events_2.UI.RECEIVE_DEVICE)) {
99
+ await uiPromises.get(events_2.UI.RECEIVE_DEVICE);
100
+ }
126
101
  if (!device) {
127
102
  throw constants_1.ERRORS.TypedError('Device_NotFound');
128
103
  }
129
104
  return device;
130
105
  };
131
106
  const MAX_PIN_TRIES = 3;
132
- const getInvalidDeviceState = async (device, preauthorized) => {
107
+ const getInvalidDeviceState = async ({ sendCoreMessage }, device, preauthorized) => {
133
108
  for (let i = 0; i < MAX_PIN_TRIES - 1; ++i) {
134
109
  try {
135
110
  return await device.validateState(preauthorized);
136
111
  }
137
112
  catch (error) {
138
113
  if (error.message.includes('PIN invalid')) {
139
- postMessage((0, events_2.createUiMessage)(events_2.UI.INVALID_PIN, { device: device.toMessageObject() }));
114
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.INVALID_PIN, { device: device.toMessageObject() }));
140
115
  }
141
116
  else {
142
117
  throw error;
@@ -145,25 +120,26 @@ const getInvalidDeviceState = async (device, preauthorized) => {
145
120
  }
146
121
  return device.validateState(preauthorized);
147
122
  };
148
- const inner = async (method, device) => {
123
+ const inner = async (context, method, device) => {
149
124
  var _a;
125
+ const { uiPromises, sendCoreMessage } = context;
150
126
  const trustedHost = DataManager_1.DataManager.getSettings('trustedHost');
151
127
  const isUsingPopup = (_a = DataManager_1.DataManager.getSettings('popup')) !== null && _a !== void 0 ? _a : false;
152
128
  const firmwareException = method.checkFirmwareRange();
153
129
  if (firmwareException) {
154
130
  if (isUsingPopup) {
155
131
  if (firmwareException === events_2.UI.FIRMWARE_NOT_COMPATIBLE) {
156
- await waitForPopup();
132
+ await waitForPopup(context);
157
133
  const uiPromise = uiPromises.create(events_2.UI.RECEIVE_CONFIRMATION, device);
158
- postMessage((0, events_2.createUiMessage)(events_2.UI.FIRMWARE_NOT_COMPATIBLE, device.toMessageObject()));
134
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.FIRMWARE_NOT_COMPATIBLE, device.toMessageObject()));
159
135
  const uiResp = await uiPromise.promise;
160
136
  if (!uiResp.payload) {
161
137
  throw constants_1.ERRORS.TypedError('Method_PermissionsNotGranted');
162
138
  }
163
139
  }
164
140
  else {
165
- await waitForPopup();
166
- postMessage((0, events_2.createUiMessage)(firmwareException, device.toMessageObject()));
141
+ await waitForPopup(context);
142
+ sendCoreMessage((0, events_2.createUiMessage)(firmwareException, device.toMessageObject()));
167
143
  await uiPromises.create(events_2.DEVICE.DISCONNECT, device).promise;
168
144
  return Promise.reject(constants_1.ERRORS.TypedError('Method_Cancel'));
169
145
  }
@@ -176,8 +152,8 @@ const inner = async (method, device) => {
176
152
  if (unexpectedMode) {
177
153
  device.keepSession = false;
178
154
  if (isUsingPopup) {
179
- await waitForPopup();
180
- postMessage((0, events_2.createUiMessage)(unexpectedMode, device.toMessageObject()));
155
+ await waitForPopup(context);
156
+ sendCoreMessage((0, events_2.createUiMessage)(unexpectedMode, device.toMessageObject()));
181
157
  await uiPromises.create(events_2.DEVICE.DISCONNECT, device).promise;
182
158
  return Promise.reject(constants_1.ERRORS.TypedError('Device_ModeException', unexpectedMode));
183
159
  }
@@ -185,9 +161,9 @@ const inner = async (method, device) => {
185
161
  }
186
162
  method.checkPermissions();
187
163
  if (!trustedHost && method.requiredPermissions.length > 0) {
188
- await waitForPopup();
164
+ await waitForPopup(context);
189
165
  const uiPromise = uiPromises.create(events_2.UI.RECEIVE_PERMISSION, device);
190
- postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PERMISSION, {
166
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PERMISSION, {
191
167
  permissions: method.requiredPermissions,
192
168
  device: device.toMessageObject(),
193
169
  }));
@@ -203,9 +179,9 @@ const inner = async (method, device) => {
203
179
  if (deviceNeedsBackup) {
204
180
  if (method.noBackupConfirmationMode === 'always' ||
205
181
  (method.noBackupConfirmationMode === 'popup-only' && isUsingPopup)) {
206
- await waitForPopup();
182
+ await waitForPopup(context);
207
183
  const uiPromise = uiPromises.create(events_2.UI.RECEIVE_CONFIRMATION, device);
208
- postMessage((0, analyticsInfo_1.enhanceMessageWithAnalytics)((0, events_2.createUiMessage)(events_2.UI.REQUEST_CONFIRMATION, {
184
+ sendCoreMessage((0, analyticsInfo_1.enhanceMessageWithAnalytics)((0, events_2.createUiMessage)(events_2.UI.REQUEST_CONFIRMATION, {
209
185
  view: 'no-backup',
210
186
  }), { device: device.toMessageObject() }));
211
187
  const permitted = await uiPromise.promise.then(({ payload }) => payload);
@@ -213,19 +189,19 @@ const inner = async (method, device) => {
213
189
  return Promise.reject(constants_1.ERRORS.TypedError('Method_PermissionsNotGranted'));
214
190
  }
215
191
  }
216
- await waitForPopup();
217
- postMessage((0, events_2.createUiMessage)(events_2.UI.DEVICE_NEEDS_BACKUP, device.toMessageObject()));
192
+ await waitForPopup(context);
193
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.DEVICE_NEEDS_BACKUP, device.toMessageObject()));
218
194
  }
219
195
  if (device.firmwareStatus === 'outdated') {
220
- await waitForPopup();
221
- postMessage((0, events_2.createUiMessage)(events_2.UI.FIRMWARE_OUTDATED, device.toMessageObject()));
196
+ await waitForPopup(context);
197
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.FIRMWARE_OUTDATED, device.toMessageObject()));
222
198
  }
223
199
  if (!trustedHost) {
224
200
  const requestConfirmation = method.confirmation;
225
201
  if (requestConfirmation) {
226
- await waitForPopup();
202
+ await waitForPopup(context);
227
203
  const uiPromise = uiPromises.create(events_2.UI.RECEIVE_CONFIRMATION, device);
228
- postMessage((0, analyticsInfo_1.enhanceMessageWithAnalytics)((0, events_2.createUiMessage)(events_2.UI.REQUEST_CONFIRMATION, requestConfirmation), { device: device.toMessageObject() }));
204
+ sendCoreMessage((0, analyticsInfo_1.enhanceMessageWithAnalytics)((0, events_2.createUiMessage)(events_2.UI.REQUEST_CONFIRMATION, requestConfirmation), { device: device.toMessageObject() }));
229
205
  const confirmed = await uiPromise.promise.then(({ payload }) => payload);
230
206
  if (!confirmed) {
231
207
  return Promise.reject(constants_1.ERRORS.TypedError('Method_Cancel'));
@@ -235,18 +211,18 @@ const inner = async (method, device) => {
235
211
  const isDeviceUnlocked = device.features.unlocked;
236
212
  if (method.useDeviceState) {
237
213
  try {
238
- let invalidDeviceState = await getInvalidDeviceState(device, method.preauthorized);
214
+ let invalidDeviceState = await getInvalidDeviceState(context, device, method.preauthorized);
239
215
  if (isUsingPopup) {
240
216
  while (invalidDeviceState) {
241
217
  const uiPromise = uiPromises.create(events_2.UI.INVALID_PASSPHRASE_ACTION, device);
242
- postMessage((0, events_2.createUiMessage)(events_2.UI.INVALID_PASSPHRASE, {
218
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.INVALID_PASSPHRASE, {
243
219
  device: device.toMessageObject(),
244
220
  }));
245
221
  const uiResp = await uiPromise.promise;
246
222
  if (uiResp.payload) {
247
223
  device.setInternalState(undefined);
248
224
  await device.initialize(method.useCardanoDerivation);
249
- invalidDeviceState = await getInvalidDeviceState(device, method.preauthorized);
225
+ invalidDeviceState = await getInvalidDeviceState(context, device, method.preauthorized);
250
226
  }
251
227
  else {
252
228
  device.setExternalState(invalidDeviceState);
@@ -264,13 +240,13 @@ const inner = async (method, device) => {
264
240
  }
265
241
  }
266
242
  if (!isDeviceUnlocked && device.features.unlocked) {
267
- postMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CHANGED, device.toMessageObject()));
243
+ sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CHANGED, device.toMessageObject()));
268
244
  }
269
245
  if (method.useUi) {
270
- await waitForPopup();
246
+ await waitForPopup(context);
271
247
  }
272
248
  else {
273
- postMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
249
+ sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
274
250
  }
275
251
  try {
276
252
  const response = await method.run();
@@ -280,11 +256,12 @@ const inner = async (method, device) => {
280
256
  return Promise.reject(error);
281
257
  }
282
258
  };
283
- const onCall = async (message) => {
259
+ const onCall = async (context, message) => {
284
260
  var _a;
285
261
  if (!message.id || !message.payload || message.type !== events_2.IFRAME.CALL) {
286
262
  throw constants_1.ERRORS.TypedError('Method_InvalidParameter', 'onCall: message.id or message.payload is missing');
287
263
  }
264
+ const { uiPromises, deviceList, callMethods, methodSynchronize, resolveWaitForFirstMethod, getOverridePromise, setOverridePromise, sendCoreMessage, } = context;
288
265
  const responseID = message.id;
289
266
  const origin = DataManager_1.DataManager.getSettings('origin');
290
267
  const env = DataManager_1.DataManager.getSettings('env');
@@ -301,27 +278,27 @@ const onCall = async (message) => {
301
278
  _log.debug('loading method...');
302
279
  const method = await (0, method_1.getMethod)(message);
303
280
  _log.debug('method selected', method.name);
304
- method.postMessage = postMessage;
281
+ method.postMessage = sendCoreMessage;
305
282
  method.createUiPromise = uiPromises.create;
306
283
  method.init();
307
284
  await ((_a = method.initAsync) === null || _a === void 0 ? void 0 : _a.call(method));
308
285
  return method;
309
286
  });
310
- waitForFirstMethod.resolve();
311
- _callMethods.push(method);
287
+ resolveWaitForFirstMethod();
288
+ callMethods.push(method);
312
289
  }
313
290
  catch (error) {
314
- postMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
315
- postMessage((0, events_2.createResponseMessage)(responseID, false, { error }));
291
+ sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
292
+ sendCoreMessage((0, events_2.createResponseMessage)(responseID, false, { error }));
316
293
  return Promise.resolve();
317
294
  }
318
295
  if (!method.useDevice) {
319
296
  try {
320
297
  if (method.useUi) {
321
- await waitForPopup();
298
+ await waitForPopup(context);
322
299
  }
323
300
  else {
324
- postMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
301
+ sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
325
302
  }
326
303
  const response = await method.run();
327
304
  messageResponse = (0, events_2.createResponseMessage)(method.responseID, true, response);
@@ -329,45 +306,47 @@ const onCall = async (message) => {
329
306
  catch (error) {
330
307
  messageResponse = (0, events_2.createResponseMessage)(method.responseID, false, { error });
331
308
  }
332
- postMessage(messageResponse);
309
+ sendCoreMessage(messageResponse);
333
310
  return Promise.resolve();
334
311
  }
335
- if (!_deviceList && !DataManager_1.DataManager.getSettings('transportReconnect')) {
336
- await initDeviceList(false);
312
+ if (!deviceList.isConnected() && !deviceList.pendingConnection()) {
313
+ const { transports, pendingTransportEvent } = DataManager_1.DataManager.getSettings();
314
+ deviceList.setTransports(transports);
315
+ await deviceList.init({ pendingTransportEvent });
337
316
  }
338
317
  if (method.isManagementRestricted()) {
339
- postMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
340
- postMessage((0, events_2.createResponseMessage)(responseID, false, {
318
+ sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
319
+ sendCoreMessage((0, events_2.createResponseMessage)(responseID, false, {
341
320
  error: constants_1.ERRORS.TypedError('Method_NotAllowed'),
342
321
  }));
343
322
  return Promise.resolve();
344
323
  }
345
324
  let device;
346
325
  try {
347
- device = await initDevice(method.devicePath);
326
+ device = await initDevice(context, method.devicePath);
348
327
  }
349
328
  catch (error) {
350
329
  if (error.code === 'Transport_Missing') {
351
- await waitForPopup();
352
- postMessage((0, events_2.createUiMessage)(events_2.UI.TRANSPORT));
330
+ await waitForPopup(context);
331
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.TRANSPORT));
353
332
  }
354
333
  else {
355
- postMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
334
+ sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
356
335
  }
357
- postMessage((0, events_2.createResponseMessage)(responseID, false, { error }));
336
+ sendCoreMessage((0, events_2.createResponseMessage)(responseID, false, { error }));
358
337
  throw error;
359
338
  }
360
339
  method.setDevice(device);
361
- const previousCall = _callMethods.filter(call => call && call !== method && call.devicePath === method.devicePath);
340
+ const previousCall = callMethods.filter(call => call && call !== method && call.devicePath === method.devicePath);
362
341
  if (previousCall.length > 0 && method.overridePreviousCall) {
363
342
  previousCall.forEach(call => {
364
343
  call.overridden = true;
365
344
  });
366
345
  const overrideError = constants_1.ERRORS.TypedError('Method_Override');
367
- _overridePromise = device.override(overrideError);
368
- await _overridePromise;
346
+ setOverridePromise(device.override(overrideError));
347
+ await getOverridePromise();
369
348
  if (method.overridden) {
370
- postMessage((0, events_2.createResponseMessage)(method.responseID, false, { error: overrideError }));
349
+ sendCoreMessage((0, events_2.createResponseMessage)(method.responseID, false, { error: overrideError }));
371
350
  throw overrideError;
372
351
  }
373
352
  }
@@ -376,7 +355,7 @@ const onCall = async (message) => {
376
355
  await device.waitForFirstRun();
377
356
  }
378
357
  else {
379
- postMessage((0, events_2.createResponseMessage)(responseID, false, {
358
+ sendCoreMessage((0, events_2.createResponseMessage)(responseID, false, {
380
359
  error: constants_1.ERRORS.TypedError('Device_CallInProgress'),
381
360
  }));
382
361
  throw constants_1.ERRORS.TypedError('Device_CallInProgress');
@@ -386,14 +365,12 @@ const onCall = async (message) => {
386
365
  if (method.hasExpectedDeviceState) {
387
366
  device.setExternalState(method.deviceState);
388
367
  }
389
- device.on(events_2.DEVICE.BUTTON, (d, code) => {
390
- onDeviceButtonHandler(d, code, method);
391
- });
392
- device.on(events_2.DEVICE.PIN, onDevicePinHandler);
393
- device.on(events_2.DEVICE.WORD, onDeviceWordHandler);
394
- device.on(events_2.DEVICE.PASSPHRASE, method.useEmptyPassphrase ? onEmptyPassphraseHandler : onDevicePassphraseHandler);
368
+ device.on(events_2.DEVICE.BUTTON, onDeviceButtonHandler(context, method));
369
+ device.on(events_2.DEVICE.PIN, onDevicePinHandler(context));
370
+ device.on(events_2.DEVICE.WORD, onDeviceWordHandler(context));
371
+ device.on(events_2.DEVICE.PASSPHRASE, (method.useEmptyPassphrase ? onEmptyPassphraseHandler : onDevicePassphraseHandler)(context));
395
372
  device.on(events_2.DEVICE.PASSPHRASE_ON_DEVICE, () => {
396
- postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PASSPHRASE_ON_DEVICE, { device: device.toMessageObject() }));
373
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PASSPHRASE_ON_DEVICE, { device: device.toMessageObject() }));
397
374
  });
398
375
  device.on(events_2.DEVICE.SAVE_STATE, (state) => {
399
376
  if (useCoreInPopup && env === 'webextension') {
@@ -420,10 +397,10 @@ const onCall = async (message) => {
420
397
  }
421
398
  }
422
399
  try {
423
- if (_overridePromise) {
424
- await _overridePromise;
400
+ if (getOverridePromise()) {
401
+ await getOverridePromise();
425
402
  }
426
- const innerAction = () => inner(method, device).then(response => {
403
+ const innerAction = () => inner(context, method, device).then(response => {
427
404
  messageResponse = response;
428
405
  });
429
406
  await device.run(innerAction, {
@@ -433,19 +410,20 @@ const onCall = async (message) => {
433
410
  });
434
411
  }
435
412
  catch (error) {
436
- if (_deviceList && error.code === 'Device_Disconnected') {
437
- _deviceList.addAuthPenalty(device);
413
+ if (error.code === 'Device_Disconnected') {
414
+ deviceList.addAuthPenalty(device);
438
415
  }
439
416
  if (method) {
440
- if (_deviceList && error.message === transport_1.TRANSPORT_ERROR.SESSION_WRONG_PREVIOUS) {
441
- await _deviceList.enumerate();
417
+ if (deviceList.isConnected() &&
418
+ error.message === transport_1.TRANSPORT_ERROR.SESSION_WRONG_PREVIOUS) {
419
+ await deviceList.enumerate();
442
420
  }
443
421
  messageResponse = (0, events_2.createResponseMessage)(method.responseID, false, { error });
444
422
  }
445
423
  }
446
424
  finally {
447
- if (_overridePromise) {
448
- await _overridePromise;
425
+ if (getOverridePromise()) {
426
+ await getOverridePromise();
449
427
  }
450
428
  const response = messageResponse;
451
429
  if (response) {
@@ -459,73 +437,75 @@ const onCall = async (message) => {
459
437
  }
460
438
  await device.cleanup();
461
439
  if (useCoreInPopup) {
462
- postMessage(response);
440
+ sendCoreMessage(response);
463
441
  }
464
- closePopup();
465
- cleanup();
442
+ closePopup(context);
443
+ cleanup(context);
466
444
  if (method) {
467
445
  method.dispose();
468
446
  }
469
- if (_deviceList) {
470
- if (response.success) {
471
- _deviceList.removeAuthPenalty(device);
472
- }
447
+ if (response.success) {
448
+ deviceList.removeAuthPenalty(device);
473
449
  }
474
450
  if (!useCoreInPopup) {
475
- postMessage(response);
451
+ sendCoreMessage(response);
476
452
  }
477
453
  }
478
454
  }
479
455
  };
480
- const cleanup = () => {
456
+ const cleanup = ({ uiPromises, popupPromise, interactionTimeout }) => {
481
457
  popupPromise.clear();
482
458
  uiPromises.clear();
483
- _interactionTimeout.stop();
459
+ interactionTimeout.stop();
484
460
  _log.debug('Cleanup...');
485
461
  };
486
- const closePopup = () => {
462
+ const closePopup = ({ popupPromise, sendCoreMessage }) => {
487
463
  if (popupPromise.isWaiting()) {
488
- postMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
464
+ sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
489
465
  }
490
- postMessage((0, events_2.createUiMessage)(events_2.UI.CLOSE_UI_WINDOW));
466
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.CLOSE_UI_WINDOW));
491
467
  };
492
- const onDeviceButtonHandler = async (...[device, request, method]) => {
468
+ const onDeviceButtonHandler = (context, method) => async (...[device, request]) => {
469
+ const { sendCoreMessage } = context;
493
470
  const addressRequest = request.code === 'ButtonRequest_Address';
494
471
  if (!addressRequest || (addressRequest && method.useUi)) {
495
- await waitForPopup();
472
+ await waitForPopup(context);
496
473
  }
497
474
  const data = typeof method.getButtonRequestData === 'function' && request.code
498
475
  ? method.getButtonRequestData(request.code)
499
476
  : undefined;
500
- interactionTimeout();
501
- postMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.BUTTON, { ...request, device: device.toMessageObject() }));
502
- postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_BUTTON, {
477
+ startInteractionTimeout(context);
478
+ sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.BUTTON, { ...request, device: device.toMessageObject() }));
479
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_BUTTON, {
503
480
  ...request,
504
481
  device: device.toMessageObject(),
505
482
  data,
506
483
  }));
507
484
  if (addressRequest && !method.useUi) {
508
- postMessage((0, events_2.createUiMessage)(events_2.UI.ADDRESS_VALIDATION, data));
485
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.ADDRESS_VALIDATION, data));
509
486
  }
510
487
  };
511
- const onDevicePinHandler = async (...[device, type, callback]) => {
512
- await waitForPopup();
488
+ const onDevicePinHandler = (context) => async (...[device, type, callback]) => {
489
+ const { uiPromises, sendCoreMessage } = context;
490
+ await waitForPopup(context);
513
491
  const uiPromise = uiPromises.create(events_2.UI.RECEIVE_PIN, device);
514
- postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PIN, { device: device.toMessageObject(), type }));
492
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PIN, { device: device.toMessageObject(), type }));
515
493
  const uiResp = await uiPromise.promise;
516
494
  callback(null, uiResp.payload);
517
495
  };
518
- const onDeviceWordHandler = async (...[device, type, callback]) => {
519
- await waitForPopup();
496
+ const onDeviceWordHandler = (context) => async (...[device, type, callback]) => {
497
+ const { uiPromises, sendCoreMessage } = context;
498
+ await waitForPopup(context);
520
499
  const uiPromise = uiPromises.create(events_2.UI.RECEIVE_WORD, device);
521
- postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_WORD, { device: device.toMessageObject(), type }));
500
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_WORD, { device: device.toMessageObject(), type }));
522
501
  const uiResp = await uiPromise.promise;
523
502
  callback(null, uiResp.payload);
524
503
  };
525
- const onDevicePassphraseHandler = async (...[device, callback]) => {
526
- await waitForPopup();
504
+ const onDevicePassphraseHandler = (context) => async (...[device, callback]) => {
505
+ const { uiPromises, sendCoreMessage } = context;
506
+ await waitForPopup(context);
527
507
  const uiPromise = uiPromises.create(events_2.UI.RECEIVE_PASSPHRASE, device);
528
- postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PASSPHRASE, { device: device.toMessageObject() }));
508
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_PASSPHRASE, { device: device.toMessageObject() }));
529
509
  const uiResp = await uiPromise.promise;
530
510
  const { value, passphraseOnDevice, save } = uiResp.payload;
531
511
  callback({
@@ -534,27 +514,28 @@ const onDevicePassphraseHandler = async (...[device, callback]) => {
534
514
  cache: save,
535
515
  });
536
516
  };
537
- const onEmptyPassphraseHandler = (...[_, callback]) => {
517
+ const onEmptyPassphraseHandler = () => (...[_, callback]) => {
538
518
  callback({ passphrase: '' });
539
519
  };
540
- const onPopupClosed = (customErrorMessage) => {
520
+ const onPopupClosed = (context, customErrorMessage) => {
521
+ const { uiPromises, popupPromise, deviceList, callMethods, resetWaitForFirstMethod, setOverridePromise, sendCoreMessage, } = context;
541
522
  const error = customErrorMessage
542
523
  ? constants_1.ERRORS.TypedError('Method_Cancel', customErrorMessage)
543
524
  : constants_1.ERRORS.TypedError('Method_Interrupted');
544
- if (_deviceList && _deviceList.asArray().length > 0) {
545
- _deviceList.allDevices().forEach(d => {
525
+ if (deviceList.isConnected() && deviceList.asArray().length > 0) {
526
+ deviceList.allDevices().forEach(d => {
546
527
  d.keepSession = false;
547
528
  if (d.isUsedHere()) {
548
- _overridePromise = d.interruptionFromUser(error);
529
+ setOverridePromise(d.interruptionFromUser(error));
549
530
  }
550
531
  else {
551
532
  const success = uiPromises.resolve({ type: events_2.DEVICE.DISCONNECT, payload: undefined });
552
533
  if (!success) {
553
- _callMethods.forEach(m => {
554
- postMessage((0, events_2.createResponseMessage)(m.responseID, false, { error }));
534
+ callMethods.forEach(m => {
535
+ sendCoreMessage((0, events_2.createResponseMessage)(m.responseID, false, { error }));
555
536
  });
556
- _callMethods.splice(0, _callMethods.length);
557
- waitForFirstMethod = (0, utils_1.createDeferred)();
537
+ callMethods.splice(0, callMethods.length);
538
+ resetWaitForFirstMethod();
558
539
  }
559
540
  }
560
541
  });
@@ -563,13 +544,14 @@ const onPopupClosed = (customErrorMessage) => {
563
544
  uiPromises.rejectAll(error);
564
545
  popupPromise.reject(error);
565
546
  }
566
- cleanup();
547
+ cleanup(context);
567
548
  };
568
- const handleDeviceSelectionChanges = (interruptDevice) => {
549
+ const handleDeviceSelectionChanges = (context, interruptDevice) => {
550
+ const { uiPromises, deviceList, sendCoreMessage } = context;
569
551
  const promiseExists = uiPromises.exists(events_2.UI.RECEIVE_DEVICE);
570
- if (promiseExists && _deviceList) {
571
- const list = _deviceList.asArray();
572
- const isWebUsb = _deviceList.transportType() === 'WebUsbTransport';
552
+ if (promiseExists && deviceList.isConnected()) {
553
+ const list = deviceList.asArray();
554
+ const isWebUsb = deviceList.transportType() === 'WebUsbTransport';
573
555
  if (list.length === 1 && !isWebUsb) {
574
556
  uiPromises.resolve({
575
557
  type: events_2.UI.RECEIVE_DEVICE,
@@ -577,7 +559,7 @@ const handleDeviceSelectionChanges = (interruptDevice) => {
577
559
  });
578
560
  }
579
561
  else {
580
- postMessage((0, events_2.createUiMessage)(events_2.UI.SELECT_DEVICE, {
562
+ sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.SELECT_DEVICE, {
581
563
  webusb: isWebUsb,
582
564
  devices: list,
583
565
  }));
@@ -587,91 +569,107 @@ const handleDeviceSelectionChanges = (interruptDevice) => {
587
569
  const { path } = interruptDevice;
588
570
  const shouldClosePopup = uiPromises.disconnected(path);
589
571
  if (shouldClosePopup) {
590
- closePopup();
591
- cleanup();
572
+ closePopup(context);
573
+ cleanup(context);
592
574
  }
593
575
  }
594
576
  };
595
- const initDeviceList = async (transportReconnect) => {
596
- try {
597
- _deviceList = new DeviceList_1.DeviceList({
598
- settings: DataManager_1.DataManager.getSettings(),
599
- messages: DataManager_1.DataManager.getProtobufMessages(),
600
- });
601
- _deviceList.on(events_2.DEVICE.CONNECT, device => {
602
- handleDeviceSelectionChanges();
603
- postMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CONNECT, device));
604
- });
605
- _deviceList.on(events_2.DEVICE.CONNECT_UNACQUIRED, device => {
606
- handleDeviceSelectionChanges();
607
- postMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CONNECT_UNACQUIRED, device));
608
- });
609
- _deviceList.on(events_2.DEVICE.DISCONNECT, device => {
610
- handleDeviceSelectionChanges(device);
611
- postMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.DISCONNECT, device));
612
- });
613
- _deviceList.on(events_2.DEVICE.CHANGED, device => {
614
- postMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CHANGED, device));
615
- });
616
- _deviceList.on(transport_1.TRANSPORT.ERROR, error => {
617
- _log.warn('TRANSPORT.ERROR', error);
618
- if (_deviceList) {
619
- _deviceList.disconnectDevices();
620
- _deviceList.dispose();
621
- }
622
- _deviceList = undefined;
623
- postMessage((0, events_2.createTransportMessage)(transport_1.TRANSPORT.ERROR, { error }));
624
- if (transportReconnect) {
625
- const { promise, timeout } = (0, promiseUtils_1.resolveAfter)(1000, null);
626
- _deviceListInitTimeout = timeout;
627
- promise.then(() => {
628
- initDeviceList(transportReconnect);
629
- });
630
- }
631
- });
632
- _deviceList.on(transport_1.TRANSPORT.START, transportType => postMessage((0, events_2.createTransportMessage)(transport_1.TRANSPORT.START, transportType)));
633
- _deviceList.init();
634
- if (_deviceList) {
635
- await _deviceList.waitForTransportFirstEvent();
636
- }
637
- }
638
- catch (error) {
639
- _deviceList = undefined;
640
- postMessage((0, events_2.createTransportMessage)(transport_1.TRANSPORT.ERROR, { error }));
641
- if (!transportReconnect) {
642
- throw error;
643
- }
644
- else {
645
- const { promise, timeout } = (0, promiseUtils_1.resolveAfter)(3000, null);
646
- _deviceListInitTimeout = timeout;
647
- await promise;
648
- await initDeviceList(transportReconnect);
649
- }
650
- }
577
+ const initDeviceList = (context) => {
578
+ const { deviceList, sendCoreMessage } = context;
579
+ deviceList.on(events_2.DEVICE.CONNECT, device => {
580
+ handleDeviceSelectionChanges(context);
581
+ sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CONNECT, device));
582
+ });
583
+ deviceList.on(events_2.DEVICE.CONNECT_UNACQUIRED, device => {
584
+ handleDeviceSelectionChanges(context);
585
+ sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CONNECT_UNACQUIRED, device));
586
+ });
587
+ deviceList.on(events_2.DEVICE.DISCONNECT, device => {
588
+ handleDeviceSelectionChanges(context);
589
+ sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.DISCONNECT, device));
590
+ });
591
+ deviceList.on(events_2.DEVICE.CHANGED, device => {
592
+ sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CHANGED, device));
593
+ });
594
+ deviceList.on(transport_1.TRANSPORT.START, transportType => sendCoreMessage((0, events_2.createTransportMessage)(transport_1.TRANSPORT.START, transportType)));
595
+ deviceList.on(transport_1.TRANSPORT.ERROR, error => {
596
+ _log.warn('TRANSPORT.ERROR', error);
597
+ sendCoreMessage((0, events_2.createTransportMessage)(transport_1.TRANSPORT.ERROR, { error }));
598
+ });
651
599
  };
652
600
  class Core extends events_1.default {
653
601
  constructor() {
654
602
  super(...arguments);
655
603
  this.abortController = new AbortController();
604
+ this.callMethods = [];
605
+ this.popupPromise = (0, popupPromiseManager_1.createPopupPromiseManager)();
606
+ this.methodSynchronize = (0, utils_2.getSynchronize)();
607
+ this.uiPromises = (0, uiPromiseManager_1.createUiPromiseManager)(() => startInteractionTimeout(this.getCoreContext()));
608
+ this.waitForFirstMethod = (0, utils_1.createDeferred)();
609
+ }
610
+ get interactionTimeout() {
611
+ var _a;
612
+ return (_a = this._interactionTimeout) !== null && _a !== void 0 ? _a : (0, utils_1.throwError)('Core not initialized: interactionTimeout');
613
+ }
614
+ get deviceList() {
615
+ var _a;
616
+ return (_a = this._deviceList) !== null && _a !== void 0 ? _a : (0, utils_1.throwError)('Core not initialized: deviceList');
617
+ }
618
+ sendCoreMessage(message) {
619
+ if (message.event === events_2.RESPONSE_EVENT) {
620
+ const index = this.callMethods.findIndex(call => call && call.responseID === message.id);
621
+ if (index >= 0) {
622
+ this.callMethods.splice(index, 1);
623
+ if (this.callMethods.length === 0) {
624
+ this.waitForFirstMethod = (0, utils_1.createDeferred)();
625
+ }
626
+ }
627
+ }
628
+ this.emit(events_2.CORE_EVENT, message);
629
+ }
630
+ getCoreContext() {
631
+ return {
632
+ uiPromises: this.uiPromises,
633
+ popupPromise: this.popupPromise,
634
+ interactionTimeout: this.interactionTimeout,
635
+ deviceList: this.deviceList,
636
+ callMethods: this.callMethods,
637
+ methodSynchronize: this.methodSynchronize,
638
+ sendCoreMessage: this.sendCoreMessage.bind(this),
639
+ resetWaitForFirstMethod: () => {
640
+ this.waitForFirstMethod = (0, utils_1.createDeferred)();
641
+ },
642
+ resolveWaitForFirstMethod: () => {
643
+ this.waitForFirstMethod.resolve();
644
+ },
645
+ getOverridePromise: () => {
646
+ return this.overridePromise;
647
+ },
648
+ setOverridePromise: (promise) => {
649
+ this.overridePromise = promise;
650
+ },
651
+ };
656
652
  }
657
653
  handleMessage(message) {
658
654
  _log.debug('handleMessage', message);
659
655
  switch (message.type) {
660
656
  case events_2.POPUP.HANDSHAKE:
661
- popupPromise.resolve();
657
+ this.popupPromise.resolve();
662
658
  break;
663
659
  case events_2.POPUP.CLOSED:
664
- popupPromise.clear();
665
- onPopupClosed(message.payload ? message.payload.error : null);
660
+ this.popupPromise.clear();
661
+ onPopupClosed(this.getCoreContext(), message.payload ? message.payload.error : null);
666
662
  break;
667
663
  case transport_1.TRANSPORT.DISABLE_WEBUSB:
668
- disableWebUSBTransport();
664
+ disableWebUSBTransport(this.getCoreContext());
669
665
  break;
670
666
  case transport_1.TRANSPORT.REQUEST_DEVICE:
671
- _deviceList === null || _deviceList === void 0 ? void 0 : _deviceList.enumerate();
667
+ if (this.deviceList.isConnected()) {
668
+ this.deviceList.enumerate();
669
+ }
672
670
  break;
673
671
  case transport_1.TRANSPORT.GET_INFO:
674
- postMessage((0, events_2.createResponseMessage)(message.id, true, this.getTransportInfo()));
672
+ this.sendCoreMessage((0, events_2.createResponseMessage)(message.id, true, this.getTransportInfo()));
675
673
  break;
676
674
  case events_2.UI.RECEIVE_DEVICE:
677
675
  case events_2.UI.RECEIVE_CONFIRMATION:
@@ -683,30 +681,31 @@ class Core extends events_1.default {
683
681
  case events_2.UI.RECEIVE_FEE:
684
682
  case events_2.UI.RECEIVE_WORD:
685
683
  case events_2.UI.LOGIN_CHALLENGE_RESPONSE:
686
- uiPromises.resolve(message);
684
+ this.uiPromises.resolve(message);
687
685
  break;
688
686
  case events_2.IFRAME.CALL:
689
687
  if (message.payload.method === 'firmwareUpdate') {
688
+ (0, DeviceList_1.assertDeviceListConnected)(this.deviceList);
690
689
  (0, onCallFirmwareUpdate_1.onCallFirmwareUpdate)({
691
690
  params: message.payload,
692
691
  context: {
693
- deviceList: _deviceList,
694
- postMessage,
695
- initDevice,
692
+ deviceList: this.deviceList,
693
+ postMessage: this.sendCoreMessage.bind(this),
694
+ initDevice: path => initDevice(this.getCoreContext(), path),
696
695
  log: _log,
697
696
  abortSignal: this.abortController.signal,
698
697
  },
699
698
  })
700
699
  .then(payload => {
701
- postMessage((0, events_2.createResponseMessage)(message.id, true, payload));
700
+ this.sendCoreMessage((0, events_2.createResponseMessage)(message.id, true, payload));
702
701
  })
703
702
  .catch(error => {
704
- postMessage((0, events_2.createResponseMessage)(message.id, false, { error }));
703
+ this.sendCoreMessage((0, events_2.createResponseMessage)(message.id, false, { error }));
705
704
  _log.error('onCallFirmwareUpdate', error);
706
705
  });
707
706
  }
708
707
  else {
709
- onCall(message).catch(error => {
708
+ onCall(this.getCoreContext(), message).catch(error => {
710
709
  _log.error('onCall', error);
711
710
  });
712
711
  }
@@ -714,97 +713,97 @@ class Core extends events_1.default {
714
713
  }
715
714
  dispose() {
716
715
  (0, BlockchainLink_1.dispose)();
717
- if (_deviceListInitTimeout) {
718
- clearTimeout(_deviceListInitTimeout);
719
- }
720
716
  this.removeAllListeners();
721
717
  this.abortController.abort();
722
- if (_deviceList) {
723
- _deviceList.dispose();
724
- }
718
+ this.deviceList.dispose();
725
719
  }
726
720
  async getCurrentMethod() {
727
- await waitForFirstMethod.promise;
728
- return await methodSynchronize(() => _callMethods[0]);
721
+ await this.waitForFirstMethod.promise;
722
+ return await this.methodSynchronize(() => this.callMethods[0]);
729
723
  }
730
724
  getTransportInfo() {
731
- if (!_deviceList) {
732
- return undefined;
725
+ if (this.deviceList.isConnected()) {
726
+ return this.deviceList.getTransportInfo();
733
727
  }
734
- return _deviceList.getTransportInfo();
735
728
  }
736
729
  enumerate() {
737
- if (!_deviceList) {
738
- return;
730
+ if (this.deviceList.isConnected()) {
731
+ this.deviceList.enumerate();
739
732
  }
740
- _deviceList.enumerate();
741
733
  }
742
734
  async init(settings, onCoreEvent, logWriterFactory) {
743
735
  if (logWriterFactory) {
744
736
  (0, debug_1.setLogWriter)(logWriterFactory);
745
737
  }
738
+ const throttlePromise = (0, utils_1.createDeferred)();
739
+ throttlePromise.promise.catch(() => { });
740
+ const onCoreEventThrottled = (message) => throttlePromise.promise.then(() => onCoreEvent(message));
746
741
  try {
747
742
  await DataManager_1.DataManager.load(settings);
748
- (0, debug_1.enableLog)(DataManager_1.DataManager.getSettings('debug'));
749
- _core = this;
750
- _interactionTimeout = new interactionTimeout_1.InteractionTimeout(settings.popup ? settings.interactionTimeout : 0);
751
- this.on(events_2.CORE_EVENT, onCoreEvent);
743
+ const { debug, priority } = DataManager_1.DataManager.getSettings();
744
+ const messages = DataManager_1.DataManager.getProtobufMessages();
745
+ (0, debug_1.enableLog)(debug);
746
+ this._interactionTimeout = new interactionTimeout_1.InteractionTimeout(settings.popup ? settings.interactionTimeout : 0);
747
+ this._deviceList = new DeviceList_1.DeviceList({
748
+ debug,
749
+ messages,
750
+ priority,
751
+ });
752
+ initDeviceList(this.getCoreContext());
753
+ this.on(events_2.CORE_EVENT, onCoreEventThrottled);
752
754
  }
753
755
  catch (error) {
754
756
  _log.error('init', error);
757
+ throttlePromise.reject(error);
755
758
  throw error;
756
759
  }
760
+ const { transports, pendingTransportEvent, transportReconnect, coreMode } = DataManager_1.DataManager.getSettings();
757
761
  try {
758
- if (!DataManager_1.DataManager.getSettings('transportReconnect') ||
759
- DataManager_1.DataManager.getSettings('coreMode') === 'auto') {
760
- await initDeviceList(false);
761
- }
762
- else {
763
- initDeviceList(true);
764
- }
762
+ this.deviceList.setTransports(transports);
765
763
  }
766
764
  catch (error) {
767
- _log.error('initTransport', error);
765
+ _log.error('setTransports', error);
766
+ this.sendCoreMessage((0, events_2.createTransportMessage)(transport_1.TRANSPORT.ERROR, { error }));
767
+ throttlePromise.reject(error);
768
768
  throw error;
769
769
  }
770
+ this.deviceList.init({ pendingTransportEvent, transportReconnect });
771
+ if (!transportReconnect || coreMode === 'auto') {
772
+ await this.deviceList.pendingConnection();
773
+ }
774
+ this.on(events_2.CORE_EVENT, onCoreEvent);
775
+ this.off(events_2.CORE_EVENT, onCoreEventThrottled);
776
+ setTimeout(throttlePromise.resolve, 0);
770
777
  }
771
778
  }
772
779
  exports.Core = Core;
773
- const disableWebUSBTransport = async () => {
774
- var _a;
775
- if (!_deviceList)
780
+ const disableWebUSBTransport = async ({ deviceList, sendCoreMessage }) => {
781
+ if (!deviceList.isConnected())
776
782
  return;
777
- if (_deviceList.transportType() !== 'WebUsbTransport')
783
+ if (deviceList.transportType() !== 'WebUsbTransport')
778
784
  return;
779
- const settings = DataManager_1.DataManager.getSettings();
780
- if (settings.transports) {
781
- const transportStr = (_a = settings.transports) === null || _a === void 0 ? void 0 : _a.filter(transport => typeof transport !== 'object');
785
+ const { transports, pendingTransportEvent, transportReconnect } = DataManager_1.DataManager.getSettings();
786
+ if (transports) {
787
+ const transportStr = transports === null || transports === void 0 ? void 0 : transports.filter(transport => typeof transport !== 'object');
782
788
  if (transportStr.includes('WebUsbTransport')) {
783
- settings.transports.splice(settings.transports.indexOf('WebUsbTransport'), 1);
789
+ transports.splice(transports.indexOf('WebUsbTransport'), 1);
784
790
  }
785
791
  if (!transportStr.includes('BridgeTransport')) {
786
- settings.transports.unshift('BridgeTransport');
792
+ transports.unshift('BridgeTransport');
787
793
  }
788
794
  }
789
795
  try {
790
- _deviceList.dispose();
791
- await initDeviceList(settings.transportReconnect);
796
+ deviceList.cleanup();
797
+ deviceList.setTransports(transports);
798
+ await deviceList.init({ pendingTransportEvent, transportReconnect });
792
799
  }
793
800
  catch (error) {
801
+ sendCoreMessage((0, events_2.createTransportMessage)(transport_1.TRANSPORT.ERROR, { error }));
794
802
  }
795
803
  };
796
- const initCore = async (settings, onCoreEvent, logWriterFactory) => {
804
+ const initCore = async (...params) => {
797
805
  const core = new Core();
798
- let promise;
799
- const eventThrottle = (...args) => promise
800
- .then(() => {
801
- setTimeout(() => onCoreEvent(...args), 0);
802
- })
803
- .catch(() => { });
804
- promise = core.init(settings, eventThrottle, logWriterFactory);
805
- await promise;
806
- core.on(events_2.CORE_EVENT, onCoreEvent);
807
- core.off(events_2.CORE_EVENT, eventThrottle);
806
+ await core.init(...params);
808
807
  return core;
809
808
  };
810
809
  const disposeCore = (core) => {