@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/CHANGELOG.md +121 -30
- package/README.md +1 -1
- package/lib/api/ethereum/api/ethereumSignTypedData.js +3 -1
- package/lib/api/getAccountInfo.d.ts +2 -0
- package/lib/backend/Blockchain.js +0 -3
- package/lib/core/index.d.ts +14 -2
- package/lib/core/index.js +273 -274
- package/lib/data/DataManager.d.ts +5 -0
- package/lib/data/config.d.ts +5 -0
- package/lib/data/config.js +5 -0
- package/lib/data/downloadReleasesMetadata.d.ts +7 -0
- package/lib/data/downloadReleasesMetadata.js +15 -0
- package/lib/data/version.d.ts +2 -1
- package/lib/data/version.js +3 -2
- package/lib/device/Device.d.ts +5 -2
- package/lib/device/Device.js +39 -4
- package/lib/device/DeviceCommands.js +1 -1
- package/lib/device/DeviceList.d.ts +41 -27
- package/lib/device/DeviceList.js +251 -234
- package/lib/device/calculateRevisionForDevice.d.ts +8 -0
- package/lib/device/calculateRevisionForDevice.js +21 -0
- package/lib/device/checkFirmwareRevision.d.ts +11 -0
- package/lib/device/checkFirmwareRevision.js +65 -0
- package/lib/events/popup.d.ts +1 -0
- package/lib/types/device.d.ts +9 -0
- package/lib/types/firmware.d.ts +1 -0
- package/lib/utils/assets-browser.d.ts +1 -1
- package/lib/utils/assets-browser.js +3 -2
- package/lib/utils/assets.d.ts +3 -3
- package/lib/utils/assets.js +3 -3
- package/lib/utils/deviceFeaturesUtils.js +22 -6
- package/lib/utils/promiseUtils.d.ts +3 -3
- package/lib/utils/promiseUtils.js +7 -5
- package/package.json +15 -15
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
|
|
33
|
-
|
|
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
|
|
50
|
-
onPopupClosed('Interaction timeout');
|
|
28
|
+
const startInteractionTimeout = (context) => context.interactionTimeout.start(() => {
|
|
29
|
+
onPopupClosed(context, 'Interaction timeout');
|
|
51
30
|
});
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
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 &&
|
|
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 =
|
|
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 =
|
|
55
|
+
const devices = deviceList.asArray();
|
|
82
56
|
if (devices.length === 1 && (!isWebUsb || !isUsingPopup)) {
|
|
83
|
-
device =
|
|
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
|
-
|
|
95
|
-
|
|
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 =
|
|
75
|
+
device = deviceList.getDevice(devices[0].path);
|
|
104
76
|
}
|
|
105
77
|
else {
|
|
106
|
-
|
|
78
|
+
sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.SELECT_DEVICE, {
|
|
107
79
|
webusb: isWebUsb,
|
|
108
|
-
devices:
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
311
|
-
|
|
287
|
+
resolveWaitForFirstMethod();
|
|
288
|
+
callMethods.push(method);
|
|
312
289
|
}
|
|
313
290
|
catch (error) {
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
|
|
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
|
-
|
|
309
|
+
sendCoreMessage(messageResponse);
|
|
333
310
|
return Promise.resolve();
|
|
334
311
|
}
|
|
335
|
-
if (!
|
|
336
|
-
|
|
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
|
-
|
|
340
|
-
|
|
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
|
-
|
|
330
|
+
await waitForPopup(context);
|
|
331
|
+
sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.TRANSPORT));
|
|
353
332
|
}
|
|
354
333
|
else {
|
|
355
|
-
|
|
334
|
+
sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
|
|
356
335
|
}
|
|
357
|
-
|
|
336
|
+
sendCoreMessage((0, events_2.createResponseMessage)(responseID, false, { error }));
|
|
358
337
|
throw error;
|
|
359
338
|
}
|
|
360
339
|
method.setDevice(device);
|
|
361
|
-
const previousCall =
|
|
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
|
-
|
|
368
|
-
await
|
|
346
|
+
setOverridePromise(device.override(overrideError));
|
|
347
|
+
await getOverridePromise();
|
|
369
348
|
if (method.overridden) {
|
|
370
|
-
|
|
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
|
-
|
|
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, (
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
device.on(events_2.DEVICE.
|
|
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
|
-
|
|
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 (
|
|
424
|
-
await
|
|
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 (
|
|
437
|
-
|
|
413
|
+
if (error.code === 'Device_Disconnected') {
|
|
414
|
+
deviceList.addAuthPenalty(device);
|
|
438
415
|
}
|
|
439
416
|
if (method) {
|
|
440
|
-
if (
|
|
441
|
-
|
|
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 (
|
|
448
|
-
await
|
|
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
|
-
|
|
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 (
|
|
470
|
-
|
|
471
|
-
_deviceList.removeAuthPenalty(device);
|
|
472
|
-
}
|
|
447
|
+
if (response.success) {
|
|
448
|
+
deviceList.removeAuthPenalty(device);
|
|
473
449
|
}
|
|
474
450
|
if (!useCoreInPopup) {
|
|
475
|
-
|
|
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
|
-
|
|
459
|
+
interactionTimeout.stop();
|
|
484
460
|
_log.debug('Cleanup...');
|
|
485
461
|
};
|
|
486
|
-
const closePopup = () => {
|
|
462
|
+
const closePopup = ({ popupPromise, sendCoreMessage }) => {
|
|
487
463
|
if (popupPromise.isWaiting()) {
|
|
488
|
-
|
|
464
|
+
sendCoreMessage((0, events_2.createPopupMessage)(events_2.POPUP.CANCEL_POPUP_REQUEST));
|
|
489
465
|
}
|
|
490
|
-
|
|
466
|
+
sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.CLOSE_UI_WINDOW));
|
|
491
467
|
};
|
|
492
|
-
const onDeviceButtonHandler = async (...[device, request
|
|
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
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
485
|
+
sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.ADDRESS_VALIDATION, data));
|
|
509
486
|
}
|
|
510
487
|
};
|
|
511
|
-
const onDevicePinHandler = async (...[device, type, callback]) => {
|
|
512
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
545
|
-
|
|
525
|
+
if (deviceList.isConnected() && deviceList.asArray().length > 0) {
|
|
526
|
+
deviceList.allDevices().forEach(d => {
|
|
546
527
|
d.keepSession = false;
|
|
547
528
|
if (d.isUsedHere()) {
|
|
548
|
-
|
|
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
|
-
|
|
554
|
-
|
|
534
|
+
callMethods.forEach(m => {
|
|
535
|
+
sendCoreMessage((0, events_2.createResponseMessage)(m.responseID, false, { error }));
|
|
555
536
|
});
|
|
556
|
-
|
|
557
|
-
|
|
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 &&
|
|
571
|
-
const list =
|
|
572
|
-
const isWebUsb =
|
|
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
|
-
|
|
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 =
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
});
|
|
616
|
-
|
|
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
|
-
|
|
667
|
+
if (this.deviceList.isConnected()) {
|
|
668
|
+
this.deviceList.enumerate();
|
|
669
|
+
}
|
|
672
670
|
break;
|
|
673
671
|
case transport_1.TRANSPORT.GET_INFO:
|
|
674
|
-
|
|
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:
|
|
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
|
-
|
|
700
|
+
this.sendCoreMessage((0, events_2.createResponseMessage)(message.id, true, payload));
|
|
702
701
|
})
|
|
703
702
|
.catch(error => {
|
|
704
|
-
|
|
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
|
-
|
|
723
|
-
_deviceList.dispose();
|
|
724
|
-
}
|
|
718
|
+
this.deviceList.dispose();
|
|
725
719
|
}
|
|
726
720
|
async getCurrentMethod() {
|
|
727
|
-
await waitForFirstMethod.promise;
|
|
728
|
-
return await methodSynchronize(() =>
|
|
721
|
+
await this.waitForFirstMethod.promise;
|
|
722
|
+
return await this.methodSynchronize(() => this.callMethods[0]);
|
|
729
723
|
}
|
|
730
724
|
getTransportInfo() {
|
|
731
|
-
if (
|
|
732
|
-
return
|
|
725
|
+
if (this.deviceList.isConnected()) {
|
|
726
|
+
return this.deviceList.getTransportInfo();
|
|
733
727
|
}
|
|
734
|
-
return _deviceList.getTransportInfo();
|
|
735
728
|
}
|
|
736
729
|
enumerate() {
|
|
737
|
-
if (
|
|
738
|
-
|
|
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
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
this.
|
|
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
|
-
|
|
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('
|
|
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
|
-
|
|
775
|
-
if (!_deviceList)
|
|
780
|
+
const disableWebUSBTransport = async ({ deviceList, sendCoreMessage }) => {
|
|
781
|
+
if (!deviceList.isConnected())
|
|
776
782
|
return;
|
|
777
|
-
if (
|
|
783
|
+
if (deviceList.transportType() !== 'WebUsbTransport')
|
|
778
784
|
return;
|
|
779
|
-
const
|
|
780
|
-
if (
|
|
781
|
-
const transportStr =
|
|
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
|
-
|
|
789
|
+
transports.splice(transports.indexOf('WebUsbTransport'), 1);
|
|
784
790
|
}
|
|
785
791
|
if (!transportStr.includes('BridgeTransport')) {
|
|
786
|
-
|
|
792
|
+
transports.unshift('BridgeTransport');
|
|
787
793
|
}
|
|
788
794
|
}
|
|
789
795
|
try {
|
|
790
|
-
|
|
791
|
-
|
|
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 (
|
|
804
|
+
const initCore = async (...params) => {
|
|
797
805
|
const core = new Core();
|
|
798
|
-
|
|
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) => {
|