@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/device/DeviceList.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DeviceList = void 0;
|
|
3
|
+
exports.DeviceList = exports.assertDeviceListConnected = void 0;
|
|
4
4
|
const utils_1 = require("@trezor/utils");
|
|
5
5
|
const transport_1 = require("@trezor/transport");
|
|
6
6
|
const constants_1 = require("../constants");
|
|
@@ -10,239 +10,265 @@ const transportInfo_1 = require("../data/transportInfo");
|
|
|
10
10
|
const debug_1 = require("../utils/debug");
|
|
11
11
|
const promiseUtils_1 = require("../utils/promiseUtils");
|
|
12
12
|
const _log = (0, debug_1.initLog)('DeviceList');
|
|
13
|
-
|
|
13
|
+
const createAuthPenaltyManager = (priority) => {
|
|
14
|
+
const penalizedDevices = {};
|
|
15
|
+
const get = () => 100 * priority +
|
|
16
|
+
Object.keys(penalizedDevices).reduce((penalty, key) => Math.max(penalty, penalizedDevices[key]), 0);
|
|
17
|
+
const add = (device) => {
|
|
18
|
+
if (!device.isInitialized() || device.isBootloader() || !device.features.device_id)
|
|
19
|
+
return;
|
|
20
|
+
const deviceID = device.features.device_id;
|
|
21
|
+
const penalty = penalizedDevices[deviceID] ? penalizedDevices[deviceID] + 500 : 2000;
|
|
22
|
+
penalizedDevices[deviceID] = Math.min(penalty, 5000);
|
|
23
|
+
};
|
|
24
|
+
const remove = (device) => {
|
|
25
|
+
if (!device.isInitialized() || device.isBootloader() || !device.features.device_id)
|
|
26
|
+
return;
|
|
27
|
+
const deviceID = device.features.device_id;
|
|
28
|
+
delete penalizedDevices[deviceID];
|
|
29
|
+
};
|
|
30
|
+
const clear = () => Object.keys(penalizedDevices).forEach(key => delete penalizedDevices[key]);
|
|
31
|
+
return { get, add, remove, clear };
|
|
32
|
+
};
|
|
33
|
+
const assertDeviceListConnected = deviceList => {
|
|
34
|
+
if (!deviceList.isConnected())
|
|
35
|
+
throw constants_1.ERRORS.TypedError('Transport_Missing');
|
|
36
|
+
};
|
|
37
|
+
exports.assertDeviceListConnected = assertDeviceListConnected;
|
|
14
38
|
class DeviceList extends utils_1.TypedEmitter {
|
|
15
|
-
|
|
39
|
+
isConnected() {
|
|
40
|
+
return !!this.transport;
|
|
41
|
+
}
|
|
42
|
+
pendingConnection() {
|
|
43
|
+
return this.initPromise;
|
|
44
|
+
}
|
|
45
|
+
constructor({ messages, priority, debug }) {
|
|
16
46
|
super();
|
|
17
|
-
this.transports = [];
|
|
18
47
|
this.devices = {};
|
|
19
48
|
this.creatingDevicesDescriptors = {};
|
|
20
|
-
|
|
21
|
-
this.penalizedDevices = {};
|
|
22
|
-
this.settings = settings;
|
|
23
|
-
const transports = [...(settings.transports || [])];
|
|
24
|
-
if (!transports.length) {
|
|
25
|
-
transports.push('BridgeTransport');
|
|
26
|
-
}
|
|
27
|
-
const transportLogger = (0, debug_1.initLog)('@trezor/transport', this.settings.debug);
|
|
49
|
+
const transportLogger = (0, debug_1.initLog)('@trezor/transport', debug);
|
|
28
50
|
const abortController = new AbortController();
|
|
29
|
-
|
|
51
|
+
this.authPenaltyManager = createAuthPenaltyManager(priority);
|
|
52
|
+
this.transportCommonArgs = {
|
|
30
53
|
messages,
|
|
31
54
|
logger: transportLogger,
|
|
32
55
|
signal: abortController.signal,
|
|
33
56
|
};
|
|
34
|
-
transports
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
this.transports = [
|
|
58
|
+
new transport_1.BridgeTransport({
|
|
59
|
+
latestVersion: (0, transportInfo_1.getBridgeInfo)().version.join('.'),
|
|
60
|
+
...this.transportCommonArgs,
|
|
61
|
+
}),
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
createTransport(transportType) {
|
|
65
|
+
const { transportCommonArgs } = this;
|
|
66
|
+
if (typeof transportType === 'string') {
|
|
67
|
+
switch (transportType) {
|
|
68
|
+
case 'WebUsbTransport':
|
|
69
|
+
return new transport_1.WebUsbTransport(transportCommonArgs);
|
|
70
|
+
case 'NodeUsbTransport':
|
|
71
|
+
return new transport_1.NodeUsbTransport(transportCommonArgs);
|
|
72
|
+
case 'BridgeTransport':
|
|
73
|
+
return new transport_1.BridgeTransport({
|
|
74
|
+
latestVersion: (0, transportInfo_1.getBridgeInfo)().version.join('.'),
|
|
75
|
+
...transportCommonArgs,
|
|
76
|
+
});
|
|
77
|
+
case 'UdpTransport':
|
|
78
|
+
return new transport_1.UdpTransport(transportCommonArgs);
|
|
55
79
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
80
|
+
}
|
|
81
|
+
else if (typeof transportType === 'function' && 'prototype' in transportType) {
|
|
82
|
+
const transportInstance = new transportType(transportCommonArgs);
|
|
83
|
+
if ((0, transport_1.isTransportInstance)(transportInstance)) {
|
|
84
|
+
return transportInstance;
|
|
61
85
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.transports.push(transportType);
|
|
86
|
+
}
|
|
87
|
+
else if ((0, transport_1.isTransportInstance)(transportType)) {
|
|
88
|
+
if (!transportType.getMessage()) {
|
|
89
|
+
transportType.updateMessages(transportCommonArgs.messages);
|
|
67
90
|
}
|
|
68
|
-
|
|
69
|
-
|
|
91
|
+
return transportType;
|
|
92
|
+
}
|
|
93
|
+
throw constants_1.ERRORS.TypedError('Runtime', `DeviceList.init: transports[] of unexpected type: ${transportType}`);
|
|
94
|
+
}
|
|
95
|
+
setTransports(transports) {
|
|
96
|
+
const transportTypes = (transports === null || transports === void 0 ? void 0 : transports.length) ? transports : ['BridgeTransport'];
|
|
97
|
+
this.transports = transportTypes.map(this.createTransport.bind(this));
|
|
98
|
+
}
|
|
99
|
+
onTransportUpdate(diff, transport) {
|
|
100
|
+
diff.disconnected.forEach(descriptor => {
|
|
101
|
+
const path = descriptor.path.toString();
|
|
102
|
+
const device = this.devices[path];
|
|
103
|
+
if (device) {
|
|
104
|
+
device.disconnect();
|
|
105
|
+
delete this.devices[path];
|
|
106
|
+
this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
|
|
70
107
|
}
|
|
71
108
|
});
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.transport = transport;
|
|
79
|
-
const result = await this.transport.init().promise;
|
|
80
|
-
if (result.success) {
|
|
81
|
-
lastError = undefined;
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
lastError = result.error;
|
|
86
|
-
}
|
|
109
|
+
diff.connected.forEach(async (descriptor) => {
|
|
110
|
+
const path = descriptor.path.toString();
|
|
111
|
+
this.creatingDevicesDescriptors[path] = descriptor;
|
|
112
|
+
const penalty = this.authPenaltyManager.get();
|
|
113
|
+
if (penalty) {
|
|
114
|
+
await (0, promiseUtils_1.resolveAfter)(501 + penalty, null).promise;
|
|
87
115
|
}
|
|
88
|
-
if (
|
|
89
|
-
this.
|
|
90
|
-
return;
|
|
116
|
+
if (this.creatingDevicesDescriptors[path].session == null) {
|
|
117
|
+
await this._createAndSaveDevice(descriptor, transport);
|
|
91
118
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (device) {
|
|
97
|
-
device.disconnect();
|
|
98
|
-
delete this.devices[path];
|
|
99
|
-
this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
diff.connected.forEach(async (descriptor) => {
|
|
103
|
-
const path = descriptor.path.toString();
|
|
104
|
-
this.creatingDevicesDescriptors[path] = descriptor;
|
|
105
|
-
const { priority } = this.settings;
|
|
106
|
-
const penalty = this.getAuthPenalty();
|
|
107
|
-
if (priority || penalty) {
|
|
108
|
-
await (0, promiseUtils_1.resolveAfter)(501 + penalty + 100 * priority, null).promise;
|
|
109
|
-
}
|
|
110
|
-
if (this.creatingDevicesDescriptors[path].session == null) {
|
|
111
|
-
await this._createAndSaveDevice(descriptor);
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
const device = this._createUnacquiredDevice(descriptor);
|
|
115
|
-
this.devices[path] = device;
|
|
116
|
-
this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
diff.acquiredElsewhere.forEach((descriptor) => {
|
|
120
|
-
const path = descriptor.path.toString();
|
|
121
|
-
const device = this.devices[path];
|
|
122
|
-
if (device) {
|
|
123
|
-
device.featuresNeedsReload = true;
|
|
124
|
-
device.interruptionFromOutside();
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
diff.released.forEach(descriptor => {
|
|
128
|
-
var _a;
|
|
129
|
-
const path = descriptor.path.toString();
|
|
130
|
-
const device = this.devices[path];
|
|
131
|
-
const methodStillRunning = !((_a = device === null || device === void 0 ? void 0 : device.commands) === null || _a === void 0 ? void 0 : _a.disposed);
|
|
132
|
-
if (device && methodStillRunning) {
|
|
133
|
-
device.keepSession = false;
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
diff.releasedElsewhere.forEach(async (descriptor) => {
|
|
137
|
-
const path = descriptor.path.toString();
|
|
138
|
-
const device = this.devices[path];
|
|
139
|
-
await (0, promiseUtils_1.resolveAfter)(1000, null).promise;
|
|
140
|
-
if (device) {
|
|
141
|
-
if (!device.isUsed() && device.isUnacquired() && !device.isInconsistent()) {
|
|
142
|
-
_log.debug('Create device from unacquired', device.toMessageObject());
|
|
143
|
-
await this._createAndSaveDevice(descriptor);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
const events = [
|
|
148
|
-
{
|
|
149
|
-
d: diff.changedSessions,
|
|
150
|
-
e: events_1.DEVICE.CHANGED,
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
d: diff.acquired,
|
|
154
|
-
e: events_1.DEVICE.ACQUIRED,
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
d: diff.released,
|
|
158
|
-
e: events_1.DEVICE.RELEASED,
|
|
159
|
-
},
|
|
160
|
-
];
|
|
161
|
-
events.forEach(({ d, e }) => {
|
|
162
|
-
d.forEach(descriptor => {
|
|
163
|
-
const path = descriptor.path.toString();
|
|
164
|
-
const device = this.devices[path];
|
|
165
|
-
if (device) {
|
|
166
|
-
_log.debug('Event', e, device.toMessageObject());
|
|
167
|
-
this.emit(e, device.toMessageObject());
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
diff.descriptors.forEach(d => {
|
|
172
|
-
this.creatingDevicesDescriptors[d.path] = d;
|
|
173
|
-
if (this.devices[d.path]) {
|
|
174
|
-
this.devices[d.path].originalDescriptor = {
|
|
175
|
-
session: d.session,
|
|
176
|
-
path: d.path,
|
|
177
|
-
product: d.product,
|
|
178
|
-
type: d.type,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
this.transport.on(transport_1.TRANSPORT.ERROR, error => {
|
|
184
|
-
this.emit(transport_1.TRANSPORT.ERROR, error);
|
|
185
|
-
});
|
|
186
|
-
const enumerateResult = await this.transport.enumerate().promise;
|
|
187
|
-
if (!enumerateResult.success) {
|
|
188
|
-
this.emit(transport_1.TRANSPORT.ERROR, enumerateResult.error);
|
|
189
|
-
return;
|
|
119
|
+
else {
|
|
120
|
+
const device = this._createUnacquiredDevice(descriptor, transport);
|
|
121
|
+
this.devices[path] = device;
|
|
122
|
+
this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
190
123
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}, 10000);
|
|
124
|
+
});
|
|
125
|
+
diff.acquiredElsewhere.forEach((descriptor) => {
|
|
126
|
+
const path = descriptor.path.toString();
|
|
127
|
+
const device = this.devices[path];
|
|
128
|
+
if (device) {
|
|
129
|
+
device.featuresNeedsReload = true;
|
|
130
|
+
device.interruptionFromOutside();
|
|
199
131
|
}
|
|
200
|
-
|
|
201
|
-
|
|
132
|
+
});
|
|
133
|
+
diff.released.forEach(descriptor => {
|
|
134
|
+
var _a;
|
|
135
|
+
const path = descriptor.path.toString();
|
|
136
|
+
const device = this.devices[path];
|
|
137
|
+
const methodStillRunning = !((_a = device === null || device === void 0 ? void 0 : device.commands) === null || _a === void 0 ? void 0 : _a.isDisposed());
|
|
138
|
+
if (device && methodStillRunning) {
|
|
139
|
+
device.keepSession = false;
|
|
202
140
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
141
|
+
});
|
|
142
|
+
diff.releasedElsewhere.forEach(async (descriptor) => {
|
|
143
|
+
const path = descriptor.path.toString();
|
|
144
|
+
const device = this.devices[path];
|
|
145
|
+
await (0, promiseUtils_1.resolveAfter)(1000, null).promise;
|
|
146
|
+
if (device) {
|
|
147
|
+
if (!device.isUsed() && device.isUnacquired() && !device.isInconsistent()) {
|
|
148
|
+
_log.debug('Create device from unacquired', device.toMessageObject());
|
|
149
|
+
await this._createAndSaveDevice(descriptor, transport);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const forEachDescriptor = (d, e) => {
|
|
154
|
+
d.forEach(descriptor => {
|
|
155
|
+
const path = descriptor.path.toString();
|
|
156
|
+
const device = this.devices[path];
|
|
157
|
+
if (device) {
|
|
158
|
+
_log.debug('Event', e, device.toMessageObject());
|
|
159
|
+
this.emit(e, device.toMessageObject());
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
forEachDescriptor(diff.changedSessions, events_1.DEVICE.CHANGED);
|
|
164
|
+
forEachDescriptor(diff.acquired, events_1.DEVICE.ACQUIRED);
|
|
165
|
+
forEachDescriptor(diff.released, events_1.DEVICE.RELEASED);
|
|
166
|
+
diff.descriptors.forEach(d => {
|
|
167
|
+
this.creatingDevicesDescriptors[d.path] = d;
|
|
168
|
+
if (this.devices[d.path]) {
|
|
169
|
+
this.devices[d.path].originalDescriptor = {
|
|
170
|
+
session: d.session,
|
|
171
|
+
path: d.path,
|
|
172
|
+
product: d.product,
|
|
173
|
+
type: d.type,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
});
|
|
209
177
|
}
|
|
210
|
-
|
|
211
|
-
this.
|
|
212
|
-
|
|
213
|
-
|
|
178
|
+
init(initParams = {}) {
|
|
179
|
+
if (!this.initPromise) {
|
|
180
|
+
_log.debug('Initializing transports');
|
|
181
|
+
this.initPromise = this.createInitPromise(initParams);
|
|
214
182
|
}
|
|
215
|
-
|
|
183
|
+
return this.initPromise;
|
|
184
|
+
}
|
|
185
|
+
createInitPromise(initParams) {
|
|
186
|
+
return this.selectTransport(this.transports)
|
|
187
|
+
.then(transport => this.initializeTransport(transport, initParams))
|
|
188
|
+
.then(transport => {
|
|
189
|
+
this.transport = transport;
|
|
216
190
|
this.emit(transport_1.TRANSPORT.START, this.getTransportInfo());
|
|
191
|
+
this.initPromise = undefined;
|
|
192
|
+
})
|
|
193
|
+
.catch(error => {
|
|
194
|
+
this.cleanup();
|
|
195
|
+
this.emit(transport_1.TRANSPORT.ERROR, error);
|
|
196
|
+
this.initPromise = initParams.transportReconnect
|
|
197
|
+
? this.createReconnectPromise(initParams)
|
|
198
|
+
: undefined;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
createReconnectPromise(initParams) {
|
|
202
|
+
const { promise, reject } = (0, promiseUtils_1.resolveAfter)(1000, initParams);
|
|
203
|
+
this.rejectPending = reject;
|
|
204
|
+
return promise.then(this.createInitPromise.bind(this));
|
|
205
|
+
}
|
|
206
|
+
async selectTransport([transport, ...rest]) {
|
|
207
|
+
const result = await transport.init().promise;
|
|
208
|
+
if (result.success)
|
|
209
|
+
return transport;
|
|
210
|
+
else if (rest.length)
|
|
211
|
+
return this.selectTransport(rest);
|
|
212
|
+
else
|
|
213
|
+
throw new Error(result.error);
|
|
214
|
+
}
|
|
215
|
+
async initializeTransport(transport, initParams) {
|
|
216
|
+
transport.on(transport_1.TRANSPORT.UPDATE, diff => this.onTransportUpdate(diff, transport));
|
|
217
|
+
transport.on(transport_1.TRANSPORT.ERROR, error => {
|
|
218
|
+
this.cleanup();
|
|
219
|
+
this.emit(transport_1.TRANSPORT.ERROR, error);
|
|
220
|
+
if (initParams.transportReconnect) {
|
|
221
|
+
this.initPromise = this.createReconnectPromise(initParams);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
const enumerateResult = await transport.enumerate().promise;
|
|
225
|
+
if (!enumerateResult.success) {
|
|
226
|
+
throw new Error(enumerateResult.error);
|
|
227
|
+
}
|
|
228
|
+
const descriptors = enumerateResult.payload;
|
|
229
|
+
transport.handleDescriptorsChange(descriptors);
|
|
230
|
+
transport.listen();
|
|
231
|
+
const awaitedDevices = descriptors.length - Object.keys(this.devices).length;
|
|
232
|
+
if (awaitedDevices > 0 && initParams.pendingTransportEvent) {
|
|
233
|
+
await this.waitForDevices(awaitedDevices, 10000);
|
|
217
234
|
}
|
|
235
|
+
return transport;
|
|
218
236
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
237
|
+
waitForDevices(deviceCount, autoResolveMs) {
|
|
238
|
+
const { promise, resolve, reject } = (0, utils_1.createDeferred)();
|
|
239
|
+
let transportStartPending = deviceCount;
|
|
240
|
+
const autoResolveTransportEventTimeout = setTimeout(resolve, autoResolveMs);
|
|
241
|
+
this.rejectPending = reject;
|
|
242
|
+
const onDeviceConnect = () => {
|
|
243
|
+
transportStartPending--;
|
|
244
|
+
if (transportStartPending === 0) {
|
|
224
245
|
resolve();
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
this.on(events_1.DEVICE.CONNECT, onDeviceConnect);
|
|
249
|
+
this.on(events_1.DEVICE.CONNECT_UNACQUIRED, onDeviceConnect);
|
|
250
|
+
return promise.finally(() => {
|
|
251
|
+
this.rejectPending = undefined;
|
|
252
|
+
clearTimeout(autoResolveTransportEventTimeout);
|
|
253
|
+
this.off(events_1.DEVICE.CONNECT, onDeviceConnect);
|
|
254
|
+
this.off(events_1.DEVICE.CONNECT_UNACQUIRED, onDeviceConnect);
|
|
228
255
|
});
|
|
229
|
-
await this.transportFirstEventPromise;
|
|
230
256
|
}
|
|
231
|
-
async _createAndSaveDevice(descriptor) {
|
|
257
|
+
async _createAndSaveDevice(descriptor, transport) {
|
|
232
258
|
_log.debug('Creating Device', descriptor);
|
|
233
|
-
await this.handle(descriptor);
|
|
259
|
+
await this.handle(descriptor, transport);
|
|
234
260
|
}
|
|
235
|
-
_createUnacquiredDevice(descriptor) {
|
|
261
|
+
_createUnacquiredDevice(descriptor, transport) {
|
|
236
262
|
_log.debug('Creating Unacquired Device', descriptor);
|
|
237
|
-
const device = Device_1.Device.createUnacquired(
|
|
263
|
+
const device = Device_1.Device.createUnacquired(transport, descriptor);
|
|
238
264
|
device.once(events_1.DEVICE.ACQUIRED, () => {
|
|
239
265
|
this.emit(events_1.DEVICE.CONNECT, device.toMessageObject());
|
|
240
266
|
});
|
|
241
267
|
return device;
|
|
242
268
|
}
|
|
243
|
-
_createUnreadableDevice(descriptor, unreadableError) {
|
|
269
|
+
_createUnreadableDevice(descriptor, transport, unreadableError) {
|
|
244
270
|
_log.debug('Creating Unreadable Device', descriptor, unreadableError);
|
|
245
|
-
return Device_1.Device.createUnacquired(
|
|
271
|
+
return Device_1.Device.createUnacquired(transport, descriptor, unreadableError);
|
|
246
272
|
}
|
|
247
273
|
getDevice(path) {
|
|
248
274
|
return this.devices[path];
|
|
@@ -271,20 +297,24 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
271
297
|
}
|
|
272
298
|
dispose() {
|
|
273
299
|
this.removeAllListeners();
|
|
274
|
-
|
|
275
|
-
clearTimeout(autoResolveTransportEventTimeout);
|
|
276
|
-
}
|
|
277
|
-
Promise.all(this.allDevices().map(device => device.dispose())).then(() => {
|
|
278
|
-
this.transport.stop();
|
|
279
|
-
});
|
|
300
|
+
return this.cleanup();
|
|
280
301
|
}
|
|
281
|
-
|
|
282
|
-
|
|
302
|
+
async cleanup() {
|
|
303
|
+
var _a;
|
|
304
|
+
const { transport } = this;
|
|
305
|
+
const devices = this.allDevices();
|
|
306
|
+
this.transport = undefined;
|
|
307
|
+
this.authPenaltyManager.clear();
|
|
308
|
+
Object.keys(this.devices).forEach(key => delete this.devices[key]);
|
|
309
|
+
(_a = this.rejectPending) === null || _a === void 0 ? void 0 : _a.call(this, new Error('Disposed'));
|
|
310
|
+
devices.forEach(device => {
|
|
283
311
|
this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
|
|
284
312
|
});
|
|
313
|
+
await Promise.all(devices.map(device => device.dispose()));
|
|
314
|
+
transport === null || transport === void 0 ? void 0 : transport.stop();
|
|
285
315
|
}
|
|
286
|
-
async enumerate() {
|
|
287
|
-
const res = await
|
|
316
|
+
async enumerate(transport = this.transport) {
|
|
317
|
+
const res = await transport.enumerate().promise;
|
|
288
318
|
if (!res.success) {
|
|
289
319
|
return;
|
|
290
320
|
}
|
|
@@ -301,29 +331,16 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
301
331
|
});
|
|
302
332
|
}
|
|
303
333
|
addAuthPenalty(device) {
|
|
304
|
-
|
|
305
|
-
return;
|
|
306
|
-
const deviceID = device.features.device_id;
|
|
307
|
-
const penalty = this.penalizedDevices[deviceID]
|
|
308
|
-
? this.penalizedDevices[deviceID] + 500
|
|
309
|
-
: 2000;
|
|
310
|
-
this.penalizedDevices[deviceID] = Math.min(penalty, 5000);
|
|
311
|
-
}
|
|
312
|
-
getAuthPenalty() {
|
|
313
|
-
const { penalizedDevices } = this;
|
|
314
|
-
return Object.keys(penalizedDevices).reduce((penalty, key) => Math.max(penalty, penalizedDevices[key]), 0);
|
|
334
|
+
return this.authPenaltyManager.add(device);
|
|
315
335
|
}
|
|
316
336
|
removeAuthPenalty(device) {
|
|
317
|
-
|
|
318
|
-
return;
|
|
319
|
-
const deviceID = device.features.device_id;
|
|
320
|
-
delete this.penalizedDevices[deviceID];
|
|
337
|
+
return this.authPenaltyManager.remove(device);
|
|
321
338
|
}
|
|
322
|
-
async handle(descriptor) {
|
|
339
|
+
async handle(descriptor, transport) {
|
|
323
340
|
var _a;
|
|
324
341
|
const path = descriptor.path.toString();
|
|
325
342
|
try {
|
|
326
|
-
await this._takeAndCreateDevice(descriptor);
|
|
343
|
+
await this._takeAndCreateDevice(descriptor, transport);
|
|
327
344
|
}
|
|
328
345
|
catch (error) {
|
|
329
346
|
_log.debug('Cannot create device', error);
|
|
@@ -336,37 +353,37 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
336
353
|
delete this.devices[path];
|
|
337
354
|
}
|
|
338
355
|
else if (error.message === transport_1.TRANSPORT_ERROR.SESSION_WRONG_PREVIOUS) {
|
|
339
|
-
this.enumerate();
|
|
340
|
-
this._handleUsedElsewhere(descriptor);
|
|
356
|
+
this.enumerate(transport);
|
|
357
|
+
this._handleUsedElsewhere(descriptor, transport);
|
|
341
358
|
}
|
|
342
359
|
else if (error.message === transport_1.TRANSPORT_ERROR.INTERFACE_UNABLE_TO_OPEN_DEVICE ||
|
|
343
360
|
((_a = error.message) === null || _a === void 0 ? void 0 : _a.indexOf(constants_1.ERRORS.LIBUSB_ERROR_MESSAGE)) >= 0 ||
|
|
344
361
|
error.code === 'Device_InitializeFailed') {
|
|
345
|
-
const device = this._createUnreadableDevice(this.creatingDevicesDescriptors[path], error.message);
|
|
362
|
+
const device = this._createUnreadableDevice(this.creatingDevicesDescriptors[path], transport, error.message);
|
|
346
363
|
this.devices[path] = device;
|
|
347
364
|
this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
348
365
|
}
|
|
349
366
|
else if (error.code === 'Device_UsedElsewhere') {
|
|
350
|
-
this._handleUsedElsewhere(descriptor);
|
|
367
|
+
this._handleUsedElsewhere(descriptor, transport);
|
|
351
368
|
}
|
|
352
369
|
else {
|
|
353
370
|
await (0, promiseUtils_1.resolveAfter)(501, null).promise;
|
|
354
|
-
await this.handle(descriptor);
|
|
371
|
+
await this.handle(descriptor, transport);
|
|
355
372
|
}
|
|
356
373
|
}
|
|
357
374
|
delete this.creatingDevicesDescriptors[path];
|
|
358
375
|
}
|
|
359
|
-
async _takeAndCreateDevice(descriptor) {
|
|
360
|
-
const device = Device_1.Device.fromDescriptor(
|
|
376
|
+
async _takeAndCreateDevice(descriptor, transport) {
|
|
377
|
+
const device = Device_1.Device.fromDescriptor(transport, descriptor);
|
|
361
378
|
const path = descriptor.path.toString();
|
|
362
379
|
this.devices[path] = device;
|
|
363
380
|
const promise = device.run();
|
|
364
381
|
await promise;
|
|
365
382
|
this.emit(events_1.DEVICE.CONNECT, device.toMessageObject());
|
|
366
383
|
}
|
|
367
|
-
_handleUsedElsewhere(descriptor) {
|
|
384
|
+
_handleUsedElsewhere(descriptor, transport) {
|
|
368
385
|
const path = descriptor.path.toString();
|
|
369
|
-
const device = this._createUnacquiredDevice(this.creatingDevicesDescriptors[path]);
|
|
386
|
+
const device = this._createUnacquiredDevice(this.creatingDevicesDescriptors[path], transport);
|
|
370
387
|
this.devices[path] = device;
|
|
371
388
|
this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
372
389
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { VersionArray } from '../exports';
|
|
2
|
+
type calculateRevisionForDeviceParams = {
|
|
3
|
+
commitRevision: string;
|
|
4
|
+
version: VersionArray;
|
|
5
|
+
};
|
|
6
|
+
export declare const calculateRevisionForDevice: ({ commitRevision, version, }: calculateRevisionForDeviceParams) => string;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=calculateRevisionForDevice.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateRevisionForDevice = void 0;
|
|
4
|
+
const versionUtils_1 = require("@trezor/utils/lib/versionUtils");
|
|
5
|
+
const calculateRevisionForDevice = ({ commitRevision, version, }) => {
|
|
6
|
+
if ((0, versionUtils_1.isNewer)(version, '2.4.0')) {
|
|
7
|
+
return commitRevision;
|
|
8
|
+
}
|
|
9
|
+
if ((0, versionUtils_1.isNewer)(version, '2.2.0')) {
|
|
10
|
+
return commitRevision.slice(0, 9);
|
|
11
|
+
}
|
|
12
|
+
if ((0, versionUtils_1.isNewer)(version, '2.1.8')) {
|
|
13
|
+
return commitRevision;
|
|
14
|
+
}
|
|
15
|
+
if ((0, versionUtils_1.isNewer)(version, '2.0.0')) {
|
|
16
|
+
return commitRevision.slice(0, 8);
|
|
17
|
+
}
|
|
18
|
+
return commitRevision;
|
|
19
|
+
};
|
|
20
|
+
exports.calculateRevisionForDevice = calculateRevisionForDevice;
|
|
21
|
+
//# sourceMappingURL=calculateRevisionForDevice.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PROTO } from '../constants';
|
|
2
|
+
import { VersionArray } from '../types';
|
|
3
|
+
import { FirmwareRevisionCheckResult } from '../types/device';
|
|
4
|
+
export type CheckFirmwareRevisionParams = {
|
|
5
|
+
firmwareVersion: VersionArray;
|
|
6
|
+
internalModel: PROTO.DeviceModelInternal;
|
|
7
|
+
deviceRevision: string | null;
|
|
8
|
+
expectedRevision: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare const checkFirmwareRevision: ({ firmwareVersion, internalModel, deviceRevision, expectedRevision, }: CheckFirmwareRevisionParams) => Promise<FirmwareRevisionCheckResult>;
|
|
11
|
+
//# sourceMappingURL=checkFirmwareRevision.d.ts.map
|